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

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