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

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

[403]を64bitコンパイラにも対応

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