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

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

コード全体のリファクタリングを実施

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