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

Last change on this file since 435 was 435, checked in by dai_9181, 16 years ago

関数の戻り値の構造体など、一時メモリに保持された構造体のメンバに直接アクセスした場合、その一時メモリの解放が正常に行われないバグを修正(まずは32bit版のみ)

File size: 9.3 KB
RevLine 
[239]1#include "stdafx.h"
2
3#include <CodeGenerator.h>
4
5
[247]6void CodeGenerator::ResolveExitSubSchedule()
7{
8 BOOST_FOREACH( long exitSubCodePosition, exitSubCodePositions )
9 {
10 pNativeCode->Overwrite( exitSubCodePosition, (long)( pNativeCode->GetSize()-(exitSubCodePosition+sizeof(long)) ) );
11 }
12}
13
[239]14void CodeGenerator::CheckUnresolveSchedule()
15{
16 if( pertialSchedules.size() > 0 )
17 {
18 SetError();
19 }
20}
21
[357]22void CodeGenerator::opfix( const PertialSchedule *pPertialSchedule, _int64 newValue )
[251]23{
24 bool isSuccessful = false;
[239]25
[251]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 {
[357]43 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), static_cast<long>(newValue) );
44 }
45 else if( pPertialSchedule->GetTypeSize() == sizeof(_int64) )
46 {
[251]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;
[253]58 break;
[251]59 }
60 else
61 {
62 it++;
63 }
64 }
65
66 if( isSuccessful == false )
67 {
68 SetError();
69 }
70}
71
[253]72void CodeGenerator::opfix_offset( const PertialSchedule *pPertialSchedule, long offset )
73{
74 bool isSuccessful = false;
[251]75
[253]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
[239]112// 分岐関連
113void CodeGenerator::opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule )
114{
115 bool isSuccessful = false;
116
[248]117 PertialSchedules::iterator it = pertialSchedules.begin();
[239]118 while( it != pertialSchedules.end() )
119 {
120 if( (*it) == pPertialSchedule )
121 {
[241]122 long newValue = pNativeCode->GetSize() - (pPertialSchedule->GetCodePos()+pPertialSchedule->GetTypeSize());
123
[239]124 if( pPertialSchedule->GetTypeSize() == sizeof(char) )
125 {
[241]126 if( newValue < -128 || 127 < newValue )
127 {
128 // 範囲外
129 SetError();
130 }
[239]131
[241]132 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), (char)newValue );
[239]133 }
[241]134 else if( pPertialSchedule->GetTypeSize() == sizeof(long) )
135 {
136 pNativeCode->Overwrite( pPertialSchedule->GetCodePos(), newValue );
137 }
[239]138 else
139 {
140 SetError();
141 }
142
[245]143 it = pertialSchedules.erase( it );
[239]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}
[248]159const PertialSchedule *CodeGenerator::__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]160{
[241]161 long beginCodePos = pNativeCode->GetSize();
[239]162
[241]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
[245]196 const PertialSchedule *pPertialSchedule = NULL;
[239]197 if( isPertialSchedule )
198 {
199 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), op_size ) );
[251]200 pPertialSchedule = pertialSchedules.back();
[239]201 }
202
[241]203 if( isSelfOpcodeOffset )
204 {
205 // 自分自身の命令サイズを考慮する場合
[276]206 offset -= ( pNativeCode->GetSize() - beginCodePos ) + op_size;
[241]207 }
208
[239]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}
[250]224const PertialSchedule *CodeGenerator::op_jle( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]225{
[250]226 return __jmp_op_format( (char)0x0E, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]227}
[250]228const PertialSchedule *CodeGenerator::op_jbe( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]229{
[250]230 return __jmp_op_format( (char)0x06, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]231}
[250]232const PertialSchedule *CodeGenerator::op_jge( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]233{
[250]234 return __jmp_op_format( (char)0x0D, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]235}
[250]236const PertialSchedule *CodeGenerator::op_jae( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]237{
[250]238 return __jmp_op_format( (char)0x03, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]239}
[250]240const PertialSchedule *CodeGenerator::op_jl( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]241{
[250]242 return __jmp_op_format( (char)0x0C, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]243}
[250]244const PertialSchedule *CodeGenerator::op_jb( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]245{
[250]246 return __jmp_op_format( (char)0x02, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]247}
[250]248const PertialSchedule *CodeGenerator::op_jg( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]249{
[250]250 return __jmp_op_format( (char)0x0F, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]251}
[250]252const PertialSchedule *CodeGenerator::op_ja( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]253{
[250]254 return __jmp_op_format( (char)0x07, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]255}
[250]256const PertialSchedule *CodeGenerator::op_jne( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]257{
[250]258 return __jmp_op_format( (char)0x05, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]259}
[250]260const PertialSchedule *CodeGenerator::op_je( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]261{
[250]262 return __jmp_op_format( (char)0x04, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]263}
[248]264const PertialSchedule *CodeGenerator::op_jmp( long offset, int op_size, bool isPertialSchedule, bool isSelfOpcodeOffset )
[239]265{
[241]266 return __jmp_op_format( (char)0xEB, offset, op_size, isPertialSchedule, isSelfOpcodeOffset );
[239]267}
[241]268void CodeGenerator::op_jmp_continue()
269{
[254]270 if( GetContinueCodePos() == -1 )
[241]271 {
272 SetError(12,"Continue",cp);
273 return;
274 }
[254]275 op_jmp( GetContinueCodePos() - pNativeCode->GetSize(), sizeof(long), false, true );
[241]276}
[247]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}
[253]286void CodeGenerator::op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos )
[246]287{
288 // オペコード
289 pNativeCode->Put( (char)0xE9 );
290
[253]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 );
[246]301
[253]302 pertialSchedules.push_back( pGotoLabelSchedule );
303
[246]304 pNativeCode->Put( (long)0 );
305}
[435]306
307void CodeGenerator::op_AddNeedFreeTempStructure( int reg )
308{
309#ifdef _AMD64_
310 //////////////////////////////////////////////////////
311 ///// レジスタ資源のバックアップ
312 { BACKUP_REGISTER_RESOURCE
313 //////////////////////////////////////////////////////
314
315 //mov rcx,reg
316 compiler.codeGenerator.op_mov_RR( REG_RCX, reg );
317
318 //call _System_AddNeedFreeTempStructure
319 extern const UserProc *pSub_System_AddNeedFreeTempStructure;
320 compiler.codeGenerator.op_call( pSub_System_AddNeedFreeTempStructure );
321
322 /////////////////////////////////////////////
323 ////// レジスタ資源を復元
324 RESTORE_REGISTER_RESOURCE
325 }////////////////////////////////////////////
326#else
327
328 //push useReg(引き続き利用するため、退避しておく)
329 compiler.codeGenerator.op_push( reg );
330
331 //push useReg
332 compiler.codeGenerator.op_push( reg );
333
334 //call _System_AddNeedFreeTempStructure
335 extern const UserProc *pSub_System_AddNeedFreeTempStructure;
336 compiler.codeGenerator.op_call( pSub_System_AddNeedFreeTempStructure );
337
338 //pop useReg(復元する)
339 compiler.codeGenerator.op_pop( reg );
340#endif
341
342 isNeedFreeTempStructureInCurrentStep = true;
343}
344void CodeGenerator::op_FreeTempStructure()
345{
346 if( !isNeedFreeTempStructureInCurrentStep )
347 {
348 // 解放の必要はない
349 return;
350 }
351
352 // call _System_FreeTempStructure
353 extern const UserProc *pSub_System_FreeTempStructure;
354 op_call( pSub_System_FreeTempStructure );
355
356 isNeedFreeTempStructureInCurrentStep = false;
357}
Note: See TracBrowser for help on using the repository browser.