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

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

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

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