source: dev/BasicCompiler64/OperatorProc.cpp@ 50

Last change on this file since 50 was 50, checked in by dai_9181, 17 years ago

オーバーロード解決用の関数保持リストを "SUBINFO " ではなく、"vector<SUBINFO *>" に変更した。

File size: 10.9 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void FreeTempObject(int reg,CClass *pobj_c){
5 if(!IsSafeReg(reg)) SetError(300,NULL,cp);
6
7 ////////////////////////////////////////////////
8 // 演算過程で利用した一時オブジェクトを破棄
9 // Thisポインタをr14レジスタを介して渡す
10 ////////////////////////////////////////////////
11
12 if(pobj_c->DestructorMemberSubIndex!=-1){
13 //mov rcx,reg
14 op_mov_RR(REG_RCX,reg);
15
16 //call DestructorProcAddr
17 op_call(pobj_c->ppobj_Method[pobj_c->DestructorMemberSubIndex]->psi);
18 }
19
20 //mov rcx,reg
21 op_mov_RR(REG_RCX,reg);
22
23 //call free
24 extern SUBINFO *pSub_free;
25 op_call(pSub_free);
26}
27
28int CallOperatorProc(int idCalc,TYPEINFO *pBaseTypeInfo,int *type,LONG_PTR *index_stack,BOOL *bUseHeap,int &sp){
29 //オーバーロードされたオペレータ関数を呼び出す
30 CClass *pobj_c;
31 pobj_c=(CClass *)index_stack[sp-2];
32
33 std::vector<SUBINFO *> subs;
34 pobj_c->EnumMethod( idCalc, subs );
35 if( subs.size() == 0 ){
36 return 0;
37 }
38
39
40 //項の数
41 BOOL bTwoTerm=1;
42 if(idCalc==CALC_AS) bTwoTerm=0;
43
44
45 int i;
46 BOOL bReturnTypeIsObject=1;
47 TYPEINFO ReturnType={DEF_OBJECT,subs[0]->u.ReturnIndex};
48 for(i=0;i<subs.size();i++){
49 if(subs[i]->ReturnType!=DEF_OBJECT)
50 bReturnTypeIsObject=0;
51 }
52
53 if(bReturnTypeIsObject==0){
54 if(pBaseTypeInfo){
55 if(pBaseTypeInfo->type==DEF_OBJECT){
56 bReturnTypeIsObject=1;
57 ReturnType.u.lpIndex=pBaseTypeInfo->u.lpIndex;
58 }
59 }
60 }
61
62
63
64 /////////////////////////////////////////////
65 // オーバーロード解決用のパラメータを設定
66 /////////////////////////////////////////////
67
68 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
69 int iParmNum=0;
70
71 if(bTwoTerm){
72 ppi[iParmNum].bArray=0;
73 ppi[iParmNum].bByVal=0;
74 ppi[iParmNum].name=0;
75 ppi[iParmNum].type=type[sp-1];
76 ppi[iParmNum].u.index=index_stack[sp-1];
77 ppi[iParmNum].SubScripts[0]=-1;
78 iParmNum++;
79 }
80
81
82 //オーバーロードを解決
83 char temporary[255];
84 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
85 else GetCalcName(idCalc,temporary);
86 SUBINFO *psi;
87 psi=OverloadSolution(temporary,subs,ppi,iParmNum,pBaseTypeInfo);
88
89
90 if(!psi){
91 HeapDefaultFree(ppi);
92 return -1;
93 }
94 else{
95 //オーバーロードされていないが、パラメータ個数が一致しないとき
96 if(iParmNum!=psi->ParmNum){
97 HeapDefaultFree(ppi);
98 return -1;
99 }
100 }
101
102 for(i=0;i<iParmNum;i++){
103 CheckDifferentType(
104 psi->pParmInfo[i].type,
105 psi->pParmInfo[i].u.index,
106 ppi[i].type,
107 ppi[i].u.index,
108 "",
109 i);
110 }
111
112 HeapDefaultFree(ppi);
113
114 int right_side_size;
115 if(type[sp-1]==DEF_OBJECT) right_side_size=PTR_SIZE;
116 else right_side_size=GetTypeSize(type[sp-1],index_stack[sp-1]);
117
118 if(bTwoTerm){
119 if(psi->pParmInfo[1].type==DEF_OBJECT&&psi->pParmInfo[1].bByVal){
120 //一時オブジェクトはメソッド内で破棄される
121 bUseHeap[sp-1]=0;
122 }
123 }
124
125
126 if(psi->ReturnType==DEF_OBJECT){
127 //////////////////////////////////////////////////////
128 // 戻り値にオブジェクト インスタンスを持つ場合
129 // ※ByRef _System_ReturnObject パラメータ用領域を取得
130 //////////////////////////////////////////////////////
131
132
133 //////////////////////////////////////////////////////
134 ///// レジスタ資源のバックアップ
135 { BACKUP_REGISTER_RESOURCE
136 //////////////////////////////////////////////////////
137
138 int object_size;
139 object_size=GetSizeOfClass(psi->u.Return_pobj_c);
140
141 //mov rcx,object_size
142 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
143
144 //call calloc
145 extern SUBINFO *pSub_calloc;
146 op_call(pSub_calloc);
147
148 //mov r13,rax
149 op_mov_RR(REG_R13,REG_RAX);
150
151 /////////////////////////////////////////////
152 ////// レジスタ資源を復元
153 RESTORE_REGISTER_RESOURCE
154 }////////////////////////////////////////////
155 }
156
157
158 int reg1,reg2;
159 if(bTwoTerm){
160 //右の項(実数の場合が未完成)
161 SetOneTermToReg_Whole64Calc(type[sp-1],&reg2);
162 pobj_reg->UnlockReg();
163 }
164
165 //左の項
166 SetOneTermToReg_Whole64Calc(DEF_INT64,&reg1);
167 pobj_reg->UnlockReg();
168
169 //ヒープ解放用に退避
170 if(bUseHeap[sp-1]){
171 //mov qword ptr[rsp+offset],reg2 ※スタックフレームを利用
172 pobj_sf->push(reg2);
173 }
174 if(bUseHeap[sp-2]){
175 //mov qword ptr[rsp+offset],reg1 ※スタックフレームを利用
176 pobj_sf->push(reg1);
177 }
178
179
180
181 //////////////////////////////////////////////////////
182 ///// レジスタ資源のバックアップ
183 { BACKUP_REGISTER_RESOURCE
184 //////////////////////////////////////////////////////
185
186 if(reg1==REG_RDX||reg1==REG_R8){
187 //mov r14,reg1
188 op_mov_RR(REG_R14,reg1);
189 reg1=REG_R14;
190 }
191
192
193 if(bTwoTerm){
194 if(psi->ReturnType==DEF_OBJECT){
195 //mov r8,reg2
196 op_mov_RR(REG_R8,reg2);
197 }
198 else{
199 //mov rdx,reg2
200 op_mov_RR(REG_RDX,reg2);
201 }
202 }
203
204 if(psi->ReturnType==DEF_OBJECT){
205 //mov rdx,r13
206 op_mov_RR(REG_RDX,REG_R13);
207 }
208
209 //mov rcx,reg1
210 op_mov_RR(REG_RCX,reg1);
211
212 //call operator_proc
213 op_call(psi);
214
215 if(psi->ReturnType!=-1){
216 //戻り値を一時的に退避
217
218 //mov r13,rax
219 op_mov_RR(REG_R13,REG_RAX);
220 }
221
222
223 /////////////////////////////////////////////
224 ////// レジスタ資源を復元
225 RESTORE_REGISTER_RESOURCE
226 }////////////////////////////////////////////
227
228
229
230 if(bUseHeap[sp-2]||bUseHeap[sp-1]){
231
232 //////////////////////////////////////////////////////
233 ///// レジスタ資源のバックアップ
234 { BACKUP_REGISTER_RESOURCE
235 //////////////////////////////////////////////////////
236
237 if(bUseHeap[sp-2]){
238 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
239 pobj_sf->pop(REG_R14);
240
241 FreeTempObject(REG_R14,(CClass *)index_stack[sp-2]);
242 }
243 if(bUseHeap[sp-1]){
244 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
245 pobj_sf->pop(REG_R14);
246
247 FreeTempObject(REG_R14,(CClass *)index_stack[sp-1]);
248 }
249
250 /////////////////////////////////////////////
251 ////// レジスタ資源を復元
252 RESTORE_REGISTER_RESOURCE
253 }////////////////////////////////////////////
254 }
255
256 if(psi->ReturnType!=-1){
257 //戻り値をreg1にセット
258 reg1=pobj_reg->LockReg();
259
260 //mov reg1,r13
261 op_mov_RR(reg1,REG_R13);
262 }
263
264 sp--;
265 type[sp-1]=psi->ReturnType;
266 index_stack[sp-1]=psi->u.ReturnIndex;
267
268 if(psi->ReturnType==DEF_OBJECT){
269 //Object型が戻ったときはヒープ領域にインスタンスが格納されている
270 //※後にfreeする必要あり
271 bUseHeap[sp-1]=1;
272 }
273 else bUseHeap[sp-1]=0;
274
275 return 1;
276}
277
278void CallCastOperatorProc(int reg,int &CalcType,LONG_PTR &lpCalcIndex,BOOL bCalcUseHeap,int ToType,LONG_PTR lpToIndex){
279 int type[10];
280 LONG_PTR index_stack[10];
281 BOOL array_bUseHeap[10];
282 int sp=2;
283 int iRet;
284
285
286 //////////////////////////////////////////////////////
287 ///// レジスタ資源のバックアップ
288 { BACKUP_REGISTER_RESOURCE
289 //////////////////////////////////////////////////////
290
291 //regを第一項目としてロック
292 pobj_reg=new CRegister(reg);
293 pobj_reg->LockReg();
294
295 if(bCalcUseHeap){
296 /*
297 //未解放のインスタンスが存在する場合
298 //※専用のローカル変数を用意し、メモリリークを回避
299 char temporary[VN_SIZE],temp2[VN_SIZE];
300
301
302 ////////////////////////////////
303 // 一時オブジェクト変数を用意
304 ////////////////////////////////
305 char szTempVarName[255];
306 GetTypeName(CalcType,lpCalcIndex,temp2);
307 sprintf(szTempVarName,"_System_strDummy%d",obp);
308 wsprintf(temporary,"%s%c%c%s",szTempVarName,1,ESC_AS,temp2);
309 InsertDimStatement_ToProcHead(temporary);
310
311 RELATIVE_VAR VarRelativeVar;
312 int VarType;
313 LONG_PTR lpVarIndex;
314 if(!GetVarOffsetReadOnly(
315 szTempVarName,
316 &VarType,
317 &VarRelativeVar,
318 &lpVarIndex)) return;
319
320
321 CClass *pobj_c;
322 pobj_c=(CClass *)lpCalcIndex;
323 if(pobj_c->DestructorMemberSubIndex!=-1){
324
325 //////////////////////////////////////////////////////
326 ///// レジスタ資源のバックアップ
327 { BACKUP_REGISTER_RESOURCE
328 //////////////////////////////////////////////////////
329
330 //ループの場合、古い一時オブジェクトのデストラクタを呼ぶ
331
332 //rcxに変数アドレスをコピー
333 SetVarPtrToReg(REG_RCX,&VarRelativeVar);
334
335 //call destructor
336 OpBuffer[obp++]=(char)0xE8;
337 pobj_SubAddrSchedule->add(pobj_c->ppobj_Method[pobj_c->DestructorMemberSubIndex]->psi,1);
338 obp+=sizeof(long);
339
340 /////////////////////////////////////////////
341 ////// レジスタ資源を復元
342 RESTORE_REGISTER_RESOURCE
343 }////////////////////////////////////////////
344 }
345
346 //mov r15,reg
347 op_mov_RR(REG_R15,reg);
348
349
350 int object_size;
351 object_size=GetSizeOfClass((CClass *)lpVarIndex);
352
353 //mov rcx,object_size
354 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
355
356 //rdiに変数アドレスをコピー
357 SetVarPtrToReg(REG_RDI,&VarRelativeVar);
358
359 //mov rsi,reg
360 op_mov_RR(REG_RSI,reg);
361
362 //mov r14,rdi
363 op_mov_RR(REG_R14,REG_RDI);
364 pobj_BlockReg->lock(REG_R14);
365
366 //rep movs byte ptr[rdi],byte ptr[rsi]
367 op_rep_movs(sizeof(BYTE));
368
369 //////////////////////////////////////////////////////
370 ///// レジスタ資源のバックアップ
371 { BACKUP_REGISTER_RESOURCE
372 //////////////////////////////////////////////////////
373
374 //mov rcx,r15
375 op_mov_RR(REG_RCX,REG_R15);
376
377 //call free
378 extern SUBINFO *pSub_free;
379 OpBuffer[obp++]=(char)0xE8;
380 pobj_SubAddrSchedule->add(pSub_free,1);
381 obp+=sizeof(long);
382
383 /////////////////////////////////////////////
384 ////// レジスタ資源を復元
385 RESTORE_REGISTER_RESOURCE
386 }////////////////////////////////////////////
387
388
389 //mov reg,r14
390 op_mov_RR(reg,REG_R14);
391
392 pobj_BlockReg->unlock(REG_R14);
393 */
394
395 //未解放のインスタンスが存在する旨を示す警告
396 SetError(-105,NULL,cp);
397
398 }
399
400 //左辺
401 type[0]=CalcType;
402 index_stack[0]=lpCalcIndex;
403 array_bUseHeap[0]=0;
404 type[1]=ToType;
405 index_stack[1]=lpToIndex;
406 array_bUseHeap[1]=0;
407
408 TYPEINFO BaseTypeInfo={ToType,lpToIndex};
409
410 iRet=CallOperatorProc(CALC_AS,&BaseTypeInfo,type,index_stack,array_bUseHeap,sp);
411
412 pobj_reg->UnlockReg();
413
414 /////////////////////////////////////////////
415 ////// レジスタ資源を復元
416 RESTORE_REGISTER_RESOURCE
417 }////////////////////////////////////////////
418
419
420 if(iRet==1){
421 //成功したとき
422 CalcType=type[0];
423 lpCalcIndex=index_stack[0];
424 return;
425 }
426 else if(iRet==-1){
427 //エラーが発行されたとき
428 return;
429 }
430
431 //エラーを発行
432 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
433}
434
435//インデクサ(getter)を呼び出す
436void CallIndexerGetterProc(int reg,CClass *pobj_Class,char *ObjectName,char *Parameter,TYPEINFO &RetTypeInfo){
437
438 std::vector<SUBINFO *> subs;
439 pobj_Class->EnumMethod( CALC_ARRAY_GET, subs );
440 if( subs.size() == 0 ){
441 return;
442 }
443
444 //////////////////////////////////////////////////////
445 ///// レジスタ資源のバックアップ
446 { BACKUP_REGISTER_RESOURCE
447 //////////////////////////////////////////////////////
448
449 Opcode_CallProc(Parameter,subs[0],0,ObjectName,DEF_OBJECT);
450 RetTypeInfo.type = subs[0]->ReturnType;
451 RetTypeInfo.u.lpIndex = subs[0]->u.ReturnIndex;
452
453 //mov reg,rax
454 op_mov_RR(reg,REG_RAX);
455
456 /////////////////////////////////////////////
457 ////// レジスタ資源を復元
458 RESTORE_REGISTER_RESOURCE
459 }////////////////////////////////////////////
460
461}
Note: See TracBrowser for help on using the repository browser.