source: dev/BasicCompiler32/OperatorProc.cpp@ 51

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

ppobj_Member及びppobj_StaticMemberを廃止し、vectorに統一した(methods及びstaticMethods)。

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