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