source: dev/BasicCompiler64/CParameter.cpp@ 47

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

列挙子の比較演算が正常に行えないバグを修正。
クラス名と同名のグローバル関数を定義できないバグを修正

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