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

Last change on this file since 430 was 430, checked in by dai_9181, 16 years ago

[429]を64bit版にマージ。

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