source: dev/BasicCompiler64/OperatorProc.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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