source: dev/BasicCompiler32/OperatorProc.cpp@ 66

Last change on this file since 66 was 64, checked in by dai_9181, 18 years ago

すべてのオブジェクトを参照型に切り替えた。

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 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 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 = GetTypeSize(type[sp-1],index_stack[sp-1]);
109
110 if(bTwoTerm){
111 if(psi->pRealParmInfo[1].type==DEF_STRUCT&&psi->pRealParmInfo[1].bByVal){
112 //一時オブジェクトはメソッド内で破棄される
113 bUseHeap[sp-1]=0;
114 }
115 }
116
117
118 if(psi->ReturnType==DEF_STRUCT){
119 //////////////////////////////////////////////////////
120 // 戻り値に構造体インスタンスを持つ場合
121 // ※ByRef _System_ReturnValue パラメータ用領域を取得
122 //////////////////////////////////////////////////////
123
124 int object_size = psi->u.Return_pobj_c->GetSize();
125
126 //push object_size
127 op_push_value(object_size);
128
129 //call calloc
130 extern SUBINFO *pSub_calloc;
131 op_call(pSub_calloc);
132
133 //mov ebx,eax
134 op_mov_RR(REG_EBX,REG_EAX);
135 }
136
137
138 //2つの項を取り出す
139 if(bTwoTerm){
140 if(right_side_size==sizeof(_int64)){
141 //pop eax
142 op_pop(REG_EAX);
143
144 //pop edx
145 op_pop(REG_EDX);
146 }
147 else{
148 //pop eax
149 op_pop(REG_EAX);
150 }
151 }
152
153 //pop ecx
154 op_pop(REG_ECX);
155
156
157 //ヒープ解放用に退避
158 if(bUseHeap[sp-1]){
159 //mov esi,eax
160 op_mov_RR(REG_ESI,REG_EAX);
161 }
162 if(bUseHeap[sp-2]){
163 //mov edi,ecx
164 op_mov_RR(REG_EDI,REG_ECX);
165 }
166
167
168
169 if(bTwoTerm){
170 if(right_side_size==sizeof(_int64)){
171 //push edx
172 op_push(REG_EDX);
173
174 //push eax
175 op_push(REG_EAX);
176 }
177 else{
178 //push eax
179 op_push(REG_EAX);
180 }
181
182 if( !psi->pRealParmInfo[1].bByVal ){
183 //一時参照を作成
184
185 //mov eax,esp
186 op_mov_RR( REG_EAX, REG_ESP );
187
188 //push eax
189 op_push( REG_EAX );
190 }
191 }
192
193 if(psi->ReturnType==DEF_STRUCT){
194 //push ebx
195 op_push(REG_EBX);
196 }
197
198 //push ecx
199 op_push(REG_ECX);
200
201 //call operator_proc
202 op_call(psi);
203
204 if(bTwoTerm){
205 if( !psi->pRealParmInfo[1].bByVal ){
206 //一時参照を破棄
207 op_pop( REG_NON );
208 }
209 }
210
211 if(psi->ReturnType!=DEF_NON){
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_STRUCT){
228 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
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 CallIndexerGetterProc(CClass *pobj_Class,char *ObjectName,char *Parameter,TYPEINFO &RetTypeInfo){
275 std::vector<SUBINFO *> subs;
276 pobj_Class->EnumMethod( CALC_ARRAY_GET, subs );
277 if( subs.size() == 0 ){
278 return;
279 }
280
281 Opcode_CallProc(Parameter,subs[0],0,ObjectName,DEF_OBJECT);
282 RetTypeInfo.type = subs[0]->ReturnType;
283 RetTypeInfo.u.lpIndex = subs[0]->u.ReturnIndex;
284}
Note: See TracBrowser for help on using the repository browser.