source: dev/trunk/abdev/BasicCompiler32/CParameter.cpp@ 195

Last change on this file since 195 was 76, checked in by dai_9181, 18 years ago

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

File size: 9.2 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4int ParamImpl::NewTempParameters( const string &procName, const Parameters &params, int SecondParmNum ){
5 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
6
7 ///////////////////////////////////////////////////////
8 // 一時オブジェクトをあらかじめスタックに積んでおく
9 ///////////////////////////////////////////////////////
10
11 useTempObject = false;
12
13 //一時参照の数
14 nCountOfTempObjects = 0;
15
16 BOOL bEllipse;
17 if(params.size()){
18 if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1;
19 else bEllipse=0;
20 }
21 else bEllipse=0;
22
23 for(int i2=ParmsNum-1;i2>=0;i2--){
24 useTempParameters[i2] = false;
25
26 if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0;
27
28 if(i2==0){
29 if( params[i2]->GetVarName() == "_System_LocalThis" ){
30 //オブジェクトメンバの第一パラメータのThisポインタ
31 continue;
32 }
33 }
34 if( i2==0||i2==1 ){
35 if( params[i2]->GetVarName() == procName ){
36 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
37 continue;
38 }
39 }
40
41 Type dummyType;
42 BOOL bByVal;
43 if(bEllipse){
44 NumOpe_GetType( Parms[i2], Type(), dummyType );
45 bByVal=1;
46 }
47 else{
48 dummyType = *params[i2];
49 bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE;
50 }
51
52
53 if( !bByVal ){
54 //ポインタ参照
55 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
56 //ポインタ指定
57 continue;
58 }
59
60 if( !GetVarType( Parms[i2], Type(), FALSE ) ){
61 //変数ではないとき
62 Type calcType;
63 NumOpe( Parms[i2], dummyType, calcType );
64 //↑ここでスタックに積む
65
66 nCountOfTempObjects++;
67
68 if( !calcType.IsStruct() ){
69 //一時参照を作成
70
71 //push esp
72 op_push( REG_ESP );
73
74 nCountOfTempObjects++;
75 }
76
77 bool result = CheckDifferentType(
78 dummyType,
79 calcType,
80 procName.c_str(),
81 i2);
82
83 if( result ){
84 useTempParameters[i2] = true;
85 useTempObject = true;
86
87 types[i2] = calcType;
88 }
89 }
90 }
91 }
92
93 return nCountOfTempObjects * PTR_SIZE;
94}
95
96void ParamImpl::DeleteTempParameters(){
97 ///////////////////////////////////////////////////////
98 // 一時オブジェクトを破棄
99 ///////////////////////////////////////////////////////
100 if( !useTempObject ) return;
101
102 for(int i2=ParmsNum-1;i2>=0;i2--){
103 if( useTempParameters[i2] ){
104 if( types[i2].IsStruct() ){
105 // 構造体の一時メモリ
106
107 //メモリを解放する
108
109 //call free
110 extern UserProc *pSub_free;
111 op_call(pSub_free);
112 }
113 else{
114 if( types[i2].Is64() ){
115 //pop ... 参照を消す
116 //pop ... 上位32ビット
117 //pop ... 下位32ビット
118 op_add_esp( PTR_SIZE * 3 );
119 }
120 else{
121 //pop ... 参照を消す
122 //pop ... 値を消す
123 op_add_esp( PTR_SIZE * 2 );
124 }
125 }
126 }
127 }
128}
129
130void ParamImpl::SetStructParameter( const Type &baseType, const char *expression ){
131 int object_size = baseType.GetClass().GetSize();
132
133 //push object_size
134 op_push_V(object_size);
135
136 //call calloc
137 extern UserProc *pSub_calloc;
138 op_call(pSub_calloc);
139
140 //push eax(ここでプッシュされた値が実際にパラメータとして引き渡される)
141 op_push(REG_EAX);
142
143 //push eax
144 op_push(REG_EAX);
145
146 Type calcType;
147 BOOL bUseHeap;
148 NumOpe( expression,
149 baseType,
150 calcType,
151 &bUseHeap );
152
153 // ※スタックにある二つのデータ(コピー先、コピー元)の値を必要とする
154 SetStructVariable( baseType, calcType, bUseHeap );
155}
156
157int ParamImpl::SetParameter( const string &procName, const Parameters &params, int SecondParmNum ){
158 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
159
160 ///////////////////////////////////////////////////////////
161 // パラメータをレジスタ及びスタックフレームにセット
162 ///////////////////////////////////////////////////////////
163 int i2,i3;
164
165 BOOL bEllipse;
166 if( params.size() ){
167 if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1;
168 else bEllipse=0;
169 }
170 else bEllipse=0;
171
172 BOOL bHas_System_LocalThis=0;
173 if(ParmsNum>=1){
174 if( params[0]->GetVarName() == "_System_LocalThis" ){
175 bHas_System_LocalThis=1;
176 }
177 }
178
179 //戻り値用の変数名を取得
180 const char *lpszVarNameToReturn = (procName[0]==1&&procName[1]==ESC_OPERATOR)?"_System_ReturnValue":procName.c_str();
181
182 //パラメータをレジスタとスタックに格納
183 int ParmSize=0;
184 RELATIVE_VAR RelativeVar;
185 int nCountOfNowTempObjects = 0;
186 for(i2=ParmsNum-1;i2>=0;i2--){
187 if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0;
188
189 if(i2==0){
190 if( params[i2]->GetVarName() == "_System_LocalThis" ){
191 //オブジェクトメンバの第一パラメータのThisポインタ
192 continue;
193 }
194 }
195 if(i2==0||i2==1){
196 if( params[i2]->GetVarName() == lpszVarNameToReturn ){
197 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
198 continue;
199 }
200 }
201
202 Type dummyType;
203 BOOL bByVal;
204 if(bEllipse){
205 NumOpe_GetType( Parms[i2], Type(), dummyType );
206 bByVal=1;
207 }
208 else{
209 dummyType = *params[i2];
210 bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE;
211 }
212
213 if(bByVal==1){
214 //値参照
215
216 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
217 char temp2[255];
218 sprintf(temp2,"%s関数の第%dパラメータ",procName,i2+1);
219 SetError(19,temp2,cp);
220 continue;
221 }
222
223 if( dummyType.IsStruct() ){
224 SetStructParameter( dummyType, Parms[i2] );
225 goto next;
226 }
227
228 extern LONG_PTR ProcPtr_BaseIndex;
229 LONG_PTR back_ProcPtr_BaseIndex = ProcPtr_BaseIndex;
230 if( dummyType.IsProcPtr() ){
231 ProcPtr_BaseIndex = dummyType.GetIndex();
232 }
233 else{
234 ProcPtr_BaseIndex=-1;
235 }
236
237 BOOL bCalcUseHeap;
238 Type calcType;
239 if( !NumOpe( Parms[i2], dummyType, calcType, &bCalcUseHeap ) ){
240 break;
241 }
242
243 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
244
245 if( calcType.IsObject() ){
246 if( !dummyType.IsObject()
247 ||
248 dummyType.IsObject() &&
249 !dummyType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
250 //キャスト演算子のオーバーロードに対応する
251 CallCastOperatorProc( calcType, bCalcUseHeap,dummyType );
252 }
253 }
254
255 if(!bEllipse){
256 //型チェック
257 // TODO: _System_ReturnValueが考慮されていない?
258 if(bHas_System_LocalThis) i3=i2-1;
259 else i3=i2;
260 CheckDifferentType(
261 dummyType,
262 calcType,
263 procName.c_str(),
264 i3);
265 }
266
267 if( dummyType.IsDouble() ){
268 ChangeTypeToDouble( calcType.GetBasicType() );
269 ParmSize+=sizeof(long)*2;
270 }
271 else if( dummyType.IsSingle() ){
272 ChangeTypeToSingle( calcType.GetBasicType() );
273 ParmSize+=sizeof(long);
274 }
275 else if( dummyType.Is64() ){
276 ChangeTypeToInt64( calcType.GetBasicType() );
277 ParmSize+=sizeof(long)*2;
278 }
279 else if( dummyType.IsLong() || dummyType.IsDWord()
280 || dummyType.IsPointer()
281 || dummyType.IsObject() || dummyType.IsStruct() ){
282 ChangeTypeToLong( calcType.GetBasicType() );
283 ParmSize+=sizeof(long);
284 }
285 else if( dummyType.IsInteger() || dummyType.IsWord() ){
286 ChangeTypeToInteger( calcType.GetBasicType() );
287 ParmSize+=sizeof(long);
288 }
289 else if( dummyType.IsSByte() || dummyType.IsByte() || dummyType.IsBoolean() ){
290 ChangeTypeToByte( calcType.GetBasicType() );
291 ParmSize+=sizeof(long);
292 }
293 else{
294 SetError(300,NULL,cp);
295 }
296 }
297 else{
298 //ポインタ参照
299 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
300 //ポインタ指定
301
302 Type calcType;
303 if( !NumOpe( Parms[i2]+2, dummyType, calcType) ){
304 break;
305 }
306
307 ChangeTypeToLong( calcType.GetBasicType() );
308
309 dummyType.PtrLevelUp();
310
311 //型チェック
312 if(bHas_System_LocalThis) i3=i2-1;
313 else i3=i2;
314 CheckDifferentType(
315 dummyType,
316 calcType,
317 procName.c_str(),
318 i3);
319 }
320 else{
321 if( useTempParameters[i2] ){
322 //一時オブジェクトをコピー
323
324 if( !types[i2].IsStruct() ){
325 // 一時参照のための領域を考慮する
326 nCountOfNowTempObjects++;
327 }
328
329 nCountOfNowTempObjects++;
330
331 //mov eax, dword ptr[esp+offset]
332 op_mov_RM(
333 sizeof(long),
334 REG_EAX,
335 REG_ESP,
336 ( ( ParmsNum - i2 - 1 ) + ( nCountOfTempObjects - nCountOfNowTempObjects ) ) * PTR_SIZE,
337 MOD_BASE_DISP32 );
338
339 //push eax
340 op_push(REG_EAX);
341 }
342 else{
343 //変数のアドレスを取得
344 Type varType;
345 if(GetVarOffset(
346 false,
347 false,
348 Parms[i2],
349 &RelativeVar,
350 varType)){
351 if( !dummyType.IsAny() ){
352 //型チェックを行う
353 if( dummyType.GetBasicType() == varType.GetBasicType() ){
354 if( dummyType.IsObject() ){
355 if( !dummyType.GetClass().IsEqualsOrSubClass( &varType.GetClass() ) ){
356 SetError(11,Parms[i2],cp);
357 }
358 }
359 else if( dummyType.IsStruct() ){
360 if( !dummyType.GetClass().IsEquals( &varType.GetClass() ) ){
361 SetError(11,Parms[i2],cp);
362 }
363 }
364 }
365 else if( (varType.GetBasicType()&FLAG_PTR)
366 &&((varType.GetBasicType()^FLAG_PTR)==dummyType.GetBasicType())){
367 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
368 }
369 else{
370 SetError(11,Parms[i2],cp);
371 }
372 }
373
374 //変数アドレスをレジスタにセット
375 SetVarPtrToEax(&RelativeVar);
376
377 //push eax
378 op_push(REG_EAX);
379 }
380 }
381 }
382
383 ParmSize+=PTR_SIZE;
384 }
385
386next:;
387 }
388
389 return ParmSize;
390}
Note: See TracBrowser for help on using the repository browser.