source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Func.cpp @ 537

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

UserProcクラスによるコンパイル中関数管理用メソッドを除去(すべてCompilerクラス内で処理するようにした)。

File size: 22.6 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8#include "FunctionValue.h"
9
10int GetFunctionFromName(char *FuncName){
11    if( lstrcmpi( FuncName, "CUDbl" ) == 0 )            return FUNC_CUDBL;
12    if( lstrcmpi( FuncName, "Fix" ) == 0 )              return FUNC_FIX;
13    if( lstrcmpi( FuncName, "Len" ) == 0 )              return FUNC_LEN;
14    if( lstrcmpi( FuncName, "AddressOf" ) == 0 )        return FUNC_ADDRESSOF;
15    if( lstrcmpi( FuncName, "SizeOf" ) == 0 )           return FUNC_SIZEOF;
16    if( lstrcmpi( FuncName, "VarPtr" ) == 0 )           return FUNC_VARPTR;
17    if( lstrcmpi( FuncName, "ObjPtr" ) == 0 )           return FUNC_OBJPTR;
18    if( lstrcmpi( FuncName, "__delegate_dynamicmethod_call" ) == 0 )    return FUNC_DELEGATE_DYNAMICMETHOD_CALL;
19    if( lstrcmpi( FuncName, "__delegate_staticmethod_call" ) == 0 )     return FUNC_DELEGATE_STATICMETHOD_CALL;
20    if( lstrcmpi( FuncName, "_System_GetNowScopeCatchAddresses" ) == 0 )return FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS;
21    if( lstrcmpi( FuncName, "_System_GetNowScopeFinallyAddresses" ) == 0 )return FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS;
22    if( lstrcmpi( FuncName, "_System_GetBp" ) == 0 )    return FUNC_SYSTEM_GET_BP;
23    if( lstrcmpi( FuncName, "_System_GetSp" ) == 0 )    return FUNC_SYSTEM_GET_SP;
24    if( lstrcmp( FuncName, "_System_GetComVtbl" ) == 0 )        return FUNC_SYSTEM_GET_COM_VTBL;
25    if( lstrcmp( FuncName, "_System_GetVtblList" ) == 0 )       return FUNC_SYSTEM_GET_VTBL_LIST;
26    if( lstrcmp( FuncName, "_System_GetDefaultConstructor" ) == 0 ) return FUNC_SYSTEM_GET_DEFAULT_CONSTRUCTOR;
27    if( lstrcmp( FuncName, "_System_GetDestructor" ) == 0 )         return FUNC_SYSTEM_GET_DESTRUCTOR;
28    if( lstrcmpi( FuncName, "GetDouble" ) == 0 )        return FUNC_GETDOUBLE;
29    if( lstrcmpi( FuncName, "GetSingle" ) == 0 )        return FUNC_GETSINGLE;
30    if( lstrcmpi( FuncName, "GetQWord" ) == 0 )         return FUNC_GETQWORD;
31    if( lstrcmpi( FuncName, "GetDWord" ) == 0 )         return FUNC_GETDWORD;
32    if( lstrcmpi( FuncName, "GetWord" ) == 0 )          return FUNC_GETWORD;
33    if( lstrcmpi( FuncName, "GetByte" ) == 0 )          return FUNC_GETBYTE;
34    return 0;
35}
36
37void Opcode_Func_Fix(const char *lpszParms){
38    Type resultType;
39    if( !NumOpe( lpszParms, Type(), resultType ) ){
40        return;
41    }
42
43    if( resultType.IsDouble() ){
44        //fld qword ptr[esp]
45        compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
46
47        //fnstcw word ptr[esp]
48        compiler.codeGenerator.PutOld(
49            (char)0xD9,
50            (char)0x3C,
51            (char)0x24
52        );
53
54        //mov ax,word ptr[esp]
55        compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_ESP, 0, MOD_BASE );
56
57        //or ah,0Ch
58        compiler.codeGenerator.PutOld(
59            (char)0x80,
60            (char)0xCC,
61            (char)0x0C
62        );
63
64        //mov word ptr[esp-2],ax
65        compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EAX, REG_ESP, -2, MOD_BASE_DISP8 );
66
67        //fldcw word ptr[esp-2]
68        compiler.codeGenerator.PutOld(
69            (char)0xD9,
70            (char)0x6C,
71            (char)0x24,
72            (char)0xFE
73        );
74
75        //fistp dword ptr[esp+4]
76        compiler.codeGenerator.PutOld(
77            (char)0xDB,
78            (char)0x5C,
79            (char)0x24,
80            (char)0x04
81        );
82
83        //fldcw word ptr[esp]
84        compiler.codeGenerator.PutOld(
85            (char)0xD9,
86            (char)0x2C,
87            (char)0x24
88        );
89
90        //add esp,4
91        compiler.codeGenerator.op_add_esp(4);
92    }
93    else if( resultType.IsSingle() ){
94        //fld dword ptr[esp]
95        compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
96
97        //sub esp,4
98        compiler.codeGenerator.op_sub_esp(4);
99
100        //fnstcw word ptr[esp]
101        compiler.codeGenerator.PutOld(
102            (char)0xD9,
103            (char)0x3C,
104            (char)0x24
105        );
106
107        //mov ax,word ptr[esp]
108        compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_ESP, 0, MOD_BASE );
109
110        //or ah,0Ch
111        compiler.codeGenerator.PutOld(
112            (char)0x80,
113            (char)0xCC,
114            (char)0x0C
115        );
116
117        //mov word ptr[esp-2],ax
118        compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EAX, REG_ESP, -2, MOD_BASE_DISP8 );
119
120        //fldcw word ptr[esp-2]
121        compiler.codeGenerator.PutOld(
122            (char)0xD9,
123            (char)0x6C,
124            (char)0x24,
125            (char)0xFE
126        );
127
128        //fistp dword ptr[esp+4]
129        compiler.codeGenerator.PutOld(
130            (char)0xDB,
131            (char)0x5C,
132            (char)0x24,
133            (char)0x04
134        );
135
136        //fldcw word ptr[esp]
137        compiler.codeGenerator.PutOld(
138            (char)0xD9,
139            (char)0x2C,
140            (char)0x24
141        );
142
143        //add esp,4
144        compiler.codeGenerator.op_add_esp(4);
145    }
146    else if( resultType.Is64() ){
147        //pop eax
148        compiler.codeGenerator.op_pop(REG_EAX);
149
150        //add esp,4
151        compiler.codeGenerator.op_add_esp(4);
152
153        //push eax
154        compiler.codeGenerator.op_push(REG_EAX);
155    }
156
157    //pop eax
158    compiler.codeGenerator.op_pop(REG_EAX);
159}
160
161void Opcode_Func_CUDbl(const char *Parameter){
162    Type resultType;
163    if( !NumOpe(Parameter,Type(),resultType) ){
164        return;
165    }
166    ChangeTypeToLong(resultType.GetBasicType());
167
168    //pop eax
169    compiler.codeGenerator.op_pop(REG_EAX);
170
171    //push 0
172    compiler.codeGenerator.op_push_V( 0 );
173
174    //push eax
175    compiler.codeGenerator.op_push(REG_EAX);
176
177    //fild qword ptr[esp]
178    compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
179
180    //add esp,8
181    compiler.codeGenerator.op_add_esp(8);
182}
183void Opcode_Func_Len(const char *Parameter){
184    BOOL bArrayHead;
185
186    const char *tempParm=Parameter;
187    char temporary[VN_SIZE];
188    char temp2[32];
189    Type type;
190    if( !GetVarType(Parameter,type,0) ){
191        sprintf(temporary,"_System_DummyStr2=%s",Parameter);
192        OpcodeCalc(temporary);
193
194        lstrcpy(temp2,"_System_DummyStr2");
195        tempParm=temp2;
196
197        type.SetType( DEF_OBJECT, compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() );
198    }
199
200    if( type.IsStringClass() ){
201        //Stringオブジェクトの場合
202        sprintf(temporary,"%s.Length",tempParm);
203
204        int reg=REG_RAX;
205        NumOpe(temporary,Type(),Type());
206
207        //pop eax
208        compiler.codeGenerator.op_pop(REG_EAX);
209
210        return;
211    }
212
213    Subscripts subscripts;
214    RELATIVE_VAR RelativeVar;
215    if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,&subscripts)) return;
216
217    if(type.GetBasicType()&FLAG_PTR){
218        type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
219
220        bArrayHead=1;
221    }
222    else bArrayHead=0;
223
224    int typeSize = type.GetSize();
225
226    if(bArrayHead) typeSize*=JumpSubScripts(subscripts);
227
228    //mov eax,typeSize
229    compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
230}
231
232void _Opcode_Func_AddressOf( const char *methodInstanceName, const UserProc &userProc )
233{
234    if( userProc.IsVirtual() ){
235        ///////////////////////////////
236        // 仮想関数の場合
237        // thisポインタをrcxにコピー
238        ///////////////////////////////
239
240        const CClass *pobj_c;
241
242        char ObjectName[VN_SIZE];
243        ReferenceKind referenceKind;
244        SplitObjectName( methodInstanceName, ObjectName, referenceKind );
245
246        if(ObjectName[0]){
247            if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
248            else{
249                RELATIVE_VAR RelativeVar;
250                Type type;
251                if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
252                SetVarPtrToEax(&RelativeVar);
253
254                //mov ecx,eax
255                compiler.codeGenerator.op_mov_RR(REG_ECX,REG_EAX);
256
257                //参照タイプが整合しているかをチェック
258                if( !( type.IsObject() && referenceKind == RefDot
259                    || type.IsObjectPtr() && referenceKind == RefPointer ) )
260                {
261                    compiler.errorMessenger.Output(104,ObjectName,cp);
262                }
263
264                if(type.IsObjectPtr()){
265                    //mov ecx,dword ptr[ecx]
266                    compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
267                }
268            }
269        }
270        else{
271InClassMember:
272            //自身のオブジェクトのThisポインタをrcxにコピー
273            SetThisPtrToReg(REG_RCX);
274
275            pobj_c = &compiler.GetCompilingClass();
276        }
277
278
279        int vtblIndex;
280        if( pobj_c->IsInterface() )
281        {
282            // インターフェイスメソッド呼び出し
283
284            int offset_vtbl = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__vtbl" );
285
286
287            // vtblのポインタを取得
288            //mov edx,dword ptr[ecx+offset_vtbl]
289            compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, offset_vtbl, MOD_BASE_DISP8 );
290
291            int offset_this = compiler.GetObjectModule().meta.GetClasses().GetInterfaceInfoClassPtr()->GetMemberOffset( "__this" );
292
293
294
295            // インターフェイスの場合は更に__thisを取得する
296            //mov rcx,qword ptr[rcx+offset_this]
297            compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, offset_this, MOD_BASE_DISP8 );
298
299            int vtblMasterListIndex;
300            pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
301            if( vtblMasterListIndex != 0 )
302            {
303                compiler.errorMessenger.OutputFatalError();
304            }
305        }
306        else if( pobj_c->IsComInterface() )
307        {
308            // COMインターフェイス メソッド呼び出し
309
310            //仮想関数(オブジェクトメソッド)呼び出し
311            // pObj -> vtbl1 -> func1
312            //               -> func2
313            //               -> func3
314
315            int vtblMasterListIndex;
316            pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
317
318            // vtblのポインタを取得
319            //mov edx,dword ptr[ecx]
320            compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
321        }
322        else
323        {
324            //仮想関数(オブジェクトメソッド)呼び出し
325            // pObj -> vtbl_master_list -> vtbl1 -> func1
326            //                                   -> func2
327            //                                   -> func3
328            //                          -> vtbl2 -> func1
329            //                                   -> func2
330            //                                   -> func3
331
332            int vtblMasterListIndex;
333            pobj_c->GetVtblMasterListIndexAndVtblIndex( &userProc, vtblMasterListIndex, vtblIndex );
334
335            // vtblマスターリストのポインタを取得
336            //mov edx,dword ptr[ecx+sizeof(com_vtbl)]
337            compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, PTR_SIZE, MOD_BASE_DISP8 );
338           
339            // vtblのポインタを取得
340            //mov edx,dword ptr[edx+vtblMasterListIndex]
341            compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_EDX, vtblMasterListIndex*PTR_SIZE, MOD_BASE_DISP32 );
342        }
343
344        //mov eax,dword ptr[edx+func_index]
345        if( vtblIndex * PTR_SIZE <= 0x7F )
346        {
347            compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,vtblIndex*PTR_SIZE,MOD_BASE_DISP8);
348        }
349        else{
350            compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,vtblIndex*PTR_SIZE,MOD_BASE_DISP32);
351        }
352    }
353    else{
354        //一般の関数
355
356        //mov eax,ProcAddr
357        compiler.codeGenerator.op_addressof( REG_EAX, &userProc );
358    }
359
360    userProc.Using();
361}
362void Opcode_CreateDelegate( const CClass &dgClass, const char *methodInstanceName, const UserProc &userProc )
363{
364    /////////////////////////////////////////////////////////////////
365    // 関数ポインタをpush
366    /////////////////////////////////////////////////////////////////
367
368    //push AddressOf(userProc)
369    _Opcode_Func_AddressOf( methodInstanceName, userProc );
370    compiler.codeGenerator.op_push( REG_EAX );
371
372
373    if( userProc.GetMethod().IsDynamic() )
374    {
375        /////////////////////////////////////////////////////////////////
376        // オブジェクト ポインタをpush
377        /////////////////////////////////////////////////////////////////
378
379        // オブジェクト名を取得
380        char objectName[VN_SIZE];
381        char memberName[VN_SIZE];
382        char *thisPtrName = "This";
383        Type type;
384        if( SplitMemberName( methodInstanceName, objectName, memberName ) )
385        {
386            if( GetVarType( objectName, type, false ) )
387            {
388                thisPtrName = objectName;
389            }
390        }
391
392        // オブジェクト ポインタを取得
393        RELATIVE_VAR relativeVar;
394        GetVarOffsetReadOnly( thisPtrName, &relativeVar, type );
395        if( !type.IsObject() )
396        {
397            extern int cp;
398            compiler.errorMessenger.Output(1,NULL,cp);
399            return;
400        }
401
402        SetVarPtrToEax( &relativeVar );
403
404        //mov eax,dword ptr[eax]
405        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
406
407        //push eax
408        compiler.codeGenerator.op_push( REG_EAX );
409    }
410
411
412    /////////////////////////////////////////////////////////////////
413    // call _CreateDynamicDelegate/_CreateStaticDelegate
414    /////////////////////////////////////////////////////////////////
415
416    std::vector<const UserProc *> subs;
417    if( userProc.GetMethod().IsDynamic() )
418    {
419        dgClass.GetStaticMethods().Enum( "_CreateDynamicDelegate", subs );
420    }
421    else
422    {
423        dgClass.GetStaticMethods().Enum( "_CreateStaticDelegate", subs );
424    }
425
426    // call _CreateDynamicDelegate
427    compiler.codeGenerator.op_call( subs[0] );
428}
429void Opcode_Func_AddressOf( const char *name, const Type &baseType, bool isCallOn, Type &resultType )
430{
431    extern int cp;
432
433    const Parameters *pBaseParams = NULL;
434    const Type *pBaseReturnType = NULL;
435    if( baseType.IsProcPtr() )
436    {
437        // 左辺で関数ポインタを要求されているとき
438        const ProcPointer *pTempProcPointer = compiler.GetObjectModule().meta.GetProcPointers()[baseType.GetIndex()];
439        pBaseParams = &pTempProcPointer->Params();
440        pBaseReturnType = &pTempProcPointer->ReturnType();
441    }
442    else if( baseType.IsDelegate() )
443    {
444        // 左辺でデリゲートを要求されているとき
445        const Delegate *pTempDelegate = &baseType.GetClass().GetDelegate();
446        pBaseParams = &pTempDelegate->Params();
447        pBaseReturnType = &pTempDelegate->ReturnType();
448    }
449
450    const UserProc *pUserProc;
451    if( pBaseParams && pBaseReturnType )
452    {
453        //左辺の型にのっとり、オーバーロードを解決
454
455        std::vector<const UserProc *> subs;
456        GetOverloadSubHash( name, subs );
457        if( subs.size() == 0 ){
458            compiler.errorMessenger.Output(27,name,cp);
459            return;
460        }
461
462        //オーバーロードを解決
463        pUserProc=OverloadSolution( name, subs, *pBaseParams, Type(), Type() );
464
465        if( isCallOn )
466        {
467            // コード生成を伴う場合はエラーチェックを行う
468
469            if( baseType.IsDelegate() )
470            {
471                // デリゲート
472                // 共変戻り値、反変引数をサポート
473                if( !(
474                    pBaseParams->Equals( pUserProc->Params(), true )
475                    && ( pBaseReturnType->Equals( pUserProc->ReturnType() ) || pBaseReturnType->IsCovariant( pUserProc->ReturnType() ) )
476                    ) )
477                {
478                    compiler.errorMessenger.Output(67, name, cp );
479                }
480            }
481            else
482            {
483                // 関数ポインタ
484                if( !(
485                    pBaseParams->Equals( pUserProc->Params() )
486                    && pBaseReturnType->Equals( pUserProc->ReturnType() )
487                    ) )
488                {
489                    compiler.errorMessenger.Output(66, name, cp );
490                }
491            }
492        }
493
494        if(!pUserProc){
495            compiler.errorMessenger.Output(27,name,cp);
496            return;
497        }
498    }
499    else{
500        pUserProc=GetSubHash(name);
501        if(!pUserProc){
502            compiler.errorMessenger.Output(27,name,cp);
503            return;
504        }
505    }
506
507    if( baseType.IsDelegate() )
508    {
509        if( isCallOn )
510        {
511            // デリゲートのとき
512            Opcode_CreateDelegate( baseType.GetClass(), name, *pUserProc );
513        }
514        resultType = baseType;
515    }
516    else
517    {
518        if( isCallOn )
519        {
520            // 関数ポインタのとき
521            _Opcode_Func_AddressOf( name, *pUserProc );
522        }
523        resultType.SetBasicType( DEF_PTR_VOID );
524    }
525}
526void Opcode_Func_SizeOf( const std::string &typeName ){
527    Type tempType;
528    if( !compiler.StringToType( typeName, tempType ) ){
529        compiler.errorMessenger.Output(3,typeName,cp);
530        return;
531    }
532
533    int typeSize = ( tempType.IsObject() ) ?
534        tempType.GetClass().GetSize() : tempType.GetSize();
535
536    //mov eax,size
537    compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
538}
539void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn ){
540    if( isCallOn == false ){
541        // 戻り値の型を取得するだけ
542
543        //変数のアドレスを取得
544        if(!GetVarType( Parameter, resultType, true )) return;
545
546        resultType.PtrLevelUp();
547
548        return;
549    }
550
551    RELATIVE_VAR RelativeVar;
552
553    //変数のアドレスを取得
554    if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
555
556    int beforeType = resultType.GetBasicType();
557
558    resultType.PtrLevelUp();
559
560    SetVarPtrToEax(&RelativeVar);
561}
562void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
563    if( isCallOn == false ){
564        // 戻り値の型を取得するだけ
565
566        //変数のアドレスを取得
567        if(!GetVarType( Parameter, resultType, true )) return;
568
569        resultType.PtrLevelUp();
570
571        return;
572    }
573
574    RELATIVE_VAR RelativeVar;
575
576    //変数のアドレスを取得
577    if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
578
579    int beforeType = resultType.GetBasicType();
580
581    resultType.PtrLevelUp();
582
583    SetVarPtrToEax(&RelativeVar);
584
585    if( lstrcmpi( Parameter, "This" )==0 ){
586        // Thisの場合は特別にオブジェクトポインタが返ってくるので、何もせずに抜ける
587    }
588    else if( beforeType == DEF_OBJECT ){
589        //参照をオブジェクトポインタに変更
590
591        //mov eax,dword ptr[eax]
592        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
593    }
594    else{
595        compiler.errorMessenger.Output(134,NULL,cp );
596    }
597}
598
599void Opcode_Func_delegate_call( const char *paramsStr, Type &resultType, bool isDynamicCall, bool isCallOn )
600{
601    if( isCallOn )
602    {
603        int i = 0;
604        char methodPtrParamStr[VN_SIZE];
605        i = GetOneParameter( paramsStr, i, methodPtrParamStr );
606
607        char objPtrValueStr[VN_SIZE]="";
608        if( isDynamicCall )
609        {
610            i = GetOneParameter( paramsStr, i, objPtrValueStr );
611        }
612
613        Opcode_CallDelegate( compiler.GetCompilingClass().GetDelegate(), methodPtrParamStr, objPtrValueStr, paramsStr + i );
614    }
615
616    resultType = compiler.GetCompilingUserProc().ReturnType();
617}
618void Opcode_Func_System_Get_Bp()
619{
620    //mov eax,ebp
621    compiler.codeGenerator.op_mov_RR(REG_EAX,REG_EBP);
622}
623void Opcode_Func_System_Get_Sp()
624{
625    //mov eax,esp
626    compiler.codeGenerator.op_mov_RR(REG_EAX,REG_ESP);
627}
628
629void Opcode_Func_System_GetComVtbl( const char *parameter )
630{
631    Type classType;
632    compiler.StringToType( parameter, classType );
633
634    // mov eax,com_vtbl
635    compiler.codeGenerator.op_mov_RV_com_vtbl( REG_EAX, &classType.GetClass() );
636}
637void Opcode_Func_System_GetVtblList( const char *parameter )
638{
639    Type classType;
640    compiler.StringToType( parameter, classType );
641
642    // mov eax,com_vtbl
643    compiler.codeGenerator.op_mov_RV_vtbl( REG_EAX, &classType.GetClass() );
644}
645void Opcode_Func_System_GetDefaultConstructor( const char *parameter )
646{
647    Type classType;
648    compiler.StringToType( parameter, classType );
649
650    if( classType.GetClass().GetConstructorMethod() )
651    {
652        //mov eax,ProcAddr
653        compiler.codeGenerator.op_addressof( REG_EAX, &classType.GetClass().GetConstructorMethod()->GetUserProc() );
654    }
655    else
656    {
657        // デフォルトコンストラクタを持たない
658
659        //xor eax,eax
660        compiler.codeGenerator.op_zero_reg( REG_EAX );
661    }
662}
663void Opcode_Func_System_GetDestructor( const char *parameter )
664{
665    Type classType;
666    compiler.StringToType( parameter, classType );
667
668    //mov eax,ProcAddr
669    compiler.codeGenerator.op_addressof( REG_EAX, &classType.GetClass().GetDestructorMethod()->GetUserProc() );
670}
671
672void Opcode_Func_GetPtrData(const char *Parameter,const int type){
673    Type tempType;
674    if( !NumOpe(Parameter,Type(),tempType) ){
675        return;
676    }
677    if(!tempType.IsWhole()){
678        compiler.errorMessenger.Output(11,Parameter,cp);
679        return;
680    }
681    ChangeTypeToLong(tempType.GetBasicType());
682
683    if(type==DEF_DOUBLE){
684        //pop eax
685        compiler.codeGenerator.op_pop(REG_EAX);
686
687        //fld qword ptr[eax]
688        compiler.codeGenerator.PutOld(
689            (char)0xDD,
690            (char)0x00
691        );
692    }
693    else if(type==DEF_SINGLE||type==DEF_DWORD){
694        //pop eax
695        compiler.codeGenerator.op_pop(REG_EAX);
696
697        //mov eax,dword ptr[eax]
698        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
699    }
700    else if(type==DEF_QWORD){
701        //pop ecx
702        compiler.codeGenerator.op_pop(REG_ECX);
703
704        //mov eax,dword ptr[ecx]
705        compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
706
707        //mov edx,dword ptr[ecx+sizeof(long)]
708        compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
709    }
710    else if(type==DEF_WORD){
711        //pop ebx
712        compiler.codeGenerator.op_pop(REG_EBX);
713
714        //xor eax,eax
715        compiler.codeGenerator.op_xor_RR(REG_EAX);
716
717        //mov ax,word ptr[ebx]
718        compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_EBX, 0, MOD_BASE );
719    }
720    else if(type==DEF_BYTE){
721        //pop ebx
722        compiler.codeGenerator.op_pop(REG_EBX);
723
724        //xor eax,eax
725        compiler.codeGenerator.op_xor_RR(REG_EAX);
726
727        //mov al,byte ptr[ebx]
728        compiler.codeGenerator.op_mov_RM( sizeof(char), REG_EAX, REG_EBX, 0, MOD_BASE );
729    }
730}
731
732bool Opcode_CallFunc( const char *Parameter, const int FuncNum, const Type &baseType, Type &resultType, bool isCallOn )
733{
734    switch(FuncNum){
735        case FUNC_FIX:
736            if( isCallOn ) Opcode_Func_Fix(Parameter);
737            resultType.SetBasicType( DEF_LONG );
738            break;
739        case FUNC_CUDBL:
740            if( isCallOn ) Opcode_Func_CUDbl(Parameter);
741            resultType.SetBasicType( DEF_DOUBLE );
742            break;
743        case FUNC_LEN:
744            if( isCallOn ) Opcode_Func_Len(Parameter);
745            resultType.SetBasicType( DEF_LONG );
746            break;
747        case FUNC_ADDRESSOF:
748            Opcode_Func_AddressOf( Parameter, baseType, isCallOn, resultType );
749            break;
750        case FUNC_SIZEOF:
751            if( isCallOn ) Opcode_Func_SizeOf(Parameter);
752            resultType.SetBasicType( DEF_LONG );
753            break;
754        case FUNC_VARPTR:
755            Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
756            break;
757        case FUNC_OBJPTR:
758            Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
759            break;
760        case FUNC_DELEGATE_DYNAMICMETHOD_CALL:
761            Opcode_Func_delegate_call( Parameter, resultType, true, isCallOn );
762            break;
763        case FUNC_DELEGATE_STATICMETHOD_CALL:
764            Opcode_Func_delegate_call( Parameter, resultType, false, isCallOn );
765            break;
766        case FUNC_SYSTEM_GET_NOW_SCOPE_CATCH_ADDRESS:
767            if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeCatchAddress();
768            resultType.SetBasicType( DEF_PTR_VOID );
769            break;
770        case FUNC_SYSTEM_GET_NOW_SCOPE_FINALLY_ADDRESS:
771            if( isCallOn ) Exception::Opcode_Func_System_GetNowScopeFinallyAddress();
772            resultType.SetBasicType( DEF_PTR_VOID );
773            break;
774        case FUNC_SYSTEM_GET_BP:
775            if( isCallOn ) Opcode_Func_System_Get_Bp();
776            resultType.SetBasicType( DEF_LONG );
777            break;
778        case FUNC_SYSTEM_GET_SP:
779            if( isCallOn ) Opcode_Func_System_Get_Sp();
780            resultType.SetBasicType( DEF_LONG );
781            break;
782        case FUNC_SYSTEM_GET_COM_VTBL:
783            if( isCallOn ) Opcode_Func_System_GetComVtbl( Parameter );
784            resultType.SetBasicType( DEF_PTR_VOID );
785            break;
786        case FUNC_SYSTEM_GET_VTBL_LIST:
787            if( isCallOn ) Opcode_Func_System_GetVtblList( Parameter );
788            resultType.SetBasicType( DEF_PTR_VOID );
789            break;
790        case FUNC_SYSTEM_GET_DEFAULT_CONSTRUCTOR:
791            if( isCallOn ) Opcode_Func_System_GetDefaultConstructor( Parameter );
792            resultType.SetBasicType( DEF_PTR_VOID );
793            break;
794        case FUNC_SYSTEM_GET_DESTRUCTOR:
795            if( isCallOn ) Opcode_Func_System_GetDestructor( Parameter );
796            resultType.SetBasicType( DEF_PTR_VOID );
797            break;
798
799        case FUNC_GETDOUBLE:
800            if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
801            resultType.SetBasicType( DEF_DOUBLE );
802            break;
803        case FUNC_GETSINGLE:
804            if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
805            resultType.SetBasicType( DEF_SINGLE );
806            break;
807        case FUNC_GETQWORD:
808            if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
809            resultType.SetBasicType( DEF_QWORD );
810            break;
811        case FUNC_GETDWORD:
812            if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
813            resultType.SetBasicType( DEF_DWORD );
814            break;
815        case FUNC_GETWORD:
816            if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
817            resultType.SetBasicType( DEF_WORD );
818            break;
819        case FUNC_GETBYTE:
820            if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
821            resultType.SetBasicType( DEF_BYTE );
822            break;
823        default:
824            return false;
825    }
826    return true;
827}
Note: See TracBrowser for help on using the repository browser.