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

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

インターフェイスを実装

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