source: dev/trunk/abdev/BasicCompiler32/Compile_ProcOp.cpp@ 183

Last change on this file since 183 was 183, checked in by dai_9181, 17 years ago
File size: 26.8 KB
RevLine 
[183]1#include <jenga/include/smoothie/Smoothie.h>
2#include <jenga/include/smoothie/LexicalAnalysis.h>
3
4#include <Program.h>
5#include <LexicalScopingImpl.h>
6#include <ClassImpl.h>
7
[3]8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
11
[86]12void SystemProc( const UserProc &userProc ){
13 if( userProc.GetName() == "_System_GetEip" ){
[3]14 //mov eax,dword ptr[esp]
15 OpBuffer[obp++]=(char)0x8B;
16 OpBuffer[obp++]=(char)0x04;
17 OpBuffer[obp++]=(char)0x24;
18
19 //ret
[142]20 op_ret();
[3]21 }
[86]22 else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){
[3]23 ////////////////////////////////////////
24 // DLLのグローバル領域をコンパイル
25 ////////////////////////////////////////
26
27 extern BOOL bDll;
28 if(!bDll){
29 //ret
[142]30 op_ret();
[3]31
32 return;
33 }
34
[76]35 UserProc *pBackUserProc;
36 pBackUserProc = &UserProc::CompilingUserProc();
37 UserProc::CompileStartForGlobalArea();
[3]38
39 int BackCp;
40 BackCp=cp;
41 cp=-1;
42
43 extern BOOL bDebugCompile;
44 if(bDebugCompile){
45 //デバッグ用の変数を定義
46 DebugVariable();
47 }
48
49 //GC用の変数を定義
50 InitGCVariables();
51
[129]52 //_System_StartupProgramの呼び出し
53 extern UserProc *pSub_System_StartupProgram;
54 op_call(pSub_System_StartupProgram);
55
[42]56 //クラスに属する静的メンバを定義
[183]57 Smoothie::GetMeta().GetClasses().InitStaticMember();
[42]58
[3]59 GetGlobalDataForDll();
60
[76]61 UserProc::CompileStartForUserProc( pBackUserProc );
[3]62 cp=BackCp;
63
64 //ret
[142]65 op_ret();
[3]66 }
[86]67 else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
[3]68 //静的ローカルオブジェクトのコンストラクタ呼び出し
69
[183]70 BOOST_FOREACH( Variable *pVar, globalVars ){
[76]71 if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){
[3]72 //コンストラクタ呼び出し
[76]73 if( pVar->IsObject() ){
[3]74
75 //エラー用
[76]76 cp=pVar->source_code_address;
[3]77
[50]78 CallConstructor(
[76]79 pVar->GetName().c_str(),
80 pVar->GetSubScriptsPtr(),
81 *pVar,
82 pVar->paramStrForConstructor.c_str());
[3]83 }
84 }
85 }
86
87 //ret
[142]88 op_ret();
[3]89 }
[86]90 else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){
[3]91
[76]92 UserProc *pBackUserProc;
93 pBackUserProc = &UserProc::CompilingUserProc();
94 UserProc::CompileStartForGlobalArea();
[3]95
[183]96 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]97
[76]98 UserProc::CompileStartForUserProc( pBackUserProc );
[3]99
100
101 //ret
[142]102 op_ret();
[3]103 }
[86]104 else if( userProc.GetName() == "_System_GetSp" ){
[3]105 //mov eax,esp
106 op_mov_RR(REG_EAX,REG_ESP);
107
108 //add eax,PTR_SIZE
109 op_add_RV8(REG_EAX,PTR_SIZE);
110
111 //ret
[142]112 op_ret();
[3]113 }
[86]114 else if( userProc.GetName() == "_allrem" ){
[3]115 //乗除演算用の特殊関数(64ビット整数対応)
116 BYTE Buffer_allrem[]={
117 0x53,0x57,0x33,0xFF,0x8B,0x44,0x24,0x10,0x0B,0xC0,0x7D,0x14,0x47,0x8B,0x54,0x24,0x0C,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x10,0x89,0x54,0x24,0x0C,0x8B,0x44,0x24,0x18,0x0B,0xC0,0x7D,0x13,0x8B,0x54,0x24,0x14,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x18,0x89,0x54,0x24,0x14,0x0B,0xC0,0x75,0x1B,0x8B,0x4C,0x24,0x14,0x8B,0x44,0x24,0x10,0x33,0xD2,0xF7,0xF1,0x8B,0x44,0x24,0x0C,0xF7,0xF1,0x8B,0xC2,0x33,0xD2,0x4F,0x79,0x4E,0xEB,0x53,0x8B,0xD8,0x8B,0x4C,0x24,0x14,0x8B,0x54,0x24,0x10,0x8B,0x44,0x24,0x0C,0xD1,0xEB,0xD1,0xD9,0xD1,0xEA,0xD1,0xD8,0x0B,0xDB,0x75,0xF4,0xF7,0xF1,0x8B,0xC8,0xF7,0x64,0x24,0x18,0x91,0xF7,0x64,0x24,0x14,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x10,0x77,0x08,0x72,0x0E,0x3B,0x44,0x24,0x0C,0x76,0x08,0x2B,0x44,0x24,0x14,0x1B,0x54,0x24,0x18,0x2B,0x44,0x24,0x0C,0x1B,0x54,0x24,0x10,0x4F,0x79,0x07,0xF7,0xDA,0xF7,0xD8,0x83,0xDA,0x00,0x5F,0x5B,0xC2,0x10,0x00
118 };
119
120 memcpy(OpBuffer+obp,Buffer_allrem,178);
121 obp+=178;
122 }
[86]123 else if( userProc.GetName() == "_aullrem" ){
[3]124 //乗除演算用の特殊関数(64ビット整数対応)
125 BYTE Buffer_aullrem[]={
126 0x53,0x8B,0x44,0x24,0x14,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x10,0x8B,
127 0x44,0x24,0x0C,0x33,0xD2,0xF7,0xF1,0x8B,0x44,0x24,0x08,0xF7,0xF1,0x8B,
128 0xC2,0x33,0xD2,0xEB,0x50,0x8B,0xC8,0x8B,0x5C,0x24,0x10,0x8B,0x54,0x24,
129 0x0C,0x8B,0x44,0x24,0x08,0xD1,0xE9,0xD1,0xDB,0xD1,0xEA,0xD1,0xD8,0x0B,
130 0xC9,0x75,0xF4,0xF7,0xF3,0x8B,0xC8,0xF7,0x64,0x24,0x14,0x91,0xF7,0x64,
131 0x24,0x10,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x0C,0x77,0x08,0x72,0x0E,
132 0x3B,0x44,0x24,0x08,0x76,0x08,0x2B,0x44,0x24,0x10,0x1B,0x54,0x24,0x14,
133 0x2B,0x44,0x24,0x08,0x1B,0x54,0x24,0x0C,0xF7,0xDA,0xF7,0xD8,0x83,0xDA,
134 0x00,0x5B,0xC2,0x10,0x00
135 };
136
137 memcpy(OpBuffer+obp,Buffer_aullrem,117);
138 obp+=117;
139 }
[86]140 else if( userProc.GetName() == "_allmul" ){
[3]141 //乗算用の特殊関数(64ビット整数対応)
142 BYTE Buffer_allmul[]={
143 0x8B,0x44,0x24,0x08,0x8B,0x4C,0x24,0x10,0x0B,0xC8,0x8B,0x4C,0x24,0x0C,0x75,0x09,0x8B,0x44,0x24,0x04,0xF7,0xE1,0xC2,0x10,0x00,0x53,0xF7,0xE1,0x8B,0xD8,0x8B,0x44,0x24,0x08,0xF7,0x64,0x24,0x14,0x03,0xD8,0x8B,0x44,0x24,0x08,0xF7,0xE1,0x03,0xD3,0x5B,0xC2,0x10,0x00
144 };
145
146 memcpy(OpBuffer+obp,Buffer_allmul,52);
147 obp+=52;
148 }
[86]149 else if( userProc.GetName() == "_alldiv" ){
[3]150 //除算用の特殊関数(64ビット整数対応)
151 BYTE Buffer_alldiv[]={
152 0x57,0x56,0x53,0x33,0xFF,0x8B,0x44,0x24,0x14,0x0B,0xC0,0x7D,0x14,0x47,0x8B,0x54,0x24,0x10,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x14,0x89,0x54,0x24,0x10,0x8B,0x44,0x24,0x1C,0x0B,0xC0,0x7D,0x14,0x47,0x8B,0x54,0x24,0x18,0xF7,0xD8,0xF7,0xDA,0x83,0xD8,0x00,0x89,0x44,0x24,0x1C,0x89,0x54,0x24,0x18,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x18,0x8B,0x44,0x24,0x14,0x33,0xD2,0xF7,0xF1,0x8B,0xD8,0x8B,0x44,0x24,0x10,0xF7,0xF1,0x8B,0xD3,0xEB,0x41,0x8B,0xD8,0x8B,0x4C,0x24,0x18,0x8B,0x54,0x24,0x14,0x8B,0x44,0x24,0x10,0xD1,0xEB,0xD1,0xD9,0xD1,0xEA,0xD1,0xD8,0x0B,0xDB,0x75,0xF4,0xF7,0xF1,0x8B,0xF0,0xF7,0x64,0x24,0x1C,0x8B,0xC8,0x8B,0x44,0x24,0x18,0xF7,0xE6,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x14,0x77,0x08,0x72,0x07,0x3B,0x44,0x24,0x10,0x76,0x01,0x4E,0x33,0xD2,0x8B,0xC6,0x4F,0x75,0x07,0xF7,0xDA,0xF7,0xD8,0x83,0xDA,0x00,0x5B,0x5E,0x5F,0xC2,0x10,0x00
153 };
154
155 memcpy(OpBuffer+obp,Buffer_alldiv,170);
156 obp+=170;
157 }
[86]158 else if( userProc.GetName() == "_aulldiv" ){
[3]159 //整数除算用の特殊関数(64ビット整数対応)
160 BYTE Buffer_aulldiv[]={
161 0x53,0x56,0x8B,0x44,0x24,0x18,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x14,
162 0x8B,0x44,0x24,0x10,0x33,0xD2,0xF7,0xF1,0x8B,0xD8,0x8B,0x44,0x24,0x0C,
163 0xF7,0xF1,0x8B,0xD3,0xEB,0x41,0x8B,0xC8,0x8B,0x5C,0x24,0x14,0x8B,0x54,
164 0x24,0x10,0x8B,0x44,0x24,0x0C,0xD1,0xE9,0xD1,0xDB,0xD1,0xEA,0xD1,0xD8,
165 0x0B,0xC9,0x75,0xF4,0xF7,0xF3,0x8B,0xF0,0xF7,0x64,0x24,0x18,0x8B,0xC8,
166 0x8B,0x44,0x24,0x14,0xF7,0xE6,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x10,
167 0x77,0x08,0x72,0x07,0x3B,0x44,0x24,0x0C,0x76,0x01,0x4E,0x33,0xD2,0x8B,
168 0xC6,0x5E,0x5B,0xC2,0x10,0x00
169 };
170
171 memcpy(OpBuffer+obp,Buffer_aulldiv,104);
172 obp+=104;
173 }
[86]174 else if( userProc.GetName() == "_allshl" ){
[3]175 //符号あり左ビットシフト用の特殊関数(64ビット整数対応)
176 BYTE Buffer_allshl[]={
177 0x80,0xF9,0x40,0x73,0x15,0x80,0xF9,0x20,0x73,0x06,0x0F,0xA5,0xC2,0xD3,0xE0,0xC3,0x8B,0xD0,0x33,0xC0,0x80,0xE1,0x1F,0xD3,0xE2,0xC3,0x33,0xC0,0x33,0xD2,0xC3
178 };
179
180 memcpy(OpBuffer+obp,Buffer_allshl,31);
181 obp+=31;
182 }
[86]183 else if( userProc.GetName() == "_allshr" ){
[3]184 //符号あり右ビットシフト用の特殊関数(64ビット整数対応)
185 BYTE Buffer_allshr[]={
186 0x80,0xF9,0x40,0x73,0x16,0x80,0xF9,0x20,0x73,0x06,0x0F,0xAD,0xD0,0xD3,0xFA,0xC3,0x8B,0xC2,0xC1,0xFA,0x1F,0x80,0xE1,0x1F,0xD3,0xF8,0xC3,0xC1,0xFA,0x1F,0x8B,0xC2,0xC3
187 };
188
189 memcpy(OpBuffer+obp,Buffer_allshr,33);
190 obp+=33;
191 }
[86]192 else if( userProc.GetName() == "_aullshr" ){
[3]193 //符号なし右ビットシフト用の特殊関数(64ビット整数対応)
194 BYTE Buffer_aullshr[]={
195 0x80,0xF9,0x40, //cmp cl,40h
196 0x73,0x15, //jae RETZERO (0040d71a)
197 0x80,0xF9,0x20, //cmp cl,20h
198 0x73,0x06, //jae MORE32 (0040d710)
199 0x0F,0xAD,0xD0, //shrd eax,edx,cl
200 0xD3,0xEA, //shr edx,cl
201 0xC3, //ret
202 //MORE32:
203 0x8B,0xC2, //mov eax,edx
204 0x33,0xD2, //xor edx,edx
205 0x80,0xE1,0x1F, //and cl,1Fh
206 0xD3,0xE8, //shr eax,cl
207 0xC3, //ret
208 //RETZERO:
209 0x33,0xC0, //xor eax,eax
210 0x33,0xD2, //xor edx,edx
211 0xC3 //ret
212 };
213
214 memcpy(OpBuffer+obp,Buffer_aullshr,31);
215 obp+=31;
216 }
[90]217 else{
218 SetError();
219 }
220}
221void AutoGeneration(UserProc &userProc){
222 if( userProc.GetName() == "InitializeUserTypes"
[89]223 && userProc.HasParentClass()
[131]224 && userProc.GetParentClass().GetName() == "_System_TypeBase" ){
[89]225
[183]226 Smoothie::GetMeta().GetClasses().Compile_System_InitializeUserTypes();
[86]227 }
[95]228 else if( userProc.GetName() == "RegisterGlobalRoots"
229 && userProc.HasParentClass()
[131]230 && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" ){
[95]231
232 Compile_AddGlobalRootsForGc();
233 }
[78]234 else{
235 SetError();
236 }
[3]237}
238
[91]239void _compile_proc(UserProc *pUserProc){
[3]240 extern char *basbuf;
241 extern HANDLE hHeap;
[100]242 extern GlobalProc **ppSubHash;
[3]243 extern BOOL bDebugCompile;
[76]244 int i3,i4,LocalVarSchedule,EspOffsetSchedule,BaseOffset;
[3]245 char temporary[VN_SIZE];
246
[75]247 if( pUserProc->IsUsing() == false || pUserProc->IsCompiled() ) return;
[3]248
[76]249 if( pUserProc->localVars.size() ){
250 SetError();
251 return;
252 }
253
[75]254 pUserProc->CompleteCompile();
[3]255
256 extern BOOL bSystemProc;
[75]257 if(memcmp(pUserProc->GetName().c_str(),"_System_",8)==0) bSystemProc=1;
[3]258 else bSystemProc=0;
259
260 extern BOOL bDebugSupportProc;
[75]261 if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0){
[3]262 if(!bDebugCompile){
263 return;
264 }
265 bDebugSupportProc=1;
266 }
267 else bDebugSupportProc=0;
268
[75]269 pUserProc->beginOpAddress=obp;
[3]270
[89]271 //コンパイル中の関数が属するクラス
[183]272 Smoothie::Temp::pCompilingClass=pUserProc->GetParentClassPtr();
[89]273
274 //コンパイルスタートをクラス管理クラスに追加
[183]275 Smoothie::GetMeta().GetClasses().StartCompile( pUserProc );
[89]276
277 //コンパイル中の関数
278 UserProc::CompileStartForUserProc( pUserProc );
279
[101]280 // コンパイル中の関数が属する名前空間
[183]281 Smoothie::Temp::liveingNamespaceScopes = pUserProc->GetNamespaceScopes();
[101]282
[108]283 // コンパイル中の関数でImportsされている名前空間
[143]284 Smoothie::Temp::importedNamespaces = pUserProc->GetImportedNamespaces();
[108]285
[75]286 if(pUserProc->IsSystem()){
[89]287 ////////////////////
288 // 特殊関数
289 ////////////////////
290
[3]291 extern int AllLocalVarSize;
292 AllLocalVarSize=0;
293
[86]294 SystemProc(*pUserProc);
[3]295
[75]296 pUserProc->endOpAddress=obp;
[3]297 return;
298 }
299
[75]300 cp=pUserProc->GetCodePos();
[3]301 for(;;cp++){
302 if(IsCommandDelimitation(basbuf[cp])) break;
303 }
304 cp--;
305
306 //ローカル変数に関する情報
307 extern int AllLocalVarSize;
308 AllLocalVarSize=0;
309
310 //ローカル変数アドレススケジュール
311 extern DWORD *pLocalVarAddrSchedule;
312 extern int LocalVarAddrScheduleNum;
313 pLocalVarAddrSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
314 LocalVarAddrScheduleNum=0;
315
316 //パラメータ用の変数データを考慮
[75]317 for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
318 Parameter &param = *pUserProc->RealParams()[i3];
[73]319
[76]320 Variable *pVar = new Variable( param.GetVarName(), param, false, param.IsRef() );
[3]321
[76]322 if( param.IsArray() ){
323 pVar->SetArray( param.GetSubScriptsPtr() );
[3]324 }
325
[76]326 int varSize;
[73]327 if( param.IsRef() == false && param.IsStruct() ){
[64]328 //構造体のByValパラメータ
[76]329 pVar->ThisIsParameter();
330 varSize=PTR_SIZE;
[3]331 }
332 else{
[76]333 if( param.IsArray() == false ){
334 varSize = pVar->GetMemorySize();
[3]335 }
336 else{
[76]337 varSize=PTR_SIZE;
[3]338 }
339 }
[76]340 AllLocalVarSize+=varSize;
341 pVar->offset=AllLocalVarSize;
[3]342
343 //レキシカルスコープ情報
[183]344 pVar->ScopeLevel=GetLexicalScopes().GetNowLevel();
345 pVar->ScopeStartAddress=GetLexicalScopes().GetStartAddress();
[76]346 pVar->bLiving=TRUE;
[3]347
[76]348 pUserProc->localVars.push_back( pVar );
[3]349 }
350
351 //Thisポインタを示すローカルオフセット値をセット
352 extern int LocalVar_ThisPtrOffset;
353 LocalVar_ThisPtrOffset=AllLocalVarSize;
354
355 BaseOffset=AllLocalVarSize;
356
357 //ret用のアドレスを考慮
358 AllLocalVarSize+=sizeof(long);
359
360
361 ///////////////////////
362 // ここからコード生成
363
364 //sub esp,AllLocalVarSize(スケジュール)
365 op_sub_esp(0xFFFFFFFF);
366 LocalVarSchedule=obp-sizeof(long);
367
368 //push ebp
369 op_push(REG_EBP);
370
371 //mov ebp,esp
372 OpBuffer[obp++]=(char)0x8B;
373 OpBuffer[obp++]=(char)0xEC;
374
375 //push ebx
376 op_push(REG_EBX);
377
378 //push esi
379 OpBuffer[obp++]=(char)0x56;
380
381 //push edi
382 OpBuffer[obp++]=(char)0x57;
383
[75]384 if( !pUserProc->ReturnType().IsNull() ){
[3]385 //戻り値が存在するとき
386
[75]387 const char *temp = pUserProc->GetName().c_str();
388 if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
389 temp = "_System_ReturnValue";
390 }
[3]391
[75]392 if( pUserProc->ReturnType().IsStruct() ){
[64]393 //戻り値用の構造体(値型)はパラメータで引き渡される
[3]394 }
395 else{
[89]396 if( pUserProc->ReturnType().IsObject() ){
397 sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, pUserProc->ReturnType().ToString().c_str() );
398 }
399 else{
400 //戻り値用の変数の定義
401 sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, pUserProc->ReturnType().ToString().c_str() );
402 }
[40]403
[3]404 OpcodeDim(temporary,0);
405 }
406 }
407
408 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
409 extern DWORD *pExitSubSchedule;
410 extern int ExitSubScheduleNum;
411 pExitSubSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
412 ExitSubScheduleNum=0;
413
414 //ラベル用のメモリを確保
415 extern LABEL *pLabelNames;
416 extern int MaxLabelNum;
417 pLabelNames=(LABEL *)HeapAlloc(hHeap,0,1);
418 MaxLabelNum=0;
419
420 //Gotoラベルスケジュール
421 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
422 extern int GotoLabelScheduleNum;
423 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapAlloc(hHeap,0,1);
424 GotoLabelScheduleNum=0;
425
426 //With情報のメモリを確保
427 extern WITHINFO WithInfo;
428 WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1);
429 WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1);
430 WithInfo.num=0;
431
432 //重複エラー情報管理のメモリを確保
433 extern char **SynonymErrorWords;
434 extern int SynonymErrorNum;
435 SynonymErrorNum=0;
436 SynonymErrorWords=(char **)HeapAlloc(hHeap,0,1);
437
438 //Continueアドレスを初期化
439 extern DWORD dwContinueAddress;
440 dwContinueAddress=-1;
441
442 if(bDebugCompile&&bDebugSupportProc==0){
443 //push dword ptr[ebp+(AllLocalVarSize-BaseOffset)](スケジュール)
444 OpBuffer[obp++]=(char)0xFF;
445 OpBuffer[obp++]=(char)0xB5;
446 EspOffsetSchedule=obp;
447 obp+=sizeof(long);
448
449 //push dword ptr[ebp](以前のebp)
450 OpBuffer[obp++]=(char)0xFF;
451 OpBuffer[obp++]=(char)0x75;
452 OpBuffer[obp++]=(char)0x00;
453
454 //call _DebugSys_StartProc
[75]455 extern UserProc *pSub_DebugSys_StartProc;
[3]456 op_call(pSub_DebugSys_StartProc);
457 }
458
[183]459 if(Smoothie::Temp::pCompilingClass){
460 if( pUserProc->GetName() == Smoothie::Temp::pCompilingClass->GetName() ){
[3]461 ////////////////////////////////////
462 // コンストラクタをコンパイルするとき
463 ////////////////////////////////////
464
[17]465 //コンストラクタのコンパイル開始を通知
[183]466 Smoothie::Temp::pCompilingClass->NotifyStartConstructorCompile();
[17]467
[27]468 //基底クラスかどうかの識別
469 //(継承元がインターフェイスの場合も基底クラスと見なす)
[3]470 BOOL bThisIsSuperClass;
[183]471 if(Smoothie::Temp::pCompilingClass->pobj_InheritsClass==0) bThisIsSuperClass=1;
472 else if( Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod() == NULL ){
[3]473 //インターフェイスを継承したときはコンストラクタを持たない
474 bThisIsSuperClass=1;
475 }
476 else bThisIsSuperClass=0;
477
478 if(!bThisIsSuperClass){
479 /* サブクラスコンストラクタをコンパイルしているときは、
[27]480 基底クラスのコンストラクタを呼び出す */
[3]481
482 i3=cp+1;
483 while(IsCommandDelimitation(basbuf[i3])) i3++;
484 for(i4=0;;i3++,i4++){
485 if(!IsVariableChar(basbuf[i3])){
486 temporary[i4]=0;
487 break;
488 }
489 temporary[i4]=basbuf[i3];
490 }
[183]491 if( Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetName() == temporary ){
[27]492 //基底クラスのコンストラクタを呼び出す
[3]493 cp=i3;
494 for(i4=0;;cp++,i4++){
495 if(IsCommandDelimitation(basbuf[cp])){
496 temporary[i4]=0;
497 break;
498 }
499 temporary[i4]=basbuf[cp];
500 }
501 if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
502 SetError(1,NULL,cp);
503 }
504 RemoveStringPare(temporary);
505
[89]506 Type dummyType;
507 CallProc( PROC_DEFAULT
[183]508 , Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc
509 , Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc->GetName().c_str()
[89]510 , temporary
511 , dummyType );
[3]512 }
513 else{
[27]514 //基底クラスのコンストラクタを暗黙的に呼び出す
[3]515 Opcode_CallProc("",
[183]516 Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc,
[3]517 0,
518 "",
519 0);
520 }
521 }
522
523 //仮想関数テーブルを初期化
[183]524 if( Smoothie::Temp::pCompilingClass->IsExistVirtualFunctions()
525 && !Smoothie::Temp::pCompilingClass->IsAbstract() ){
[28]526 //関数テーブルに値をセット
[183]527 int offset = (int)Smoothie::Temp::pCompilingClass->GetVtblGlobalOffset();
[3]528
[28]529 //mov eax,offset
530 OpBuffer[obp++]=(char)0xB8;
531 *((long *)(OpBuffer+obp))=offset;
532 pobj_DataTableSchedule->add();
533 obp+=sizeof(long);
[3]534
[28]535 //Thisポインタをecxにコピー
536 SetThisPtrToReg(REG_ECX);
[3]537
[28]538 //mov dword ptr[ecx],eax
539 OpBuffer[obp++]=(char)0x89;
540 OpBuffer[obp++]=(char)0x01;
[3]541 }
542 }
[75]543 else if( pUserProc->IsDestructor() ){
[18]544 //デストラクタをコンパイルしたとき
545
546 //デストラクタのコンパイル開始を通知
[183]547 Smoothie::Temp::pCompilingClass->NotifyStartDestructorCompile();
[18]548 }
[3]549 }
550
551 //////////////////////////////////////////
552 //////////////////////////////////////////
553 ////// プロシージャ内をコンパイル ////////
[90]554 if( pUserProc->IsAutoGeneration() ){
555 AutoGeneration( *pUserProc );
556 }
[75]557 else{
[90]558 if(pUserProc->IsMacro()){
559 CompileBuffer(ESC_ENDMACRO,0);
560 }
561 else{
562 if(pUserProc->IsSub()){
563 CompileBuffer(ESC_ENDSUB,0);
564 }
565 else if(pUserProc->IsFunction()){
566 CompileBuffer(ESC_ENDFUNCTION,0);
567 }
568 }
[75]569 }
[3]570 //////////////////////////////////////////
571 //////////////////////////////////////////
572
[183]573 if( Smoothie::Temp::pCompilingClass ){
[17]574
[183]575 if( Smoothie::Temp::pCompilingClass->IsCompilingConstructor() ){
[17]576 // コンストラクタをコンパイルしていたとき
[18]577
[17]578 // コンストラクタのコンパイルが完了したことを通知
[183]579 Smoothie::Temp::pCompilingClass->NotifyFinishConstructorCompile();
[17]580 }
[75]581 else if( pUserProc->IsDestructor() ){
[3]582 ////////////////////////////////////
583 //デストラクタをコンパイルしたとき
584 ////////////////////////////////////
585
[18]586 // デストラクタのコンパイルが完了したことを通知
[183]587 Smoothie::Temp::pCompilingClass->NotifyFinishDestructorCompile();
[18]588
[183]589 if(Smoothie::Temp::pCompilingClass->pobj_InheritsClass){
[3]590 /* サブクラスのデストラクタをコンパイルしているときは、
[27]591 基底クラスのデストラクタを呼び出す */
[3]592
[183]593 const CMethod *method = Smoothie::Temp::pCompilingClass->pobj_InheritsClass->GetDestructorMethod();
[51]594 if( method ){
[3]595 Opcode_CallProc("",
[75]596 method->pUserProc,
[3]597 0,
598 "",
599 0);
600 }
601 }
602 }
603 }
604
605 //ラベル用のメモリを解放
606 for(i3=0;i3<MaxLabelNum;i3++){
607 if(pLabelNames[i3].pName) HeapDefaultFree(pLabelNames[i3].pName);
608 }
609 HeapDefaultFree(pLabelNames);
610
611 //Goto未知ラベルスケジュールを解放
612 for(i3=0;i3<GotoLabelScheduleNum;i3++){
613 if(pGotoLabelSchedule[i3].pName){
614 SetError(6,pGotoLabelSchedule[i3].pName,pGotoLabelSchedule[i3].now_cp);
615 HeapDefaultFree(pGotoLabelSchedule[i3].pName);
616 }
617 else{
618 sprintf(temporary,"%d",pGotoLabelSchedule[i3].line);
619 SetError(6,temporary,pGotoLabelSchedule[i3].now_cp);
620 }
621 }
622 HeapDefaultFree(pGotoLabelSchedule);
623
624 //With情報のメモリを解放
625 for(i3=0;i3<WithInfo.num;i3++){
626 SetError(22,"With",WithInfo.pWithCp[i3]);
627 HeapDefaultFree(WithInfo.ppName[i3]);
628 }
629 HeapDefaultFree(WithInfo.ppName);
630 HeapDefaultFree(WithInfo.pWithCp);
631
632 //push ebp
633 AllLocalVarSize+=sizeof(long);
634
635 //ローカルオブジェクトの解放処理
[183]636 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]637
[34]638 //プロシージャ抜け出しスケジュール(Exit Sub/Function)
639 for(i3=0;i3<ExitSubScheduleNum;i3++){
640 *((long *)(OpBuffer+pExitSubSchedule[i3]))=obp-(pExitSubSchedule[i3]+sizeof(long));
641 }
642 HeapDefaultFree(pExitSubSchedule);
643
644 if(bDebugCompile&&bDebugSupportProc==0){
[64]645 *((long *)(OpBuffer+EspOffsetSchedule))=AllLocalVarSize-BaseOffset-sizeof(long);
[34]646
647 //call _DebugSys_EndProc
[75]648 extern UserProc *pSub_DebugSys_EndProc;
[34]649 op_call(pSub_DebugSys_EndProc);
650 }
651
[75]652 if( !pUserProc->ReturnType().IsNull() ){
[3]653 //戻り値をeax、edxに設定
654 RELATIVE_VAR RelativeVar;
655
[75]656 const char *temp = pUserProc->GetName().c_str();
657 if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
[3]658 temp="_System_ReturnValue";
[75]659 }
[76]660 GetVarOffsetReadWrite(temp,&RelativeVar,Type());
[3]661
[75]662 i3=pUserProc->ReturnType().GetBasicType();
[3]663
[64]664 if(i3==DEF_OBJECT || i3==DEF_STRUCT){
[3]665 SetVarPtrToEax(&RelativeVar);
[64]666 if( i3==DEF_OBJECT ){
667 //mov eax,dword ptr[eax]
668 op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
669 }
[3]670 }
671 else if(i3==DEF_DOUBLE){
672 //fld qword ptr[ebp+offset]
673 OpBuffer[obp++]=(char)0xDD;
674 OpBuffer[obp++]=(char)0x85;
675 *((long *)(OpBuffer+obp))=RelativeVar.offset;
676 AddLocalVarAddrSchedule();
677 obp+=sizeof(long);
678 }
679 else if(i3==DEF_SINGLE){
680 //fld dword ptr[ebp+offset]
681 OpBuffer[obp++]=(char)0xD9;
682 OpBuffer[obp++]=(char)0x85;
683 *((long *)(OpBuffer+obp))=RelativeVar.offset;
684 AddLocalVarAddrSchedule();
685 obp+=sizeof(long);
686 }
687 else if(i3==DEF_INT64||i3==DEF_QWORD){
688 //mov eax,dword ptr[ebp+offset]
689 OpBuffer[obp++]=(char)0x8B;
690 OpBuffer[obp++]=(char)0x85;
691 *((long *)(OpBuffer+obp))=RelativeVar.offset;
692 AddLocalVarAddrSchedule();
693 obp+=sizeof(long);
694
695 //mov edx,dword ptr[ebp+offset+sizeof(long)]
696 OpBuffer[obp++]=(char)0x8B;
697 OpBuffer[obp++]=(char)0x95;
698 *((long *)(OpBuffer+obp))=RelativeVar.offset+sizeof(long);
699 AddLocalVarAddrSchedule();
700 obp+=sizeof(long);
701 }
702 else if(i3==DEF_LONG||i3==DEF_DWORD||
703 IsPtrType(i3)){
704 //mov eax,dword ptr[ebp+offset]
705 OpBuffer[obp++]=(char)0x8B;
706 OpBuffer[obp++]=(char)0x85;
707 *((long *)(OpBuffer+obp))=RelativeVar.offset;
708 AddLocalVarAddrSchedule();
709 obp+=sizeof(long);
710 }
[183]711 else if(i3==DEF_INTEGER||i3==DEF_WORD || (Smoothie::IsUnicode()&&i3==DEF_CHAR)){
[3]712 //xor eax,eax(eaxを0に初期化する)
713 op_zero_reg(REG_EAX);
714
715 //mov ax,word ptr[ebp+offset]
716 OpBuffer[obp++]=(char)0x66;
717 OpBuffer[obp++]=(char)0x8B;
718 OpBuffer[obp++]=(char)0x85;
719 *((long *)(OpBuffer+obp))=RelativeVar.offset;
720 AddLocalVarAddrSchedule();
721 obp+=sizeof(long);
722 }
[183]723 else if(i3==DEF_SBYTE||i3==DEF_BYTE||i3==DEF_BOOLEAN || (Smoothie::IsUnicode()==false&&i3==DEF_CHAR)){
[3]724 //xor eax,eax(eaxを0に初期化する)
725 op_zero_reg(REG_EAX);
726
727 //mov al,byte ptr[ebp+offset]
728 OpBuffer[obp++]=(char)0x8A;
729 OpBuffer[obp++]=(char)0x85;
730 *((long *)(OpBuffer+obp))=RelativeVar.offset;
731 AddLocalVarAddrSchedule();
732 obp+=sizeof(long);
733 }
734 }
735
736 //ローカル変数アドレススケジュール
737 for(i3=0;i3<LocalVarAddrScheduleNum;i3++){
738 *((long *)(OpBuffer+pLocalVarAddrSchedule[i3]))+=AllLocalVarSize;
739 }
740 HeapDefaultFree(pLocalVarAddrSchedule);
[183]741 BOOST_FOREACH( Variable *pVar, pUserProc->localVars ){
[76]742 //後にデバッグで利用する
743 pVar->offset = AllLocalVarSize - pVar->offset;
[3]744 }
745
746 //push ebp、ret用のアドレスを考慮
747 AllLocalVarSize-=sizeof(long)*2;
748
749 //ローカル変数用メモリを確保するためのスケジュール(subコマンド)
750 *((long *)(OpBuffer+LocalVarSchedule))=AllLocalVarSize-BaseOffset;
751
752 //pop edi
753 OpBuffer[obp++]=(char)0x5F;
754
755 //pop esi
756 OpBuffer[obp++]=(char)0x5E;
757
758 //pop ebx
759 op_pop(REG_EBX);
760
[64]761 if(bDebugCompile){
762 //cmp esp,ebp
763 op_cmp_RR( REG_ESP, REG_EBP );
764
765 //jz 6(次のcallとbreakpointを飛び越す)
766 OpBuffer[obp++]=(char)0x74;
767 OpBuffer[obp++]=(char)0x06;
768
769 //call _esp_error
[75]770 extern UserProc *pSub_esp_error;
[64]771 op_call( pSub_esp_error );
772
773 breakpoint;
774 }
775
[3]776 //mov esp,ebp
777 OpBuffer[obp++]=(char)0x8B;
778 OpBuffer[obp++]=(char)0xE5;
779
780 //pop ebp
781 op_pop(REG_EBP);
782
783 //add esp AllLocalVarSize
784 op_add_esp(AllLocalVarSize-BaseOffset);
785
[75]786 if( BaseOffset==0 || pUserProc->IsCdecl() ){
[142]787 //ret
788 op_ret();
[3]789 }
790 else{
791 //ret BaseOffset(パラメータ分のスタック領域を解放)
792 OpBuffer[obp++]=(char)0xC2;
793 *((_int16 *)(OpBuffer+obp))=(_int16)BaseOffset;
794 obp+=sizeof(_int16);
795 }
796
[76]797
[75]798 pUserProc->endOpAddress=obp;
[3]799
[75]800
801 //重複エラー情報管理のメモリを解放
802 for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]);
803 HeapDefaultFree(SynonymErrorWords);
804 SynonymErrorWords=0;
805
806
[3]807 //ローカル変数のネーム情報は後に解放する
808}
[91]809
810void CompileBufferInProcedure( UserProc &userProc ){
811 if( userProc.IsUsing() == false || userProc.IsCompiled() ) return;
812
813 _compile_proc( &userProc );
[92]814/*
[91]815 // ログを履く
816 char temporary[8192];
817 temporary[0]=0;
818 lstrcat( temporary, "------------------------------------------------------------------\n" );
819 sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
820 sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
821 lstrcat( temporary, "------------------------------------------------------------------\n" );
822 lstrcat( temporary, "\n" );
[92]823 Smoothie::Logger::Put( temporary );*/
[91]824}
[3]825void CompileLocal(){
[100]826 extern GlobalProc **ppSubHash;
[3]827 int i2;
828
829 extern BOOL bDll;
830 if(bDll){
831 //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
[100]832 UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
[75]833 if(pUserProc){
[91]834 CompileBufferInProcedure( *pUserProc );
[3]835 }
836 else SetError(300,NULL,cp);
837 }
838
[94]839 //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
840 extern UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
841 pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
842
[3]843 //_System_InitStaticLocalVariablesは一番最後にコンパイル
844 //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
[75]845 extern UserProc *pSub_System_InitStaticLocalVariables;
846 pSub_System_InitStaticLocalVariables->CompleteCompile();
[3]847
848 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
[75]849 extern UserProc *pSub_System_Call_Destructor_of_GlobalObject;
850 pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
[3]851
[94]852repeat:
[100]853 GlobalProc *pGlobalProc;
[3]854 for(i2=0;i2<MAX_HASH;i2++){
[100]855 pGlobalProc=ppSubHash[i2];
856 while(pGlobalProc){
857 CompileBufferInProcedure( *pGlobalProc );
858 pGlobalProc=pGlobalProc->pNextData;
[3]859 }
860 }
861
[94]862 if( IsNeedProcCompile() ){
863 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
864 goto repeat;
865 }
866
867 //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
868 pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
869 CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
870
871 if( IsNeedProcCompile() ){
872 //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
873 for(i2=0;i2<MAX_HASH;i2++){
[100]874 pGlobalProc=ppSubHash[i2];
875 while(pGlobalProc){
876 CompileBufferInProcedure( *pGlobalProc );
877 pGlobalProc=pGlobalProc->pNextData;
[3]878 }
879 }
880 }
881
882 //_System_InitStaticLocalVariablesは一番最後にコンパイル
[75]883 pSub_System_InitStaticLocalVariables->KillCompileStatus();
[91]884 CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
[3]885
886 //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
[75]887 pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
[91]888 CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
[3]889}
Note: See TracBrowser for help on using the repository browser.