source: dev/trunk/ab5.0/abdev/compiler_x86/OperatorProc.cpp @ 673

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

・オーバーロード解決時、戻り値に型パラメータだった場合に型解決されずに、正しいオーバーロード解決が行われない不具合を修正。
・演算子メソッドの戻り値が型パラメータだったとき、型解決が行われない不具合を修正。

File size: 6.5 KB
RevLine 
[206]1#include "stdafx.h"
2
[225]3#include <Compiler.h>
4
[3]5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
[76]8void FreeTempObject(int reg,const CClass *pobj_c){
[465]9    if(!IsSafeReg(reg)) compiler.errorMessenger.Output(300,NULL,cp);
[3]10
[135]11    const CMethod *method = pobj_c->GetDestructorMethod();
[51]12    if( method ){
[3]13        //push reg
[225]14        compiler.codeGenerator.op_push(reg);
[3]15
16        //call DestructorProcAddr
[225]17        compiler.codeGenerator.op_call( &method->GetUserProc() );
[3]18    }
19
20    //push reg
[225]21    compiler.codeGenerator.op_push(reg);
[3]22
23    //call free
[206]24    extern const UserProc *pSub_free;
[225]25    compiler.codeGenerator.op_call(pSub_free);
[3]26}
27
[435]28int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,bool isNeedHeapFreeStructureStack[],int &sp)
[350]29{
30    Type leftType( type_stack[sp-2], index_stack[sp-2] );
31    Type rightType( type_stack[sp-1] & (~FLAG_CAST), index_stack[sp-1] );
32
[3]33    //オーバーロードされたオペレータ関数を呼び出す
[350]34    const CClass *pobj_c = &leftType.GetClass();
[3]35
[206]36    std::vector<const UserProc *> subs;
[342]37    pobj_c->GetDynamicMethods().Enum( idCalc, subs );
[50]38    if( subs.size() == 0 ){
[3]39        return 0;
40    }
41
42
43    //項の数
44    BOOL bTwoTerm=1;
45    if(idCalc==CALC_AS) bTwoTerm=0;
46
47
48    /////////////////////////////////////////////
49    // オーバーロード解決用のパラメータを設定
50    /////////////////////////////////////////////
51
[75]52    Parameters params;
[3]53
54    if(bTwoTerm){
[350]55        params.push_back( new Parameter( "", rightType ) );
[3]56    }
57
58    //オーバーロードを解決
59    char temporary[255];
60    if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
61    else GetCalcName(idCalc,temporary);
[424]62    const UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType, leftType );
[3]63
[75]64    if(!pUserProc){
65        if(bTwoTerm){
66            delete params[0];
67        }
[3]68        return -1;
69    }
70    else{
71        //オーバーロードされていないが、パラメータ個数が一致しないとき
[75]72        if(params.size()!=pUserProc->Params().size()){
73            if(bTwoTerm){
74                delete params[0];
75            }
[3]76            return -1;
77        }
78    }
79
[76]80    for(int i=0;i<(int)params.size();i++){
[3]81        CheckDifferentType(
[290]82            *pUserProc->Params()[i],
83            *params[i],
[448]84            NULL,
[3]85            i);
86    }
87
[75]88    if(bTwoTerm){
89        delete params[0];
90    }
[3]91
[350]92    int right_side_size = rightType.GetSize();
[3]93
94    if(bTwoTerm){
[75]95        if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){
[3]96            //一時オブジェクトはメソッド内で破棄される
[435]97            isNeedHeapFreeStructureStack[sp-1] = false;
[3]98        }
99    }
100
101
[75]102    if( pUserProc->ReturnType().IsStruct() ){
[3]103        //////////////////////////////////////////////////////
[64]104        // 戻り値に構造体インスタンスを持つ場合
105        // ※ByRef _System_ReturnValue パラメータ用領域を取得
[3]106        //////////////////////////////////////////////////////
107
[75]108        int object_size = pUserProc->ReturnType().GetClass().GetSize();
[3]109
110        //push object_size
[225]111        compiler.codeGenerator.op_push_V(object_size);
[3]112
113        //call calloc
[206]114        extern const UserProc *pSub_calloc;
[225]115        compiler.codeGenerator.op_call(pSub_calloc);
[3]116
117        //mov ebx,eax
[225]118        compiler.codeGenerator.op_mov_RR(REG_EBX,REG_EAX);
[3]119    }
120
121
122    //2つの項を取り出す
123    if(bTwoTerm){
124        if(right_side_size==sizeof(_int64)){
125            //pop eax
[225]126            compiler.codeGenerator.op_pop(REG_EAX);
[3]127
128            //pop edx
[225]129            compiler.codeGenerator.op_pop(REG_EDX);
[3]130        }
131        else{
132            //pop eax
[225]133            compiler.codeGenerator.op_pop(REG_EAX);
[3]134        }
135    }
136
137    //pop ecx
[225]138    compiler.codeGenerator.op_pop(REG_ECX);
[3]139
140
141    //ヒープ解放用に退避
[435]142    if(isNeedHeapFreeStructureStack[sp-1]){
[3]143        //mov esi,eax
[225]144        compiler.codeGenerator.op_mov_RR(REG_ESI,REG_EAX);
[3]145    }
[435]146    if(isNeedHeapFreeStructureStack[sp-2]){
[3]147        //mov edi,ecx
[225]148        compiler.codeGenerator.op_mov_RR(REG_EDI,REG_ECX);
[3]149    }
150
151
152
153    if(bTwoTerm){
154        if(right_side_size==sizeof(_int64)){
155            //push edx
[225]156            compiler.codeGenerator.op_push(REG_EDX);
[3]157
158            //push eax
[225]159            compiler.codeGenerator.op_push(REG_EAX);
[3]160        }
161        else{
162            //push eax
[225]163            compiler.codeGenerator.op_push(REG_EAX);
[3]164        }
[64]165
[75]166        if( pUserProc->RealParams()[1]->IsRef() ){
[64]167            //一時参照を作成
168
169            //mov eax,esp
[225]170            compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ESP );
[64]171
172            //push eax
[225]173            compiler.codeGenerator.op_push( REG_EAX );
[64]174        }
[3]175    }
176
[75]177    if( pUserProc->ReturnType().IsStruct() ){
[3]178        //push ebx
[225]179        compiler.codeGenerator.op_push(REG_EBX);
[3]180    }
181
182    //push ecx
[225]183    compiler.codeGenerator.op_push(REG_ECX);
[3]184
185    //call operator_proc
[225]186    compiler.codeGenerator.op_call(pUserProc);
[3]187
[64]188    if(bTwoTerm){
[75]189        if( pUserProc->RealParams()[1]->IsRef() ){
[64]190            //一時参照を破棄
[225]191            compiler.codeGenerator.op_pop( REG_NON );
[64]192        }
193    }
194
[75]195    if( !pUserProc->ReturnType().IsNull() ){
[3]196        //スタックへプッシュ
[673]197        PushReturnValue( pUserProc->ReturnType() );
[3]198    }
199
[435]200    if(isNeedHeapFreeStructureStack[sp-1]){
[3]201        FreeTempObject(REG_ESI,(CClass *)index_stack[sp-1]);
202    }
[435]203    if(isNeedHeapFreeStructureStack[sp-2]){
[3]204        FreeTempObject(REG_EDI,(CClass *)index_stack[sp-2]);
205    }
206
[673]207    Type temp( pUserProc->ReturnType() );
208    ResolveFormalGenericTypeParameter( temp, leftType, pUserProc );
209
[3]210    sp--;
[673]211    type_stack[sp-1] = temp.GetBasicType();
212    index_stack[sp-1] = temp.GetIndex();
[3]213
[435]214    if( pUserProc->ReturnType().IsStruct() )
215    {
[64]216        //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]217        //※後にfreeする必要あり
[435]218        isNeedHeapFreeStructureStack[sp-1] = true;
[3]219    }
[435]220    else
221    {
222        isNeedHeapFreeStructureStack[sp-1] = false;
223    }
[3]224
225    return 1;
226}
227
[76]228void CallCastOperatorProc(Type &calcType,BOOL bCalcUseHeap,const Type &toType){
229    int type_stack[10];
[3]230    LONG_PTR index_stack[10];
[435]231    bool array_bUseHeap[10];
[3]232    int sp=2;
233
234    if(bCalcUseHeap){
235        //未解放のインスタンスが存在する旨を示す警告
[465]236        compiler.errorMessenger.Output(-105,NULL,cp);
[3]237    }
238
239    //左辺
[76]240    type_stack[0]=calcType.GetBasicType();
241    index_stack[0]=calcType.GetIndex();
[3]242    array_bUseHeap[0]=0;
[76]243    type_stack[1]=toType.GetBasicType();
244    index_stack[1]=toType.GetIndex();
[3]245    array_bUseHeap[1]=0;
246
[76]247    int iRet = CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp);
[3]248
249    if(iRet==1){
250        //成功したとき
[76]251        calcType.SetType( type_stack[0], index_stack[0] );
[3]252        return;
253    }
254    else if(iRet==-1){
255        //エラーが発行されたとき
256        return;
257    }
258
259    //エラーを発行
[465]260    compiler.errorMessenger.Output(-1,"キャスト演算子がオーバーロードされていません。",cp);
[3]261}
[334]262void CallIndexerGetterProc( const Type &classType, const char *ObjectName, char *Parameter,Type &resultType, DWORD dwProcFlags ){
[206]263    std::vector<const UserProc *> subs;
[342]264    classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
[50]265    if( subs.size() == 0 ){
[3]266        return;
267    }
268
[299]269    const UserProc *pUserProc = subs[0];
[292]270
[334]271    Opcode_CallProc(Parameter,pUserProc,dwProcFlags,ObjectName);
[299]272    resultType = pUserProc->ReturnType();
[292]273
[299]274    // 型パラメータを解決
275    ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
[3]276}
Note: See TracBrowser for help on using the repository browser.