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

Last change on this file since 299 was 299, checked in by dai_9181, 17 years ago
File size: 6.1 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
[76]30int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack,LONG_PTR *index_stack,BOOL *bUseHeap,int &sp){
[3]31 //オーバーロードされたオペレータ関数を呼び出す
32 CClass *pobj_c;
33 pobj_c=(CClass *)index_stack[sp-2];
34
[206]35 std::vector<const UserProc *> subs;
[135]36 pobj_c->GetMethods().Enum( idCalc, subs );
[50]37 if( subs.size() == 0 ){
[3]38 return 0;
39 }
40
41
42 //項の数
43 BOOL bTwoTerm=1;
44 if(idCalc==CALC_AS) bTwoTerm=0;
45
46
47 /////////////////////////////////////////////
48 // オーバーロード解決用のパラメータを設定
49 /////////////////////////////////////////////
50
[75]51 Parameters params;
[3]52
53 if(bTwoTerm){
[76]54 params.push_back( new Parameter( "", Type( type_stack[sp-1], index_stack[sp-1] ) ) );
[3]55 }
56
57 //オーバーロードを解決
58 char temporary[255];
59 if(idCalc==CALC_EQUAL) lstrcpy(temporary,"==");
60 else GetCalcName(idCalc,temporary);
[206]61 const UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType );
[3]62
[75]63 if(!pUserProc){
64 if(bTwoTerm){
65 delete params[0];
66 }
[3]67 return -1;
68 }
69 else{
70 //オーバーロードされていないが、パラメータ個数が一致しないとき
[75]71 if(params.size()!=pUserProc->Params().size()){
72 if(bTwoTerm){
73 delete params[0];
74 }
[3]75 return -1;
76 }
77 }
78
[76]79 for(int i=0;i<(int)params.size();i++){
[3]80 CheckDifferentType(
[290]81 *pUserProc->Params()[i],
82 *params[i],
[3]83 "",
84 i);
85 }
86
[75]87 if(bTwoTerm){
88 delete params[0];
89 }
[3]90
[290]91 int right_side_size = Type(type_stack[sp-1],index_stack[sp-1]).GetSize();
[3]92
93 if(bTwoTerm){
[75]94 if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){
[3]95 //一時オブジェクトはメソッド内で破棄される
96 bUseHeap[sp-1]=0;
97 }
98 }
99
100
[75]101 if( pUserProc->ReturnType().IsStruct() ){
[3]102 //////////////////////////////////////////////////////
[64]103 // 戻り値に構造体インスタンスを持つ場合
104 // ※ByRef _System_ReturnValue パラメータ用領域を取得
[3]105 //////////////////////////////////////////////////////
106
[75]107 int object_size = pUserProc->ReturnType().GetClass().GetSize();
[3]108
109 //push object_size
[225]110 compiler.codeGenerator.op_push_V(object_size);
[3]111
112 //call calloc
[206]113 extern const UserProc *pSub_calloc;
[225]114 compiler.codeGenerator.op_call(pSub_calloc);
[3]115
116 //mov ebx,eax
[225]117 compiler.codeGenerator.op_mov_RR(REG_EBX,REG_EAX);
[3]118 }
119
120
121 //2つの項を取り出す
122 if(bTwoTerm){
123 if(right_side_size==sizeof(_int64)){
124 //pop eax
[225]125 compiler.codeGenerator.op_pop(REG_EAX);
[3]126
127 //pop edx
[225]128 compiler.codeGenerator.op_pop(REG_EDX);
[3]129 }
130 else{
131 //pop eax
[225]132 compiler.codeGenerator.op_pop(REG_EAX);
[3]133 }
134 }
135
136 //pop ecx
[225]137 compiler.codeGenerator.op_pop(REG_ECX);
[3]138
139
140 //ヒープ解放用に退避
141 if(bUseHeap[sp-1]){
142 //mov esi,eax
[225]143 compiler.codeGenerator.op_mov_RR(REG_ESI,REG_EAX);
[3]144 }
145 if(bUseHeap[sp-2]){
146 //mov edi,ecx
[225]147 compiler.codeGenerator.op_mov_RR(REG_EDI,REG_ECX);
[3]148 }
149
150
151
152 if(bTwoTerm){
153 if(right_side_size==sizeof(_int64)){
154 //push edx
[225]155 compiler.codeGenerator.op_push(REG_EDX);
[3]156
157 //push eax
[225]158 compiler.codeGenerator.op_push(REG_EAX);
[3]159 }
160 else{
161 //push eax
[225]162 compiler.codeGenerator.op_push(REG_EAX);
[3]163 }
[64]164
[75]165 if( pUserProc->RealParams()[1]->IsRef() ){
[64]166 //一時参照を作成
167
168 //mov eax,esp
[225]169 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ESP );
[64]170
171 //push eax
[225]172 compiler.codeGenerator.op_push( REG_EAX );
[64]173 }
[3]174 }
175
[75]176 if( pUserProc->ReturnType().IsStruct() ){
[3]177 //push ebx
[225]178 compiler.codeGenerator.op_push(REG_EBX);
[3]179 }
180
181 //push ecx
[225]182 compiler.codeGenerator.op_push(REG_ECX);
[3]183
184 //call operator_proc
[225]185 compiler.codeGenerator.op_call(pUserProc);
[3]186
[64]187 if(bTwoTerm){
[75]188 if( pUserProc->RealParams()[1]->IsRef() ){
[64]189 //一時参照を破棄
[225]190 compiler.codeGenerator.op_pop( REG_NON );
[64]191 }
192 }
193
[75]194 if( !pUserProc->ReturnType().IsNull() ){
[3]195 //スタックへプッシュ
[75]196 PushReturnValue(pUserProc->ReturnType().GetBasicType());
[3]197 }
198
199 if(bUseHeap[sp-1]){
200 FreeTempObject(REG_ESI,(CClass *)index_stack[sp-1]);
201 }
202 if(bUseHeap[sp-2]){
203 FreeTempObject(REG_EDI,(CClass *)index_stack[sp-2]);
204 }
205
206 sp--;
[76]207 type_stack[sp-1]=pUserProc->ReturnType().GetBasicType();
[75]208 index_stack[sp-1]=pUserProc->ReturnType().GetIndex();
[3]209
[75]210 if( pUserProc->ReturnType().IsStruct() ){
[64]211 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]212 //※後にfreeする必要あり
213 bUseHeap[sp-1]=1;
214 }
215 else bUseHeap[sp-1]=0;
216
217 return 1;
218}
219
[76]220void CallCastOperatorProc(Type &calcType,BOOL bCalcUseHeap,const Type &toType){
221 int type_stack[10];
[3]222 LONG_PTR index_stack[10];
223 BOOL array_bUseHeap[10];
224 int sp=2;
225
226 if(bCalcUseHeap){
227 //未解放のインスタンスが存在する旨を示す警告
228 SetError(-105,NULL,cp);
229 }
230
231 //左辺
[76]232 type_stack[0]=calcType.GetBasicType();
233 index_stack[0]=calcType.GetIndex();
[3]234 array_bUseHeap[0]=0;
[76]235 type_stack[1]=toType.GetBasicType();
236 index_stack[1]=toType.GetIndex();
[3]237 array_bUseHeap[1]=0;
238
[76]239 int iRet = CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp);
[3]240
241 if(iRet==1){
242 //成功したとき
[76]243 calcType.SetType( type_stack[0], index_stack[0] );
[3]244 return;
245 }
246 else if(iRet==-1){
247 //エラーが発行されたとき
248 return;
249 }
250
251 //エラーを発行
252 SetError(-1,"キャスト演算子がオーバーロードされていません。",cp);
253}
[293]254void CallIndexerGetterProc( const Type &classType, char *ObjectName, char *Parameter,Type &resultType){
[206]255 std::vector<const UserProc *> subs;
[293]256 classType.GetClass().GetMethods().Enum( CALC_ARRAY_GET, subs );
[50]257 if( subs.size() == 0 ){
[3]258 return;
259 }
260
[299]261 const UserProc *pUserProc = subs[0];
[292]262
[299]263 Opcode_CallProc(Parameter,pUserProc,0,ObjectName);
264 resultType = pUserProc->ReturnType();
[292]265
[299]266 // 型パラメータを解決
267 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
[3]268}
Note: See TracBrowser for help on using the repository browser.