source: dev/BasicCompiler32/OperatorProc.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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