source: dev/BasicCompiler32/OperatorProc.cpp@ 38

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

戻り値に基本型を持つインデクサ(Getter)が正常に呼び出せないバグを修正。

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