source: dev/branches/egtra/ab5.0/abdev/compiler_x86/OperatorProc.cpp@ 813

Last change on this file since 813 was 675, checked in by dai_9181, 16 years ago

・キャスト演算子が存在せずに型変換できなかった場合のエラーメッセージを変更した。

File size: 6.5 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8void 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
28int 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() );
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 Type temp( pUserProc->ReturnType() );
208 ResolveFormalGenericTypeParameter( temp, leftType, pUserProc );
209
210 sp--;
211 type_stack[sp-1] = temp.GetBasicType();
212 index_stack[sp-1] = temp.GetIndex();
213
214 if( pUserProc->ReturnType().IsStruct() )
215 {
216 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
217 //※後にfreeする必要あり
218 isNeedHeapFreeStructureStack[sp-1] = true;
219 }
220 else
221 {
222 isNeedHeapFreeStructureStack[sp-1] = false;
223 }
224
225 return 1;
226}
227
228void CallCastOperatorProc(Type &calcType,BOOL bCalcUseHeap,const Type &toType){
229 int type_stack[10];
230 LONG_PTR index_stack[10];
231 bool array_bUseHeap[10];
232 int sp=2;
233
234 if(bCalcUseHeap){
235 //未解放のインスタンスが存在する旨を示す警告
236 compiler.errorMessenger.Output(-105,NULL,cp);
237 }
238
239 //左辺
240 type_stack[0]=calcType.GetBasicType();
241 index_stack[0]=calcType.GetIndex();
242 array_bUseHeap[0]=0;
243 type_stack[1]=toType.GetBasicType();
244 index_stack[1]=toType.GetIndex();
245 array_bUseHeap[1]=0;
246
247 int iRet = CallOperatorProc(CALC_AS,toType,type_stack,index_stack,array_bUseHeap,sp);
248
249 if(iRet==1){
250 //成功したとき
251 calcType.SetType( type_stack[0], index_stack[0] );
252 return;
253 }
254 else if(iRet==-1){
255 //エラーが発行されたとき
256 return;
257 }
258
259 //エラーを発行
260 compiler.errorMessenger.Output(-1,calcType.ToString() + " から " + toType.ToString() + " へ型変換できません。",cp);
261}
262void CallIndexerGetterProc( const Type &classType, const char *ObjectName, char *Parameter,Type &resultType, DWORD dwProcFlags ){
263 std::vector<const UserProc *> subs;
264 classType.GetClass().GetDynamicMethods().Enum( CALC_ARRAY_GET, subs );
265 if( subs.size() == 0 ){
266 return;
267 }
268
269 const UserProc *pUserProc = subs[0];
270
271 Opcode_CallProc(Parameter,pUserProc,dwProcFlags,ObjectName);
272 resultType = pUserProc->ReturnType();
273
274 // 型パラメータを解決
275 ResolveFormalGenericTypeParameter( resultType, classType, pUserProc );
276}
Note: See TracBrowser for help on using the repository browser.