source: dev/BasicCompiler32/OperatorProc.cpp@ 50

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

オーバーロード解決用の関数保持リストを "SUBINFO " ではなく、"vector<SUBINFO *>" に変更した。

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