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
RevLine 
[3]1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
[75]4void FreeTempObject(int reg,const CClass *pobj_c){
[3]5 if(!IsSafeReg(reg)) SetError(300,NULL,cp);
6
7 ////////////////////////////////////////////////
8 // 演算過程で利用した一時オブジェクトを破棄
9 // Thisポインタをr14レジスタを介して渡す
10 ////////////////////////////////////////////////
11
[51]12 CMethod *method = pobj_c->GetDestructorMethod();
13 if( method ){
[3]14 //mov rcx,reg
15 op_mov_RR(REG_RCX,reg);
16
17 //call DestructorProcAddr
[75]18 op_call( method->pUserProc );
[3]19 }
20
21 //mov rcx,reg
22 op_mov_RR(REG_RCX,reg);
23
24 //call free
[75]25 extern UserProc *pSub_free;
[3]26 op_call(pSub_free);
27}
28
[75]29int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack,LONG_PTR *index_stack,BOOL *bUseHeap,int &sp){
[3]30 //オーバーロードされたオペレータ関数を呼び出す
31 CClass *pobj_c;
32 pobj_c=(CClass *)index_stack[sp-2];
33
[75]34 std::vector<UserProc *> subs;
[50]35 pobj_c->EnumMethod( idCalc, subs );
36 if( subs.size() == 0 ){
[3]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
[75]53 Parameters params;
[3]54
55 if(bTwoTerm){
[75]56 params.push_back( new Parameter( "", Type( type_stack[sp-1], index_stack[sp-1] ) ) );
[3]57 }
58
59 //オーバーロードを解決
60 char temporary[255];
61 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
62 else GetCalcName(idCalc,temporary);
[75]63 UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType );
[3]64
[75]65 if(!pUserProc){
66 if(bTwoTerm){
67 delete params[0];
68 }
[3]69 return -1;
70 }
71 else{
72 //オーバーロードされていないが、パラメータ個数が一致しないとき
[75]73 if(params.size()!=pUserProc->Params().size()){
74 if(bTwoTerm){
75 delete params[0];
76 }
[3]77 return -1;
78 }
79 }
80
[75]81 for(i=0;i<(int)params.size();i++){
[3]82 CheckDifferentType(
[75]83 pUserProc->Params()[i]->GetBasicType(),
84 pUserProc->Params()[i]->GetIndex(),
85 params[i]->GetBasicType(),
86 params[i]->GetIndex(),
[3]87 "",
88 i);
89 }
90
[75]91 if(bTwoTerm){
92 delete params[0];
93 }
[3]94
[75]95 int right_side_size = GetTypeSize(type_stack[sp-1],index_stack[sp-1]);
96
[3]97 if(bTwoTerm){
[75]98 if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){
[3]99 //一時オブジェクトはメソッド内で破棄される
100 bUseHeap[sp-1]=0;
101 }
102 }
103
[75]104
105 if( pUserProc->ReturnType().IsStruct() ){
[3]106 //////////////////////////////////////////////////////
[64]107 // 戻り値に構造体インスタンスを持つ場合
108 // ※ByRef _System_ReturnValue パラメータ用領域を取得
[3]109 //////////////////////////////////////////////////////
110
111
112 //////////////////////////////////////////////////////
113 ///// レジスタ資源のバックアップ
114 { BACKUP_REGISTER_RESOURCE
115 //////////////////////////////////////////////////////
116
[75]117 int object_size = pUserProc->ReturnType().GetClass().GetSize();
[3]118
119 //mov rcx,object_size
120 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
121
122 //call calloc
[75]123 extern UserProc *pSub_calloc;
[3]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 //右の項(実数の場合が未完成)
[75]138 SetOneTermToReg_Whole64Calc(type_stack[sp-1],&reg2);
[3]139 pobj_reg->UnlockReg();
[75]140 if( !pUserProc->RealParams()[1]->IsRef() == false ){
[64]141 //一時参照を作成
142 pobj_sf->push( reg2 );
143 pobj_sf->mov_sp( reg2 );
144 }
[3]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){
[75]176 if( pUserProc->ReturnType().IsStruct() ){
[3]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
[75]186 if( pUserProc->ReturnType().IsStruct() ){
[3]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
[75]195 op_call(pUserProc);
[3]196
[75]197 if( !pUserProc->ReturnType().IsNull() ){
[3]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
[64]238 if(bTwoTerm){
[75]239 if( !pUserProc->RealParams()[1]->IsRef() == false ){
[64]240 //一時参照を破棄
241 pobj_sf->pop();
242 }
243 }
244
[75]245 if( !pUserProc->ReturnType().IsNull() ){
[3]246 //戻り値をreg1にセット
247 reg1=pobj_reg->LockReg();
248
249 //mov reg1,r13
250 op_mov_RR(reg1,REG_R13);
251 }
252
253 sp--;
[75]254 type_stack[sp-1]=pUserProc->ReturnType().GetBasicType();
255 index_stack[sp-1]=pUserProc->ReturnType().GetIndex();
[3]256
[75]257 if( pUserProc->ReturnType().IsStruct() ){
[64]258 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]259 //※後にfreeする必要あり
260 bUseHeap[sp-1]=1;
261 }
262 else bUseHeap[sp-1]=0;
263
264 return 1;
265}
266
[75]267void CallCastOperatorProc(int reg,Type &calcType,BOOL bCalcUseHeap,const Type &toType){
268 int type_stack[10];
[3]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 //左辺
[75]290 type_stack[0]=calcType.GetBasicType();
291 index_stack[0]=calcType.GetIndex();
[3]292 array_bUseHeap[0]=0;
[75]293 type_stack[1]=toType.GetBasicType();
294 index_stack[1]=toType.GetIndex();
[3]295 array_bUseHeap[1]=0;
296
[75]297 iRet=CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp);
[3]298
299 pobj_reg->UnlockReg();
300
301 /////////////////////////////////////////////
302 ////// レジスタ資源を復元
303 RESTORE_REGISTER_RESOURCE
304 }////////////////////////////////////////////
305
306
307 if(iRet==1){
308 //成功したとき
[75]309 calcType.SetType( type_stack[0], index_stack[0] );
[3]310 return;
311 }
312 else if(iRet==-1){
313 //エラーが発行されたとき
314 return;
315 }
316
317 //エラーを発行
318 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
319}
320
[38]321//インデクサ(getter)を呼び出す
[75]322void CallIndexerGetterProc(int reg,const CClass *pobj_Class,char *ObjectName,char *Parameter,Type &resultType ){
[3]323
[75]324 std::vector<UserProc *> subs;
[50]325 pobj_Class->EnumMethod( CALC_ARRAY_GET, subs );
326 if( subs.size() == 0 ){
[3]327 return;
328 }
329
330 //////////////////////////////////////////////////////
331 ///// レジスタ資源のバックアップ
332 { BACKUP_REGISTER_RESOURCE
333 //////////////////////////////////////////////////////
334
[50]335 Opcode_CallProc(Parameter,subs[0],0,ObjectName,DEF_OBJECT);
[75]336 resultType = subs[0]->ReturnType();
[3]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.