source: dev/BasicCompiler32/OperatorProc.cpp@ 8

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