source: dev/BasicCompiler64/OperatorProc.cpp@ 63

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

CClass::GetSize、CClass::GetMemberOffsetを追加

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 = psi->u.Return_pobj_c->GetSize();
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 SetError(-105,NULL,cp);
298 }
299
300 //左辺
301 type[0]=CalcType;
302 index_stack[0]=lpCalcIndex;
303 array_bUseHeap[0]=0;
304 type[1]=ToType;
305 index_stack[1]=lpToIndex;
306 array_bUseHeap[1]=0;
307
308 TYPEINFO BaseTypeInfo={ToType,lpToIndex};
309
310 iRet=CallOperatorProc(CALC_AS,&BaseTypeInfo,type,index_stack,array_bUseHeap,sp);
311
312 pobj_reg->UnlockReg();
313
314 /////////////////////////////////////////////
315 ////// レジスタ資源を復元
316 RESTORE_REGISTER_RESOURCE
317 }////////////////////////////////////////////
318
319
320 if(iRet==1){
321 //成功したとき
322 CalcType=type[0];
323 lpCalcIndex=index_stack[0];
324 return;
325 }
326 else if(iRet==-1){
327 //エラーが発行されたとき
328 return;
329 }
330
331 //エラーを発行
332 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
333}
334
335//インデクサ(getter)を呼び出す
336void CallIndexerGetterProc(int reg,CClass *pobj_Class,char *ObjectName,char *Parameter,TYPEINFO &RetTypeInfo){
337
338 std::vector<SUBINFO *> subs;
339 pobj_Class->EnumMethod( CALC_ARRAY_GET, subs );
340 if( subs.size() == 0 ){
341 return;
342 }
343
344 //////////////////////////////////////////////////////
345 ///// レジスタ資源のバックアップ
346 { BACKUP_REGISTER_RESOURCE
347 //////////////////////////////////////////////////////
348
349 Opcode_CallProc(Parameter,subs[0],0,ObjectName,DEF_OBJECT);
350 RetTypeInfo.type = subs[0]->ReturnType;
351 RetTypeInfo.u.lpIndex = subs[0]->u.ReturnIndex;
352
353 //mov reg,rax
354 op_mov_RR(reg,REG_RAX);
355
356 /////////////////////////////////////////////
357 ////// レジスタ資源を復元
358 RESTORE_REGISTER_RESOURCE
359 }////////////////////////////////////////////
360
361}
Note: See TracBrowser for help on using the repository browser.