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

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

[416]のコミットによって発生した64bit版での不具合を修正。

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