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

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

VarPtr?(This)をエラーとして扱うようにした。
・デリゲート生成時にThisに対するオブジェクトポインタが正常に取得できないバグを修正。

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