source: dev/BasicCompiler64/OperatorProc.cpp@ 135

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

Method/Memberのリファクタリング

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