source: dev/BasicCompiler64/OperatorProc.cpp@ 20

Last change on this file since 20 was 11, checked in by dai_9181, 18 years ago

Const変数の書き込み規制を有効化(グローバル/ローカル変数のみ)
定数オブジェクトと定数メンバは未実装。

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(!GetVarOffsetReadOnly(
328 szTempVarName,
329 &VarType,
330 &VarRelativeVar,
331 &lpVarIndex)) return;
332
333
334 CClass *pobj_c;
335 pobj_c=(CClass *)lpCalcIndex;
336 if(pobj_c->DestructorMemberSubIndex!=-1){
337
338 //////////////////////////////////////////////////////
339 ///// レジスタ資源のバックアップ
340 { BACKUP_REGISTER_RESOURCE
341 //////////////////////////////////////////////////////
342
343 //ループの場合、古い一時オブジェクトのデストラクタを呼ぶ
344
345 //rcxに変数アドレスをコピー
346 SetVarPtrToReg(REG_RCX,&VarRelativeVar);
347
348 //call destructor
349 OpBuffer[obp++]=(char)0xE8;
350 pobj_SubAddrSchedule->add(pobj_c->ppobj_Method[pobj_c->DestructorMemberSubIndex]->psi,1);
351 obp+=sizeof(long);
352
353 /////////////////////////////////////////////
354 ////// レジスタ資源を復元
355 RESTORE_REGISTER_RESOURCE
356 }////////////////////////////////////////////
357 }
358
359 //mov r15,reg
360 op_mov_RR(REG_R15,reg);
361
362
363 int object_size;
364 object_size=GetSizeOfClass((CClass *)lpVarIndex);
365
366 //mov rcx,object_size
367 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
368
369 //rdiに変数アドレスをコピー
370 SetVarPtrToReg(REG_RDI,&VarRelativeVar);
371
372 //mov rsi,reg
373 op_mov_RR(REG_RSI,reg);
374
375 //mov r14,rdi
376 op_mov_RR(REG_R14,REG_RDI);
377 pobj_BlockReg->lock(REG_R14);
378
379 //rep movs byte ptr[rdi],byte ptr[rsi]
380 op_rep_movs(sizeof(BYTE));
381
382 //////////////////////////////////////////////////////
383 ///// レジスタ資源のバックアップ
384 { BACKUP_REGISTER_RESOURCE
385 //////////////////////////////////////////////////////
386
387 //mov rcx,r15
388 op_mov_RR(REG_RCX,REG_R15);
389
390 //call free
391 extern SUBINFO *pSub_free;
392 OpBuffer[obp++]=(char)0xE8;
393 pobj_SubAddrSchedule->add(pSub_free,1);
394 obp+=sizeof(long);
395
396 /////////////////////////////////////////////
397 ////// レジスタ資源を復元
398 RESTORE_REGISTER_RESOURCE
399 }////////////////////////////////////////////
400
401
402 //mov reg,r14
403 op_mov_RR(reg,REG_R14);
404
405 pobj_BlockReg->unlock(REG_R14);
406 */
407
408 //未解放のインスタンスが存在する旨を示す警告
409 SetError(-105,NULL,cp);
410
411 }
412
413 //左辺
414 type[0]=CalcType;
415 index_stack[0]=lpCalcIndex;
416 array_bUseHeap[0]=0;
417 type[1]=ToType;
418 index_stack[1]=lpToIndex;
419 array_bUseHeap[1]=0;
420
421 TYPEINFO BaseTypeInfo={ToType,lpToIndex};
422
423 iRet=CallOperatorProc(CALC_AS,&BaseTypeInfo,type,index_stack,array_bUseHeap,sp);
424
425 pobj_reg->UnlockReg();
426
427 /////////////////////////////////////////////
428 ////// レジスタ資源を復元
429 RESTORE_REGISTER_RESOURCE
430 }////////////////////////////////////////////
431
432
433 if(iRet==1){
434 //成功したとき
435 CalcType=type[0];
436 lpCalcIndex=index_stack[0];
437 return;
438 }
439 else if(iRet==-1){
440 //エラーが発行されたとき
441 return;
442 }
443
444 //エラーを発行
445 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
446}
447
448void CallArrayOperatorProc(int reg,CClass *pobj_Class,char *ObjectName,char *Parameter,TYPEINFO &RetTypeInfo){
449 SUBINFO **ppsi;
450 int num;
451 ppsi=pobj_Class->GetOperatorSubInfo(CALC_ARRAY_GET,num);
452 if(num==0){
453 HeapDefaultFree(ppsi);
454
455 return;
456 }
457
458 //////////////////////////////////////////////////////
459 ///// レジスタ資源のバックアップ
460 { BACKUP_REGISTER_RESOURCE
461 //////////////////////////////////////////////////////
462
463 RetTypeInfo.type=Opcode_CallProc(Parameter,ppsi[0],&RetTypeInfo.u.lpIndex,0,ObjectName,DEF_OBJECT);
464
465 //mov reg,rax
466 op_mov_RR(reg,REG_RAX);
467
468 /////////////////////////////////////////////
469 ////// レジスタ資源を復元
470 RESTORE_REGISTER_RESOURCE
471 }////////////////////////////////////////////
472
473 HeapDefaultFree(ppsi);
474}
Note: See TracBrowser for help on using the repository browser.