source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_ProcOp.cpp @ 642

Last change on this file since 642 was 642, checked in by dai_9181, 15 years ago

[641]のコミット漏れ

File size: 24.6 KB
Line 
1#include "stdafx.h"
2
3#include "Opcode.h"
4
5
6void SystemProc( const UserProc &userProc ){
7    if( userProc.GetName() == "_System_GetEip" ){
8        //mov eax,dword ptr[esp]
9        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );
10
11        //ret
12        compiler.codeGenerator.op_ret();
13    }
14    else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){
15        ////////////////////////////////////////
16        // DLLのグローバル領域をコンパイル
17        ////////////////////////////////////////
18
19        if( !compiler.IsDll() ){
20            //ret
21            compiler.codeGenerator.op_ret();
22
23            return;
24        }
25
26        int BackCp;
27        BackCp=cp;
28        cp=-1;
29
30        if( compiler.IsDebug() )
31        {
32            //デバッグ用の変数を定義
33            DebugVariable();
34        }
35
36        //GC用の変数を定義
37        InitGCVariables();
38
39        //_System_StartupProgramの呼び出し
40        extern const UserProc *pSub_System_StartupProgram;
41        compiler.codeGenerator.op_call(pSub_System_StartupProgram);
42
43        //クラスに属する静的メンバを定義
44        ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember(
45            compiler.GetObjectModule().meta.GetClasses()
46        );
47
48        GetGlobalDataForDll();
49
50        cp=BackCp;
51
52        //ret
53        compiler.codeGenerator.op_ret();
54    }
55    else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
56        //静的ローカルオブジェクトのコンストラクタ呼び出し
57
58        BOOST_FOREACH( Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
59            if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){
60                //コンストラクタ呼び出し
61                if( pVar->GetType().IsObject() ){
62
63                    //エラー用
64                    cp=pVar->source_code_address;
65
66                    CallConstructor(
67                        pVar->GetName().c_str(),
68                        pVar->GetSubscripts(),
69                        pVar->GetType(),
70                        pVar->GetParamStrForConstructor().c_str());
71                }
72            }
73        }
74
75        //ret
76        compiler.codeGenerator.op_ret();
77    }
78    else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" )
79    {
80        compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
81
82        //ret
83        compiler.codeGenerator.op_ret();
84    }
85    else if( userProc.GetName() == "_allrem" ){
86        //乗除演算用の特殊関数(64ビット整数対応)
87        BYTE Buffer_allrem[]={
88            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
89        };
90
91        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allrem, 178 ) );
92    }
93    else if( userProc.GetName() == "_aullrem" ){
94        //乗除演算用の特殊関数(64ビット整数対応)
95        BYTE Buffer_aullrem[]={
96            0x53,0x8B,0x44,0x24,0x14,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x10,0x8B,
97            0x44,0x24,0x0C,0x33,0xD2,0xF7,0xF1,0x8B,0x44,0x24,0x08,0xF7,0xF1,0x8B,
98            0xC2,0x33,0xD2,0xEB,0x50,0x8B,0xC8,0x8B,0x5C,0x24,0x10,0x8B,0x54,0x24,
99            0x0C,0x8B,0x44,0x24,0x08,0xD1,0xE9,0xD1,0xDB,0xD1,0xEA,0xD1,0xD8,0x0B,
100            0xC9,0x75,0xF4,0xF7,0xF3,0x8B,0xC8,0xF7,0x64,0x24,0x14,0x91,0xF7,0x64,
101            0x24,0x10,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x0C,0x77,0x08,0x72,0x0E,
102            0x3B,0x44,0x24,0x08,0x76,0x08,0x2B,0x44,0x24,0x10,0x1B,0x54,0x24,0x14,
103            0x2B,0x44,0x24,0x08,0x1B,0x54,0x24,0x0C,0xF7,0xDA,0xF7,0xD8,0x83,0xDA,
104            0x00,0x5B,0xC2,0x10,0x00
105        };
106
107        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_aullrem, 117 ) );
108    }
109    else if( userProc.GetName() == "_allmul" ){
110        //乗算用の特殊関数(64ビット整数対応)
111        BYTE Buffer_allmul[]={
112            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
113        };
114
115        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allmul, 52 ) );
116    }
117    else if( userProc.GetName() == "_alldiv" ){
118        //除算用の特殊関数(64ビット整数対応)
119        BYTE Buffer_alldiv[]={
120            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
121        };
122
123        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_alldiv, 170 ) );
124    }
125    else if( userProc.GetName() == "_aulldiv" ){
126        //整数除算用の特殊関数(64ビット整数対応)
127        BYTE Buffer_aulldiv[]={
128            0x53,0x56,0x8B,0x44,0x24,0x18,0x0B,0xC0,0x75,0x18,0x8B,0x4C,0x24,0x14,
129            0x8B,0x44,0x24,0x10,0x33,0xD2,0xF7,0xF1,0x8B,0xD8,0x8B,0x44,0x24,0x0C,
130            0xF7,0xF1,0x8B,0xD3,0xEB,0x41,0x8B,0xC8,0x8B,0x5C,0x24,0x14,0x8B,0x54,
131            0x24,0x10,0x8B,0x44,0x24,0x0C,0xD1,0xE9,0xD1,0xDB,0xD1,0xEA,0xD1,0xD8,
132            0x0B,0xC9,0x75,0xF4,0xF7,0xF3,0x8B,0xF0,0xF7,0x64,0x24,0x18,0x8B,0xC8,
133            0x8B,0x44,0x24,0x14,0xF7,0xE6,0x03,0xD1,0x72,0x0E,0x3B,0x54,0x24,0x10,
134            0x77,0x08,0x72,0x07,0x3B,0x44,0x24,0x0C,0x76,0x01,0x4E,0x33,0xD2,0x8B,
135            0xC6,0x5E,0x5B,0xC2,0x10,0x00
136        };
137
138        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_aulldiv, 104 ) );
139    }
140    else if( userProc.GetName() == "_allshl" ){
141        //符号あり左ビットシフト用の特殊関数(64ビット整数対応)
142        BYTE Buffer_allshl[]={
143            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
144        };
145
146        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allshl, 31 ) );
147    }
148    else if( userProc.GetName() == "_allshr" ){
149        //符号あり右ビットシフト用の特殊関数(64ビット整数対応)
150        BYTE Buffer_allshr[]={
151            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
152        };
153
154        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_allshr, 33 ) );
155    }
156    else if( userProc.GetName() == "_aullshr" ){
157        //符号なし右ビットシフト用の特殊関数(64ビット整数対応)
158        BYTE Buffer_aullshr[]={
159            0x80,0xF9,0x40,         //cmp         cl,40h
160            0x73,0x15,              //jae         RETZERO (0040d71a)
161            0x80,0xF9,0x20,         //cmp         cl,20h
162            0x73,0x06,              //jae         MORE32 (0040d710)
163            0x0F,0xAD,0xD0,         //shrd        eax,edx,cl
164            0xD3,0xEA,              //shr         edx,cl
165            0xC3,                   //ret
166            //MORE32:
167            0x8B,0xC2,              //mov         eax,edx
168            0x33,0xD2,              //xor         edx,edx
169            0x80,0xE1,0x1F,         //and         cl,1Fh
170            0xD3,0xE8,              //shr         eax,cl
171            0xC3,                   //ret
172            //RETZERO:
173            0x33,0xC0,              //xor         eax,eax
174            0x33,0xD2,              //xor         edx,edx
175            0xC3                    //ret
176        };
177
178        compiler.codeGenerator.PutOld( NativeCode( (const char *)Buffer_aullshr, 31 ) );
179    }
180    else{
181        compiler.errorMessenger.OutputFatalError();
182    }
183}
184void AutoGeneration( const UserProc &userProc){
185    if( userProc.GetName() == "InitializeUserTypes"
186        && userProc.HasParentClass()
187        && userProc.GetParentClass().GetName() == "_System_TypeBase" )
188    {
189        ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypes(
190            compiler.GetObjectModule().meta.GetClasses()
191        );
192    }
193    else if( userProc.GetName() == "InitializeUserTypesForBaseType"
194        && userProc.HasParentClass()
195        && userProc.GetParentClass().GetName() == "_System_TypeBase" )
196    {
197        ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypesForBaseType(
198            compiler.GetObjectModule().meta.GetClasses()
199        );
200    }
201    else if( userProc.GetName() == "RegisterGlobalRoots"
202        && userProc.HasParentClass()
203        && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" )
204    {
205        Compile_AddGlobalRootsForGc();
206    }
207    else if( userProc.GetName() == compiler.globalAreaProcName )
208    {
209        ////////////////////////////////////////
210        // グローバル領域をコンパイル
211        ////////////////////////////////////////
212
213        UserProc::pGlobalProc = &userProc;
214
215        int BackCp = cp;
216        cp=-1;
217
218        //クラスに属する静的メンバを定義
219        ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember(
220            compiler.GetObjectModule().meta.GetClasses()
221        );
222
223        //グローバル実行領域をコンパイル開始
224        CompileBuffer(0,0);
225
226        //Goto未知ラベルスケジュールが存在したらエラーにする
227        BOOST_FOREACH( const GotoLabelSchedule *pGotoLabelSchedule, compiler.codeGenerator.gotoLabelSchedules )
228        {
229            if(pGotoLabelSchedule->GetName().size()>0){
230                compiler.errorMessenger.Output(6,pGotoLabelSchedule->GetName(),pGotoLabelSchedule->GetSourceCodePos());
231            }
232            else{
233                char temporary[255];
234                sprintf(temporary,"%d",pGotoLabelSchedule->GetLineNum());
235                compiler.errorMessenger.Output(6,temporary,pGotoLabelSchedule->GetSourceCodePos());
236            }
237        }
238
239        cp=BackCp;
240    }
241    else if( userProc.HasParentClass()
242        && userProc.IsCastOperator()
243        && userProc.ReturnType().IsInterface() )
244    {
245        // インターフェイス型にキャストするためのメソッド
246
247        int vtblMasterListIndex = userProc.GetParentClass().GetVtblMasterListIndex( &userProc.ReturnType().GetClass() );
248
249        char temporary[1024];
250        sprintf( temporary,
251            "Return New %s(ObjPtr( This ),Get_LONG_PTR( (Get_LONG_PTR( ObjPtr(This)+SizeOf(VoidPtr) ) + SizeOf(LONG_PTR)*%d) As VoidPtr ) As VoidPtr )",
252            userProc.ReturnType().GetClass().GetName().c_str(),
253            vtblMasterListIndex
254        );
255        MakeMiddleCode( temporary );
256
257        ChangeOpcode( temporary );
258    }
259    else{
260        compiler.errorMessenger.OutputFatalError();
261    }
262}
263
264void _compile_proc(const UserProc *pUserProc)
265{
266    extern char *basbuf;
267    extern HANDLE hHeap;
268    int i3,i4,BaseOffset;
269    char temporary[VN_SIZE];
270
271    if( pUserProc->GetLocalVars().size() ){
272        compiler.errorMessenger.OutputFatalError();
273        return;
274    }
275
276    trace_for_sourcecodestep( "★★★ " << FormatEscapeSequenceStringToDefaultString( pUserProc->GetFullName() ) << "のコンパイルを開始" );
277
278    pUserProc->CompleteCompile();
279
280    extern BOOL bDebugSupportProc;
281    if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0)
282    {
283        if( !compiler.IsDebug() )
284        {
285            return;
286        }
287        bDebugSupportProc=1;
288    }
289    else bDebugSupportProc=0;
290
291    if( pUserProc->GetCodeSize() != 0 || pUserProc->GetNativeCode().GetSize() != 0 )
292    {
293        // 既にコード生成が行われている場合はエラー
294        compiler.errorMessenger.OutputFatalError();
295    }
296
297    compiler.StartProcedureCompile( pUserProc );
298
299    if(pUserProc->IsAutoGenerationSystem()){
300        ////////////////////
301        // 特殊関数
302        ////////////////////
303
304        extern int AllLocalVarSize;
305        AllLocalVarSize=0;
306
307        SystemProc(*pUserProc);
308        return;
309    }
310
311    if( !pUserProc->IsAutoGeneration() )
312    {
313        // 対象のソースコードを含むオブジェクトモジュールのインデックスを指定する
314        // ※テンプレート展開がされている場合、対象のソースコードが現在のオブジェクトモジュールではない場合がある
315        compiler.SetCurrentRelationalObjectModuleIndexForSource( pUserProc->GetSourceCodePosition().GetRelationalObjectModuleIndex() );
316        basbuf = const_cast<char *>(compiler.GetCurrentSource().GetBuffer());
317
318        cp=pUserProc->GetSourceCodePosition().GetPos();
319        for(;;cp++){
320            if(IsCommandDelimitation(basbuf[cp])) break;
321        }
322        cp--;
323    }
324
325    //ローカル変数に関する情報
326    extern int AllLocalVarSize;
327    AllLocalVarSize=0;
328
329    //パラメータ用の変数データを考慮
330    for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
331        Parameter &param = *pUserProc->RealParams()[i3];
332
333        Variable *pVar = new Variable(
334            ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( param.GetVarName().c_str() ),
335            param,
336            false,
337            param.IsRef(),
338            "",
339            false
340        );
341
342        if( param.IsArray() ){
343            pVar->SetArray( param.GetSubscripts() );
344        }
345
346        int varSize;
347        if( param.IsRef() == false && param.IsStruct() ){
348            //構造体のByValパラメータ
349            pVar->ThisIsParameter();
350            varSize=PTR_SIZE;
351        }
352        else{
353            if( param.IsArray() == false ){
354                varSize = pVar->GetMemorySize();
355            }
356            else{
357                varSize=PTR_SIZE;
358            }
359        }
360        AllLocalVarSize+=varSize;
361        pVar->SetOffsetAddress( AllLocalVarSize );
362
363        //レキシカルスコープ情報
364        pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
365        pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
366        pVar->isLiving = true;
367
368        pUserProc->GetLocalVars().push_back( pVar );
369    }
370
371    //Thisポインタを示すローカルオフセット値をセット
372    extern int LocalVar_ThisPtrOffset;
373    LocalVar_ThisPtrOffset=AllLocalVarSize;
374
375    BaseOffset=AllLocalVarSize;
376
377    //ret用のアドレスを考慮
378    AllLocalVarSize+=sizeof(long);
379
380
381    ///////////////////////
382    // ここからコード生成
383
384    //sub esp,AllLocalVarSize(スケジュール)
385    const PertialSchedule *pAllLocalVarPertialSchedule = compiler.codeGenerator.op_sub_esp( 0, true );
386
387    //push ebp
388    compiler.codeGenerator.op_push(REG_EBP);
389
390    //mov ebp,esp
391    compiler.codeGenerator.op_mov_RR( REG_EBP, REG_ESP );
392
393    //push ebx
394    compiler.codeGenerator.op_push(REG_EBX);
395
396    //push esi
397    compiler.codeGenerator.op_push( REG_ESI );
398
399    //push edi
400    compiler.codeGenerator.op_push( REG_EDI );
401
402    if( !pUserProc->ReturnType().IsNull() ){
403        //戻り値が存在するとき
404
405        const char *temp = pUserProc->GetName().c_str();
406        if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
407            temp = "_System_ReturnValue";
408        }
409
410        if( pUserProc->ReturnType().IsStruct() ){
411            //戻り値用の構造体(値型)はパラメータで引き渡される
412        }
413        else{
414            if( pUserProc->ReturnType().IsObject() ){
415                sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() );
416            }
417            else{
418                //戻り値用の変数の定義
419                sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() );
420            }
421
422            OpcodeDim(temporary,0);
423        }
424    }
425
426    //プロシージャ抜け出しスケジュール(Exit Sub/Function)
427    compiler.codeGenerator.exitSubCodePositions.clear();
428
429    //ラベル管理オブジェクトを初期化
430    compiler.codeGenerator.gotoLabels.clear();
431
432    //Gotoラベルスケジュール
433    compiler.codeGenerator.gotoLabelSchedules.clear();
434
435    //With情報のメモリを確保
436    extern WITHINFO WithInfo;
437    WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1);
438    WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1);
439    WithInfo.num=0;
440
441    // 重複エラー情報をクリア
442    compiler.errorMessenger.ClearSynonymKeyWords();
443
444    //Continueアドレスを初期化
445    compiler.codeGenerator.ClearContinueArea();
446
447    //レキシカルスコープ情報を初期化
448    compiler.codeGenerator.lexicalScopes.Init( compiler.codeGenerator.GetNativeCodeSize() );
449
450    const PertialSchedule *pEspOffsetPertialSchedule = NULL;
451    if( compiler.IsDebug() && bDebugSupportProc == 0 )
452    {
453        //push dword ptr[ebp+(AllLocalVarSize-BaseOffset)](スケジュール)
454        pEspOffsetPertialSchedule = compiler.codeGenerator.op_push_M( REG_EBP, 0, Schedule::None, true );
455
456        //push dword ptr[ebp](以前のebp)
457        compiler.codeGenerator.op_push_M( REG_EBP );
458
459        //call _DebugSys_StartProc
460        extern const UserProc *pSub_DebugSys_StartProc;
461        compiler.codeGenerator.op_call(pSub_DebugSys_StartProc);
462    }
463
464    if( compiler.IsCompilingClass() ){
465        if( pUserProc->GetName() == compiler.GetCompilingClass().GetName() ){
466            ////////////////////////////////////
467            // コンストラクタをコンパイルするとき
468            ////////////////////////////////////
469
470            //コンストラクタのコンパイル開始を通知
471            compiler.GetCompilingClass().NotifyStartConstructorCompile();
472
473            //基底クラスかどうかの識別
474            //(継承元がインターフェイスの場合も基底クラスと見なす)
475            BOOL bThisIsSuperClass;
476            if( !compiler.GetCompilingClass().HasSuperClass() ) bThisIsSuperClass=1;
477            else if( compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod() == NULL ){
478                //インターフェイスを継承したときはコンストラクタを持たない
479                bThisIsSuperClass=1;
480            }
481            else bThisIsSuperClass=0;
482
483            if(!bThisIsSuperClass){
484                /* サブクラスコンストラクタをコンパイルしているときは、
485                    基底クラスのコンストラクタを呼び出す */
486
487                i3=cp+1;
488                while(IsCommandDelimitation(basbuf[i3])) i3++;
489                for(i4=0;;i3++,i4++){
490                    if(!IsVariableChar(basbuf[i3])){
491                        temporary[i4]=0;
492                        break;
493                    }
494                    temporary[i4]=basbuf[i3];
495                }
496                if( compiler.GetCompilingClass().GetSuperClass().GetName() == temporary ){
497                    //基底クラスのコンストラクタを呼び出す
498                    cp=i3;
499                    for(i4=0;;cp++,i4++){
500                        if(IsCommandDelimitation(basbuf[cp])){
501                            temporary[i4]=0;
502                            break;
503                        }
504                        temporary[i4]=basbuf[cp];
505                    }
506                    if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
507                        compiler.errorMessenger.Output(1,NULL,cp);
508                    }
509                    RemoveStringPare(temporary);
510
511                    Type dummyType;
512                    CallProc( PROC_DEFAULT
513                        , &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc()
514                        , compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc().GetName().c_str()
515                        , temporary
516                        , Type()        // baseTypeはなし
517                        , dummyType
518                    );
519                }
520                else{
521                    //基底クラスのコンストラクタを暗黙的に呼び出す
522                    Opcode_CallProc("",
523                        &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc(),
524                        0,
525                        ""
526                    );
527                }
528            }
529        }
530        else if( pUserProc->IsDestructor() ){
531            //デストラクタをコンパイルしたとき
532
533            //デストラクタのコンパイル開始を通知
534            compiler.GetCompilingClass().NotifyStartDestructorCompile();
535        }
536    }
537
538    //////////////////////////////////////////
539    //////////////////////////////////////////
540    ////// プロシージャ内をコンパイル ////////
541    if( pUserProc->IsAutoGeneration() ){
542        AutoGeneration( *pUserProc );
543    }
544    else{
545        if(pUserProc->IsMacro()){
546            CompileBuffer(ESC_ENDMACRO,0);
547        }
548        else{
549            if(pUserProc->IsSub()){
550                CompileBuffer(ESC_ENDSUB,0);
551            }
552            else if(pUserProc->IsFunction()){
553                CompileBuffer(ESC_ENDFUNCTION,0);
554            }
555        }
556    }
557    //////////////////////////////////////////
558    //////////////////////////////////////////
559
560    if( compiler.IsCompilingClass() ){
561
562        if( compiler.GetCompilingClass().IsCompilingConstructor() ){
563            // コンストラクタをコンパイルしていたとき
564
565            // コンストラクタのコンパイルが完了したことを通知
566            compiler.GetCompilingClass().NotifyFinishConstructorCompile();
567        }
568        else if( pUserProc->IsDestructor() ){
569            ////////////////////////////////////
570            //デストラクタをコンパイルしたとき
571            ////////////////////////////////////
572
573            // デストラクタのコンパイルが完了したことを通知
574            compiler.GetCompilingClass().NotifyFinishDestructorCompile();
575
576            if( compiler.GetCompilingClass().HasSuperClass() ){
577                /* サブクラスのデストラクタをコンパイルしているときは、
578                    基底クラスのデストラクタを呼び出す */
579
580                const CMethod *method = compiler.GetCompilingClass().GetSuperClass().GetDestructorMethod();
581                if( method ){
582                    Opcode_CallProc("",
583                        &method->GetUserProc(),
584                        0,
585                        ""
586                    );
587                }
588            }
589        }
590    }
591
592    //With情報のメモリを解放
593    for(i3=0;i3<WithInfo.num;i3++){
594        compiler.errorMessenger.Output(22,"With",WithInfo.pWithCp[i3]);
595        HeapDefaultFree(WithInfo.ppName[i3]);
596    }
597    HeapDefaultFree(WithInfo.ppName);
598    HeapDefaultFree(WithInfo.pWithCp);
599
600    //push ebp
601    AllLocalVarSize+=sizeof(long);
602
603    //ローカルオブジェクトの解放処理
604    compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
605
606    //プロシージャ抜け出しスケジュール(Exit Sub/Function)
607    compiler.codeGenerator.ResolveExitSubSchedule();
608
609    if( compiler.IsDebug() && bDebugSupportProc == 0 )
610    {
611        compiler.codeGenerator.opfix( pEspOffsetPertialSchedule, AllLocalVarSize-BaseOffset-sizeof(long) );
612
613        //call _DebugSys_EndProc
614        extern const UserProc *pSub_DebugSys_EndProc;
615        compiler.codeGenerator.op_call(pSub_DebugSys_EndProc);
616    }
617
618    if( !pUserProc->ReturnType().IsNull() ){
619        //戻り値をeax、edxに設定
620        RELATIVE_VAR RelativeVar;
621
622        const char *temp = pUserProc->GetName().c_str();
623        if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
624            temp="_System_ReturnValue";
625        }
626        GetVarOffsetReadWrite(temp,&RelativeVar,Type());
627
628        const Type &returnType = pUserProc->ReturnType();
629        if( returnType.IsObject() || returnType.IsStruct() )
630        {
631            SetVarPtrToEax(&RelativeVar);
632            if( returnType.IsObject() )
633            {
634                //mov eax,dword ptr[eax]
635                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
636            }
637        }
638        else if( returnType.IsReal() )
639        {
640            //fld qword ptr[ebp+offset]
641            compiler.codeGenerator.localVarPertialSchedules.push_back(
642                compiler.codeGenerator.op_fld_base_offset( returnType.GetBasicType(), REG_EBP, RelativeVar.offset, Schedule::None, true )
643            );
644        }
645        else if( returnType.Is64() )
646        {
647            //mov eax,dword ptr[ebp+offset]
648            compiler.codeGenerator.localVarPertialSchedules.push_back(
649                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true )
650            );
651
652            //mov edx,dword ptr[ebp+offset+sizeof(long)]
653            compiler.codeGenerator.localVarPertialSchedules.push_back(
654                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EBP, RelativeVar.offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
655            );
656        }
657        else if( returnType.GetSize() == sizeof(long) )
658        {
659            //mov eax,dword ptr[ebp+offset]
660            compiler.codeGenerator.localVarPertialSchedules.push_back(
661                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true )
662            );
663        }
664        else if( returnType.GetSize() == sizeof(short) )
665        {
666            //xor eax,eax(eaxを0に初期化する)
667            compiler.codeGenerator.op_zero_reg(REG_EAX);
668
669            //mov ax,word ptr[ebp+offset]
670            compiler.codeGenerator.localVarPertialSchedules.push_back(
671                compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true )
672            );
673        }
674        else if( returnType.GetSize() == sizeof(char) )
675        {
676            //xor eax,eax(eaxを0に初期化する)
677            compiler.codeGenerator.op_zero_reg(REG_EAX);
678
679            //mov al,byte ptr[ebp+offset]
680            compiler.codeGenerator.localVarPertialSchedules.push_back(
681                compiler.codeGenerator.op_mov_RM( sizeof(char), REG_EAX, REG_EBP, RelativeVar.offset, MOD_BASE_DISP32, Schedule::None, true )
682            );
683        }
684        else
685        {
686            compiler.errorMessenger.OutputFatalError();
687        }
688    }
689
690    //ローカル変数アドレススケジュール
691    BOOST_FOREACH( const PertialSchedule *pPertialSchedule, compiler.codeGenerator.localVarPertialSchedules )
692    {
693        compiler.codeGenerator.opfix_offset( pPertialSchedule, AllLocalVarSize );
694    }
695    compiler.codeGenerator.localVarPertialSchedules.clear();
696    BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){
697        //後にデバッグで利用する
698        pVar->SetOffsetAddress( AllLocalVarSize - pVar->GetOffsetAddress() );
699    }
700
701    //push ebp、ret用のアドレスを考慮
702    AllLocalVarSize-=sizeof(long)*2;
703
704    //ローカル変数用メモリを確保するためのスケジュール(subコマンド)
705    compiler.codeGenerator.opfix( pAllLocalVarPertialSchedule, AllLocalVarSize - BaseOffset );
706
707    //pop edi
708    compiler.codeGenerator.op_pop( REG_EDI );
709
710    //pop esi
711    compiler.codeGenerator.op_pop( REG_ESI );
712
713    //pop ebx
714    compiler.codeGenerator.op_pop(REG_EBX);
715
716    if( compiler.IsDebug() )
717    {
718        //cmp esp,ebp
719        compiler.codeGenerator.op_cmp_RR( REG_ESP, REG_EBP );
720
721        //je 6(次のcallとbreakpointを飛び越す)
722        compiler.codeGenerator.op_je( 6 );
723
724        //call _esp_error
725        extern const UserProc *pSub_esp_error;
726        compiler.codeGenerator.op_call( pSub_esp_error );
727
728        breakpoint;
729    }
730
731    //mov esp,ebp
732    compiler.codeGenerator.op_mov_RR( REG_ESP, REG_EBP );
733
734    //pop ebp
735    compiler.codeGenerator.op_pop(REG_EBP);
736
737    //add esp AllLocalVarSize
738    compiler.codeGenerator.op_add_esp(AllLocalVarSize-BaseOffset);
739
740    if( BaseOffset==0 || pUserProc->IsCdecl() ){
741        //ret
742        compiler.codeGenerator.op_ret();
743    }
744    else{
745        //ret BaseOffset(パラメータ分のスタック領域を解放)
746        compiler.codeGenerator.op_ret( (_int16)BaseOffset );
747    }
748
749    compiler.FinishProcedureCompile();
750
751
752    //ローカル変数のネーム情報は後に解放する
753}
Note: See TracBrowser for help on using the repository browser.