source: dev/BasicCompiler32/CParameter.cpp@ 63

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

CClass::GetSize、CClass::GetMemberOffsetを追加

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