source: dev/BasicCompiler32/OperatorProc.cpp@ 140

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

Method/Memberのリファクタリング

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