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

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

CodeGeneratorクラスのベースを実装

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