source: dev/BasicCompiler32/CParameter.cpp@ 76

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

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

File size: 9.2 KB
RevLine 
[3]1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
[75]4int ParamImpl::NewTempParameters( const string &procName, const Parameters &params, int SecondParmNum ){
5 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
[20]6
[73]7 ///////////////////////////////////////////////////////
8 // 一時オブジェクトをあらかじめスタックに積んでおく
9 ///////////////////////////////////////////////////////
[64]10
[73]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
[76]41 Type dummyType;
[73]42 BOOL bByVal;
43 if(bEllipse){
[76]44 NumOpe_GetType( Parms[i2], Type(), dummyType );
[73]45 bByVal=1;
46 }
47 else{
[76]48 dummyType = *params[i2];
[73]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
[76]60 if( !GetVarType( Parms[i2], Type(), FALSE ) ){
[73]61 //変数ではないとき
[76]62 Type calcType;
63 NumOpe( Parms[i2], dummyType, calcType );
[73]64 //↑ここでスタックに積む
65
66 nCountOfTempObjects++;
67
[76]68 if( !calcType.IsStruct() ){
[73]69 //一時参照を作成
70
71 //push esp
72 op_push( REG_ESP );
73
74 nCountOfTempObjects++;
75 }
76
77 bool result = CheckDifferentType(
[76]78 dummyType,
79 calcType,
[75]80 procName.c_str(),
[73]81 i2);
82
83 if( result ){
84 useTempParameters[i2] = true;
85 useTempObject = true;
86
[76]87 types[i2] = calcType;
[73]88 }
89 }
90 }
91 }
92
93 return nCountOfTempObjects * PTR_SIZE;
94}
95
[71]96void ParamImpl::DeleteTempParameters(){
[20]97 ///////////////////////////////////////////////////////
98 // 一時オブジェクトを破棄
99 ///////////////////////////////////////////////////////
100 if( !useTempObject ) return;
101
102 for(int i2=ParmsNum-1;i2>=0;i2--){
103 if( useTempParameters[i2] ){
[76]104 if( types[i2].IsStruct() ){
[64]105 // 構造体の一時メモリ
[20]106
[64]107 //メモリを解放する
[20]108
[64]109 //call free
[75]110 extern UserProc *pSub_free;
[64]111 op_call(pSub_free);
[45]112 }
[64]113 else{
[76]114 if( types[i2].Is64() ){
[66]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 }
[64]125 }
[20]126 }
127 }
128}
129
[76]130void ParamImpl::SetStructParameter( const Type &baseType, const char *expression ){
131 int object_size = baseType.GetClass().GetSize();
[3]132
133 //push object_size
[67]134 op_push_V(object_size);
[3]135
136 //call calloc
[75]137 extern UserProc *pSub_calloc;
[3]138 op_call(pSub_calloc);
139
[76]140 //push eax(ここでプッシュされた値が実際にパラメータとして引き渡される)
141 op_push(REG_EAX);
142
[3]143 //push eax
144 op_push(REG_EAX);
145
[76]146 Type calcType;
147 BOOL bUseHeap;
148 NumOpe( expression,
149 baseType,
150 calcType,
151 &bUseHeap );
[3]152
[76]153 // ※スタックにある二つのデータ(コピー先、コピー元)の値を必要とする
154 SetStructVariable( baseType, calcType, bUseHeap );
[3]155}
156
[75]157int ParamImpl::SetParameter( const string &procName, const Parameters &params, int SecondParmNum ){
158 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
[3]159
[73]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 //戻り値用の変数名を取得
[75]180 const char *lpszVarNameToReturn = (procName[0]==1&&procName[1]==ESC_OPERATOR)?"_System_ReturnValue":procName.c_str();
[73]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
[76]202 Type dummyType;
[73]203 BOOL bByVal;
204 if(bEllipse){
[76]205 NumOpe_GetType( Parms[i2], Type(), dummyType );
[73]206 bByVal=1;
207 }
208 else{
[76]209 dummyType = *params[i2];
210 bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE;
[73]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
[76]223 if( dummyType.IsStruct() ){
224 SetStructParameter( dummyType, Parms[i2] );
[73]225 goto next;
226 }
227
228 extern LONG_PTR ProcPtr_BaseIndex;
[76]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 }
[73]236
[76]237 BOOL bCalcUseHeap;
238 Type calcType;
239 if( !NumOpe( Parms[i2], dummyType, calcType, &bCalcUseHeap ) ){
240 break;
241 }
[73]242
243 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
244
[76]245 if( calcType.IsObject() ){
246 if( !dummyType.IsObject()
[73]247 ||
[76]248 dummyType.IsObject() &&
249 !dummyType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
[73]250 //キャスト演算子のオーバーロードに対応する
[76]251 CallCastOperatorProc( calcType, bCalcUseHeap,dummyType );
[73]252 }
253 }
254
255 if(!bEllipse){
256 //型チェック
[76]257 // TODO: _System_ReturnValueが考慮されていない?
[73]258 if(bHas_System_LocalThis) i3=i2-1;
259 else i3=i2;
260 CheckDifferentType(
[76]261 dummyType,
262 calcType,
[75]263 procName.c_str(),
[73]264 i3);
265 }
266
[76]267 if( dummyType.IsDouble() ){
268 ChangeTypeToDouble( calcType.GetBasicType() );
[73]269 ParmSize+=sizeof(long)*2;
270 }
[76]271 else if( dummyType.IsSingle() ){
272 ChangeTypeToSingle( calcType.GetBasicType() );
[73]273 ParmSize+=sizeof(long);
274 }
[76]275 else if( dummyType.Is64() ){
276 ChangeTypeToInt64( calcType.GetBasicType() );
[73]277 ParmSize+=sizeof(long)*2;
278 }
[76]279 else if( dummyType.IsLong() || dummyType.IsDWord()
280 || dummyType.IsPointer()
281 || dummyType.IsObject() || dummyType.IsStruct() ){
282 ChangeTypeToLong( calcType.GetBasicType() );
283 ParmSize+=sizeof(long);
[73]284 }
[76]285 else if( dummyType.IsInteger() || dummyType.IsWord() ){
286 ChangeTypeToInteger( calcType.GetBasicType() );
[73]287 ParmSize+=sizeof(long);
288 }
[76]289 else if( dummyType.IsSByte() || dummyType.IsByte() || dummyType.IsBoolean() ){
290 ChangeTypeToByte( calcType.GetBasicType() );
[73]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
[76]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);
[73]319 }
320 else{
321 if( useTempParameters[i2] ){
322 //一時オブジェクトをコピー
323
[76]324 if( !types[i2].IsStruct() ){
[73]325 // 一時参照のための領域を考慮する
326 nCountOfNowTempObjects++;
327 }
328
329 nCountOfNowTempObjects++;
[3]330
[20]331 //mov eax, dword ptr[esp+offset]
332 op_mov_RM(
333 sizeof(long),
334 REG_EAX,
335 REG_ESP,
[64]336 ( ( ParmsNum - i2 - 1 ) + ( nCountOfTempObjects - nCountOfNowTempObjects ) ) * PTR_SIZE,
[20]337 MOD_BASE_DISP32 );
[3]338
[20]339 //push eax
340 op_push(REG_EAX);
[64]341 }
342 else{
343 //変数のアドレスを取得
[76]344 Type varType;
[64]345 if(GetVarOffset(
346 false,
347 false,
348 Parms[i2],
349 &RelativeVar,
[76]350 varType)){
351 if( !dummyType.IsAny() ){
[64]352 //型チェックを行う
[76]353 if( dummyType.GetBasicType() == varType.GetBasicType() ){
354 if( dummyType.IsObject() ){
355 if( !dummyType.GetClass().IsEqualsOrSubClass( &varType.GetClass() ) ){
[64]356 SetError(11,Parms[i2],cp);
357 }
358 }
[76]359 else if( dummyType.IsStruct() ){
360 if( !dummyType.GetClass().IsEquals( &varType.GetClass() ) ){
[64]361 SetError(11,Parms[i2],cp);
362 }
363 }
364 }
[76]365 else if( (varType.GetBasicType()&FLAG_PTR)
366 &&((varType.GetBasicType()^FLAG_PTR)==dummyType.GetBasicType())){
[64]367 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
368 }
369 else{
370 SetError(11,Parms[i2],cp);
371 }
372 }
[20]373
[64]374 //変数アドレスをレジスタにセット
375 SetVarPtrToEax(&RelativeVar);
376
377 //push eax
378 op_push(REG_EAX);
379 }
[20]380 }
[3]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.