source: dev/BasicCompiler64/OperatorProc.cpp@ 60

Last change on this file since 60 was 51, checked in by dai_9181, 18 years ago

ppobj_Member及びppobj_StaticMemberを廃止し、vectorに統一した(methods及びstaticMethods)。

File size: 8.3 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 CMethod *method = pobj_c->GetDestructorMethod();
13 if( method ){
14 //mov rcx,reg
15 op_mov_RR(REG_RCX,reg);
16
17 //call DestructorProcAddr
18 op_call( method->psi );
19 }
20
21 //mov rcx,reg
22 op_mov_RR(REG_RCX,reg);
23
24 //call free
25 extern SUBINFO *pSub_free;
26 op_call(pSub_free);
27}
28
29int CallOperatorProc(int idCalc,TYPEINFO *pBaseTypeInfo,int *type,LONG_PTR *index_stack,BOOL *bUseHeap,int &sp){
30 //オーバーロードされたオペレータ関数を呼び出す
31 CClass *pobj_c;
32 pobj_c=(CClass *)index_stack[sp-2];
33
34 std::vector<SUBINFO *> subs;
35 pobj_c->EnumMethod( idCalc, subs );
36 if( subs.size() == 0 ){
37 return 0;
38 }
39
40
41 //項の数
42 BOOL bTwoTerm=1;
43 if(idCalc==CALC_AS) bTwoTerm=0;
44
45
46 int i;
47 BOOL bReturnTypeIsObject=1;
48 TYPEINFO ReturnType={DEF_OBJECT,subs[0]->u.ReturnIndex};
49 for(i=0;i<subs.size();i++){
50 if(subs[i]->ReturnType!=DEF_OBJECT)
51 bReturnTypeIsObject=0;
52 }
53
54 if(bReturnTypeIsObject==0){
55 if(pBaseTypeInfo){
56 if(pBaseTypeInfo->type==DEF_OBJECT){
57 bReturnTypeIsObject=1;
58 ReturnType.u.lpIndex=pBaseTypeInfo->u.lpIndex;
59 }
60 }
61 }
62
63
64
65 /////////////////////////////////////////////
66 // オーバーロード解決用のパラメータを設定
67 /////////////////////////////////////////////
68
69 PARAMETER_INFO *ppi = (PARAMETER_INFO *)HeapAlloc(hHeap,0,sizeof(PARAMETER_INFO)*3);
70 int iParmNum=0;
71
72 if(bTwoTerm){
73 ppi[iParmNum].bArray=0;
74 ppi[iParmNum].bByVal=0;
75 ppi[iParmNum].name=0;
76 ppi[iParmNum].type=type[sp-1];
77 ppi[iParmNum].u.index=index_stack[sp-1];
78 ppi[iParmNum].SubScripts[0]=-1;
79 iParmNum++;
80 }
81
82
83 //オーバーロードを解決
84 char temporary[255];
85 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
86 else GetCalcName(idCalc,temporary);
87 SUBINFO *psi;
88 psi=OverloadSolution(temporary,subs,ppi,iParmNum,pBaseTypeInfo);
89
90
91 if(!psi){
92 HeapDefaultFree(ppi);
93 return -1;
94 }
95 else{
96 //オーバーロードされていないが、パラメータ個数が一致しないとき
97 if(iParmNum!=psi->ParmNum){
98 HeapDefaultFree(ppi);
99 return -1;
100 }
101 }
102
103 for(i=0;i<iParmNum;i++){
104 CheckDifferentType(
105 psi->pParmInfo[i].type,
106 psi->pParmInfo[i].u.index,
107 ppi[i].type,
108 ppi[i].u.index,
109 "",
110 i);
111 }
112
113 HeapDefaultFree(ppi);
114
115 int right_side_size;
116 if(type[sp-1]==DEF_OBJECT) right_side_size=PTR_SIZE;
117 else right_side_size=GetTypeSize(type[sp-1],index_stack[sp-1]);
118
119 if(bTwoTerm){
120 if(psi->pParmInfo[1].type==DEF_OBJECT&&psi->pParmInfo[1].bByVal){
121 //一時オブジェクトはメソッド内で破棄される
122 bUseHeap[sp-1]=0;
123 }
124 }
125
126
127 if(psi->ReturnType==DEF_OBJECT){
128 //////////////////////////////////////////////////////
129 // 戻り値にオブジェクト インスタンスを持つ場合
130 // ※ByRef _System_ReturnObject パラメータ用領域を取得
131 //////////////////////////////////////////////////////
132
133
134 //////////////////////////////////////////////////////
135 ///// レジスタ資源のバックアップ
136 { BACKUP_REGISTER_RESOURCE
137 //////////////////////////////////////////////////////
138
139 int object_size;
140 object_size=GetSizeOfClass(psi->u.Return_pobj_c);
141
142 //mov rcx,object_size
143 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
144
145 //call calloc
146 extern SUBINFO *pSub_calloc;
147 op_call(pSub_calloc);
148
149 //mov r13,rax
150 op_mov_RR(REG_R13,REG_RAX);
151
152 /////////////////////////////////////////////
153 ////// レジスタ資源を復元
154 RESTORE_REGISTER_RESOURCE
155 }////////////////////////////////////////////
156 }
157
158
159 int reg1,reg2;
160 if(bTwoTerm){
161 //右の項(実数の場合が未完成)
162 SetOneTermToReg_Whole64Calc(type[sp-1],&reg2);
163 pobj_reg->UnlockReg();
164 }
165
166 //左の項
167 SetOneTermToReg_Whole64Calc(DEF_INT64,&reg1);
168 pobj_reg->UnlockReg();
169
170 //ヒープ解放用に退避
171 if(bUseHeap[sp-1]){
172 //mov qword ptr[rsp+offset],reg2 ※スタックフレームを利用
173 pobj_sf->push(reg2);
174 }
175 if(bUseHeap[sp-2]){
176 //mov qword ptr[rsp+offset],reg1 ※スタックフレームを利用
177 pobj_sf->push(reg1);
178 }
179
180
181
182 //////////////////////////////////////////////////////
183 ///// レジスタ資源のバックアップ
184 { BACKUP_REGISTER_RESOURCE
185 //////////////////////////////////////////////////////
186
187 if(reg1==REG_RDX||reg1==REG_R8){
188 //mov r14,reg1
189 op_mov_RR(REG_R14,reg1);
190 reg1=REG_R14;
191 }
192
193
194 if(bTwoTerm){
195 if(psi->ReturnType==DEF_OBJECT){
196 //mov r8,reg2
197 op_mov_RR(REG_R8,reg2);
198 }
199 else{
200 //mov rdx,reg2
201 op_mov_RR(REG_RDX,reg2);
202 }
203 }
204
205 if(psi->ReturnType==DEF_OBJECT){
206 //mov rdx,r13
207 op_mov_RR(REG_RDX,REG_R13);
208 }
209
210 //mov rcx,reg1
211 op_mov_RR(REG_RCX,reg1);
212
213 //call operator_proc
214 op_call(psi);
215
216 if(psi->ReturnType!=-1){
217 //戻り値を一時的に退避
218
219 //mov r13,rax
220 op_mov_RR(REG_R13,REG_RAX);
221 }
222
223
224 /////////////////////////////////////////////
225 ////// レジスタ資源を復元
226 RESTORE_REGISTER_RESOURCE
227 }////////////////////////////////////////////
228
229
230
231 if(bUseHeap[sp-2]||bUseHeap[sp-1]){
232
233 //////////////////////////////////////////////////////
234 ///// レジスタ資源のバックアップ
235 { BACKUP_REGISTER_RESOURCE
236 //////////////////////////////////////////////////////
237
238 if(bUseHeap[sp-2]){
239 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
240 pobj_sf->pop(REG_R14);
241
242 FreeTempObject(REG_R14,(CClass *)index_stack[sp-2]);
243 }
244 if(bUseHeap[sp-1]){
245 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
246 pobj_sf->pop(REG_R14);
247
248 FreeTempObject(REG_R14,(CClass *)index_stack[sp-1]);
249 }
250
251 /////////////////////////////////////////////
252 ////// レジスタ資源を復元
253 RESTORE_REGISTER_RESOURCE
254 }////////////////////////////////////////////
255 }
256
257 if(psi->ReturnType!=-1){
258 //戻り値をreg1にセット
259 reg1=pobj_reg->LockReg();
260
261 //mov reg1,r13
262 op_mov_RR(reg1,REG_R13);
263 }
264
265 sp--;
266 type[sp-1]=psi->ReturnType;
267 index_stack[sp-1]=psi->u.ReturnIndex;
268
269 if(psi->ReturnType==DEF_OBJECT){
270 //Object型が戻ったときはヒープ領域にインスタンスが格納されている
271 //※後にfreeする必要あり
272 bUseHeap[sp-1]=1;
273 }
274 else bUseHeap[sp-1]=0;
275
276 return 1;
277}
278
279void CallCastOperatorProc(int reg,int &CalcType,LONG_PTR &lpCalcIndex,BOOL bCalcUseHeap,int ToType,LONG_PTR lpToIndex){
280 int type[10];
281 LONG_PTR index_stack[10];
282 BOOL array_bUseHeap[10];
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 //未解放のインスタンスが存在する旨を示す警告
298 SetError(-105,NULL,cp);
299 }
300
301 //左辺
302 type[0]=CalcType;
303 index_stack[0]=lpCalcIndex;
304 array_bUseHeap[0]=0;
305 type[1]=ToType;
306 index_stack[1]=lpToIndex;
307 array_bUseHeap[1]=0;
308
309 TYPEINFO BaseTypeInfo={ToType,lpToIndex};
310
311 iRet=CallOperatorProc(CALC_AS,&BaseTypeInfo,type,index_stack,array_bUseHeap,sp);
312
313 pobj_reg->UnlockReg();
314
315 /////////////////////////////////////////////
316 ////// レジスタ資源を復元
317 RESTORE_REGISTER_RESOURCE
318 }////////////////////////////////////////////
319
320
321 if(iRet==1){
322 //成功したとき
323 CalcType=type[0];
324 lpCalcIndex=index_stack[0];
325 return;
326 }
327 else if(iRet==-1){
328 //エラーが発行されたとき
329 return;
330 }
331
332 //エラーを発行
333 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
334}
335
336//インデクサ(getter)を呼び出す
337void CallIndexerGetterProc(int reg,CClass *pobj_Class,char *ObjectName,char *Parameter,TYPEINFO &RetTypeInfo){
338
339 std::vector<SUBINFO *> subs;
340 pobj_Class->EnumMethod( CALC_ARRAY_GET, subs );
341 if( subs.size() == 0 ){
342 return;
343 }
344
345 //////////////////////////////////////////////////////
346 ///// レジスタ資源のバックアップ
347 { BACKUP_REGISTER_RESOURCE
348 //////////////////////////////////////////////////////
349
350 Opcode_CallProc(Parameter,subs[0],0,ObjectName,DEF_OBJECT);
351 RetTypeInfo.type = subs[0]->ReturnType;
352 RetTypeInfo.u.lpIndex = subs[0]->u.ReturnIndex;
353
354 //mov reg,rax
355 op_mov_RR(reg,REG_RAX);
356
357 /////////////////////////////////////////////
358 ////// レジスタ資源を復元
359 RESTORE_REGISTER_RESOURCE
360 }////////////////////////////////////////////
361
362}
Note: See TracBrowser for help on using the repository browser.