1 | #include "stdafx.h" |
---|
2 | |
---|
3 | #include <Compiler.h> |
---|
4 | |
---|
5 | #include "../BasicCompiler_Common/common.h" |
---|
6 | #include "Opcode.h" |
---|
7 | |
---|
8 | void FreeTempObject(int reg,const CClass *pobj_c){ |
---|
9 | if(!IsSafeReg(reg)) compiler.errorMessenger.Output(300,NULL,cp); |
---|
10 | |
---|
11 | const CMethod *method = pobj_c->GetDestructorMethod(); |
---|
12 | if( method ){ |
---|
13 | //push reg |
---|
14 | compiler.codeGenerator.op_push(reg); |
---|
15 | |
---|
16 | //call DestructorProcAddr |
---|
17 | compiler.codeGenerator.op_call( &method->GetUserProc() ); |
---|
18 | } |
---|
19 | |
---|
20 | //push reg |
---|
21 | compiler.codeGenerator.op_push(reg); |
---|
22 | |
---|
23 | //call free |
---|
24 | extern const UserProc *pSub_free; |
---|
25 | compiler.codeGenerator.op_call(pSub_free); |
---|
26 | } |
---|
27 | |
---|
28 | int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,bool isNeedHeapFreeStructureStack[],int &sp) |
---|
29 | { |
---|
30 | Type leftType( type_stack[sp-2], index_stack[sp-2] ); |
---|
31 | Type rightType( type_stack[sp-1] & (~FLAG_CAST), index_stack[sp-1] ); |
---|
32 | |
---|
33 | //オーバーロードされたオペレータ関数を呼び出す |
---|
34 | const CClass *pobj_c = &leftType.GetClass(); |
---|
35 | |
---|
36 | std::vector<const UserProc *> subs; |
---|
37 | pobj_c->GetDynamicMethods().Enum( idCalc, subs ); |
---|
38 | if( subs.size() == 0 ){ |
---|
39 | return 0; |
---|
40 | } |
---|
41 | |
---|
42 | |
---|
43 | //項の数 |
---|
44 | BOOL bTwoTerm=1; |
---|
45 | if(idCalc==CALC_AS) bTwoTerm=0; |
---|
46 | |
---|
47 | |
---|
48 | ///////////////////////////////////////////// |
---|
49 | // オーバーロード解決用のパラメータを設定 |
---|
50 | ///////////////////////////////////////////// |
---|
51 | |
---|
52 | Parameters params; |
---|
53 | |
---|
54 | if(bTwoTerm){ |
---|
55 | params.push_back( new Parameter( "", rightType ) ); |
---|
56 | } |
---|
57 | |
---|
58 | //オーバーロードを解決 |
---|
59 | char temporary[255]; |
---|
60 | if(idCalc==CALC_EQUAL) lstrcpy(temporary,"=="); |
---|
61 | else GetCalcName(idCalc,temporary); |
---|
62 | const UserProc *pUserProc = OverloadSolution( temporary, subs, params, baseType, leftType ); |
---|
63 | |
---|
64 | if(!pUserProc){ |
---|
65 | if(bTwoTerm){ |
---|
66 | delete params[0]; |
---|
67 | } |
---|
68 | return -1; |
---|
69 | } |
---|
70 | else{ |
---|
71 | //オーバーロードされていないが、パラメータ個数が一致しないとき |
---|
72 | if(params.size()!=pUserProc->Params().size()){ |
---|
73 | if(bTwoTerm){ |
---|
74 | delete params[0]; |
---|
75 | } |
---|
76 | return -1; |
---|
77 | } |
---|
78 | } |
---|
79 | |
---|
80 | for(int i=0;i<(int)params.size();i++){ |
---|
81 | CheckDifferentType( |
---|
82 | *pUserProc->Params()[i], |
---|
83 | *params[i], |
---|
84 | NULL, |
---|
85 | i); |
---|
86 | } |
---|
87 | |
---|
88 | if(bTwoTerm){ |
---|
89 | delete params[0]; |
---|
90 | } |
---|
91 | |
---|
92 | int right_side_size = rightType.GetSize(); |
---|
93 | |
---|
94 | if(bTwoTerm){ |
---|
95 | if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){ |
---|
96 | //一時オブジェクトはメソッド内で破棄される |
---|
97 | isNeedHeapFreeStructureStack[sp-1] = false; |
---|
98 | } |
---|
99 | } |
---|
100 | |
---|
101 | |
---|
102 | if( pUserProc->ReturnType().IsStruct() ){ |
---|
103 | ////////////////////////////////////////////////////// |
---|
104 | // 戻り値に構造体インスタンスを持つ場合 |
---|
105 | // ※ByRef _System_ReturnValue パラメータ用領域を取得 |
---|
106 | ////////////////////////////////////////////////////// |
---|
107 | |
---|
108 | int object_size = pUserProc->ReturnType().GetClass().GetSize(); |
---|
109 | |
---|
110 | //push object_size |
---|
111 | compiler.codeGenerator.op_push_V(object_size); |
---|
112 | |
---|
113 | //call calloc |
---|
114 | extern const UserProc *pSub_calloc; |
---|
115 | compiler.codeGenerator.op_call(pSub_calloc); |
---|
116 | |
---|
117 | //mov ebx,eax |
---|
118 | compiler.codeGenerator.op_mov_RR(REG_EBX,REG_EAX); |
---|
119 | } |
---|
120 | |
---|
121 | |
---|
122 | //2つの項を取り出す |
---|
123 | if(bTwoTerm){ |
---|
124 | if(right_side_size==sizeof(_int64)){ |
---|
125 | //pop eax |
---|
126 | compiler.codeGenerator.op_pop(REG_EAX); |
---|
127 | |
---|
128 | //pop edx |
---|
129 | compiler.codeGenerator.op_pop(REG_EDX); |
---|
130 | } |
---|
131 | else{ |
---|
132 | //pop eax |
---|
133 | compiler.codeGenerator.op_pop(REG_EAX); |
---|
134 | } |
---|
135 | } |
---|
136 | |
---|
137 | //pop ecx |
---|
138 | compiler.codeGenerator.op_pop(REG_ECX); |
---|
139 | |
---|
140 | |
---|
141 | //ヒープ解放用に退避 |
---|
142 | if(isNeedHeapFreeStructureStack[sp-1]){ |
---|
143 | //mov esi,eax |
---|
144 | compiler.codeGenerator.op_mov_RR(REG_ESI,REG_EAX); |
---|
145 | } |
---|
146 | if(isNeedHeapFreeStructureStack[sp-2]){ |
---|
147 | //mov edi,ecx |
---|
148 | compiler.codeGenerator.op_mov_RR(REG_EDI,REG_ECX); |
---|
149 | } |
---|
150 | |
---|
151 | |
---|
152 | |
---|
153 | if(bTwoTerm){ |
---|
154 | if(right_side_size==sizeof(_int64)){ |
---|
155 | //push edx |
---|
156 | compiler.codeGenerator.op_push(REG_EDX); |
---|
157 | |
---|
158 | //push eax |
---|
159 | compiler.codeGenerator.op_push(REG_EAX); |
---|
160 | } |
---|
161 | else{ |
---|
162 | //push eax |
---|
163 | compiler.codeGenerator.op_push(REG_EAX); |
---|
164 | } |
---|
165 | |
---|
166 | if( pUserProc->RealParams()[1]->IsRef() ){ |
---|
167 | //一時参照を作成 |
---|
168 | |
---|
169 | //mov eax,esp |
---|
170 | compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ESP ); |
---|
171 | |
---|
172 | //push eax |
---|
173 | compiler.codeGenerator.op_push( REG_EAX ); |
---|
174 | } |
---|
175 | } |
---|
176 | |
---|
177 | if( pUserProc->ReturnType().IsStruct() ){ |
---|
178 | //push ebx |
---|
179 | compiler.codeGenerator.op_push(REG_EBX); |
---|
180 | } |
---|
181 | |
---|
182 | //push ecx |
---|
183 | compiler.codeGenerator.op_push(REG_ECX); |
---|
184 | |
---|
185 | //call operator_proc |
---|
186 | compiler.codeGenerator.op_call(pUserProc); |
---|
187 | |
---|
188 | if(bTwoTerm){ |
---|
189 | if( pUserProc->RealParams()[1]->IsRef() ){ |
---|
190 | //一時参照を破棄 |
---|
191 | compiler.codeGenerator.op_pop( REG_NON ); |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | if( !pUserProc->ReturnType().IsNull() ){ |
---|
196 | //スタックへプッシュ |
---|
197 | PushReturnValue(pUserProc->ReturnType().GetBasicType()); |
---|
198 | } |
---|
199 | |
---|
200 | if(isNeedHeapFreeStructureStack[sp-1]){ |
---|
201 | FreeTempObject(REG_ESI,(CClass *)index_stack[sp-1]); |
---|
202 | } |
---|
203 | if(isNeedHeapFreeStructureStack[sp-2]){ |
---|
204 | FreeTempObject(REG_EDI,(CClass *)index_stack[sp-2]); |
---|
205 | } |
---|
206 | |
---|
207 | sp--; |
---|
208 | type_stack[sp-1]=pUserProc->ReturnType().GetBasicType(); |
---|
209 | index_stack[sp-1]=pUserProc->ReturnType().GetIndex(); |
---|
210 | |
---|
211 | if( pUserProc->ReturnType().IsStruct() ) |
---|
212 | { |
---|
213 | //構造体が戻ったときはヒープ領域にインスタンスが格納されている |
---|
214 | //※後にfreeする必要あり |
---|
215 | isNeedHeapFreeStructureStack[sp-1] = true; |
---|
216 | } |
---|
217 | else |
---|
218 | { |
---|
219 | isNeedHeapFreeStructureStack[sp-1] = false; |
---|
220 | } |
---|
221 | |
---|
222 | return 1; |
---|
223 | } |
---|
224 | |
---|
225 | void CallCastOperatorProc(Type &calcType,BOOL bCalcUseHeap,const Type &toType){ |
---|
226 | int type_stack[10]; |
---|
227 | LONG_PTR index_stack[10]; |
---|
228 | bool array_bUseHeap[10]; |
---|
229 | int sp=2; |
---|
230 | |
---|
231 | if(bCalcUseHeap){ |
---|
232 | //未解放のインスタンスが存在する旨を示す警告 |
---|
233 | compiler.errorMessenger.Output(-105,NULL,cp); |
---|
234 | } |
---|
235 | |
---|
236 | //左辺 |
---|
237 | type_stack[0]=calcType.GetBasicType(); |
---|
238 | index_stack[0]=calcType.GetIndex(); |
---|
239 | array_bUseHeap[0]=0; |
---|
240 | type_stack[1]=toType.GetBasicType(); |
---|
241 | index_stack[1]=toType.GetIndex(); |
---|
242 | array_bUseHeap[1]=0; |
---|
243 | |
---|
244 | int iRet = CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp); |
---|
245 | |
---|
246 | if(iRet==1){ |
---|
247 | //成功したとき |
---|
248 | calcType.SetType( type_stack[0], index_stack[0] ); |
---|
249 | return; |
---|
250 | } |
---|
251 | else if(iRet==-1){ |
---|
252 | //エラーが発行されたとき |
---|
253 | return; |
---|
254 | } |
---|
255 | |
---|
256 | //エラーを発行 |
---|
257 | compiler.errorMessenger.Output(-1,"キャスト演算子がオーバーロードされていません。",cp); |
---|
258 | } |
---|
259 | void CallIndexerGetterProc( const Type &classType, const char *ObjectName, char *Parameter,Type &resultType, DWORD dwProcFlags ){ |
---|
260 | std::vector<const UserProc *> subs; |
---|
261 | classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs ); |
---|
262 | if( subs.size() == 0 ){ |
---|
263 | return; |
---|
264 | } |
---|
265 | |
---|
266 | const UserProc *pUserProc = subs[0]; |
---|
267 | |
---|
268 | Opcode_CallProc(Parameter,pUserProc,dwProcFlags,ObjectName); |
---|
269 | resultType = pUserProc->ReturnType(); |
---|
270 | |
---|
271 | // 型パラメータを解決 |
---|
272 | ResolveFormalGenericTypeParameter( resultType, classType, pUserProc ); |
---|
273 | } |
---|