source: dev/BasicCompiler64/NumOpe.cpp@ 122

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

(呼び出し単体コードも対応→)関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

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