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
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4int ParamImpl::NewTempParameters( const string &procName, const Parameters &params, int SecondParmNum ){
5 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
6
7 ///////////////////////////////////////////////////////
8 // 一時オブジェクトをあらかじめスタックに積んでおく
9 ///////////////////////////////////////////////////////
10
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
41 Type DummyTypeInfo;
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,
84 procName.c_str(),
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
101void ParamImpl::DeleteTempParameters(){
102 ///////////////////////////////////////////////////////
103 // 一時オブジェクトを破棄
104 ///////////////////////////////////////////////////////
105 if( !useTempObject ) return;
106
107 for(int i2=ParmsNum-1;i2>=0;i2--){
108 if( useTempParameters[i2] ){
109 if( types[i2].type == DEF_STRUCT ){
110 // 構造体の一時メモリ
111
112 //メモリを解放する
113
114 //call free
115 extern UserProc *pSub_free;
116 op_call(pSub_free);
117 }
118 else{
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 }
130 }
131 }
132 }
133}
134
135void ParamImpl::SetStructParameter(CClass *pobj_Class,LPSTR Parameter){
136 int object_size = pobj_Class->GetSize();
137
138 //push object_size
139 op_push_V(object_size);
140
141 //call calloc
142 extern UserProc *pSub_calloc;
143 op_call(pSub_calloc);
144
145 //push eax
146 op_push(REG_EAX);
147
148
149 Type BaseType={DEF_STRUCT,(LONG_PTR)pobj_Class};
150 Type CalcType;
151 CalcType.type=NumOpe_GetType_Old(Parameter,&BaseType,&CalcType.u.lpIndex);
152
153 /*
154 TODO: 消す
155 if( pobj_Class->GetCopyConstructorMethod()
156 && CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
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
186 op_call(pobj_Class->GetCopyConstructorMethod()->pUserProc);
187
188
189 if(bUseHeap){
190 FreeTempObject(REG_ESI,pobj_Class);
191 }
192 }
193 else{*/
194
195
196 //push eax
197 op_push(REG_EAX);
198
199/*
200 TODO: 消す
201 if( pobj_Class->GetConstructorMethod() ){
202 ////////////////////////////////
203 // コンストラクタを呼び出す
204 ////////////////////////////////
205
206 //push this
207 op_push(REG_EAX);
208
209 //call constructor
210 op_call(pobj_Class->GetConstructorMethod()->pUserProc);
211 }
212*/
213
214 BOOL bUseHeap;
215 CalcType.type=NumOpe(Parameter,DEF_STRUCT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
216
217
218
219 SetStructVariable((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,bUseHeap);
220 //}
221}
222
223int ParamImpl::SetParameter( const string &procName, const Parameters &params, int SecondParmNum ){
224 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
225
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 //戻り値用の変数名を取得
246 const char *lpszVarNameToReturn = (procName[0]==1&&procName[1]==ESC_OPERATOR)?"_System_ReturnValue":procName.c_str();
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
271 Type DummyTypeInfo;
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,
330 procName.c_str(),
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++;
381
382 //mov eax, dword ptr[esp+offset]
383 op_mov_RM(
384 sizeof(long),
385 REG_EAX,
386 REG_ESP,
387 ( ( ParmsNum - i2 - 1 ) + ( nCountOfTempObjects - nCountOfNowTempObjects ) ) * PTR_SIZE,
388 MOD_BASE_DISP32 );
389
390 //push eax
391 op_push(REG_EAX);
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 }
425
426 //変数アドレスをレジスタにセット
427 SetVarPtrToEax(&RelativeVar);
428
429 //push eax
430 op_push(REG_EAX);
431 }
432 }
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.