source: dev/BasicCompiler64/NumOpe.cpp@ 97

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

関数の戻り値オブジェクトのメンバ・メソッドを一時オブジェクトを介さずに参照できるようにした。

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