source: dev/BasicCompiler64/CParameter.cpp@ 45

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

・オーバーロードが解決できない場合のエラーが表示されないバグを修正。
・DLL関数のByRefパラメータに変数以外の数値を指定すると正常にコンパイルされないバグを修正。

File size: 20.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4CParameter::CParameter(char *buffer){
5 ///////////////////////////
6 // パラメータ文字列を整理
7 ///////////////////////////
8
9 extern HANDLE hHeap;
10 int i,i2,i3;
11 char temporary[VN_SIZE];
12
13 i=0;
14 ParmsNum=0;
15 while(1){
16 if(buffer[i]=='\0') break;
17
18 for(i2=0;;i2++,i++){
19 if(buffer[i]=='\"'){
20 temporary[i2]=buffer[i];
21 for(i++,i2++;;i++,i2++){
22 temporary[i2]=buffer[i];
23 if(buffer[i]=='\"') break;
24 }
25 continue;
26 }
27
28 if(buffer[i]=='('){
29 i3=GetStringInPare(temporary+i2,buffer+i);
30 i2+=i3-1;
31 i+=i3-1;
32 continue;
33 }
34 if(buffer[i]=='['){
35 i3=GetStringInBracket(temporary+i2,buffer+i);
36 i2+=i3-1;
37 i+=i3-1;
38 continue;
39 }
40
41 if(buffer[i]==','||buffer[i]=='\0'){
42 temporary[i2]=0;
43 break;
44 }
45 temporary[i2]=buffer[i];
46 }
47
48 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
49 lstrcpy(Parms[ParmsNum],temporary);
50 ParmsNum++;
51
52 if(buffer[i]==',') i++;
53 }
54
55 ReturnTypeInfo.type=0;
56 ReturnTypeInfo.u.lpIndex=0;
57}
58CParameter::CParameter(PARAMETER_INFO *pParamInfo,int ParmNum){
59 int i;
60 for(i=0;i<ParmNum;i++){
61 Parms[i]=0;
62 types[i].type=pParamInfo[i].type;
63 types[i].u.lpIndex=pParamInfo[i].u.index;
64 }
65 this->ParmsNum=ParmNum;
66
67 ReturnTypeInfo.type=0;
68 ReturnTypeInfo.u.lpIndex=0;
69}
70CParameter::~CParameter(){
71 int i2;
72
73 //パラメータ文字列を解放
74 for(i2=0;i2<ParmsNum;i2++){
75 if(Parms[i2]==(char *)-1) continue;
76
77 if(Parms[i2]) HeapDefaultFree(Parms[i2]);
78 }
79}
80
81void CParameter::SetReturnType(TYPEINFO *pTypeInfo){
82 ReturnTypeInfo=*pTypeInfo;
83}
84
85BOOL CParameter::_overload_check(PARAMETER_INFO *ppi,int pi_num,TYPEINFO *pReturnTypeInfo,int overload_level){
86 //パラメータを識別してオーバーロードを解決
87
88 //パラメータの個数が不一致の場合
89 if(pi_num!=ParmsNum) return 0;
90
91 int i,type;
92 LONG_PTR lpIndex;
93 for(i=0;i<pi_num;i++){
94 if(Parms[i]){
95 TYPEINFO BaseType={ppi[i].type,ppi[i].u.index};
96 if(Parms[i][0]==1&&Parms[i][1]==ESC_BYVAL){
97 type=NumOpe_GetType(Parms[i]+2,&BaseType,&lpIndex);
98 type=MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)-1);
99 }
100 else{
101 type=NumOpe_GetType(Parms[i],&BaseType,&lpIndex);
102 }
103 }
104 else{
105 type=types[i].type;
106 lpIndex=types[i].u.lpIndex;
107 }
108
109 if(type!=ppi[i].type){
110 if(overload_level==OVERLOAD_LEVEL1){
111 return 0;
112 }
113 else if(overload_level==OVERLOAD_LEVEL2){
114 if(!(
115 IsWholeNumberType(type)&&IsWholeNumberType(ppi[i].type)||
116 IsRealNumberType(type)&&IsRealNumberType(ppi[i].type)
117 )) return 0;
118 }
119 else if(overload_level==OVERLOAD_LEVEL3){
120 if(type==DEF_OBJECT||ppi[i].type==DEF_OBJECT) return 0;
121 }
122 }
123 else{
124 if(NATURAL_TYPE(type)==DEF_OBJECT){
125 if(lpIndex!=ppi[i].u.index) return 0;
126 }
127 }
128 }
129
130 if(pReturnTypeInfo){
131 //戻り値も比較対象にする
132 if(ReturnTypeInfo.type==pReturnTypeInfo->type){
133 if(NATURAL_TYPE(ReturnTypeInfo.type)==DEF_OBJECT){
134 if(ReturnTypeInfo.u.lpIndex != pReturnTypeInfo->u.lpIndex) return 0;
135 }
136 }
137 else return 0;
138 }
139
140 return 1;
141}
142SUBINFO *CParameter::OverloadSolutionWithReturnType(char *name,SUBINFO **ppsi,int num){
143 int i,sw=0;
144 SUBINFO *psi;
145 psi=0;
146 for(i=0;i<num;i++){
147 psi=ppsi[i];
148
149 TYPEINFO ReturnTypeInfo;
150 ReturnTypeInfo.type=psi->ReturnType;
151 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
152
153 //エラーチェック
154 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL1)){
155 if(sw){
156 SetError(52,name,cp);
157 return 0;
158 }
159 sw=1;
160 break;
161 }
162 }
163
164 if(!sw){
165 for(i=0;i<num;i++){
166 psi=ppsi[i];
167
168 TYPEINFO ReturnTypeInfo;
169 ReturnTypeInfo.type=psi->ReturnType;
170 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
171
172 //エラーチェック
173 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL2)){
174 if(sw){
175 SetError(52,name,cp);
176 return 0;
177 }
178 sw=1;
179 break;
180 }
181 }
182 }
183
184 if(!sw){
185 for(i=0;i<num;i++){
186 psi=ppsi[i];
187
188 TYPEINFO ReturnTypeInfo;
189 ReturnTypeInfo.type=psi->ReturnType;
190 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
191
192 //エラーチェック
193 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL3)){
194 if(sw){
195 SetError(52,name,cp);
196 return 0;
197 }
198 sw=1;
199 break;
200 }
201 }
202 }
203
204 if(!sw){
205 SetError(52,name,cp);
206 return 0;
207 }
208
209 return psi;
210}
211
212SUBINFO *CParameter::OverloadSolution(char *name,SUBINFO **ppsi,int num){
213 int i,sw=0;
214 SUBINFO *psi;
215 psi=0;
216 for(i=0;i<num;i++){
217 psi=ppsi[i];
218
219 //エラーチェック
220 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL1)){
221 if(sw){
222 return OverloadSolutionWithReturnType(name,ppsi,num);
223 }
224 sw=1;
225 break;
226 }
227 }
228
229 if(!sw){
230 for(i=0;i<num;i++){
231 psi=ppsi[i];
232
233 //エラーチェック
234 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL2)){
235 if(sw){
236 return OverloadSolutionWithReturnType(name,ppsi,num);
237 }
238 sw=1;
239 break;
240 }
241 }
242 }
243
244 if(!sw){
245 for(i=0;i<num;i++){
246 psi=ppsi[i];
247
248 //エラーチェック
249 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL3)){
250 if(sw){
251 return OverloadSolutionWithReturnType(name,ppsi,num);
252 }
253 sw=1;
254 break;
255 }
256 }
257 }
258
259 if(!sw){
260 SUBINFO *temp_psi;
261 for(i=0;i<num;i++){
262 temp_psi=ppsi[i];
263
264 //エラーチェック
265 if(temp_psi->ParmNum==this->ParmsNum){
266 if(sw){
267 sw=0;
268 break;
269 }
270 sw=1;
271
272 psi=temp_psi;
273 }
274 }
275 }
276
277 if(!sw){
278 SetError(52,name,cp);
279 return 0;
280 }
281
282 return psi;
283}
284
285BOOL CParameter::ErrorCheck(char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
286 if(ParmsNum>pi_num){
287 if(ppi[pi_num-1].type!=DEF_ELLIPSE){
288 //パラメータが多すぎるとき
289 SetError(10,FuncName,cp);
290 return 0;
291 }
292 }
293 else if(ParmsNum<pi_num){
294 if(ParmsNum<SecondParmNum){
295 if(ppi[ParmsNum].type==DEF_ELLIPSE){
296 return 1;
297 }
298
299 //パラメータが少なすぎるとき
300 SetError(10,FuncName,cp);
301 return 0;
302 }
303
304 //省略パラメータに "0" を指定する
305 for(;ParmsNum < pi_num;ParmsNum++){
306 extern HANDLE hHeap;
307 char temporary[64];
308 if(ppi[ParmsNum].bByVal) lstrcpy(temporary,"0");
309 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
310 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
311 lstrcpy(Parms[ParmsNum],temporary);
312 }
313 }
314
315 return 1;
316}
317void CParameter::MacroParameterSupport(PARAMETER_INFO *ppi){
318 int i;
319 for(i=0;i<ParmsNum;i++){
320 if(Parms[i][0]=='\0'){
321 extern HANDLE hHeap;
322 char temporary[64];
323 if(ppi[i].bByVal) lstrcpy(temporary,"0");
324 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
325 HeapDefaultFree(Parms[i]);
326 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
327 lstrcpy(Parms[i],temporary);
328 }
329 }
330}
331
332void CParameter::NewTempParameters( char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum ){
333 ///////////////////////////////////////////////////////
334 // 一時オブジェクトをあらかじめスタックに積んでおく
335 ///////////////////////////////////////////////////////
336
337 useTempObject = false;
338
339 BOOL bEllipse;
340 if(pi_num){
341 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
342 else bEllipse=0;
343 }
344 else bEllipse=0;
345
346 for(int i2=ParmsNum-1;i2>=0;i2--){
347 useTempParameters[i2] = false;
348
349 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
350
351 if(i2==0&&ppi[i2].name){
352 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
353 //オブジェクトメンバの第一パラメータのThisポインタ
354 continue;
355 }
356 }
357 if((i2==0||i2==1)&&ppi[i2].name){
358 if(lstrcmp(ppi[i2].name,FuncName)==0){
359 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
360 continue;
361 }
362 }
363
364 TYPEINFO DummyTypeInfo;
365 BOOL bByVal;
366 if(bEllipse){
367 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
368 bByVal=1;
369 }
370 else{
371 DummyTypeInfo.type=ppi[i2].type;
372 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
373 bByVal=ppi[i2].bByVal;
374 }
375
376
377 if( !bByVal ){
378 //ポインタ参照
379 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
380 //ポインタ指定
381 continue;
382 }
383
384 LONG_PTR lpVarIndex;
385 if( GetVarType( Parms[i2], &lpVarIndex, FALSE ) == -1 ){
386 //変数ではないとき
387 int reg = REG_RAX;
388 int type = NumOpe( &reg, Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
389
390 //スタックフレームへコピー
391 StackOffsetOfTempObject[i2] = pobj_sf->push(reg);
392
393 bool result = CheckDifferentType(
394 DummyTypeInfo.type,
395 DummyTypeInfo.u.lpIndex,
396 type,
397 lpVarIndex,
398 FuncName,
399 i2);
400
401 if( result ){
402 useTempParameters[i2] = true;
403 useTempObject = true;
404
405 types[i2].type = type;
406 types[i2].u.lpIndex = lpVarIndex;
407 }
408 }
409 }
410 }
411}
412void CParameter::DeleteTempParameters(){
413 ///////////////////////////////////////////////////////
414 // 一時オブジェクトを破棄
415 ///////////////////////////////////////////////////////
416 if( !useTempObject ) return;
417
418 for(int i2=ParmsNum-1;i2>=0;i2--){
419 if( useTempParameters[i2] ){
420 //スタックフレームから取得
421 pobj_sf->ref(REG_RCX);
422
423 //デストラクタを呼び出す
424
425 //call destructor
426 int i5 = types[i2].u.pobj_Class->DestructorMemberSubIndex;
427 if( i5 != -1 ){
428 op_call( types[i2].u.pobj_Class->ppobj_Method[i5]->psi );
429 }
430
431 //メモリを解放する
432
433 pobj_sf->pop(REG_RCX);
434
435 //call free
436 extern SUBINFO *pSub_free;
437 op_call(pSub_free);
438 }
439 }
440}
441
442void CParameter::SetObjectParameter(int reg,CClass *pobj_Class,LPSTR Parameter){
443 //////////////////////////////////////////////////////
444 ///// レジスタ資源のバックアップ
445 { BACKUP_REGISTER_RESOURCE
446 //////////////////////////////////////////////////////
447
448 int object_size;
449 object_size=GetSizeOfClass(pobj_Class);
450
451 //mov rcx,object_size
452 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
453
454 //call calloc
455 extern SUBINFO *pSub_calloc;
456 op_call(pSub_calloc);
457
458 //mov r11,rax
459 op_mov_RR(REG_R11,REG_RAX);
460
461 //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用
462 pobj_sf->push(REG_R11);
463
464 TYPEINFO BaseType={DEF_OBJECT,(LONG_PTR)pobj_Class};
465 TYPEINFO CalcType;
466 CalcType.type=NumOpe_GetType(Parameter,&BaseType,&CalcType.u.lpIndex);
467
468 if(pobj_Class->CopyConstructorMemberSubIndex!=-1&&
469 CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
470 ////////////////////////////////////
471 // コピーコンストラクタを呼び出す
472 ////////////////////////////////////
473
474 BOOL bUseHeap;
475 int temp_reg=REG_RDX;
476 CalcType.type=NumOpe(&temp_reg,Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
477
478 if(bUseHeap){
479 //mov r14,rdx
480 op_mov_RR(REG_R14,REG_RDX);
481 }
482
483 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
484 pobj_sf->ref(REG_R11);
485
486 //mov rcx,this
487 op_mov_RR(REG_RCX,REG_R11);
488
489 //call constructor
490 op_call(pobj_Class->ppobj_Method[pobj_Class->CopyConstructorMemberSubIndex]->psi);
491
492
493 if(bUseHeap){
494 FreeTempObject(REG_R14,pobj_Class);
495 }
496 }
497 else{
498 if(pobj_Class->ConstructorMemberSubIndex!=-1){
499 ////////////////////////////////
500 // コンストラクタを呼び出す
501 ////////////////////////////////
502
503 //mov rcx,this
504 op_mov_RR(REG_RCX,REG_R11);
505
506 //call constructor
507 op_call(pobj_Class->ppobj_Method[pobj_Class->ConstructorMemberSubIndex]->psi);
508 }
509
510
511 BOOL bUseHeap;
512 int temp_reg=REG_RAX;
513 CalcType.type=NumOpe(&temp_reg,Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
514
515
516 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
517 pobj_sf->ref(REG_R11);
518
519
520 RELATIVE_VAR RelativeVar;
521 RelativeVar.bOffsetOffset=0;
522 RelativeVar.offset=0;
523 RelativeVar.dwKind=VAR_DIRECTMEM;
524
525 SetObjectVariableFromRax((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,&RelativeVar,bUseHeap);
526
527 }
528
529 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
530 pobj_sf->pop(REG_R11);
531
532 /////////////////////////////////////////////
533 ////// レジスタ資源を復元
534 RESTORE_REGISTER_RESOURCE
535 }////////////////////////////////////////////
536
537 //mov reg,r11
538 op_mov_RR(reg,REG_R11);
539}
540
541void CParameter::SetParameter(char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
542 ///////////////////////////////////////////////////////////
543 // パラメータをレジスタ及びスタックフレームにセット
544 ///////////////////////////////////////////////////////////
545 int i2,i3;
546
547 BOOL bEllipse;
548 if(pi_num){
549 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
550 else bEllipse=0;
551 }
552 else bEllipse=0;
553
554 BOOL bHas_System_LocalThis=0;
555 if(ParmsNum>=1){
556 if(lstrcmp(ppi[0].name,"_System_LocalThis")==0)
557 bHas_System_LocalThis=1;
558 }
559
560 //戻り値用の変数名を取得
561 char *lpszVarNameToReturn;
562 if(FuncName[0]==1&&FuncName[1]==ESC_OPERATOR) lpszVarNameToReturn="_System_ReturnValue";
563 else lpszVarNameToReturn=FuncName;
564
565 //パラメータをレジスタとスタックに格納
566 int CalcType;
567 LONG_PTR lpCalcIndex;
568 BOOL bCalcUseHeap;
569 int ParmSize=0;
570 int reg,temp_reg;
571 RELATIVE_VAR RelativeVar;
572 for(i2=ParmsNum-1;i2>=0;i2--){
573 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
574
575 if(i2==0&&ppi[i2].name){
576 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
577 //オブジェクトメンバの第一パラメータのThisポインタ
578 continue;
579 }
580 }
581 if((i2==0||i2==1)&&ppi[i2].name){
582 if(lstrcmp(ppi[i2].name,lpszVarNameToReturn)==0){
583 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
584 continue;
585 }
586 }
587
588 TYPEINFO DummyTypeInfo;
589 BOOL bByVal;
590 if(bEllipse){
591 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
592 bByVal=1;
593 }
594 else{
595 DummyTypeInfo.type=ppi[i2].type;
596 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
597 bByVal=ppi[i2].bByVal;
598 }
599
600 int xmm_temp_sw=0;
601 if(IsRealNumberType(DummyTypeInfo.type)&&bByVal){
602 //実数型
603 if(i2==0) reg=REG_XMM0;
604 else if(i2==1) reg=REG_XMM1;
605 else if(i2==2) reg=REG_XMM2;
606 else if(i2==3) reg=REG_XMM3;
607 else{
608 reg=REG_XMM0;
609 xmm_temp_sw=1;
610 }
611 }
612 else{
613 //整数型
614 if(i2==0) reg=REG_RCX;
615 else if(i2==1) reg=REG_RDX;
616 else if(i2==2) reg=REG_R8;
617 else if(i2==3) reg=REG_R9;
618 else reg=REG_RAX;
619 }
620
621 if(bByVal==1){
622 //値参照
623
624 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
625 char temp2[255];
626 sprintf(temp2,"%s関数の第%dパラメータ",FuncName,i2+1);
627 SetError(19,temp2,cp);
628 continue;
629 }
630
631 if(DummyTypeInfo.type==DEF_OBJECT){
632 SetObjectParameter(reg,DummyTypeInfo.u.pobj_Class,Parms[i2]);
633 goto next;
634 }
635
636 temp_reg=reg;
637
638 extern LONG_PTR ProcPtr_BaseIndex;
639 LONG_PTR back_ProcPtr_BaseIndex;
640 back_ProcPtr_BaseIndex=ProcPtr_BaseIndex;
641 if(DummyTypeInfo.type==DEF_PTR_PROC) ProcPtr_BaseIndex=DummyTypeInfo.u.lpIndex;
642 else ProcPtr_BaseIndex=-1;
643
644 CalcType=NumOpe(&temp_reg,Parms[i2],DummyTypeInfo.type,DummyTypeInfo.u.lpIndex,&lpCalcIndex,&bCalcUseHeap);
645
646 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
647
648 if(CalcType==-1) break;
649
650 if(CalcType==DEF_OBJECT){
651 //キャスト演算子のオーバーロードに対応する
652 CallCastOperatorProc(reg,CalcType,lpCalcIndex,bCalcUseHeap,DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
653 }
654
655
656 if(bEllipse){
657 if(IsRealNumberType(CalcType)){
658 //整数レジスタへコピー
659 //※cdeclの拡張パラメータは実数の場合も汎用レジスタで引渡し
660
661 if(0<=i2&&i2<=3){
662 if(i2==0) reg=REG_RCX;
663 else if(i2==1) reg=REG_RDX;
664 else if(i2==2) reg=REG_R8;
665 else if(i2==3) reg=REG_R9;
666
667 //movd reg,temp_reg
668 op_movd_RX(reg,temp_reg);
669 }
670 }
671 else if(IsWholeNumberType(CalcType)){
672 //整数型の場合は、64ビットへ拡張する
673 ExtendTypeTo64(CalcType,temp_reg);
674 }
675 }
676 else{
677 //型チェック
678 // TODO: _System_ReturnValueが考慮されていない?
679 if(bHas_System_LocalThis) i3=i2-1;
680 else i3=i2;
681 CheckDifferentType(
682 DummyTypeInfo.type,
683 DummyTypeInfo.u.lpIndex,
684 CalcType,
685 lpCalcIndex,
686 FuncName,
687 i3);
688
689
690 if(DummyTypeInfo.type==DEF_DOUBLE){
691 //Double型へ変換
692 ChangeTypeToXmm_Double(CalcType,reg,temp_reg);
693 }
694 else if(DummyTypeInfo.type==DEF_SINGLE){
695 //Single型へ変換
696 ChangeTypeToXmm_Single(CalcType,reg,temp_reg);
697 }
698 else if(IsWholeNumberType(DummyTypeInfo.type)){
699 //実数型 → 整数型
700 ChangeTypeToWhole(CalcType,DummyTypeInfo.type,reg,temp_reg);
701 }
702 }
703 }
704 else{
705 //ポインタ参照
706 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
707 //ポインタ指定
708
709 temp_reg=reg;
710 CalcType=NumOpe(&temp_reg,Parms[i2]+2,0,0,&lpCalcIndex);
711 if(CalcType==-1) break;
712
713 int ptr_type;
714 ptr_type=GetPtrType(DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
715
716 //型チェック
717 if(bHas_System_LocalThis) i3=i2-1;
718 else i3=i2;
719 CheckDifferentType(
720 ptr_type,
721 DummyTypeInfo.u.lpIndex,
722 CalcType,
723 lpCalcIndex,
724 FuncName,
725 i3);
726
727 if(IsRealNumberType(CalcType)){
728 //実数型 → 整数型
729 ChangeTypeToWhole(CalcType,DEF_QWORD,reg,temp_reg);
730 }
731 }
732 else{
733 //変数のアドレスを取得
734 int VarType;
735 LONG_PTR lpVarIndex;
736 if(GetVarOffset(
737 false,
738 false,
739 Parms[i2],
740 &VarType,
741 &RelativeVar,
742 &lpVarIndex)){
743
744 if(DummyTypeInfo.type!=DEF_ANY){
745 //型チェックを行う
746 if(DummyTypeInfo.type==VarType){
747 if(DummyTypeInfo.type==DEF_OBJECT){
748 if(DummyTypeInfo.u.lpIndex!=lpVarIndex){
749 SetError(11,Parms[i2],cp);
750 }
751 }
752 }
753 else if((VarType&FLAG_PTR)&&((VarType^FLAG_PTR)==DummyTypeInfo.type)){
754 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
755 }
756 else{
757 SetError(11,Parms[i2],cp);
758 }
759 }
760
761 //変数アドレスをレジスタにセット
762 SetVarPtrToReg(reg,&RelativeVar);
763
764 }
765 else{
766 //一時オブジェクトをコピー
767
768 //mov reg, qword ptr[rsp+offset]
769 pobj_sf->ref_offset_data( reg, StackOffsetOfTempObject[i2] );
770
771 //VarType = NumOpe( &reg, Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
772 }
773 }
774 }
775next:
776 if(reg==REG_RAX){
777 //スタックフレームへコピー
778 //mov qword ptr[rsp+offset],rax
779 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
780 }
781 else if(xmm_temp_sw){
782 //スタックフレームへコピー
783
784 //movlpd qword ptr[rsp+offset],xmm0
785 op_movlpd_MR(REG_XMM0,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
786 }
787
788
789 /////////////////////
790 // レジスタをロック
791 /////////////////////
792
793 if(0<=i2&&i2<=3){
794 // ※rcx, rdx, r8, r9の場合のみ
795 pobj_BlockReg->lock(reg);
796 }
797 }
798
799 //パラメータが収まるだけのスタックフレームを確保
800 pobj_sf->parameter_allocate(pi_num*sizeof(_int64)+ sizeof(_int64)/*ret用*/ );
801}
802void CParameter::BackupParameter(int pi_num){
803 ///////////////////////////////////////////////////////////
804 // スタックフレームに存在する既存のパラメータをバックアップ
805 ///////////////////////////////////////////////////////////
806 int i2;
807
808 for(i2=0;i2<ParmsNum;i2++){
809 /////////////////////
810 // バックアップ
811 /////////////////////
812
813 extern CDBLockParms obj_DBLockParms;
814 if(obj_DBLockParms.array_LevelCount[i2]){
815 //mov r14,qword ptr[rsp+offset]
816 op_mov_RM(sizeof(_int64),REG_R14,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
817
818 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
819 pobj_sf->push(REG_R14);
820 }
821
822 if(3<i2){
823 //スタックフレームをロック
824 extern CDBLockParms obj_DBLockParms;
825 obj_DBLockParms.lock(i2);
826 }
827 }
828}
829void CParameter::RestoreParameter(int pi_num){
830 ///////////////////////////////////////////////////////////
831 // スタックフレームに存在する既存のパラメータを復元
832 ///////////////////////////////////////////////////////////
833 int i2;
834
835 for(i2=ParmsNum-1;i2>=0;i2--){
836 /////////////////////
837 // 復元
838 /////////////////////
839
840 if(3<i2){
841 //スタックフレームをアンロック
842 extern CDBLockParms obj_DBLockParms;
843 obj_DBLockParms.unlock(i2);
844 }
845
846 extern CDBLockParms obj_DBLockParms;
847 if(obj_DBLockParms.array_LevelCount[i2]){
848 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
849 pobj_sf->pop(REG_R14);
850
851 //mov qword ptr[rsp+offset],r14
852 op_mov_MR(sizeof(_int64),REG_R14,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
853 }
854 }
855}
Note: See TracBrowser for help on using the repository browser.