source: dev/BasicCompiler32/Compile_ProcOp.cpp @ 129

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

_System_StartupProgramの呼び出し順序を変更。

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