source: dev/trunk/ab5.0/abdev/compiler_x64/OperatorProc.cpp@ 675

Last change on this file since 675 was 675, checked in by dai_9181, 16 years ago

・キャスト演算子が存在せずに型変換できなかった場合のエラーメッセージを変更した。

File size: 9.2 KB
RevLine 
[206]1#include "stdafx.h"
2
[226]3#include <Compiler.h>
4
[3]5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
[75]8void FreeTempObject(int reg,const CClass *pobj_c){
[468]9 if(!IsSafeReg(reg)) compiler.errorMessenger.Output(300,NULL,cp);
[3]10
11 ////////////////////////////////////////////////
12 // 演算過程で利用した一時オブジェクトを破棄
13 // Thisポインタをr14レジスタを介して渡す
14 ////////////////////////////////////////////////
15
[135]16 const CMethod *method = pobj_c->GetDestructorMethod();
[51]17 if( method ){
[3]18 //mov rcx,reg
[226]19 compiler.codeGenerator.op_mov_RR(REG_RCX,reg);
[3]20
21 //call DestructorProcAddr
[226]22 compiler.codeGenerator.op_call( &method->GetUserProc() );
[3]23 }
24
25 //mov rcx,reg
[226]26 compiler.codeGenerator.op_mov_RR(REG_RCX,reg);
[3]27
28 //call free
[206]29 extern const UserProc *pSub_free;
[226]30 compiler.codeGenerator.op_call(pSub_free);
[3]31}
32
[436]33int CallOperatorProc(BYTE idCalc, const Type &baseType, int *type_stack,LONG_PTR *index_stack,bool isNeedHeapFreeStructureStack[],int &sp)
[350]34{
35 Type leftType( type_stack[sp-2], index_stack[sp-2] );
36 Type rightType( type_stack[sp-1] & (~FLAG_CAST), index_stack[sp-1] );
37
[3]38 //オーバーロードされたオペレータ関数を呼び出す
[350]39 const CClass *pobj_c = &leftType.GetClass();
[3]40
[206]41 std::vector<const UserProc *> subs;
[345]42 pobj_c->GetDynamicMethods().Enum( idCalc, subs );
[50]43 if( subs.size() == 0 ){
[3]44 return 0;
45 }
46
47
48 //項の数
49 BOOL bTwoTerm=1;
50 if(idCalc==CALC_AS) bTwoTerm=0;
51
52
53 /////////////////////////////////////////////
54 // オーバーロード解決用のパラメータを設定
55 /////////////////////////////////////////////
56
[75]57 Parameters params;
[3]58
[350]59 if(bTwoTerm)
60 {
61 params.push_back( new Parameter( "", rightType ) );
[3]62 }
63
64 //オーバーロードを解決
65 char temporary[255];
66 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
67 else GetCalcName(idCalc,temporary);
[425]68 const UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType, leftType );
[3]69
[75]70 if(!pUserProc){
71 if(bTwoTerm){
72 delete params[0];
73 }
[3]74 return -1;
75 }
76 else{
77 //オーバーロードされていないが、パラメータ個数が一致しないとき
[75]78 if(params.size()!=pUserProc->Params().size()){
79 if(bTwoTerm){
80 delete params[0];
81 }
[3]82 return -1;
83 }
84 }
85
[76]86 for(int i=0;i<(int)params.size();i++){
[3]87 CheckDifferentType(
[308]88 *pUserProc->Params()[i],
89 *params[i],
[448]90 NULL,
[3]91 i);
92 }
93
[75]94 if(bTwoTerm){
95 delete params[0];
96 }
[3]97
[350]98 int right_side_size = rightType.GetSize();
[75]99
[3]100 if(bTwoTerm){
[75]101 if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){
[3]102 //一時オブジェクトはメソッド内で破棄される
[436]103 isNeedHeapFreeStructureStack[sp-1] = false;
[3]104 }
105 }
106
[75]107
108 if( pUserProc->ReturnType().IsStruct() ){
[3]109 //////////////////////////////////////////////////////
[64]110 // 戻り値に構造体インスタンスを持つ場合
111 // ※ByRef _System_ReturnValue パラメータ用領域を取得
[3]112 //////////////////////////////////////////////////////
113
114
115 //////////////////////////////////////////////////////
116 ///// レジスタ資源のバックアップ
117 { BACKUP_REGISTER_RESOURCE
118 //////////////////////////////////////////////////////
119
[75]120 int object_size = pUserProc->ReturnType().GetClass().GetSize();
[3]121
122 //mov rcx,object_size
[226]123 compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,object_size);
[3]124
125 //call calloc
[206]126 extern const UserProc *pSub_calloc;
[226]127 compiler.codeGenerator.op_call(pSub_calloc);
[3]128
129 //mov r13,rax
[226]130 compiler.codeGenerator.op_mov_RR(REG_R13,REG_RAX);
[3]131
132 /////////////////////////////////////////////
133 ////// レジスタ資源を復元
134 RESTORE_REGISTER_RESOURCE
135 }////////////////////////////////////////////
136 }
137
138 int reg1,reg2;
139 if(bTwoTerm){
140 //右の項(実数の場合が未完成)
[75]141 SetOneTermToReg_Whole64Calc(type_stack[sp-1],&reg2);
[3]142 pobj_reg->UnlockReg();
[75]143 if( !pUserProc->RealParams()[1]->IsRef() == false ){
[64]144 //一時参照を作成
145 pobj_sf->push( reg2 );
146 pobj_sf->mov_sp( reg2 );
147 }
[3]148 }
149
150 //左の項
151 SetOneTermToReg_Whole64Calc(DEF_INT64,&reg1);
152 pobj_reg->UnlockReg();
153
154 //ヒープ解放用に退避
[436]155 if(isNeedHeapFreeStructureStack[sp-1]){
[3]156 //mov qword ptr[rsp+offset],reg2 ※スタックフレームを利用
157 pobj_sf->push(reg2);
158 }
[436]159 if(isNeedHeapFreeStructureStack[sp-2]){
[3]160 //mov qword ptr[rsp+offset],reg1 ※スタックフレームを利用
161 pobj_sf->push(reg1);
162 }
163
164
165
166 //////////////////////////////////////////////////////
167 ///// レジスタ資源のバックアップ
168 { BACKUP_REGISTER_RESOURCE
169 //////////////////////////////////////////////////////
170
171 if(reg1==REG_RDX||reg1==REG_R8){
172 //mov r14,reg1
[226]173 compiler.codeGenerator.op_mov_RR(REG_R14,reg1);
[3]174 reg1=REG_R14;
175 }
176
177
178 if(bTwoTerm){
[75]179 if( pUserProc->ReturnType().IsStruct() ){
[3]180 //mov r8,reg2
[226]181 compiler.codeGenerator.op_mov_RR(REG_R8,reg2);
[3]182 }
183 else{
184 //mov rdx,reg2
[226]185 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
[3]186 }
187 }
188
[75]189 if( pUserProc->ReturnType().IsStruct() ){
[3]190 //mov rdx,r13
[226]191 compiler.codeGenerator.op_mov_RR(REG_RDX,REG_R13);
[3]192 }
193
194 //mov rcx,reg1
[226]195 compiler.codeGenerator.op_mov_RR(REG_RCX,reg1);
[3]196
197 //call operator_proc
[226]198 compiler.codeGenerator.op_call(pUserProc);
[3]199
[75]200 if( !pUserProc->ReturnType().IsNull() ){
[3]201 //戻り値を一時的に退避
202
203 //mov r13,rax
[226]204 compiler.codeGenerator.op_mov_RR(REG_R13,REG_RAX);
[3]205 }
206
207
208 /////////////////////////////////////////////
209 ////// レジスタ資源を復元
210 RESTORE_REGISTER_RESOURCE
211 }////////////////////////////////////////////
212
213
214
[436]215 if( isNeedHeapFreeStructureStack[sp-2] || isNeedHeapFreeStructureStack[sp-1] )
216 {
[3]217 //////////////////////////////////////////////////////
218 ///// レジスタ資源のバックアップ
219 { BACKUP_REGISTER_RESOURCE
220 //////////////////////////////////////////////////////
221
[436]222 if( isNeedHeapFreeStructureStack[sp-2] )
223 {
[3]224 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
225 pobj_sf->pop(REG_R14);
226
227 FreeTempObject(REG_R14,(CClass *)index_stack[sp-2]);
228 }
[436]229 if( isNeedHeapFreeStructureStack[sp-1] )
230 {
[3]231 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
232 pobj_sf->pop(REG_R14);
233
234 FreeTempObject(REG_R14,(CClass *)index_stack[sp-1]);
235 }
236
237 /////////////////////////////////////////////
238 ////// レジスタ資源を復元
239 RESTORE_REGISTER_RESOURCE
240 }////////////////////////////////////////////
241 }
242
[64]243 if(bTwoTerm){
[75]244 if( !pUserProc->RealParams()[1]->IsRef() == false ){
[64]245 //一時参照を破棄
246 pobj_sf->pop();
247 }
248 }
249
[75]250 if( !pUserProc->ReturnType().IsNull() ){
[3]251 //戻り値をreg1にセット
252 reg1=pobj_reg->LockReg();
253
254 //mov reg1,r13
[226]255 compiler.codeGenerator.op_mov_RR(reg1,REG_R13);
[3]256 }
257
[674]258 Type temp( pUserProc->ReturnType() );
259 ResolveFormalGenericTypeParameter( temp, leftType, pUserProc );
260
[3]261 sp--;
[674]262 type_stack[sp-1] = temp.GetBasicType();
263 index_stack[sp-1] = temp.GetIndex();
[3]264
[436]265 if( pUserProc->ReturnType().IsStruct() )
266 {
[64]267 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]268 //※後にfreeする必要あり
[436]269 isNeedHeapFreeStructureStack[sp-1] = true;
[3]270 }
[436]271 else
272 {
273 isNeedHeapFreeStructureStack[sp-1] = false;
274 }
[3]275
276 return 1;
277}
278
[75]279void CallCastOperatorProc(int reg,Type &calcType,BOOL bCalcUseHeap,const Type &toType){
280 int type_stack[10];
[3]281 LONG_PTR index_stack[10];
[436]282 bool array_bUseHeap[10];
[3]283 int sp=2;
284 int iRet;
285
286
287 //////////////////////////////////////////////////////
288 ///// レジスタ資源のバックアップ
289 { BACKUP_REGISTER_RESOURCE
290 //////////////////////////////////////////////////////
291
292 //regを第一項目としてロック
293 pobj_reg=new CRegister(reg);
294 pobj_reg->LockReg();
295
296 if(bCalcUseHeap){
297 //未解放のインスタンスが存在する旨を示す警告
[468]298 compiler.errorMessenger.Output(-105,NULL,cp);
[3]299 }
300
301 //左辺
[75]302 type_stack[0]=calcType.GetBasicType();
303 index_stack[0]=calcType.GetIndex();
[3]304 array_bUseHeap[0]=0;
[75]305 type_stack[1]=toType.GetBasicType();
306 index_stack[1]=toType.GetIndex();
[3]307 array_bUseHeap[1]=0;
308
[75]309 iRet=CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp);
[3]310
311 pobj_reg->UnlockReg();
312
313 /////////////////////////////////////////////
314 ////// レジスタ資源を復元
315 RESTORE_REGISTER_RESOURCE
316 }////////////////////////////////////////////
317
318
319 if(iRet==1){
320 //成功したとき
[75]321 calcType.SetType( type_stack[0], index_stack[0] );
[3]322 return;
323 }
324 else if(iRet==-1){
325 //エラーが発行されたとき
326 return;
327 }
328
329 //エラーを発行
[675]330 compiler.errorMessenger.Output(-1,calcType.ToString() + " から " + toType.ToString() + " へ型変換できません。",cp);
[3]331}
332
[38]333//インデクサ(getter)を呼び出す
[339]334void CallIndexerGetterProc(int reg, const Type &classType, const char *ObjectName,char *Parameter,Type &resultType, DWORD dwProcFlags ){
[3]335
[206]336 std::vector<const UserProc *> subs;
[345]337 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
[50]338 if( subs.size() == 0 ){
[3]339 return;
340 }
341
[316]342 const UserProc *pUserProc = subs[0];
343
[3]344 //////////////////////////////////////////////////////
345 ///// レジスタ資源のバックアップ
346 { BACKUP_REGISTER_RESOURCE
347 //////////////////////////////////////////////////////
348
[339]349 Opcode_CallProc(Parameter,pUserProc,dwProcFlags,ObjectName);
[316]350 resultType = pUserProc->ReturnType();
[3]351
352 //mov reg,rax
[226]353 compiler.codeGenerator.op_mov_RR(reg,REG_RAX);
[3]354
355 /////////////////////////////////////////////
356 ////// レジスタ資源を復元
357 RESTORE_REGISTER_RESOURCE
358 }////////////////////////////////////////////
359
[316]360
361 // 型パラメータを解決
362 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
[3]363}
Note: See TracBrowser for help on using the repository browser.