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

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

コード全体のリファクタリングを実施

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