source: dev/trunk/abdev/BasicCompiler32/OperatorProc.cpp@ 220

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

コード全体のリファクタリングを実施

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