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

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

Compiler::pCompilingClassメンバをprivateにし、setter/getterにあたるメソッドを用意した。

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