source: dev/BasicCompiler64/NumOpe.cpp@ 115

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

64bitのほうも更新(CClassのconst化)

File size: 29.3 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void NewStringObject(int reg, const char *str){
5 ///////////////////////////////////////////////////////
6 // lpszTextを元にStringオブジェクトを生成し、
7 // オブジェクトポインタをregに格納する
8 ///////////////////////////////////////////////////////
9
10
11 //////////////////////////////////////////////////////
12 ///// レジスタ資源のバックアップ
13 { BACKUP_REGISTER_RESOURCE
14 //////////////////////////////////////////////////////
15
16 char *parameter = (char *)malloc( lstrlen( str ) + 32 );
17 sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS );
18 SetStringQuotes( parameter );
19
20 extern const CClass *pobj_StringClass;
21 Operator_New( *pobj_StringClass, "", parameter, Type( DEF_OBJECT, *pobj_StringClass ) );
22
23 free( parameter );
24
25 //mov reg,rax
26 op_mov_RR( reg, REG_RAX );
27
28 /////////////////////////////////////////////
29 ////// レジスタ資源を復元
30 RESTORE_REGISTER_RESOURCE
31 }////////////////////////////////////////////
32}
33
34void SetUseRegFromRax(int type,int UseReg,int XmmReg){
35 if(IsRealNumberType(type)){
36 //実数型
37 if(XmmReg==REG_XMM4){
38 if(type==DEF_DOUBLE){
39 //movsd qword ptr[rsp+offset],xmm0 ※スタックフレームを利用
40 pobj_sf->push(REG_XMM0,sizeof(double));
41 }
42 if(type==DEF_SINGLE){
43 //movss dword ptr[rsp+offset],xmm0 ※スタックフレームを利用
44 pobj_sf->push(REG_XMM0,sizeof(float));
45 }
46 }
47 else{
48 if(type==DEF_DOUBLE){
49 //movsd xmm_reg,xmm0
50 op_movsd_RR(XmmReg,REG_XMM0);
51 }
52 else if(type==DEF_SINGLE){
53 //movss xmm_reg,xmm0
54 op_movss_RR(XmmReg,REG_XMM0);
55 }
56 }
57 }
58 else{
59 //整数型
60 if(UseReg==REG_R14){
61 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
62 pobj_sf->push(REG_RAX);
63 }
64 else{
65 //mov reg,rax
66 op_mov_RR(UseReg,REG_RAX);
67 }
68 }
69}
70
71void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
72 switch( Type::GetBasicSize( bigBasicType ) ){
73 case sizeof(_int64):
74 ExtendTypeTo64(baseBasicType,reg);
75 break;
76 case sizeof(long):
77 ExtendTypeTo32(baseBasicType,reg);
78 break;
79 case sizeof(short):
80 ExtendTypeTo16(baseBasicType,reg);
81 break;
82 }
83}
84
85
86bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){
87 int UseReg=pobj_reg->GetNextReg();
88 int XmmReg=pobj_reg->GetNextXmmReg();
89
90 //大きな型への暗黙の変換
91 int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
92
93 if(resultType.GetBasicType()&FLAG_PTR){
94 //配列ポインタ
95 resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) );
96
97 SetVarPtrToReg(UseReg,&relativeVar);
98 }
99 else if(resultType.IsReal()){
100 //実数型
101 if( resultType.IsDouble() )
102 SetXmmReg_DoubleVariable(&relativeVar,XmmReg);
103 if( resultType.IsSingle() )
104 SetXmmReg_SingleVariable(&relativeVar,XmmReg);
105 }
106 else if( resultType.IsWhole() || resultType.IsObject()){
107 //整数型
108 SetReg_WholeVariable(resultType.GetBasicType(),&relativeVar,UseReg);
109 }
110 else if( resultType.IsStruct() ){
111 //構造体ポインタをUseRegへ格納(構造体は値型)
112 SetVarPtrToReg(UseReg,&relativeVar);
113 }
114 else{
115 return false;
116 }
117
118 if( resultType.GetBasicType() != bigType ){
119 // 大きな型へ変換された場合
120 // ※レジスタの値をキャストする
121 ExtendRegToBigType( UseReg, bigType, resultType.GetBasicType() );
122
123 resultType.SetBasicType( bigType );
124 }
125
126 return true;
127}
128bool TermMemberOpe( const CClass &objClass, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member ){
129
130 int UseReg=pobj_reg->GetNextReg();
131 int XmmReg=pobj_reg->GetNextXmmReg();
132
133
134 if( GetMemberType( objClass, member, resultType, 0, false ) ){
135 // メンバが見つかったとき
136
137 //オブジェクトポインタをr11にコピー
138 op_mov_RR( REG_R11, UseReg );
139
140 RELATIVE_VAR relativeVar;
141 relativeVar.dwKind=VAR_DIRECTMEM;
142
143 if( !_member_offset(
144 true, //エラー表示あり
145 false, //読み込み専用
146 objClass,
147 member,&relativeVar,resultType,0)){
148 return false;
149 }
150
151 if( !VarToReg( relativeVar, baseType, resultType ) ){
152 SetError(11,termFull,cp);
153 }
154
155 return true;
156 }
157
158
159 ///////////////////////////////////////////////////////////////////
160 // 動的メソッドを検索
161 ///////////////////////////////////////////////////////////////////
162 vector<UserProc *> userProcs;
163
164 char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
165 CClass::RefType refType;
166 lstrcpy( methodName, member );
167 GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType);
168
169 objClass.EnumMethod( methodName, userProcs );
170 UserProc *pUserProc;
171 if(userProcs.size()){
172 //オーバーロードを解決
173 pUserProc=OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
174
175 if( pUserProc ){
176
177 resultType = pUserProc->ReturnType();
178
179
180 //////////////////////////////////////////////////////
181 ///// レジスタ資源のバックアップ
182 { BACKUP_REGISTER_RESOURCE
183 //////////////////////////////////////////////////////
184
185 //オブジェクトポインタをスタックに入れておく
186 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
187 pobj_sf->push( UseReg );
188
189 if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft,0 ) ){
190 //レジスタ資源を復元
191 RESTORE_REGISTER_RESOURCE
192
193 return false;
194 }
195
196 pobj_sf->pop();
197
198 /////////////////////
199 // 戻り値の処理
200 /////////////////////
201
202 //大きな型への暗黙の変換
203 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
204
205 if( resultType.GetBasicType() != bigType ){
206 // 大きな型へ変換された場合
207 // ※レジスタの値をキャストする
208 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
209
210 resultType.SetBasicType( bigType );
211 }
212
213 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
214
215
216 /////////////////////////////////////////////
217 ////// レジスタ資源を復元
218 RESTORE_REGISTER_RESOURCE
219 }////////////////////////////////////////////
220
221 return true;
222 }
223 }
224
225 return false;
226}
227bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool *pIsClassName = NULL ){
228 char parameter[VN_SIZE];
229
230 // Withを解決
231 char termFull[VN_SIZE];
232 if(term[0]=='.'){
233 GetWithName(termFull);
234 lstrcat(termFull,term);
235 }
236 else lstrcpy(termFull,term);
237
238 char termLeft[VN_SIZE];
239 lstrcpy(termLeft,termFull);
240
241 // パース
242 char member[VN_SIZE];
243 CClass::RefType refType;
244 if( SplitMemberName( termFull, termLeft, member, refType ) ){
245 ///////////////////////////////////////////////////////////////////
246 // オブジェクトとメンバに分解できるとき
247 // termLeft.member
248 ///////////////////////////////////////////////////////////////////
249
250 isLiteral = false;
251
252 // オブジェクト側の型を取得
253 bool isClassName = false;
254 Type leftType;
255 if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, &isClassName ) ){
256 goto globalArea;
257 }
258
259 if( isClassName ){
260 // 静的メンバ/メソッドの場合
261 goto globalArea;
262 }
263
264 if( !leftType.HasMember() ){
265 // メンバを持たない型の場合
266 return false;
267 }
268
269 return TermMemberOpe( leftType.GetClass(), baseType, resultType, termFull, termLeft, member );
270 }
271globalArea:
272
273 //////////////////////////////////////////////
274 // クラス名かどうかをチェック(静的メンバ用)
275 //////////////////////////////////////////////
276
277 if( pIsClassName ){
278 if( pobj_DBClass->Find( termFull ) ){
279 *pIsClassName = true;
280 return true;
281 }
282 }
283
284
285 /////////////////////////////////////////////////////////////////
286 // グローバル属性エリア
287 /////////////////////////////////////////////////////////////////
288
289 int UseReg=pobj_reg->GetNextReg();
290 int XmmReg=pobj_reg->GetNextXmmReg();
291
292
293 if(lstrcmpi(termFull,"This")==0){
294 //Thisオブジェクト
295 resultType.SetType( DEF_OBJECT, pobj_CompilingClass );
296
297 SetThisPtrToReg( UseReg );
298
299 isLiteral = false;
300
301 return true;
302 }
303
304
305 //////////////////////////////////////
306 // 関数(DLL、ユーザー定義、組み込み)
307 //////////////////////////////////////
308 char procName[VN_SIZE];
309 char temporary[8192];
310
311 int i2=GetCallProcName(termFull,procName);
312 if(termFull[i2]=='('){
313 int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
314
315 void *pInfo;
316 int idProc=GetProc(procName,(void **)&pInfo);
317
318 if(idProc){
319 //閉じカッコ")"に続く文字がNULLでないとき
320 if(termFull[i2+1+i4+1]!='\0'){
321 SetError(42,NULL,cp);
322 }
323
324
325 //////////////////////////////////////////////////////
326 ///// レジスタ資源のバックアップ
327 { BACKUP_REGISTER_RESOURCE
328 //////////////////////////////////////////////////////
329
330
331 ////////////////
332 // 呼び出し
333 ////////////////
334
335 CallProc(idProc,pInfo,procName,parameter,resultType);
336
337
338 /////////////////////
339 // 戻り値の処理
340 /////////////////////
341
342 //大きな型への暗黙の変換
343 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
344
345 if( resultType.GetBasicType() != bigType ){
346 // 大きな型へ変換された場合
347 // ※レジスタの値をキャストする
348 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
349
350 resultType.SetBasicType( bigType );
351 }
352
353 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
354
355 /////////////////////////////////////////////
356 ////// レジスタ資源を復元
357 RESTORE_REGISTER_RESOURCE
358 }////////////////////////////////////////////
359
360 if(resultType.IsStruct()){
361 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
362 //※後にfreeする必要あり
363 // TODO: 解放はGCに任せる
364 *pbUseHeap = 1;
365 }
366
367 isLiteral = false;
368
369 return true;
370 }
371 else if(GetConstCalcBuffer(procName,parameter,temporary)){
372 /////////////////////////
373 // マクロ関数
374 /////////////////////////
375
376 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
377 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
378
379 //マクロ関数の場合
380 NumOpe(&UseReg,temporary,Type(),resultType);
381
382 if(!IS_LITERAL(resultType.GetIndex())){
383 //リテラル値ではなかったとき
384 isLiteral = false;
385 }
386
387 return true;
388 }
389 }
390
391
392 ////////////////////////////////
393 // インデクサ(getアクセサ)
394 ////////////////////////////////
395
396 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
397 GetArrayElement(termFull,VarName,ArrayElements);
398 if(ArrayElements[0]){
399 GetVarType(VarName,resultType,false);
400 if( resultType.IsObject() ){
401 CallIndexerGetterProc(UseReg,&resultType.GetClass(),VarName,ArrayElements,resultType);
402
403 isLiteral = false;
404
405 return true;
406 }
407 }
408
409
410 ////////////////////////////////
411 // 変数
412 ////////////////////////////////
413
414 RELATIVE_VAR relativeVar;
415 if(GetVarOffset(
416 false, //エラー表示なし
417 false, //読み込み専用
418 termFull,
419 &relativeVar,resultType)){
420 //////////
421 // 変数
422 //////////
423
424 if( !VarToReg( relativeVar, baseType, resultType ) ){
425 SetError(11,termFull,cp);
426 }
427
428 isLiteral = false;
429
430 return true;
431 }
432
433/*
434 ////////////////////////////////
435 // 型名
436 ////////////////////////////////
437
438 if( Type::StringToType( termFull, resultType ) ){
439 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
440 return true;
441 }*/
442
443
444 /////////////////////////////////
445 // プロパティ用のメソッド
446 /////////////////////////////////
447
448 //配列要素を排除
449 GetArrayElement(termFull,VarName,ArrayElements);
450
451 if(GetSubHash(VarName,0)){
452
453 //////////////////////////////////////////////////////
454 ///// レジスタ資源のバックアップ
455 { BACKUP_REGISTER_RESOURCE
456 //////////////////////////////////////////////////////
457
458 CallPropertyMethod(termFull,NULL,resultType);
459
460 //大きな型への暗黙の変換
461 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
462
463 if( resultType.GetBasicType() != bigType ){
464 // 大きな型へ変換された場合
465 // ※レジスタの値をキャストする
466 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
467
468 resultType.SetBasicType( bigType );
469 }
470
471 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
472
473 /////////////////////////////////////////////
474 ////// レジスタ資源を復元
475 RESTORE_REGISTER_RESOURCE
476 }////////////////////////////////////////////
477
478 if(resultType.IsStruct()){
479 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
480 //※後にfreeする必要あり
481 // TODO: 解放はGCに任せる
482 *pbUseHeap = 1;
483 }
484
485 isLiteral = false;
486
487 return true;
488 }
489
490
491 return false;
492}
493
494bool NumOpe( int *pReg,
495 const char *expression,
496 const Type &baseType,
497 Type &resultType,
498 BOOL *pbUseHeap ){
499
500 int i,i2,i3;
501 char temporary[1024],temp2[1024];
502
503 if(expression[0]=='\0'){
504 SetError(1,NULL,cp);
505 return false;
506 }
507
508 if(expression[0]==1&& expression[1]==ESC_NEW ){
509 //New演算子(オブジェクト生成)
510
511 if( !Operator_New( expression+2, baseType, resultType ) ){
512 return false;
513 }
514
515 //mov reg,rax
516 op_mov_RR( *pReg, REG_RAX );
517
518 return true;
519 }
520
521 if( !baseType.IsNull() && expression[0] == '[' ){
522 // リテラル配列の場合
523
524 if( !baseType.IsPointer() ){
525 SetError(1,NULL,cp);
526 return false;
527 }
528 Type tempBaseType( baseType );
529 tempBaseType.PtrLevelDown();
530
531 char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
532 lstrcpy( buffer, expression );
533 RemoveStringBracket( buffer );
534
535 void *binary = malloc( 1 );
536 int num = 0;
537
538 i = 0;
539 while( buffer[i] ){
540 i = GetOneParameter( buffer, i, temporary );
541 if( buffer[i] == ',' ){
542 i++;
543 }
544
545 Type resultType;
546 _int64 i64data;
547 if( !StaticCalculation( true, temporary, tempBaseType.GetBasicType(), &i64data, resultType ) ){
548 return false;
549 }
550 if( !resultType.IsWhole() ){
551 // TODO: 実数に未対応
552 SetError();
553 return false;
554 }
555
556 binary = realloc( binary, ( num + 1 ) * tempBaseType.GetSize() );
557 memcpy( (char *)binary + (num * tempBaseType.GetSize()), &i64data, tempBaseType.GetSize() );
558 num++;
559 }
560
561 i2 = dataTable.AddBinary( binary, num * tempBaseType.GetSize() );
562
563 //mov reg,i2
564 op_mov_RV(sizeof(_int64),*pReg,i2);
565 obp-=sizeof(long);
566 pobj_DataTableSchedule->add();
567 obp+=sizeof(long);
568
569 free( buffer );
570
571 resultType = baseType;
572
573 return true;
574 }
575
576
577 /////////////////////////////////
578 // 式要素を逆ポーランド式で取得
579 /////////////////////////////////
580
581 char *values[255];
582 long calc[255];
583 long stack[255];
584 int pnum;
585 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
586 for(i=0;i<pnum;i++){
587 if(values[i]) HeapDefaultFree(values[i]);
588 }
589 return 0;
590 }
591
592
593 BOOL bInitRegSwitch=0;
594 if(!pobj_reg){
595 bInitRegSwitch=1;
596
597 //作業用レジスタを取得
598 pobj_reg=new CRegister(*pReg);
599 }
600
601 //エラー時の復旧用
602 CRegister objReg_Backup;
603 objReg_Backup=*pobj_reg;
604
605
606
607 ////////////////////////////////
608 // 演算部分のコード生成を開始
609 ////////////////////////////////
610
611 BOOL bError;
612 bError=0;
613
614 //リテラル値のみの計算かどうかを判別するためのフラグ
615 BOOL bLiteralCalculation=1;
616
617 //リテラル演算の場合を考慮した演算前のバッファ位置
618 int BeforeObp;
619 BeforeObp=obp;
620
621 //リテラル演算の場合を考慮した演算前のプロシージャスケジュール位置
622 //※64ビットの掛け算、除算などで特殊関数が呼ばれるため
623 int Before_ProcAddrScheduleNum;
624 Before_ProcAddrScheduleNum=pobj_SubAddrSchedule->num;
625
626 //リテラル演算の場合を考慮した演算前のデータテーブルスケジュール位置
627 int Before_DataTableScheduleNum;
628 Before_DataTableScheduleNum=pobj_DataTableSchedule->num;
629
630 //リテラル演算の場合を考慮した演算前の再配置スケジュール
631 CReloc *pobj_BackReloc;
632 pobj_BackReloc=new CReloc();
633 pobj_BackReloc->copy(pobj_Reloc);
634
635 //リテラル演算の場合を考慮した演算前のスタックフレームスケジュール位置
636 int Before_StackFrameScheduleNum;
637 Before_StackFrameScheduleNum=pobj_sf->num;
638
639 double dbl;
640 int sp;
641 int type_stack[255];
642 LONG_PTR index_stack[255];
643 bool isNothing_stack[255];
644 BOOL bUseHeap[255];
645 _int64 i64data;
646 int UseReg,XmmReg;
647 BOOL bXmm;
648 for(i=0,sp=0;i<pnum;i++){
649 int idCalc;
650 idCalc=calc[i]%100;
651
652 if(idCalc){
653 if(type_stack[sp-2]==DEF_OBJECT){
654 if( idCalc == CALC_AS
655 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
656 && index_stack[sp-1] == index_stack[sp-2]
657 || isNothing_stack[sp-2] ){
658 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
659 }
660 else if( idCalc == CALC_AS
661 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
662 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
663 )){
664 // ダウンキャストを許可する
665 }
666 else{
667 //オーバーロードされたオペレータを呼び出す
668 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
669 if(i2==0){
670 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
671 else GetCalcName(idCalc,temp2);
672 sprintf(temporary,"Operator %s",temp2);
673 SetError(27,temporary,cp);
674 goto error;
675 }
676 else if(i2==-1) goto error;
677
678 continue;
679 }
680 }
681
682 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
683 }
684
685 switch(idCalc){
686 //数値
687 case 0:
688 index_stack[sp]=-1;
689 isNothing_stack[sp] = false;
690 bUseHeap[sp]=0;
691
692 UseReg=pobj_reg->GetNextReg();
693 XmmReg=pobj_reg->GetNextXmmReg();
694
695 bXmm=0;
696
697 char *term;
698 term=values[i];
699
700 if( calc[i+1]%100 == CALC_AS ){
701 // As演算子の右辺値
702 //型名
703 if( Type::StringToType( term, resultType ) ){
704 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
705 }
706 else{
707 SetError(3, term, cp );
708 goto error;
709 }
710
711 type_stack[sp] = resultType.GetBasicType();
712 index_stack[sp] = resultType.GetIndex();
713 sp++;
714
715 break;
716 }
717
718 if(term[0]=='\"'){
719 //リテラル文字列
720 if(!RemoveStringQuotes(term)){
721 SetError(43,NULL,cp);
722 goto error;
723 }
724 i3=lstrlen(term);
725StrLiteral:
726
727 if( baseType.IsObject() || baseType.IsNull() ){
728 //要求タイプがオブジェクト、または未定のとき
729
730 //String型オブジェクトを生成
731 NewStringObject(UseReg,term);
732
733 extern const CClass *pobj_StringClass;
734 type_stack[sp]=DEF_OBJECT;
735 index_stack[sp]=(LONG_PTR)pobj_StringClass;
736 bLiteralCalculation=0;
737
738 if(bXmm) pobj_reg->LockXmmReg();
739 else pobj_reg->LockReg();
740
741 sp++;
742 break;
743 }
744
745 type_stack[sp]=typeOfPtrChar;
746 bLiteralCalculation=0;
747
748 i2 = dataTable.AddString( term, i3 );
749
750 //mov reg,i2
751 op_mov_RV(sizeof(_int64),UseReg,i2);
752 obp-=sizeof(long);
753 pobj_DataTableSchedule->add();
754 obp+=sizeof(long);
755
756 if(UseReg==REG_R14){
757 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
758 pobj_sf->push(REG_R14);
759 }
760 }
761 else if((term[0]=='e'||term[0]=='E')&&
762 (term[1]=='x'||term[1]=='X')&&
763 term[2]=='\"'){
764 //拡張版リテラル文字列(エスケープシーケンス可能)
765 if(!RemoveStringQuotes(term+2)){
766 SetError(43,NULL,cp);
767 goto error;
768 }
769 i3=FormatString_EscapeSequence(term+2);
770 term+=2;
771
772 goto StrLiteral;
773 }
774 else if(IsVariableTopChar(term[0])||
775 term[0]=='*'||
776 (term[0]=='.'&&IsVariableTopChar(term[1]))){
777 //////////////////
778 // 何らかの識別子
779
780 if( (string)term=="ParentArea.NamespaceEnumTest.x"){
781 int test=0;
782 }
783
784 bool isLiteral;
785 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
786 if(resultType.IsNull()){
787 //戻り値が存在しないとき
788 for(i2=0;;i2++){
789 if(term[i2]=='('||term[i2]=='\0'){
790 term[i2]=0;
791 break;
792 }
793 }
794 SetError(38,term,cp);
795
796 goto error;
797 }
798
799 type_stack[sp] = resultType.GetBasicType();
800 index_stack[sp] = resultType.GetIndex();
801
802 if( !isLiteral ){
803 bLiteralCalculation=0;
804 }
805
806 if( resultType.GetBasicType() & FLAG_CAST ){
807 // 型名のみ
808 SetError();
809 }
810 else{
811 if( resultType.IsReal() == false && UseReg==REG_R14 ){
812 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
813 pobj_sf->push(REG_R14);
814 }
815 if( resultType.IsReal() && XmmReg==REG_XMM4 ){
816 if(resultType.IsDouble()){
817 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
818 pobj_sf->push(REG_XMM4,sizeof(double));
819 }
820 if(resultType.IsSingle()){
821 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
822 pobj_sf->push(REG_XMM4,sizeof(float));
823 }
824 }
825
826 if( resultType.IsReal() ){
827 pobj_reg->LockXmmReg();
828 }
829 else{
830 pobj_reg->LockReg();
831 }
832 }
833
834 sp++;
835 break;
836 }
837
838
839 // Nothing
840 if( lstrcmp( term, "Nothing" ) == 0 ){
841 isNothing_stack[sp] = true;
842
843 type_stack[sp] = DEF_OBJECT;
844 if( baseType.IsObject() ){
845 index_stack[sp] = baseType.GetIndex();
846 }
847 else{
848 index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass();
849 }
850
851 bLiteralCalculation = 0;
852
853 //xor reg,reg
854 op_zero_reg( UseReg );
855
856 if(UseReg==REG_R14){
857 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
858 pobj_sf->push(REG_R14);
859 }
860
861 pobj_reg->LockReg();
862 sp++;
863 break;
864 }
865
866
867 //////////////
868 // 定数の場合
869 //////////////
870
871 i3 = CDBConst::obj.GetBasicType(term);
872 if(i3){
873 if( CDBConst::obj.IsStringPtr( term ) ){
874 //リテラル文字列
875
876 double dbl = CDBConst::obj.GetDoubleData(term);
877 memcpy(&i64data,&dbl,sizeof(double));
878
879 //バイト数
880 i3=lstrlen((char *)i64data);
881
882 memcpy(term,(char *)i64data,i3);
883 term[i3]=0;
884 goto StrLiteral;
885 }
886
887 type_stack[sp] = i3;
888 if(IsRealNumberType(i3)){
889 //実数
890 double dbl = CDBConst::obj.GetDoubleData(term);
891 memcpy(&i64data,&dbl,sizeof(double));
892 goto Literal;
893 }
894 else if(IsWholeNumberType(i3)){
895 //整数
896 i64data = CDBConst::obj.GetWholeData(term);
897 goto Literal;
898 }
899 /*else if(i3==DEF_STRING){
900 //リテラル文字列
901
902 //バイト数
903 i3=(int)dbl;
904
905 memcpy(term,temporary,i3);
906 goto StrLiteral;
907 }*/
908 else{
909 SetError(1,NULL,0);
910 goto error;
911 }
912 }
913
914
915 //該当する識別子が見当たらないときはエラー扱いにする
916 bError=1;
917 SetError(3,term,cp);
918 type_stack[sp]=DEF_DOUBLE;
919 }
920 else{
921 //リテラル値
922 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
923Literal:
924 if(type_stack[sp]==DEF_DOUBLE){
925 //64ビット浮動小数型
926 bXmm=1;
927
928 if(XmmReg==REG_XMM4){
929 //mov r14,i64data
930 op_mov64_ToReg(REG_R14,i64data);
931
932
933 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
934 pobj_sf->push(REG_R14);
935 }
936 else{
937 i3 = dataTable.Add( i64data );
938
939 //movlpd xmm_reg,qword ptr[data table offset]
940 OpBuffer[obp++]=(char)0x66;
941 OpBuffer[obp++]=(char)0x0F;
942 OpBuffer[obp++]=(char)0x12;
943 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
944 OpBuffer[obp++]=(char)0x25;
945 *((long *)(OpBuffer+obp))=i3;
946 pobj_DataTableSchedule->add();
947 obp+=sizeof(long);
948 }
949 }
950 else if(type_stack[sp]==DEF_SINGLE){
951 //32ビット浮動小数型
952 bXmm=1;
953
954 float flt;
955 int i32data;
956 memcpy(&dbl,&i64data,sizeof(double));
957 flt=(float)dbl;
958 memcpy(&i32data,&flt,sizeof(long));
959
960 if(XmmReg==REG_XMM4){
961 SetError(); // TODO: 未実装
962 //push term
963 op_push_value(i32data);
964 }
965 else{
966 i3=dataTable.Add( i32data );
967
968 //movss xmm_reg,dword ptr[data table offset]
969 OpBuffer[obp++]=(char)0xF3;
970 OpBuffer[obp++]=(char)0x0F;
971 OpBuffer[obp++]=(char)0x10;
972 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
973 OpBuffer[obp++]=(char)0x25;
974 *((long *)(OpBuffer+obp))=i3;
975 pobj_DataTableSchedule->add();
976 obp+=sizeof(long);
977 }
978 }
979 else{
980 //整数
981
982 index_stack[sp]=GetLiteralIndex(i64data);
983
984 //mov reg,i64data
985 op_mov64_ToReg(UseReg,i64data);
986
987 if(UseReg==REG_R14){
988 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
989 pobj_sf->push(REG_R14);
990 }
991 }
992 }
993
994 if(bXmm) pobj_reg->LockXmmReg();
995 else pobj_reg->LockReg();
996
997 sp++;
998 break;
999
1000 //論理演算子
1001 case CALC_XOR:
1002 case CALC_OR:
1003 case CALC_AND:
1004 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
1005 break;
1006 case CALC_NOT:
1007 //value[sp-1]=Not value[sp-1]
1008 //NOT演算子
1009 if(!Calc_Not(type_stack,sp)) goto error;
1010 break;
1011
1012 //比較演算子
1013 case CALC_PE: //value[sp-2] <= value[sp-1]
1014 case CALC_QE: //value[sp-2] >= value[sp-1]
1015 case CALC_P: //value[sp-2] < value[sp-1]
1016 case CALC_Q: //value[sp-2] > value[sp-1]
1017 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1018 case CALC_EQUAL: //value[sp-2] = value[sp-1]
1019 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
1020 break;
1021
1022 //ビットシフト
1023 case CALC_SHL: //value[sp-2] << value[sp-1]
1024 case CALC_SHR: //value[sp-2] >> value[sp-1]
1025 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
1026 break;
1027
1028 //算術演算
1029 case CALC_ADDITION:
1030 case CALC_SUBTRACTION:
1031 case CALC_PRODUCT:
1032 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1033 break;
1034 case CALC_MOD:
1035 //value[sp-2]%=value[sp-1]
1036 //剰余演算
1037 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
1038 break;
1039 case CALC_QUOTIENT:
1040 //value[sp-2]/=value[sp-1];
1041 //除算
1042 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1043 break;
1044 case CALC_INTQUOTIENT:
1045 //value[sp-2]/=value[sp-1]
1046 //整数除算
1047 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1048 break;
1049 case CALC_MINUSMARK:
1050 //value[sp-1]=-value[sp-1]
1051 //符号反転
1052 if(!Calc_MinusMark(type_stack,sp)) goto error;
1053 break;
1054 case CALC_POWER:
1055 //べき乗演算(浮動小数点演算のみ)
1056 if(!Calc_Power(type_stack,&sp)) goto error;
1057 break;
1058 case CALC_AS:
1059 //キャスト
1060 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1061 break;
1062 case CALC_BYVAL:
1063 //ポインタ型→参照型
1064 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1065 //ポインタ型ではないとき
1066 SetError( 3, NULL, cp );
1067 goto error;
1068 }
1069
1070 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1071
1072 break;
1073
1074 default:
1075 SetError(300,NULL,cp);
1076 goto error;
1077 }
1078 }
1079
1080 if(bError) goto error;
1081
1082 if(sp!=1){
1083 SetError(1,NULL,cp);
1084 goto error;
1085 }
1086
1087 if(bLiteralCalculation){
1088 //右辺値が数値の定数式の場合
1089 Type resultType;
1090 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
1091
1092 obp=BeforeObp;
1093 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
1094 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
1095 pobj_Reloc->copy(pobj_BackReloc);
1096 pobj_sf->num=Before_StackFrameScheduleNum;
1097 *pobj_reg=objReg_Backup;
1098
1099 if(resultType.IsReal()){
1100 if(baseType.IsReal()) resultType=baseType;
1101
1102 XmmReg=pobj_reg->LockXmmReg();
1103
1104 if(resultType.IsDouble()){
1105 i3 = dataTable.Add( i64data );
1106
1107 //movlpd xmm_reg,qword ptr[data table offset]
1108 OpBuffer[obp++]=(char)0x66;
1109 OpBuffer[obp++]=(char)0x0F;
1110 OpBuffer[obp++]=(char)0x12;
1111 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
1112 OpBuffer[obp++]=(char)0x25;
1113 *((long *)(OpBuffer+obp))=i3;
1114 pobj_DataTableSchedule->add();
1115 obp+=sizeof(long);
1116 }
1117 if(resultType.IsSingle()){
1118 memcpy(&dbl,&i64data,sizeof(_int64));
1119
1120 float flt;
1121 int i32data;
1122 flt=(float)dbl;
1123 memcpy(&i32data,&flt,sizeof(long));
1124
1125 i3 = dataTable.Add( i32data );
1126
1127 //movss xmm_reg,dword ptr[data table offset]
1128 OpBuffer[obp++]=(char)0xF3;
1129 OpBuffer[obp++]=(char)0x0F;
1130 OpBuffer[obp++]=(char)0x10;
1131 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
1132 OpBuffer[obp++]=(char)0x25;
1133 *((long *)(OpBuffer+obp))=i3;
1134 pobj_DataTableSchedule->add();
1135 obp+=sizeof(long);
1136 }
1137 }
1138 else{
1139 if(!resultType.Is64()){
1140 //整数(符号有り/無し)
1141
1142 i3=(long)i64data;
1143
1144 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
1145 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
1146
1147 i64data=(_int64)i3;
1148 }
1149
1150 UseReg=pobj_reg->LockReg();
1151
1152 //mov reg,i64data
1153 op_mov64_ToReg(UseReg,i64data);
1154 }
1155
1156 type_stack[0]=resultType.GetBasicType();
1157 index_stack[0]=resultType.GetIndex();
1158 }
1159 else{
1160 //右辺値が数値の定数式ではないとき
1161 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1162 }
1163
1164 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1165
1166 if(IsRealNumberType(type_stack[0]))
1167 *pReg=pobj_reg->UnlockXmmReg();
1168 else
1169 *pReg=pobj_reg->UnlockReg();
1170
1171
1172 if(bInitRegSwitch){
1173 //整合性をチェック(バグ回避)
1174 pobj_reg->bug_check();
1175
1176 //作業レジスタを解放
1177 delete pobj_reg;
1178 pobj_reg=0;
1179 }
1180
1181 resultType.SetType( type_stack[0], index_stack[0] );
1182
1183 bool isSuccessful = true;
1184 goto finish;
1185
1186
1187
1188 //////////////////
1189 // エラー処理
1190 //////////////////
1191
1192error:
1193
1194 *pobj_reg=objReg_Backup;
1195
1196 if(bInitRegSwitch){
1197 //作業レジスタを解放
1198 delete pobj_reg;
1199 pobj_reg=0;
1200 }
1201
1202 isSuccessful = false;
1203 goto finish;
1204
1205
1206
1207
1208finish:
1209
1210 for(i=0;i<pnum;i++){
1211 if(values[i]) HeapDefaultFree(values[i]);
1212 }
1213
1214 //再配置スケジュールバックアップ情報を解放
1215 delete pobj_BackReloc;
1216
1217 return isSuccessful;
1218}
Note: See TracBrowser for help on using the repository browser.