source: dev/trunk/abdev/BasicCompiler64/OperatorProc.cpp@ 226

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