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

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

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

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