source: dev/trunk/abdev/BasicCompiler64/NumOpe.cpp@ 201

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