source: dev/BasicCompiler32/CParameter.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

File size: 10.9 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
[75]41 Type DummyTypeInfo;
[73]42 BOOL bByVal;
43 if(bEllipse){
44 DummyTypeInfo.type=NumOpe_GetType_Old(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
45 bByVal=1;
46 }
47 else{
48 DummyTypeInfo.type=params[i2]->GetBasicType();
49 DummyTypeInfo.u.lpIndex=params[i2]->GetIndex();
50 bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE;
51 }
52
53
54 if( !bByVal ){
55 //ポインタ参照
56 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
57 //ポインタ指定
58 continue;
59 }
60
61 LONG_PTR lpVarIndex;
62 if( GetVarType( Parms[i2], &lpVarIndex, FALSE ) == -1 ){
63 //変数ではないとき
64 int reg = REG_RAX;
65 int type = NumOpe( Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
66 //↑ここでスタックに積む
67
68 nCountOfTempObjects++;
69
70 if( type != DEF_STRUCT ){
71 //一時参照を作成
72
73 //push esp
74 op_push( REG_ESP );
75
76 nCountOfTempObjects++;
77 }
78
79 bool result = CheckDifferentType(
80 DummyTypeInfo.type,
81 DummyTypeInfo.u.lpIndex,
82 type,
83 lpVarIndex,
[75]84 procName.c_str(),
[73]85 i2);
86
87 if( result ){
88 useTempParameters[i2] = true;
89 useTempObject = true;
90
91 types[i2].type = type;
92 types[i2].u.lpIndex = lpVarIndex;
93 }
94 }
95 }
96 }
97
98 return nCountOfTempObjects * PTR_SIZE;
99}
100
[71]101void ParamImpl::DeleteTempParameters(){
[20]102 ///////////////////////////////////////////////////////
103 // 一時オブジェクトを破棄
104 ///////////////////////////////////////////////////////
105 if( !useTempObject ) return;
106
107 for(int i2=ParmsNum-1;i2>=0;i2--){
108 if( useTempParameters[i2] ){
[64]109 if( types[i2].type == DEF_STRUCT ){
110 // 構造体の一時メモリ
[20]111
[64]112 //メモリを解放する
[20]113
[64]114 //call free
[75]115 extern UserProc *pSub_free;
[64]116 op_call(pSub_free);
[45]117 }
[64]118 else{
[66]119 if( Is64Type( types[i2].type ) ){
120 //pop ... 参照を消す
121 //pop ... 上位32ビット
122 //pop ... 下位32ビット
123 op_add_esp( PTR_SIZE * 3 );
124 }
125 else{
126 //pop ... 参照を消す
127 //pop ... 値を消す
128 op_add_esp( PTR_SIZE * 2 );
129 }
[64]130 }
[20]131 }
132 }
133}
134
[71]135void ParamImpl::SetStructParameter(CClass *pobj_Class,LPSTR Parameter){
[63]136 int object_size = pobj_Class->GetSize();
[3]137
138 //push object_size
[67]139 op_push_V(object_size);
[3]140
141 //call calloc
[75]142 extern UserProc *pSub_calloc;
[3]143 op_call(pSub_calloc);
144
145 //push eax
146 op_push(REG_EAX);
147
148
[75]149 Type BaseType={DEF_STRUCT,(LONG_PTR)pobj_Class};
150 Type CalcType;
[73]151 CalcType.type=NumOpe_GetType_Old(Parameter,&BaseType,&CalcType.u.lpIndex);
[3]152
[64]153 /*
154 TODO: 消す
[51]155 if( pobj_Class->GetCopyConstructorMethod()
156 && CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
[3]157 ////////////////////////////////////
158 // コピーコンストラクタを呼び出す
159 ////////////////////////////////////
160
161 //push eax
162 op_push(REG_EAX);
163
164 BOOL bUseHeap;
165 CalcType.type=NumOpe(Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
166
167 //pop ecx
168 op_pop(REG_ECX);
169
170 //pop eax
171 op_pop(REG_EAX);
172
173 if(bUseHeap){
174 //※解放用に退避
175 //mov esi,ecx
176 op_mov_RR(REG_ESI,REG_ECX);
177 }
178
179 //push ecx
180 op_push(REG_ECX);
181
182 //push eax
183 op_push(REG_EAX);
184
185 //call constructor
[75]186 op_call(pobj_Class->GetCopyConstructorMethod()->pUserProc);
[3]187
188
189 if(bUseHeap){
190 FreeTempObject(REG_ESI,pobj_Class);
191 }
192 }
[64]193 else{*/
194
195
[3]196 //push eax
197 op_push(REG_EAX);
198
[64]199/*
200 TODO: 消す
[51]201 if( pobj_Class->GetConstructorMethod() ){
[3]202 ////////////////////////////////
203 // コンストラクタを呼び出す
204 ////////////////////////////////
205
206 //push this
207 op_push(REG_EAX);
208
209 //call constructor
[75]210 op_call(pobj_Class->GetConstructorMethod()->pUserProc);
[3]211 }
[64]212*/
[3]213
214 BOOL bUseHeap;
[64]215 CalcType.type=NumOpe(Parameter,DEF_STRUCT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
[3]216
217
218
[64]219 SetStructVariable((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,bUseHeap);
220 //}
[3]221}
222
[75]223int ParamImpl::SetParameter( const string &procName, const Parameters &params, int SecondParmNum ){
224 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
[3]225
[73]226 ///////////////////////////////////////////////////////////
227 // パラメータをレジスタ及びスタックフレームにセット
228 ///////////////////////////////////////////////////////////
229 int i2,i3;
230
231 BOOL bEllipse;
232 if( params.size() ){
233 if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1;
234 else bEllipse=0;
235 }
236 else bEllipse=0;
237
238 BOOL bHas_System_LocalThis=0;
239 if(ParmsNum>=1){
240 if( params[0]->GetVarName() == "_System_LocalThis" ){
241 bHas_System_LocalThis=1;
242 }
243 }
244
245 //戻り値用の変数名を取得
[75]246 const char *lpszVarNameToReturn = (procName[0]==1&&procName[1]==ESC_OPERATOR)?"_System_ReturnValue":procName.c_str();
[73]247
248 //パラメータをレジスタとスタックに格納
249 int CalcType;
250 LONG_PTR lpCalcIndex;
251 BOOL bCalcUseHeap;
252 int ParmSize=0;
253 RELATIVE_VAR RelativeVar;
254 int nCountOfNowTempObjects = 0;
255 for(i2=ParmsNum-1;i2>=0;i2--){
256 if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0;
257
258 if(i2==0){
259 if( params[i2]->GetVarName() == "_System_LocalThis" ){
260 //オブジェクトメンバの第一パラメータのThisポインタ
261 continue;
262 }
263 }
264 if(i2==0||i2==1){
265 if( params[i2]->GetVarName() == lpszVarNameToReturn ){
266 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
267 continue;
268 }
269 }
270
[75]271 Type DummyTypeInfo;
[73]272 BOOL bByVal;
273 if(bEllipse){
274 DummyTypeInfo.type=NumOpe_GetType_Old(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
275 bByVal=1;
276 }
277 else{
278 DummyTypeInfo.type=params[i2]->GetBasicType();
279 DummyTypeInfo.u.lpIndex=params[i2]->GetIndex();
280 bByVal = (params[i2]->IsRef() == false ) ? TRUE:FALSE;
281 }
282
283 if(bByVal==1){
284 //値参照
285
286 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
287 char temp2[255];
288 sprintf(temp2,"%s関数の第%dパラメータ",procName,i2+1);
289 SetError(19,temp2,cp);
290 continue;
291 }
292
293 if(DummyTypeInfo.type==DEF_STRUCT){
294 SetStructParameter(DummyTypeInfo.u.pobj_Class,Parms[i2]);
295 goto next;
296 }
297
298
299 extern LONG_PTR ProcPtr_BaseIndex;
300 LONG_PTR back_ProcPtr_BaseIndex;
301 back_ProcPtr_BaseIndex=ProcPtr_BaseIndex;
302 if(DummyTypeInfo.type==DEF_PTR_PROC) ProcPtr_BaseIndex=DummyTypeInfo.u.lpIndex;
303 else ProcPtr_BaseIndex=-1;
304
305 CalcType=NumOpe(Parms[i2],DummyTypeInfo.type,DummyTypeInfo.u.lpIndex,&lpCalcIndex,&bCalcUseHeap);
306
307 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
308
309 if(CalcType==-1) break;
310
311 if(CalcType==DEF_OBJECT){
312 if( DummyTypeInfo.type != DEF_OBJECT
313 ||
314 DummyTypeInfo.type == DEF_OBJECT &&
315 !DummyTypeInfo.u.pobj_Class->IsEqualsOrSubClass( (CClass *)lpCalcIndex ) ){
316 //キャスト演算子のオーバーロードに対応する
317 CallCastOperatorProc(CalcType,lpCalcIndex,bCalcUseHeap,DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
318 }
319 }
320
321 if(!bEllipse){
322 //型チェック
323 if(bHas_System_LocalThis) i3=i2-1;
324 else i3=i2;
325 CheckDifferentType(
326 DummyTypeInfo.type,
327 DummyTypeInfo.u.lpIndex,
328 CalcType,
329 lpCalcIndex,
[75]330 procName.c_str(),
[73]331 i3);
332 }
333
334 if(DummyTypeInfo.type==DEF_DOUBLE){
335 ChangeTypeToDouble(CalcType);
336 ParmSize+=sizeof(long)*2;
337 }
338 else if(DummyTypeInfo.type==DEF_SINGLE){
339 ChangeTypeToSingle(CalcType);
340 ParmSize+=sizeof(long);
341 }
342 else if(DummyTypeInfo.type==DEF_INT64||DummyTypeInfo.type==DEF_QWORD){
343 ChangeTypeToInt64(CalcType);
344 ParmSize+=sizeof(long)*2;
345 }
346 else if(DummyTypeInfo.type==DEF_LONG||DummyTypeInfo.type==DEF_DWORD||DummyTypeInfo.type==DEF_OBJECT||DummyTypeInfo.type==DEF_STRUCT||
347 (IsPtrType(DummyTypeInfo.type)/*&&DummyTypeInfo.type!=DEF_PTR_VOID&&DummyTypeInfo.type!=DEF_PTR_BYTE*/)){
348 ChangeTypeToLong(CalcType);
349 ParmSize+=sizeof(long);
350 }
351 else if(DummyTypeInfo.type==DEF_INTEGER||DummyTypeInfo.type==DEF_WORD || (isUnicode&&DummyTypeInfo.type==DEF_CHAR)){
352 ChangeTypeToInteger(CalcType);
353 ParmSize+=sizeof(long);
354 }
355 else if(DummyTypeInfo.type==DEF_SBYTE||DummyTypeInfo.type==DEF_BYTE||DummyTypeInfo.type==DEF_BOOLEAN || (isUnicode==false&&DummyTypeInfo.type==DEF_CHAR)){
356 ChangeTypeToByte(CalcType);
357 ParmSize+=sizeof(long);
358 }
359 else{
360 SetError(300,NULL,cp);
361 }
362 }
363 else{
364 //ポインタ参照
365 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
366 //ポインタ指定
367 i3=NumOpe(Parms[i2]+2,0,0,0);
368
369 ChangeTypeToLong(i3);
370 }
371 else{
372 if( useTempParameters[i2] ){
373 //一時オブジェクトをコピー
374
375 if( types[i2].type != DEF_STRUCT ){
376 // 一時参照のための領域を考慮する
377 nCountOfNowTempObjects++;
378 }
379
380 nCountOfNowTempObjects++;
[3]381
[20]382 //mov eax, dword ptr[esp+offset]
383 op_mov_RM(
384 sizeof(long),
385 REG_EAX,
386 REG_ESP,
[64]387 ( ( ParmsNum - i2 - 1 ) + ( nCountOfTempObjects - nCountOfNowTempObjects ) ) * PTR_SIZE,
[20]388 MOD_BASE_DISP32 );
[3]389
[20]390 //push eax
391 op_push(REG_EAX);
[64]392 }
393 else{
394 //変数のアドレスを取得
395 int VarType;
396 LONG_PTR lpVarIndex;
397 if(GetVarOffset(
398 false,
399 false,
400 Parms[i2],
401 &VarType,
402 &RelativeVar,
403 &lpVarIndex)){
404 if(DummyTypeInfo.type!=DEF_ANY){
405 //型チェックを行う
406 if(DummyTypeInfo.type==VarType){
407 if(DummyTypeInfo.type==DEF_OBJECT){
408 if( !DummyTypeInfo.u.pobj_Class->IsEqualsOrSubClass( (CClass *)lpVarIndex ) ){
409 SetError(11,Parms[i2],cp);
410 }
411 }
412 else if(DummyTypeInfo.type==DEF_STRUCT){
413 if( !DummyTypeInfo.u.pobj_Class->IsEquals( (CClass *)lpVarIndex ) ){
414 SetError(11,Parms[i2],cp);
415 }
416 }
417 }
418 else if((VarType&FLAG_PTR)&&((int)(VarType^FLAG_PTR)==DummyTypeInfo.type)){
419 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
420 }
421 else{
422 SetError(11,Parms[i2],cp);
423 }
424 }
[20]425
[64]426 //変数アドレスをレジスタにセット
427 SetVarPtrToEax(&RelativeVar);
428
429 //push eax
430 op_push(REG_EAX);
431 }
[20]432 }
[3]433 }
434
435 ParmSize+=PTR_SIZE;
436 }
437
438next:;
439 }
440
441 return ParmSize;
442}
Note: See TracBrowser for help on using the repository browser.