source: dev/trunk/abdev/BasicCompiler_Common/src/CommonCodeGenerator.cpp@ 422

Last change on this file since 422 was 357, checked in by dai_9181, 17 years ago

例外処理機構実装中...

File size: 7.8 KB
Line 
1#include "stdafx.h"
2
3#include <CodeGenerator.h>
4
5
6void CodeGenerator::ResolveExitSubSchedule()
7{
8 BOOST_FOREACH( long exitSubCodePosition, exitSubCodePositions )
9 {
10 pNativeCode->Overwrite( exitSubCodePosition, (long)( pNativeCode->GetSize()-(exitSubCodePosition+sizeof(long)) ) );
11 }
12}
13
14void CodeGenerator::CheckUnresolveSchedule()
15{
16 if( pertialSchedules.size() > 0 )
17 {
18 SetError();
19 }
20}
21
22void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, _int64 newValue )
23{
24 bool isSuccessful = false;
25
26 PertialSchedules::iterator it = pertialSchedules.begin();
27 while( it != pertialSchedules.end() )
28 {
29 if( (*it) == pPertialSchedule )
30 {
31 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
32 {
33 if( newValue < -128 || 127 < newValue )
34 {
35 // 範囲外
36 SetError();
37 }
38
39 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
40 }
41 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
42 {
43 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), static_cast<long>(newValue) );
44 }
45 else if( pPertialSchedule->GetTypeSize() == sizeof(_int64) )
46 {
47 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
48 }
49 else
50 {
51 SetError();
52 }
53
54 it = pertialSchedules.erase( it );
55 delete pPertialSchedule;
56
57 isSuccessful = true;
58 break;
59 }
60 else
61 {
62 it++;
63 }
64 }
65
66 if( isSuccessful == false )
67 {
68 SetError();
69 }
70}
71
72void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset )
73{
74 bool isSuccessful = false;
75
76 PertialSchedules::iterator it = pertialSchedules.begin();
77 while( it != pertialSchedules.end() )
78 {
79 if( (*it) == pPertialSchedule )
80 {
81 if( pPertialSchedule->GetTypeSize() == sizeof(long) )
82 {
83 pNativeCode->Overwrite(
84 pPertialSchedule->GetCodePos(),
85 pNativeCode->GetLong(pPertialSchedule->GetCodePos()) + offset
86 );
87 }
88 else
89 {
90 SetError();
91 }
92
93 it = pertialSchedules.erase( it );
94 delete pPertialSchedule;
95
96 isSuccessful = true;
97 break;
98 }
99 else
100 {
101 it++;
102 }
103 }
104
105 if( isSuccessful == false )
106 {
107 SetError();
108 }
109}
110
111
112// 分岐関連
113void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
114{
115 bool isSuccessful = false;
116
117 PertialSchedules::iterator it = pertialSchedules.begin();
118 while( it != pertialSchedules.end() )
119 {
120 if( (*it) == pPertialSchedule )
121 {
122 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
123
124 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
125 {
126 if( newValue < -128 || 127 < newValue )
127 {
128 // 範囲外
129 SetError();
130 }
131
132 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
133 }
134 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
135 {
136 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
137 }
138 else
139 {
140 SetError();
141 }
142
143 it = pertialSchedules.erase( it );
144 delete pPertialSchedule;
145
146 isSuccessful = true;
147 }
148 else
149 {
150 it++;
151 }
152 }
153
154 if( isSuccessful == false )
155 {
156 SetError();
157 }
158}
159const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
160{
161 long beginCodePos = pNativeCode->GetSize();
162
163 if( opcode == (char)0xEB )
164 {
165 // jmp命令のとき
166 if( op_size == sizeof(char) )
167 {
168 pNativeCode->Put( (char)opcode );
169 }
170 else if( op_size == sizeof(long) )
171 {
172 pNativeCode->Put( (char)0xE9 );
173 }
174 else
175 {
176 SetError();
177 }
178 }
179 else
180 {
181 if( op_size == sizeof(char) )
182 {
183 pNativeCode->Put( (char)((char)0x70 | opcode) );
184 }
185 else if( op_size == sizeof(long) )
186 {
187 pNativeCode->Put( (char)0x0F );
188 pNativeCode->Put( (char)((char)0x80 | opcode) );
189 }
190 else
191 {
192 SetError();
193 }
194 }
195
196 const PertialSchedule *pPertialSchedule = NULL;
197 if( isPertialSchedule )
198 {
199 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
200 pPertialSchedule = pertialSchedules.back();
201 }
202
203 if( isSelfOpcodeOffset )
204 {
205 // 自分自身の命令サイズを考慮する場合
206 offset -= ( pNativeCode->GetSize() - beginCodePos ) + op_size;
207 }
208
209 if( op_size == sizeof(char) )
210 {
211 pNativeCode->Put( (char)offset );
212 }
213 else if( op_size == sizeof(long) )
214 {
215 pNativeCode->Put( offset );
216 }
217 else
218 {
219 SetError();
220 }
221
222 return pPertialSchedule;
223}
224const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
225{
226 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
227}
228const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
229{
230 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
231}
232const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
233{
234 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
235}
236const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
237{
238 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
239}
240const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
241{
242 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
243}
244const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
245{
246 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
247}
248const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
249{
250 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
251}
252const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
253{
254 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
255}
256const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
257{
258 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
259}
260const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
261{
262 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
263}
264const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
265{
266 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
267}
268void CodeGenerator::op_jmp_continue()
269{
270 if( GetContinueCodePos() == -1 )
271 {
272 SetError(12,"Continue",cp);
273 return;
274 }
275 op_jmp( GetContinueCodePos() - pNativeCode->GetSize(), sizeof(long), false, true );
276}
277void CodeGenerator::op_jmp_exitsub()
278{
279 // オペコード
280 pNativeCode->Put( (char)0xE9 );
281
282 exitSubCodePositions.push_back( pNativeCode->GetSize() );
283
284 pNativeCode->Put( (long)0 );
285}
286void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
287{
288 // オペコード
289 pNativeCode->Put( (char)0xE9 );
290
291 const GotoLabelSchedule *pGotoLabelSchedule = NULL;
292 if( name.size() == 0 )
293 {
294 pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos );
295 }
296 else
297 {
298 pGotoLabelSchedule = new GotoLabelSchedule( name, pNativeCode->GetSize(), sourceCodePos );
299 }
300 gotoLabelSchedules.push_back( pGotoLabelSchedule );
301
302 pertialSchedules.push_back( pGotoLabelSchedule );
303
304 pNativeCode->Put( (long)0 );
305}
Note: See TracBrowser for help on using the repository browser.