source: dev/BasicCompiler64/OperatorProc.cpp@ 6

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