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

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

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

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