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

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