source: dev/trunk/abdev/BasicCompiler32/OperatorProc.cpp@ 350

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

インターフェイスを実装

File size: 6.2 KB
RevLine 
[206]1#include "stdafx.h"
2
3#include <jenga/include/smoothie/LexicalAnalysis.h>
4
[225]5#include <Compiler.h>
6
[3]7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
[76]10void FreeTempObject(int reg,const CClass *pobj_c){
[3]11 if(!IsSafeReg(reg)) SetError(300,NULL,cp);
12
[135]13 const CMethod *method = pobj_c->GetDestructorMethod();
[51]14 if( method ){
[3]15 //push reg
[225]16 compiler.codeGenerator.op_push(reg);
[3]17
18 //call DestructorProcAddr
[225]19 compiler.codeGenerator.op_call( &method->GetUserProc() );
[3]20 }
21
22 //push reg
[225]23 compiler.codeGenerator.op_push(reg);
[3]24
25 //call free
[206]26 extern const UserProc *pSub_free;
[225]27 compiler.codeGenerator.op_call(pSub_free);
[3]28}
29
[350]30int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,BOOL *bUseHeap,int &sp)
31{
32 Type leftType( type_stack[sp-2], index_stack[sp-2] );
33 Type rightType( type_stack[sp-1] & (~FLAG_CAST), index_stack[sp-1] );
34
[3]35 //オーバーロードされたオペレータ関数を呼び出す
[350]36 const CClass *pobj_c = &leftType.GetClass();
[3]37
[206]38 std::vector<const UserProc *> subs;
[342]39 pobj_c->GetDynamicMethods().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){
[350]57 params.push_back( new Parameter( "", rightType ) );
[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(
[290]84 *pUserProc->Params()[i],
85 *params[i],
[3]86 "",
87 i);
88 }
89
[75]90 if(bTwoTerm){
91 delete params[0];
92 }
[3]93
[350]94 int right_side_size = rightType.GetSize();
[3]95
96 if(bTwoTerm){
[75]97 if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){
[3]98 //一時オブジェクトはメソッド内で破棄される
99 bUseHeap[sp-1]=0;
100 }
101 }
102
103
[75]104 if( pUserProc->ReturnType().IsStruct() ){
[3]105 //////////////////////////////////////////////////////
[64]106 // 戻り値に構造体インスタンスを持つ場合
107 // ※ByRef _System_ReturnValue パラメータ用領域を取得
[3]108 //////////////////////////////////////////////////////
109
[75]110 int object_size = pUserProc->ReturnType().GetClass().GetSize();
[3]111
112 //push object_size
[225]113 compiler.codeGenerator.op_push_V(object_size);
[3]114
115 //call calloc
[206]116 extern const UserProc *pSub_calloc;
[225]117 compiler.codeGenerator.op_call(pSub_calloc);
[3]118
119 //mov ebx,eax
[225]120 compiler.codeGenerator.op_mov_RR(REG_EBX,REG_EAX);
[3]121 }
122
123
124 //2つの項を取り出す
125 if(bTwoTerm){
126 if(right_side_size==sizeof(_int64)){
127 //pop eax
[225]128 compiler.codeGenerator.op_pop(REG_EAX);
[3]129
130 //pop edx
[225]131 compiler.codeGenerator.op_pop(REG_EDX);
[3]132 }
133 else{
134 //pop eax
[225]135 compiler.codeGenerator.op_pop(REG_EAX);
[3]136 }
137 }
138
139 //pop ecx
[225]140 compiler.codeGenerator.op_pop(REG_ECX);
[3]141
142
143 //ヒープ解放用に退避
144 if(bUseHeap[sp-1]){
145 //mov esi,eax
[225]146 compiler.codeGenerator.op_mov_RR(REG_ESI,REG_EAX);
[3]147 }
148 if(bUseHeap[sp-2]){
149 //mov edi,ecx
[225]150 compiler.codeGenerator.op_mov_RR(REG_EDI,REG_ECX);
[3]151 }
152
153
154
155 if(bTwoTerm){
156 if(right_side_size==sizeof(_int64)){
157 //push edx
[225]158 compiler.codeGenerator.op_push(REG_EDX);
[3]159
160 //push eax
[225]161 compiler.codeGenerator.op_push(REG_EAX);
[3]162 }
163 else{
164 //push eax
[225]165 compiler.codeGenerator.op_push(REG_EAX);
[3]166 }
[64]167
[75]168 if( pUserProc->RealParams()[1]->IsRef() ){
[64]169 //一時参照を作成
170
171 //mov eax,esp
[225]172 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ESP );
[64]173
174 //push eax
[225]175 compiler.codeGenerator.op_push( REG_EAX );
[64]176 }
[3]177 }
178
[75]179 if( pUserProc->ReturnType().IsStruct() ){
[3]180 //push ebx
[225]181 compiler.codeGenerator.op_push(REG_EBX);
[3]182 }
183
184 //push ecx
[225]185 compiler.codeGenerator.op_push(REG_ECX);
[3]186
187 //call operator_proc
[225]188 compiler.codeGenerator.op_call(pUserProc);
[3]189
[64]190 if(bTwoTerm){
[75]191 if( pUserProc->RealParams()[1]->IsRef() ){
[64]192 //一時参照を破棄
[225]193 compiler.codeGenerator.op_pop( REG_NON );
[64]194 }
195 }
196
[75]197 if( !pUserProc->ReturnType().IsNull() ){
[3]198 //スタックへプッシュ
[75]199 PushReturnValue(pUserProc->ReturnType().GetBasicType());
[3]200 }
201
202 if(bUseHeap[sp-1]){
203 FreeTempObject(REG_ESI,(CClass *)index_stack[sp-1]);
204 }
205 if(bUseHeap[sp-2]){
206 FreeTempObject(REG_EDI,(CClass *)index_stack[sp-2]);
207 }
208
209 sp--;
[76]210 type_stack[sp-1]=pUserProc->ReturnType().GetBasicType();
[75]211 index_stack[sp-1]=pUserProc->ReturnType().GetIndex();
[3]212
[75]213 if( pUserProc->ReturnType().IsStruct() ){
[64]214 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]215 //※後にfreeする必要あり
216 bUseHeap[sp-1]=1;
217 }
218 else bUseHeap[sp-1]=0;
219
220 return 1;
221}
222
[76]223void CallCastOperatorProc(Type &calcType,BOOL bCalcUseHeap,const Type &toType){
224 int type_stack[10];
[3]225 LONG_PTR index_stack[10];
226 BOOL array_bUseHeap[10];
227 int sp=2;
228
229 if(bCalcUseHeap){
230 //未解放のインスタンスが存在する旨を示す警告
231 SetError(-105,NULL,cp);
232 }
233
234 //左辺
[76]235 type_stack[0]=calcType.GetBasicType();
236 index_stack[0]=calcType.GetIndex();
[3]237 array_bUseHeap[0]=0;
[76]238 type_stack[1]=toType.GetBasicType();
239 index_stack[1]=toType.GetIndex();
[3]240 array_bUseHeap[1]=0;
241
[76]242 int iRet = CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp);
[3]243
244 if(iRet==1){
245 //成功したとき
[76]246 calcType.SetType( type_stack[0], index_stack[0] );
[3]247 return;
248 }
249 else if(iRet==-1){
250 //エラーが発行されたとき
251 return;
252 }
253
254 //エラーを発行
255 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
256}
[334]257void CallIndexerGetterProc( const Type &classType, const char *ObjectName, char *Parameter,Type &resultType, DWORD dwProcFlags ){
[206]258 std::vector<const UserProc *> subs;
[342]259 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
[50]260 if( subs.size() == 0 ){
[3]261 return;
262 }
263
[299]264 const UserProc *pUserProc = subs[0];
[292]265
[334]266 Opcode_CallProc(Parameter,pUserProc,dwProcFlags,ObjectName);
[299]267 resultType = pUserProc->ReturnType();
[292]268
[299]269 // 型パラメータを解決
270 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
[3]271}
Note: See TracBrowser for help on using the repository browser.