source: dev/BasicCompiler64/OperatorProc.cpp@ 49

Last change on this file since 49 was 38, checked in by dai_9181, 18 years ago

戻り値に基本型を持つインデクサ(Getter)が正常に呼び出せないバグを修正。

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