source: dev/BasicCompiler64/Compile_ProcOp.cpp @ 131

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

Prototypeクラスを用意した。

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        && userProc.GetParentClass().GetName() == "_System_TypeBase" ){
209
210            pobj_DBClass->Compile_System_InitializeUserTypes();
211    }
212    else if( userProc.GetName() == "RegisterGlobalRoots"
213        && userProc.HasParentClass()
214        && userProc.GetParentClass().GetName() == "_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->GetName() ){
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( pobj_CompilingClass->pobj_InheritsClass->GetName() == temporary ){
537                    //基底クラスのコンストラクタを呼び出す
538                    cp=i3;
539                    for(i4=0;;cp++,i4++){
540                        if(IsCommandDelimitation(basbuf[cp])){
541                            temporary[i4]=0;
542                            break;
543                        }
544                        temporary[i4]=basbuf[cp];
545                    }
546                    if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
547                        SetError(1,NULL,cp);
548                    }
549                    RemoveStringPare(temporary);
550
551                    Type dummyType;
552                    CallProc( PROC_DEFAULT
553                        , pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc
554                        , pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc->GetName().c_str()
555                        , temporary
556                        , dummyType );
557                }
558                else{
559                    //基底クラスのコンストラクタを暗黙的に呼び出す
560                    Opcode_CallProc("",
561                        pobj_CompilingClass->pobj_InheritsClass->GetConstructorMethod()->pUserProc,
562                        0,
563                        "",
564                        0);
565                }
566            }
567
568            //新しいオブジェクト領域は0で初期化されているため、Nothingを明示的に代入する必要はない
569/*
570            //実体クラスを持つメンバのコンストラクタ(引数有りを除く)を呼び出す
571            for(i3=0;i3<pobj_CompilingClass->iMemberNum;i3++){
572                CMember *pMember = pobj_CompilingClass->ppobj_Member[i3];
573                if(pMember->IsObject()){
574                    // オブジェクトメンバを発見したとき
575
576                    sprintf(temporary, "This.%s=Nothing",
577                        pMember->name );
578                    OpcodeCalc( temporary );
579                }
580            }
581*/
582
583            //仮想関数テーブルを初期化
584            if(pobj_CompilingClass->vtbl_num&&
585                pobj_CompilingClass->IsAbstract()==false){
586                    //関数テーブルに値をセット
587                    int offset = (int)pobj_CompilingClass->GetVtblGlobalOffset();
588
589                    //mov rax,offset
590                    op_mov_RV(sizeof(_int64),REG_RAX,offset);
591                    obp-=sizeof(long);
592                    pobj_DataTableSchedule->add();
593                    obp+=sizeof(long);
594
595                    //Thisポインタをrcxにコピー
596                    SetThisPtrToReg(REG_RCX);
597
598                    //mov qword ptr[rcx],rax
599                    op_mov_MR(sizeof(_int64),REG_RAX,REG_RCX,0,MOD_BASE);
600            }
601        }
602        else if( pUserProc->IsDestructor() ){
603            //デストラクタをコンパイルしたとき
604
605            //デストラクタのコンパイル開始を通知
606            pobj_CompilingClass->NotifyStartDestructorCompile();
607        }
608    }
609
610    //////////////////////////////////////////
611    //////////////////////////////////////////
612    ////// プロシージャ内をコンパイル ////////
613    if( pUserProc->IsAutoGeneration() ){
614        AutoGeneration( *pUserProc );
615    }
616    else{
617        if(pUserProc->IsMacro()){
618            CompileBuffer(ESC_ENDMACRO,0);
619        }
620        else{
621            if(pUserProc->IsSub()){
622                CompileBuffer(ESC_ENDSUB,0);
623            }
624            else if(pUserProc->IsFunction()){
625                CompileBuffer(ESC_ENDFUNCTION,0);
626            }
627        }
628    }
629    //////////////////////////////////////////
630    //////////////////////////////////////////
631
632    if( pobj_CompilingClass ){
633
634        if( pobj_CompilingClass->IsCompilingConstructor() ){
635            // コンストラクタをコンパイルしていたとき
636
637            // コンストラクタのコンパイルが完了したことを通知
638            pobj_CompilingClass->NotifyFinishConstructorCompile();
639        }
640        else if( pUserProc->IsDestructor() ){
641            ////////////////////////////////////
642            //デストラクタをコンパイルしたとき
643            ////////////////////////////////////
644
645            // デストラクタのコンパイルが完了したことを通知
646            pobj_CompilingClass->NotifyFinishDestructorCompile();
647
648            if(pobj_CompilingClass->pobj_InheritsClass){
649                /* サブクラスのデストラクタをコンパイルしているときは、
650                    基底クラスのデストラクタを呼び出す */
651
652                CMethod *method = pobj_CompilingClass->pobj_InheritsClass->GetDestructorMethod();
653                if( method ){
654                    Opcode_CallProc("",
655                        method->pUserProc,
656                        0,
657                        "",
658                        0);
659                }
660            }
661
662            //実体クラスを持つメンバのデストラクタ呼び出しはGCに任せる
663            /*
664            //※コンストラクタと逆順序で呼び出す
665            for(i3=pobj_CompilingClass->iMemberNum-1;i3>=0;i3--){
666                CMember *pMember = pobj_CompilingClass->ppobj_Member[i3];
667                int MemberTypeSize=
668                    GetTypeSize(pMember->TypeInfo.type,
669                        pMember->TypeInfo.u.lpIndex);
670
671                int MemberObjectNum=
672                    JumpSubScripts(pMember->SubScripts);
673
674                int offset = pobj_CompilingClass->GetMemberOffset( pMember->name, NULL );
675
676                if(pMember->IsObject()){
677                    CMethod *method = pMember->GetClass().GetDestructorMethod();
678                    if( method ){
679                        for(i4=MemberObjectNum-1;i4>=0;i4--){
680                            //Thisポインタをrcxにコピー
681                            SetThisPtrToReg(REG_RCX);
682
683                            //add rcx,offset
684                            op_add_RV(REG_RCX,offset+i4*MemberTypeSize);
685
686                            //call destructor
687                            op_call(method->pUserProc);
688                        }
689                    }
690                }
691            }*/
692        }
693    }
694
695    //ラベル用のメモリを解放
696    for(i3=0;i3<MaxLabelNum;i3++){
697        if(pLabelNames[i3].pName) HeapDefaultFree(pLabelNames[i3].pName);
698    }
699    HeapDefaultFree(pLabelNames);
700
701    //Goto未知ラベルスケジュールを解放
702    for(i3=0;i3<GotoLabelScheduleNum;i3++){
703        if(pGotoLabelSchedule[i3].pName){
704            SetError(6,pGotoLabelSchedule[i3].pName,pGotoLabelSchedule[i3].now_cp);
705            HeapDefaultFree(pGotoLabelSchedule[i3].pName);
706        }
707        else{
708            sprintf(temporary,"%d",pGotoLabelSchedule[i3].line);
709            SetError(6,temporary,pGotoLabelSchedule[i3].now_cp);
710        }
711    }
712    HeapDefaultFree(pGotoLabelSchedule);
713
714    //With情報のメモリを解放
715    for(i3=0;i3<WithInfo.num;i3++){
716        SetError(22,"With",WithInfo.pWithCp[i3]);
717        HeapDefaultFree(WithInfo.ppName[i3]);
718    }
719    HeapDefaultFree(WithInfo.ppName);
720    HeapDefaultFree(WithInfo.pWithCp);
721
722    //ローカルオブジェクト(レキシカルスコープレベル=0)の解放処理
723    obj_LexScopes.CallDestructorsOfScopeEnd();
724
725    //プロシージャ抜け出しスケジュール(Exit Sub/Function)
726    for(i3=0;i3<ExitSubScheduleNum;i3++){
727        *((long *)(OpBuffer+pExitSubSchedule[i3]))=obp-(pExitSubSchedule[i3]+sizeof(long));
728    }
729    HeapDefaultFree(pExitSubSchedule);
730
731    if(bDebugCompile&&bDebugSupportProc==0){
732        //call _DebugSys_EndProc
733        extern UserProc *pSub_DebugSys_EndProc;
734        op_call(pSub_DebugSys_EndProc);
735    }
736
737    if( !pUserProc->ReturnType().IsNull() ){
738        //////////////////////////////////
739        // 戻り値をraxまたはxmm0に設定
740        //////////////////////////////////
741
742        RELATIVE_VAR RelativeVar;
743
744        const char *temp = pUserProc->GetName().c_str();
745        if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
746            temp="_System_ReturnValue";
747        }
748        GetVarOffsetReadWrite(temp,&RelativeVar,Type());
749
750        i3=pUserProc->ReturnType().GetBasicType();
751
752        if(i3==DEF_OBJECT || i3==DEF_STRUCT){
753            SetVarPtrToReg(REG_RAX,&RelativeVar);
754            if( i3==DEF_OBJECT ){
755                //mov rax,qword ptr[rax]
756                op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
757            }
758        }
759        else if(i3==DEF_DOUBLE){
760            //64ビット実数型
761            SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0);
762        }
763        else if(i3==DEF_SINGLE){
764            //32ビット実数型
765            SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0);
766        }
767        else if(IsWholeNumberType(i3)){
768            //整数型
769            SetReg_WholeVariable(i3,&RelativeVar,REG_RAX);
770        }
771        else SetError(300,NULL,cp);
772    }
773
774    //ローカル変数領域のサイズをスタックフレームに通知
775    int iLocalParmSize;
776    iLocalParmSize=AllLocalVarSize-BaseLocalVar;
777    pobj_sf->SetLocalParmSize(iLocalParmSize);
778
779    //ローカル変数アドレススケジュール
780    for(i3=0;i3<LocalVarAddrScheduleNum;i3++){
781        *((long *)(OpBuffer+pLocalVarAddrSchedule[i3]))+=AllLocalVarSize+pobj_sf->GetFrameSize();
782    }
783    HeapDefaultFree(pLocalVarAddrSchedule);
784    foreach( Variable *pVar, pUserProc->localVars ){
785        //後にデバッグで利用する
786        pVar->offset = AllLocalVarSize + pobj_sf->GetFrameSize() - pVar->offset;
787    }
788
789    //mov reg,qword ptr[rsp+offset]     ※スタックフレームを利用
790    pobj_sf->pop(REG_R15);
791    pobj_sf->pop(REG_R14);
792    pobj_sf->pop(REG_R13);
793    pobj_sf->pop(REG_R12);
794    pobj_sf->pop(REG_RDI);
795    pobj_sf->pop(REG_RSI);
796    pobj_sf->pop(REG_RBX);
797
798    int iStackFrameSize;
799    iStackFrameSize=iLocalParmSize + pobj_sf->GetFrameSize();
800
801    //add rsp,スタックフレームサイズ
802    op_add_rsp(iStackFrameSize);
803
804    //ret 0
805    OpBuffer[obp++]=(char)0xC3;
806
807
808    //デバッグ用
809    if(RspOffsetSchedule){
810        *((long *)(OpBuffer+RspOffsetSchedule))=iStackFrameSize;
811        *((long *)(OpBuffer+RspOffsetSchedule2))=iStackFrameSize+sizeof(_int64);
812    }
813
814
815    //スタックフレームスケジュール(subコマンド)
816    *((long *)(OpBuffer+StackFrameSchedule))=iStackFrameSize;
817
818    //スタックフレームスケジュールを実行
819    pobj_sf->RunningSchedule();
820    delete pobj_sf;
821    pobj_sf=0;
822
823
824    pUserProc->endOpAddress=obp;
825
826
827    //重複エラー情報管理のメモリを解放
828    for(i3=0;i3<SynonymErrorNum;i3++) HeapDefaultFree(SynonymErrorWords[i3]);
829    HeapDefaultFree(SynonymErrorWords);
830}
831
832void CompileBufferInProcedure( UserProc &userProc ){
833    if( userProc.IsUsing() == false || userProc.IsCompiled() ) return;
834
835    _compile_proc( &userProc );
836
837    // ログを履く
838    char temporary[8192];
839    temporary[0]=0;
840    lstrcat( temporary, "------------------------------------------------------------------\n" );
841    sprintf( temporary + lstrlen(temporary), "【 %s のコード情報】\n", userProc.GetName().c_str() );
842    sprintf( temporary + lstrlen(temporary), "code size: %d bytes\n", userProc.GetCodeSize() );
843    lstrcat( temporary, "------------------------------------------------------------------\n" );
844    lstrcat( temporary, "\n" );
845    Smoothie::Logger::Put( temporary );
846}
847void CompileLocal(){
848    extern GlobalProc **ppSubHash;
849    int i2;
850
851    extern BOOL bDll;
852    if(bDll){
853        //DLLの場合はグローバル変数を初期化するための関数を一番初めにコンパイルする
854        UserProc *pUserProc=GetSubHash("_System_InitDllGlobalVariables");
855        if(pUserProc){
856            CompileBufferInProcedure( *pUserProc );
857        }
858        else SetError(300,NULL,cp);
859    }
860
861    //_System_TypeBase_InitializeUserTypesは一番最後にコンパイル
862    extern UserProc *pSubStaticMethod_System_TypeBase_InitializeUserTypes;
863    pSubStaticMethod_System_TypeBase_InitializeUserTypes->CompleteCompile();
864
865    //_System_InitStaticLocalVariablesは一番最後にコンパイル
866    //※一般関数内の静的変数オブジェクトをすべて収集しなければならない
867    extern UserProc *pSub_System_InitStaticLocalVariables;
868    pSub_System_InitStaticLocalVariables->CompleteCompile();
869
870    //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
871    extern UserProc *pSub_System_Call_Destructor_of_GlobalObject;
872    pSub_System_Call_Destructor_of_GlobalObject->CompleteCompile();
873
874repeat:
875    GlobalProc *pGlobalProc;
876    for(i2=0;i2<MAX_HASH;i2++){
877        pGlobalProc=ppSubHash[i2];
878        while(pGlobalProc){
879            CompileBufferInProcedure( *pGlobalProc );
880            pGlobalProc=pGlobalProc->pNextData;
881        }
882    }
883
884    if( IsNeedProcCompile() ){
885        //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
886        goto repeat;
887    }
888
889    //_System_TypeBase_InitializeUserTypesは最後のほうでコンパイル
890    pSubStaticMethod_System_TypeBase_InitializeUserTypes->KillCompileStatus();
891    CompileBufferInProcedure( *pSubStaticMethod_System_TypeBase_InitializeUserTypes );
892
893    if( IsNeedProcCompile() ){
894        //プロシージャコンパイルによって、プロシージャコンパイルが必要になる場合
895        for(i2=0;i2<MAX_HASH;i2++){
896            pGlobalProc=ppSubHash[i2];
897            while(pGlobalProc){
898                CompileBufferInProcedure( *pGlobalProc );
899                pGlobalProc=pGlobalProc->pNextData;
900            }
901        }
902    }
903
904    //_System_InitStaticLocalVariablesは一番最後にコンパイル
905    pSub_System_InitStaticLocalVariables->KillCompileStatus();
906    CompileBufferInProcedure( *pSub_System_InitStaticLocalVariables );
907
908    //_System_Call_Destructor_of_GlobalObjectは一番最後にコンパイル
909    pSub_System_Call_Destructor_of_GlobalObject->KillCompileStatus();
910    CompileBufferInProcedure( *pSub_System_Call_Destructor_of_GlobalObject );
911}
Note: See TracBrowser for help on using the repository browser.