source: dev/BasicCompiler32/Compile_ProcOp.cpp @ 131

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

Prototypeクラスを用意した。

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        && userProc.GetParentClass().GetName() == "_System_TypeBase" ){
218
219            pobj_DBClass->Compile_System_InitializeUserTypes();
220    }
221    else if( userProc.GetName() == "RegisterGlobalRoots"
222        && userProc.HasParentClass()
223        && userProc.GetParentClass().GetName() == "_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->GetName() ){
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( pobj_CompilingClass->pobj_InheritsClass->GetName() == temporary ){
485                    //基底クラスのコンストラクタを呼び出す
486                    cp=i3;
487                    for(i4=0;;cp++,i4++){
488                        if(IsCommandDelimitation(basbuf[cp])){
489                            temporary[i4]=0;
490                            break;
491                        }
492                        temporary[i4]=basbuf[cp];
493                    }
494                    if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
495                        SetError(1,NULL,cp);
496                    }
497                    RemoveStringPare(temporary);
498
499                    Type dummyType;
500                    CallProc( PROC_DEFAULT
501                        , pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc
502                        , pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc->GetName().c_str()
503                        , temporary
504                        , dummyType );
505                }
506                else{
507                    //基底クラスのコンストラクタを暗黙的に呼び出す
508                    Opcode_CallProc("",
509                        pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc,
510                        0,
511                        "",
512                        0);
513                }
514            }
515
516            //新しいオブジェクト領域は0で初期化されているため、Nothingを明示的に代入する必要はない
517/*
518            //実体クラスを持つメンバのコンストラクタ(引数有りを除く)を呼び出す
519            for(i3=0;i3<pobj_CompilingClass->iMemberNum;i3++){
520                CMember *pMember = pobj_CompilingClass->ppobj_Member[i3];
521                if(pMember->IsObject()){
522                    // オブジェクトメンバを発見したとき
523
524                    sprintf(temporary, "This.%s=Nothing",
525                        pMember->name );
526                    OpcodeCalc( temporary );
527                }
528            }
529*/
530
531            //仮想関数テーブルを初期化
532            if(pobj_CompilingClass->vtbl_num&&
533                pobj_CompilingClass->IsAbstract()==false){
534                    //関数テーブルに値をセット
535                    int offset = (int)pobj_CompilingClass->GetVtblGlobalOffset();
536
537                    //mov eax,offset
538                    OpBuffer[obp++]=(char)0xB8;
539                    *((long *)(OpBuffer+obp))=offset;
540                    pobj_DataTableSchedule->add();
541                    obp+=sizeof(long);
542
543                    //Thisポインタをecxにコピー
544                    SetThisPtrToReg(REG_ECX);
545
546                    //mov dword ptr[ecx],eax
547                    OpBuffer[obp++]=(char)0x89;
548                    OpBuffer[obp++]=(char)0x01;
549            }
550        }
551        else if( pUserProc->IsDestructor() ){
552            //デストラクタをコンパイルしたとき
553
554            //デストラクタのコンパイル開始を通知
555            pobj_CompilingClass->NotifyStartDestructorCompile();
556        }
557    }
558
559    //////////////////////////////////////////
560    //////////////////////////////////////////
561    ////// プロシージャ内をコンパイル ////////
562    if( pUserProc->IsAutoGeneration() ){
563        AutoGeneration( *pUserProc );
564    }
565    else{
566        if(pUserProc->IsMacro()){
567            CompileBuffer(ESC_ENDMACRO,0);
568        }
569        else{
570            if(pUserProc->IsSub()){
571                CompileBuffer(ESC_ENDSUB,0);
572            }
573            else if(pUserProc->IsFunction()){
574                CompileBuffer(ESC_ENDFUNCTION,0);
575            }
576        }
577    }
578    //////////////////////////////////////////
579    //////////////////////////////////////////
580
581    if( pobj_CompilingClass ){
582
583        if( pobj_CompilingClass->IsCompilingConstructor() ){
584            // コンストラクタをコンパイルしていたとき
585
586            // コンストラクタのコンパイルが完了したことを通知
587            pobj_CompilingClass->NotifyFinishConstructorCompile();
588        }
589        else if( pUserProc->IsDestructor() ){
590            ////////////////////////////////////
591            //デストラクタをコンパイルしたとき
592            ////////////////////////////////////
593
594            // デストラクタのコンパイルが完了したことを通知
595            pobj_CompilingClass->NotifyFinishDestructorCompile();
596
597            if(pobj_CompilingClass->pobj_InheritsClass){
598                /* サブクラスのデストラクタをコンパイルしているときは、
599                    基底クラスのデストラクタを呼び出す */
600
601                CMethod *method = pobj_CompilingClass->pobj_InheritsClass->GetDestructorMethod();
602                if( method ){
603                    Opcode_CallProc("",
604                        method->pUserProc,
605                        0,
606                        "",
607                        0);
608                }
609            }
610
611            //実体クラスを持つメンバのデストラクタ呼び出しはGCに任せる
612            /*
613            //※コンストラクタと逆順序で呼び出す
614            int offset;
615            int MemberTypeSize;
616            int MemberObjectNum;
617            offset=GetTypeSize(DEF_OBJECT,(LONG_PTR)pobj_CompilingClass);
618            for(i3=pobj_CompilingClass->iMemberNum-1;i3>=0;i3--){
619                CMember *pMember = pobj_CompilingClass->ppobj_Member[i3];
620
621                MemberTypeSize=
622                    GetTypeSize(pMember->TypeInfo.type,
623                        pMember->TypeInfo.u.lpIndex);
624
625                MemberObjectNum=
626                    JumpSubScripts(pMember->SubScripts);
627
628                offset-=MemberTypeSize*MemberObjectNum;
629
630                if(pMember->TypeInfo.type==DEF_OBJECT){
631                    CMethod *method = pMember->TypeInfo.u.pobj_Class->GetDestructorMethod();
632                    if( method ){
633                        for(i4=MemberObjectNum-1;i4>=0;i4--){
634                            //Thisポインタをecxにコピー
635                            SetThisPtrToReg(REG_ECX);
636
637                            //add ecx,offset
638                            OpBuffer[obp++]=(char)0x81;
639                            OpBuffer[obp++]=(char)0xC1;
640                            *((long *)(OpBuffer+obp))=offset+i4*MemberTypeSize;
641                            obp+=sizeof(long);
642
643                            //push ecx
644                            op_push(REG_ECX);
645
646                            //call destructor
647                            op_call( method->pUserProc );
648                        }
649                    }
650                }
651            }*/
652        }
653    }
654
655    //ラベル用のメモリを解放
656    for(i3=0;i3<MaxLabelNum;i3++){
657        if(pLabelNames[i3].pName) HeapDefaultFree(pLabelNames[i3].pName);
658    }
659    HeapDefaultFree(pLabelNames);
660
661    //Goto未知ラベルスケジュールを解放
662    for(i3=0;i3<GotoLabelScheduleNum;i3++){
663        if(pGotoLabelSchedule[i3].pName){
664            SetError(6,pGotoLabelSchedule[i3].pName,pGotoLabelSchedule[i3].now_cp);
665            HeapDefaultFree(pGotoLabelSchedule[i3].pName);
666        }
667        else{
668            sprintf(temporary,"%d",pGotoLabelSchedule[i3].line);
669            SetError(6,temporary,pGotoLabelSchedule[i3].now_cp);
670        }
671    }
672    HeapDefaultFree(pGotoLabelSchedule);
673
674    //With情報のメモリを解放
675    for(i3=0;i3<WithInfo.num;i3++){
676        SetError(22,"With",WithInfo.pWithCp[i3]);
677        HeapDefaultFree(WithInfo.ppName[i3]);
678    }
679    HeapDefaultFree(WithInfo.ppName);
680    HeapDefaultFree(WithInfo.pWithCp);
681
682    //push ebp
683    AllLocalVarSize+=sizeof(long);
684
685    //ローカルオブジェクトの解放処理
686    obj_LexScopes.CallDestructorsOfScopeEnd();
687
688    //プロシージャ抜け出しスケジュール(Exit Sub/Function)
689    for(i3=0;i3<ExitSubScheduleNum;i3++){
690        *((long *)(OpBuffer+pExitSubSchedule[i3]))=obp-(pExitSubSchedule[i3]+sizeof(long));
691    }
692    HeapDefaultFree(pExitSubSchedule);
693
694    if(bDebugCompile&&bDebugSupportProc==0){
695        *((long *)(OpBuffer+EspOffsetSchedule))=AllLocalVarSize-BaseOffset-sizeof(long);
696
697        //call _DebugSys_EndProc
698        extern UserProc *pSub_DebugSys_EndProc;
699        op_call(pSub_DebugSys_EndProc);
700    }
701
702    if( !pUserProc->ReturnType().IsNull() ){
703        //戻り値をeax、edxに設定
704        RELATIVE_VAR RelativeVar;
705
706        const char *temp = pUserProc->GetName().c_str();
707        if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
708            temp="_System_ReturnValue";
709        }
710        GetVarOffsetReadWrite(temp,&RelativeVar,Type());
711
712        i3=pUserProc->ReturnType().GetBasicType();
713
714        if(i3==DEF_OBJECT || i3==DEF_STRUCT){
715            SetVarPtrToEax(&RelativeVar);
716            if( i3==DEF_OBJECT ){
717                //mov eax,dword ptr[eax]
718                op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
719            }
720        }
721        else if(i3==DEF_DOUBLE){
722            //fld qword ptr[ebp+offset]
723            OpBuffer[obp++]=(char)0xDD;
724            OpBuffer[obp++]=(char)0x85;
725            *((long *)(OpBuffer+obp))=RelativeVar.offset;
726            AddLocalVarAddrSchedule();
727            obp+=sizeof(long);
728        }
729        else if(i3==DEF_SINGLE){
730            //fld dword ptr[ebp+offset]
731            OpBuffer[obp++]=(char)0xD9;
732            OpBuffer[obp++]=(char)0x85;
733            *((long *)(OpBuffer+obp))=RelativeVar.offset;
734            AddLocalVarAddrSchedule();
735            obp+=sizeof(long);
736        }
737        else if(i3==DEF_INT64||i3==DEF_QWORD){
738            //mov eax,dword ptr[ebp+offset]
739            OpBuffer[obp++]=(char)0x8B;
740            OpBuffer[obp++]=(char)0x85;
741            *((long *)(OpBuffer+obp))=RelativeVar.offset;
742            AddLocalVarAddrSchedule();
743            obp+=sizeof(long);
744
745            //mov edx,dword ptr[ebp+offset+sizeof(long)]
746            OpBuffer[obp++]=(char)0x8B;
747            OpBuffer[obp++]=(char)0x95;
748            *((long *)(OpBuffer+obp))=RelativeVar.offset+sizeof(long);
749            AddLocalVarAddrSchedule();
750            obp+=sizeof(long);
751        }
752        else if(i3==DEF_LONG||i3==DEF_DWORD||
753            IsPtrType(i3)){
754            //mov eax,dword ptr[ebp+offset]
755            OpBuffer[obp++]=(char)0x8B;
756            OpBuffer[obp++]=(char)0x85;
757            *((long *)(OpBuffer+obp))=RelativeVar.offset;
758            AddLocalVarAddrSchedule();
759            obp+=sizeof(long);
760        }
761        else if(i3==DEF_INTEGER||i3==DEF_WORD || (isUnicode&&i3==DEF_CHAR)){
762            //xor eax,eax(eaxを0に初期化する)
763            op_zero_reg(REG_EAX);
764
765            //mov ax,word ptr[ebp+offset]
766            OpBuffer[obp++]=(char)0x66;
767            OpBuffer[obp++]=(char)0x8B;
768            OpBuffer[obp++]=(char)0x85;
769            *((long *)(OpBuffer+obp))=RelativeVar.offset;
770            AddLocalVarAddrSchedule();
771            obp+=sizeof(long);
772        }
773        else if(i3==DEF_SBYTE||i3==DEF_BYTE||i3==DEF_BOOLEAN || (isUnicode==false&&i3==DEF_CHAR)){
774            //xor eax,eax(eaxを0に初期化する)
775            op_zero_reg(REG_EAX);
776
777            //mov al,byte ptr[ebp+offset]
778            OpBuffer[obp++]=(char)0x8A;
779            OpBuffer[obp++]=(char)0x85;
780            *((long *)(OpBuffer+obp))=RelativeVar.offset;
781            AddLocalVarAddrSchedule();
782            obp+=sizeof(long);
783        }
784    }
785
786    //ローカル変数アドレススケジュール
787    for(i3=0;i3<LocalVarAddrScheduleNum;i3++){
788        *((long *)(OpBuffer+pLocalVarAddrSchedule[i3]))+=AllLocalVarSize;
789    }
790    HeapDefaultFree(pLocalVarAddrSchedule);
791    foreach( Variable *pVar, pUserProc->localVars ){
792        //後にデバッグで利用する
793        pVar->offset = AllLocalVarSize - pVar->offset;
794    }
795
796    //push ebp、ret用のアドレスを考慮
797    AllLocalVarSize-=sizeof(long)*2;
798
799    //ローカル変数用メモリを確保するためのスケジュール(subコマンド)
800    *((long *)(OpBuffer+LocalVarSchedule))=AllLocalVarSize-BaseOffset;
801
802    //pop edi
803    OpBuffer[obp++]=(char)0x5F;
804
805    //pop esi
806    OpBuffer[obp++]=(char)0x5E;
807
808    //pop ebx
809    op_pop(REG_EBX);
810
811    if(bDebugCompile){
812        //cmp esp,ebp
813        op_cmp_RR( REG_ESP, REG_EBP );
814
815        //jz 6(次のcallとbreakpointを飛び越す)
816        OpBuffer[obp++]=(char)0x74;
817        OpBuffer[obp++]=(char)0x06;
818
819        //call _esp_error
820        extern UserProc *pSub_esp_error;
821        op_call( pSub_esp_error );
822
823        breakpoint;
824    }
825
826    //mov esp,ebp
827    OpBuffer[obp++]=(char)0x8B;
828    OpBuffer[obp++]=(char)0xE5;
829
830    //pop ebp
831    op_pop(REG_EBP);
832
833    //add esp AllLocalVarSize
834    op_add_esp(AllLocalVarSize-BaseOffset);
835
836    if( BaseOffset==0 || pUserProc->IsCdecl() ){
837        //ret 0
838        OpBuffer[obp++]=(char)0xC3;
839    }
840    else{
841        //ret BaseOffset(パラメータ分のスタック領域を解放)
842        OpBuffer[obp++]=(char)0xC2;
843        *((_int16 *)(OpBuffer+obp))=(_int16)BaseOffset;
844        obp+=sizeof(_int16);
845    }
846
847
848    pUserProc->endOpAddress=obp;
849
850
851    //重複エラー情報管理のメモリを解放
852    for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]);
853    HeapDefaultFree(SynonymErrorWords);
854    SynonymErrorWords=0;
855
856
857    //ローカル変数のネーム情報は後に解放する
858}
859
860void CompileBufferInProcedure( UserProc &userProc ){
861    if( userProc.IsUsing() == false || userProc.IsCompiled() ) return;
862
863    _compile_proc( &userProc );
864/*
865    // ログを履く
866    char temporary[8192];
867    temporary[0]=0;
868    lstrcat( temporary, "------------------------------------------------------------------\n" );
869    sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetFullName().c_str() );
870    sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
871    lstrcat( temporary, "------------------------------------------------------------------\n" );
872    lstrcat( temporary, "\n" );
873    Smoothie::Logger::Put( temporary );*/
874}
875void CompileLocal(){
876    extern GlobalProc **ppSubHash;
877    int i2;
878
879    extern BOOL bDll;
880    if(bDll){
881        //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
882        UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
883        if(pUserProc){
884            CompileBufferInProcedure( *pUserProc );
885        }
886        else SetError(300,NULL,cp);
887    }
888
889    //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
890    extern UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
891    pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
892
893    //_System_InitStaticLocalVariablesは一番最後にコンパイル
894    //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
895    extern UserProc *pSub_System_InitStaticLocalVariables;
896    pSub_System_InitStaticLocalVariables->CompleteCompile();
897
898    //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
899    extern UserProc *pSub_System_Call_Destructor_of_GlobalObject;
900    pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
901
902repeat:
903    GlobalProc *pGlobalProc;
904    for(i2=0;i2<MAX_HASH;i2++){
905        pGlobalProc=ppSubHash[i2];
906        while(pGlobalProc){
907            CompileBufferInProcedure( *pGlobalProc );
908            pGlobalProc=pGlobalProc->pNextData;
909        }
910    }
911
912    if( IsNeedProcCompile() ){
913        //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
914        goto repeat;
915    }
916
917    //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
918    pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
919    CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
920
921    if( IsNeedProcCompile() ){
922        //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
923        for(i2=0;i2<MAX_HASH;i2++){
924            pGlobalProc=ppSubHash[i2];
925            while(pGlobalProc){
926                CompileBufferInProcedure( *pGlobalProc );
927                pGlobalProc=pGlobalProc->pNextData;
928            }
929        }
930    }
931
932    //_System_InitStaticLocalVariablesは一番最後にコンパイル
933    pSub_System_InitStaticLocalVariables->KillCompileStatus();
934    CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
935
936    //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
937    pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
938    CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
939}
Note: See TracBrowser for help on using the repository browser.