source: dev/BasicCompiler64/OperatorProc.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

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