[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] | 8 | void 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] | 28 | int 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] | 228 | void 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] | 262 | void 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 | } |
---|