source: dev/BasicCompiler32/OperatorProc.cpp@ 63

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

CClass::GetSize、CClass::GetMemberOffsetを追加

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 = psi->u.Return_pobj_c->GetSize();
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.