source: dev/BasicCompiler64/NumOpe.cpp@ 143

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

traceログ機能を搭載
動的メンバをstl::vectorにまとめた
シンボルをクラス化した

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