source: dev/BasicCompiler32/CParameter.cpp@ 60

Last change on this file since 60 was 59, checked in by dai_9181, 18 years ago

派生クラスから基底クラスへのインスタンスコピーまたは参照を可能にした

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;
133 object_size=GetSizeOfClass(pobj_Class);
134
135 //push object_size
136 op_push_value(object_size);
137
138 //call calloc
139 extern SUBINFO *pSub_calloc;
140 op_call(pSub_calloc);
141
142 //push eax
143 op_push(REG_EAX);
144
145
146 TYPEINFO BaseType={DEF_OBJECT,(LONG_PTR)pobj_Class};
147 TYPEINFO CalcType;
148 CalcType.type=NumOpe_GetType(Parameter,&BaseType,&CalcType.u.lpIndex);
149
150 if( pobj_Class->GetCopyConstructorMethod()
151 && CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
152 ////////////////////////////////////
153 // コピーコンストラクタを呼び出す
154 ////////////////////////////////////
155
156 //push eax
157 op_push(REG_EAX);
158
159 BOOL bUseHeap;
160 CalcType.type=NumOpe(Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
161
162 //pop ecx
163 op_pop(REG_ECX);
164
165 //pop eax
166 op_pop(REG_EAX);
167
168 if(bUseHeap){
169 //※解放用に退避
170 //mov esi,ecx
171 op_mov_RR(REG_ESI,REG_ECX);
172 }
173
174 //push ecx
175 op_push(REG_ECX);
176
177 //push eax
178 op_push(REG_EAX);
179
180 //call constructor
181 op_call(pobj_Class->GetCopyConstructorMethod()->psi);
182
183
184 if(bUseHeap){
185 FreeTempObject(REG_ESI,pobj_Class);
186 }
187 }
188 else{
189 //push eax
190 op_push(REG_EAX);
191
192
193 if( pobj_Class->GetConstructorMethod() ){
194 ////////////////////////////////
195 // コンストラクタを呼び出す
196 ////////////////////////////////
197
198 //push this
199 op_push(REG_EAX);
200
201 //call constructor
202 op_call(pobj_Class->GetConstructorMethod()->psi);
203 }
204
205
206 TYPEINFO CalcType;
207 BOOL bUseHeap;
208 CalcType.type=NumOpe(Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
209
210
211
212 SetObjectVariable((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,bUseHeap);
213 }
214}
215
216int CParameter::SetParameter(const char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
217 ///////////////////////////////////////////////////////////
218 // パラメータをレジスタ及びスタックフレームにセット
219 ///////////////////////////////////////////////////////////
220 int i2,i3;
221
222 BOOL bEllipse;
223 if(pi_num){
224 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
225 else bEllipse=0;
226 }
227 else bEllipse=0;
228
229 BOOL bHas_System_LocalThis=0;
230 if(ParmsNum>=1){
231 if(lstrcmp(ppi[0].name,"_System_LocalThis")==0)
232 bHas_System_LocalThis=1;
233 }
234
235 //戻り値用の変数名を取得
236 const char *lpszVarNameToReturn = (FuncName[0]==1&&FuncName[1]==ESC_OPERATOR)?"_System_ReturnValue":FuncName;
237
238 //パラメータをレジスタとスタックに格納
239 int CalcType;
240 LONG_PTR lpCalcIndex;
241 BOOL bCalcUseHeap;
242 int ParmSize=0;
243 RELATIVE_VAR RelativeVar;
244 int nCountOfNowTempObjects = 0;
245 for(i2=ParmsNum-1;i2>=0;i2--){
246 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
247
248 if(i2==0&&ppi[i2].name){
249 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
250 //オブジェクトメンバの第一パラメータのThisポインタ
251 continue;
252 }
253 }
254 if((i2==0||i2==1)&&ppi[i2].name){
255 if(lstrcmp(ppi[i2].name,lpszVarNameToReturn)==0){
256 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
257 continue;
258 }
259 }
260
261 TYPEINFO DummyTypeInfo;
262 BOOL bByVal;
263 if(bEllipse){
264 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
265 bByVal=1;
266 }
267 else{
268 DummyTypeInfo.type=ppi[i2].type;
269 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
270 bByVal=ppi[i2].bByVal;
271 }
272
273 if(bByVal==1){
274 //値参照
275
276 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
277 char temp2[255];
278 sprintf(temp2,"%s関数の第%dパラメータ",FuncName,i2+1);
279 SetError(19,temp2,cp);
280 continue;
281 }
282
283 if(DummyTypeInfo.type==DEF_OBJECT){
284 SetObjectParameter(DummyTypeInfo.u.pobj_Class,Parms[i2]);
285 goto next;
286 }
287
288
289 extern LONG_PTR ProcPtr_BaseIndex;
290 LONG_PTR back_ProcPtr_BaseIndex;
291 back_ProcPtr_BaseIndex=ProcPtr_BaseIndex;
292 if(DummyTypeInfo.type==DEF_PTR_PROC) ProcPtr_BaseIndex=DummyTypeInfo.u.lpIndex;
293 else ProcPtr_BaseIndex=-1;
294
295 CalcType=NumOpe(Parms[i2],DummyTypeInfo.type,DummyTypeInfo.u.lpIndex,&lpCalcIndex,&bCalcUseHeap);
296
297 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
298
299 if(CalcType==-1) break;
300
301 if(CalcType==DEF_OBJECT){
302 //キャスト演算子のオーバーロードに対応する
303 CallCastOperatorProc(CalcType,lpCalcIndex,bCalcUseHeap,DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
304 }
305
306 if(!bEllipse){
307 //型チェック
308 if(bHas_System_LocalThis) i3=i2-1;
309 else i3=i2;
310 CheckDifferentType(
311 DummyTypeInfo.type,
312 DummyTypeInfo.u.lpIndex,
313 CalcType,
314 lpCalcIndex,
315 FuncName,
316 i3);
317 }
318
319 if(DummyTypeInfo.type==DEF_DOUBLE){
320 ChangeTypeToDouble(CalcType);
321 ParmSize+=sizeof(long)*2;
322 }
323 else if(DummyTypeInfo.type==DEF_SINGLE){
324 ChangeTypeToSingle(CalcType);
325 ParmSize+=sizeof(long);
326 }
327 else if(DummyTypeInfo.type==DEF_INT64||DummyTypeInfo.type==DEF_QWORD){
328 ChangeTypeToInt64(CalcType);
329 ParmSize+=sizeof(long)*2;
330 }
331 else if(DummyTypeInfo.type==DEF_LONG||DummyTypeInfo.type==DEF_DWORD||
332 (IsPtrType(DummyTypeInfo.type)/*&&DummyTypeInfo.type!=DEF_PTR_VOID&&DummyTypeInfo.type!=DEF_PTR_BYTE*/)){
333 ChangeTypeToLong(CalcType);
334 ParmSize+=sizeof(long);
335 }
336 else if(DummyTypeInfo.type==DEF_INTEGER||DummyTypeInfo.type==DEF_WORD || (isUnicode&&DummyTypeInfo.type==DEF_CHAR)){
337 ChangeTypeToInteger(CalcType);
338 ParmSize+=sizeof(long);
339 }
340 else if(DummyTypeInfo.type==DEF_SBYTE||DummyTypeInfo.type==DEF_BYTE||DummyTypeInfo.type==DEF_BOOLEAN || (isUnicode==false&&DummyTypeInfo.type==DEF_CHAR)){
341 ChangeTypeToByte(CalcType);
342 ParmSize+=sizeof(long);
343 }
344 else{
345 SetError(300,NULL,cp);
346 }
347 }
348 else{
349 //ポインタ参照
350 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
351 //ポインタ指定
352 i3=NumOpe(Parms[i2]+2,0,0,0);
353
354 ChangeTypeToLong(i3);
355 }
356 else{
357 //変数のアドレスを取得
358 int VarType;
359 LONG_PTR lpVarIndex;
360 if(GetVarOffset(
361 false,
362 false,
363 Parms[i2],
364 &VarType,
365 &RelativeVar,
366 &lpVarIndex)){
367 if(DummyTypeInfo.type!=DEF_ANY){
368 //型チェックを行う
369 if(DummyTypeInfo.type==VarType){
370 if(DummyTypeInfo.type==DEF_OBJECT){
371 if( !DummyTypeInfo.u.pobj_Class->IsEqualsOrSubClass( (CClass *)lpVarIndex ) ){
372 SetError(11,Parms[i2],cp);
373 }
374 }
375 }
376 else if((VarType&FLAG_PTR)&&((int)(VarType^FLAG_PTR)==DummyTypeInfo.type)){
377 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
378 }
379 else{
380 SetError(11,Parms[i2],cp);
381 }
382 }
383
384 //変数アドレスをレジスタにセット
385 SetVarPtrToEax(&RelativeVar);
386
387 //push eax
388 op_push(REG_EAX);
389 }
390 else{
391 //一時オブジェクトをコピー
392
393 //mov eax, dword ptr[esp+offset]
394 op_mov_RM(
395 sizeof(long),
396 REG_EAX,
397 REG_ESP,
398 ( ( ParmsNum - i2 - 1 ) + ( nCountOfTempObjects - nCountOfNowTempObjects - 1 ) ) * PTR_SIZE,
399 MOD_BASE_DISP32 );
400
401 nCountOfNowTempObjects++;
402
403 //push eax
404 op_push(REG_EAX);
405
406 //VarType = NumOpe( Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
407 }
408 }
409
410 ParmSize+=PTR_SIZE;
411 }
412
413next:;
414 }
415
416 return ParmSize;
417}
Note: See TracBrowser for help on using the repository browser.