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

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

[412]をマージ。

File size: 33.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 )
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 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 RELATIVE_VAR relativeVar;
557 if(GetVarOffset(
558 false, //エラー表示なし
559 false, //読み込み専用
560 termFull,
561 &relativeVar,resultType)){
562 //////////
563 // 変数
564 //////////
565
566 if( !VarToReg( relativeVar, baseType, resultType ) ){
567 SetError(11,termFull,cp);
568 }
569
570 isLiteral = false;
571
572 return true;
573 }
574
575/*
576 ////////////////////////////////
577 // 型名
578 ////////////////////////////////
579
580 if( compiler.StringToType( termFull, resultType ) ){
581 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
582 return true;
583 }*/
584
585
586 /////////////////////////////////
587 // プロパティ用のメソッド
588 /////////////////////////////////
589
590 //配列要素を排除
591 GetArrayElement(termFull,VarName,ArrayElements);
592
593 if(GetSubHash(VarName,0)){
594
595 //////////////////////////////////////////////////////
596 ///// レジスタ資源のバックアップ
597 { BACKUP_REGISTER_RESOURCE
598 //////////////////////////////////////////////////////
599
600 CallPropertyMethod(termFull,NULL,resultType);
601
602 //大きな型への暗黙の変換
603 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
604
605 if( resultType.GetBasicType() != bigType ){
606 // 大きな型へ変換された場合
607 // ※レジスタの値をキャストする
608 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
609
610 resultType.SetBasicType( bigType );
611 }
612
613 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
614
615 /////////////////////////////////////////////
616 ////// レジスタ資源を復元
617 RESTORE_REGISTER_RESOURCE
618 }////////////////////////////////////////////
619
620 if(resultType.IsStruct()){
621 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
622 //※後にfreeする必要あり
623 // TODO: 解放はGCに任せる
624 *pbUseHeap = 1;
625 }
626
627 isLiteral = false;
628
629 return true;
630 }
631
632 if( isProcedureCallOnly )
633 {
634 SetError(3, termLeft, cp );
635 }
636
637 return false;
638}
639
640bool _numope( int *pReg,
641 const char *expression,
642 const Type &baseType,
643 Type &resultType,
644 BOOL *pbUseHeap )
645{
646 int i,i2,i3;
647 char temporary[1024],temp2[1024];
648
649 if(expression[0]=='\0'){
650 SetError(1,NULL,cp);
651 return false;
652 }
653
654 if( !baseType.IsNull() && expression[0] == '[' ){
655 // リテラル配列の場合
656
657 int dataTableOffset;
658 if( !compiler.GetObjectModule().dataTable.MakeLiteralArrayBuffer( expression, baseType, dataTableOffset ) )
659 {
660 return false;
661 }
662
663 //mov reg,i2
664 compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable );
665
666 resultType = baseType;
667
668 return true;
669 }
670
671 bool isLiteralCalculation;
672 if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
673 {
674 if( isLiteralCalculation )
675 {
676 //右辺値が数値の定数式の場合
677 _int64 i64data;
678 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
679
680 if(resultType.IsReal()){
681 if(baseType.IsReal()) resultType=baseType;
682
683 int xmmReg = pobj_reg->GetNextXmmReg();
684 *pReg = xmmReg;
685
686 if(resultType.IsDouble()){
687 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
688
689 //movlpd xmm_reg,qword ptr[data table offset]
690 compiler.codeGenerator.op_movlpd_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
691 }
692 if(resultType.IsSingle()){
693 double dbl;
694 memcpy(&dbl,&i64data,sizeof(_int64));
695
696 float flt;
697 int i32data;
698 flt=(float)dbl;
699 memcpy(&i32data,&flt,sizeof(long));
700
701 i3 = compiler.GetObjectModule().dataTable.Add( i32data );
702
703 //movss xmm_reg,dword ptr[data table offset]
704 compiler.codeGenerator.op_movss_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
705 }
706 }
707 else{
708 if(!resultType.Is64()){
709 //整数(符号有り/無し)
710
711 i3=(long)i64data;
712
713 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
714 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
715
716 i64data=(_int64)i3;
717 }
718
719 //mov reg,i64data
720 compiler.codeGenerator.op_mov_RV64(*pReg,i64data);
721 }
722 return true;
723 }
724 }
725
726 if( expression[0] == 1 )
727 {
728 if( expression[1]==ESC_NEW )
729 {
730 //New演算子(オブジェクト生成)
731
732 if( pobj_BlockReg->check(REG_RAX) ){
733 SetError();
734 }
735
736 //////////////////////////////////////////////////////
737 ///// レジスタ資源のバックアップ
738 { BACKUP_REGISTER_RESOURCE
739 //////////////////////////////////////////////////////
740
741 if( !Operator_New( expression+2, baseType, resultType ) ){
742 return false;
743 }
744
745 /////////////////////////////////////////////
746 ////// レジスタ資源を復元
747 RESTORE_REGISTER_RESOURCE
748 }////////////////////////////////////////////
749
750 //mov reg,rax
751 compiler.codeGenerator.op_mov_RR( *pReg, REG_RAX );
752
753 return true;
754 }
755 else if( expression[1] == ESC_SYSTEM_STATIC_NEW )
756 {
757 // 静的領域にオブジェクトを作る
758
759 // 静的領域にオブジェクトを生成
760 int dataTableOffset;
761 if( !compiler.GetObjectModule().dataTable.MakeConstObjectToProcessStaticBuffer( expression + 2, resultType, dataTableOffset ) )
762 {
763 return false;
764 }
765
766 //mov reg,i2
767 compiler.codeGenerator.op_mov_RV( sizeof(_int64), *pReg, dataTableOffset, Schedule::DataTable);
768
769 return true;
770 }
771 }
772
773
774 /////////////////////////////////
775 // 式要素を逆ポーランド式で取得
776 /////////////////////////////////
777
778 char *values[255];
779 long calc[255];
780 long stack[255];
781 int pnum;
782 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
783 for(i=0;i<pnum;i++){
784 if(values[i]) HeapDefaultFree(values[i]);
785 }
786 return 0;
787 }
788
789
790 ////////////////////////////////
791 // 演算部分のコード生成を開始
792 ////////////////////////////////
793
794 BOOL bError;
795 bError=0;
796
797 //リテラル値のみの計算かどうかを判別するためのフラグ
798 BOOL bLiteralCalculation=1;
799
800 double dbl;
801 int sp;
802 int type_stack[255];
803 LONG_PTR index_stack[255];
804 bool isNothing_stack[255];
805 BOOL bUseHeap[255];
806 _int64 i64data;
807 int UseReg,XmmReg;
808 BOOL bXmm;
809 for(i=0,sp=0;i<pnum;i++){
810 int idCalc;
811 idCalc=calc[i]%100;
812
813 if(idCalc){
814 if(type_stack[sp-2]==DEF_OBJECT){
815 if( idCalc == CALC_AS
816 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
817 && index_stack[sp-1] == index_stack[sp-2]
818 || isNothing_stack[sp-2] ){
819 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
820 }
821 else if( idCalc == CALC_AS
822 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
823 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
824 )){
825 // ダウンキャストを許可する
826 }
827 else{
828 //オーバーロードされたオペレータを呼び出す
829 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
830 if(i2==0){
831 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
832 else GetCalcName(idCalc,temp2);
833 sprintf(temporary,"Operator %s",temp2);
834 SetError(27,temporary,cp);
835 goto error;
836 }
837 else if(i2==-1) goto error;
838
839 continue;
840 }
841 }
842
843 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
844 }
845
846 switch(idCalc){
847 //数値
848 case 0:
849 index_stack[sp]=-1;
850 isNothing_stack[sp] = false;
851 bUseHeap[sp]=0;
852
853 UseReg=pobj_reg->GetNextReg();
854 XmmReg=pobj_reg->GetNextXmmReg();
855
856 bXmm=0;
857
858 char *term;
859 term=values[i];
860
861 if( calc[i+1]%100 == CALC_AS ){
862 // As演算子の右辺値
863 //型名
864 if( compiler.StringToType( term, resultType ) ){
865 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
866 }
867 else{
868 SetError(3, term, cp );
869 goto error;
870 }
871
872 type_stack[sp] = resultType.GetBasicType();
873 index_stack[sp] = resultType.GetIndex();
874 sp++;
875
876 break;
877 }
878
879 if( (term[0]=='e'||term[0]=='E')
880 && (term[1]=='x'||term[1]=='X')
881 && term[2]=='\"'
882 || term[0] == '\"' )
883 {
884 bool isEx = true;
885 if( term[0] == '\"' )
886 {
887 isEx = false;
888 }
889
890 if( isEx )
891 {
892 // 拡張版リテラル文字列(エスケープシーケンス可能)
893 if(!RemoveStringQuotes(term+2)){
894 SetError(43,NULL,cp);
895 goto error;
896 }
897 i3=FormatString_EscapeSequence(term+2);
898 term+=2;
899 }
900 else
901 {
902 // 通常文字列
903 if(!RemoveStringQuotes(term)){
904 SetError(43,NULL,cp);
905 goto error;
906 }
907 i3=lstrlen(term);
908 }
909
910 if( !baseType.IsPointer() )
911 {
912 //要求タイプがオブジェクト、または未定のとき
913
914 //String型オブジェクトを生成
915 i2 = compiler.GetObjectModule().dataTable.MakeConstStringObjectToProcessStaticBuffer( term );
916
917 //mov reg,i2
918 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
919
920 type_stack[sp]=DEF_OBJECT;
921 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
922 bLiteralCalculation=0;
923
924 if(bXmm) pobj_reg->LockXmmReg();
925 else pobj_reg->LockReg();
926
927 sp++;
928 break;
929 }
930
931StrLiteral:
932
933 type_stack[sp]=typeOfPtrChar;
934 bLiteralCalculation=0;
935
936 i2 = compiler.GetObjectModule().dataTable.AddString( term, i3 );
937
938 //mov reg,i2
939 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
940
941 if(UseReg==REG_R14){
942 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
943 pobj_sf->push(REG_R14);
944 }
945 }
946 else if(IsVariableTopChar(term[0])||
947 term[0]=='*'||
948 (term[0]=='.'&&IsVariableTopChar(term[1])))
949 {
950 //////////////////
951 // 何らかの識別子
952
953 bool isLiteral;
954 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
955 if(resultType.IsNull()){
956 //戻り値が存在しないとき
957 for(i2=0;;i2++){
958 if(term[i2]=='('||term[i2]=='\0'){
959 term[i2]=0;
960 break;
961 }
962 }
963 SetError(38,term,cp);
964
965 goto error;
966 }
967
968 type_stack[sp] = resultType.GetBasicType();
969 index_stack[sp] = resultType.GetIndex();
970
971 if( !isLiteral ){
972 bLiteralCalculation=0;
973 }
974
975 if( resultType.GetBasicType() & FLAG_CAST ){
976 // 型名のみ
977 SetError();
978 }
979 else{
980 if( resultType.IsReal() == false && UseReg==REG_R14 ){
981 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
982 pobj_sf->push(REG_R14);
983 }
984 if( resultType.IsReal() && XmmReg==REG_XMM4 ){
985 if(resultType.IsDouble()){
986 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
987 pobj_sf->push(REG_XMM4,sizeof(double));
988 }
989 if(resultType.IsSingle()){
990 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
991 pobj_sf->push(REG_XMM4,sizeof(float));
992 }
993 }
994
995 if( resultType.IsReal() ){
996 pobj_reg->LockXmmReg();
997 }
998 else{
999 pobj_reg->LockReg();
1000 }
1001 }
1002
1003 sp++;
1004 break;
1005 }
1006
1007
1008 // Nothing
1009 if( lstrcmp( term, "Nothing" ) == 0 ){
1010 isNothing_stack[sp] = true;
1011
1012 type_stack[sp] = DEF_OBJECT;
1013 if( baseType.IsObject() ){
1014 index_stack[sp] = baseType.GetIndex();
1015 }
1016 else{
1017 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
1018 }
1019
1020 bLiteralCalculation = 0;
1021
1022 //xor reg,reg
1023 compiler.codeGenerator.op_zero_reg( UseReg );
1024
1025 if(UseReg==REG_R14){
1026 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1027 pobj_sf->push(REG_R14);
1028 }
1029
1030 pobj_reg->LockReg();
1031 sp++;
1032 break;
1033 }
1034
1035
1036 //////////////
1037 // 定数の場合
1038 //////////////
1039
1040 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
1041 if(i3){
1042 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
1043 //リテラル文字列
1044
1045 if( baseType.IsObject() || baseType.IsNull() )
1046 {
1047 //要求タイプがオブジェクト、または未定のとき
1048
1049 //String型オブジェクトを生成
1050 NewStringObject(UseReg,term);
1051
1052 type_stack[sp]=DEF_OBJECT;
1053 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
1054 bLiteralCalculation=0;
1055
1056 if(bXmm) pobj_reg->LockXmmReg();
1057 else pobj_reg->LockReg();
1058
1059 sp++;
1060 break;
1061 }
1062
1063 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1064 memcpy(&i64data,&dbl,sizeof(double));
1065
1066 //バイト数
1067 i3=lstrlen((char *)i64data);
1068
1069 memcpy(term,(char *)i64data,i3);
1070 term[i3]=0;
1071 goto StrLiteral;
1072 }
1073
1074 type_stack[sp] = i3;
1075 if(IsRealNumberType(i3)){
1076 //実数
1077 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
1078 memcpy(&i64data,&dbl,sizeof(double));
1079 goto Literal;
1080 }
1081 else if(IsWholeNumberType(i3)){
1082 //整数
1083 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
1084 goto Literal;
1085 }
1086 else{
1087 SetError(1,NULL,0);
1088 goto error;
1089 }
1090 }
1091
1092
1093 //該当する識別子が見当たらないときはエラー扱いにする
1094 bError=1;
1095 SetError(3,term,cp);
1096 type_stack[sp]=DEF_DOUBLE;
1097 }
1098 else{
1099 //リテラル値
1100 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
1101Literal:
1102 if(type_stack[sp]==DEF_DOUBLE){
1103 //64ビット浮動小数型
1104 bXmm=1;
1105
1106 if(XmmReg==REG_XMM4){
1107 //mov r14,i64data
1108 compiler.codeGenerator.op_mov_RV64(REG_R14,i64data);
1109
1110
1111 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1112 pobj_sf->push(REG_R14);
1113 }
1114 else{
1115 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
1116
1117 //movlpd xmm_reg,qword ptr[data table offset]
1118 compiler.codeGenerator.op_movlpd_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1119 }
1120 }
1121 else if(type_stack[sp]==DEF_SINGLE){
1122 //32ビット浮動小数型
1123 bXmm=1;
1124
1125 float flt;
1126 int i32data;
1127 memcpy(&dbl,&i64data,sizeof(double));
1128 flt=(float)dbl;
1129 memcpy(&i32data,&flt,sizeof(long));
1130
1131 if(XmmReg==REG_XMM4){
1132 SetError(); // TODO: 未実装
1133 //push term
1134 //compiler.codeGenerator.op_push_value(i32data);
1135 }
1136 else{
1137 i3=compiler.GetObjectModule().dataTable.Add( i32data );
1138
1139 //movss xmm_reg,dword ptr[data table offset]
1140 compiler.codeGenerator.op_movss_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1141 }
1142 }
1143 else{
1144 //整数
1145
1146 index_stack[sp]=GetLiteralIndex(i64data);
1147
1148 //mov reg,i64data
1149 compiler.codeGenerator.op_mov_RV64(UseReg,i64data);
1150
1151 if(UseReg==REG_R14){
1152 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1153 pobj_sf->push(REG_R14);
1154 }
1155 }
1156 }
1157
1158 if(bXmm) pobj_reg->LockXmmReg();
1159 else pobj_reg->LockReg();
1160
1161 sp++;
1162 break;
1163
1164 //論理演算子
1165 case CALC_XOR:
1166 case CALC_OR:
1167 case CALC_AND:
1168 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
1169 break;
1170 case CALC_NOT:
1171 //value[sp-1]=Not value[sp-1]
1172 //NOT演算子
1173 if(!Calc_Not(type_stack,sp)) goto error;
1174 break;
1175
1176 //比較演算子
1177 case CALC_PE: //value[sp-2] <= value[sp-1]
1178 case CALC_QE: //value[sp-2] >= value[sp-1]
1179 case CALC_P: //value[sp-2] < value[sp-1]
1180 case CALC_Q: //value[sp-2] > value[sp-1]
1181 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1182 case CALC_EQUAL: //value[sp-2] = value[sp-1]
1183 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
1184 break;
1185
1186 //ビットシフト
1187 case CALC_SHL: //value[sp-2] << value[sp-1]
1188 case CALC_SHR: //value[sp-2] >> value[sp-1]
1189 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
1190 break;
1191
1192 //算術演算
1193 case CALC_ADDITION:
1194 case CALC_SUBTRACTION:
1195 case CALC_PRODUCT:
1196 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1197 break;
1198 case CALC_MOD:
1199 //value[sp-2]%=value[sp-1]
1200 //剰余演算
1201 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
1202 break;
1203 case CALC_QUOTIENT:
1204 //value[sp-2]/=value[sp-1];
1205 //除算
1206 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1207 break;
1208 case CALC_INTQUOTIENT:
1209 //value[sp-2]/=value[sp-1]
1210 //整数除算
1211 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1212 break;
1213 case CALC_MINUSMARK:
1214 //value[sp-1]=-value[sp-1]
1215 //符号反転
1216 if(!Calc_MinusMark(type_stack,sp)) goto error;
1217 break;
1218 case CALC_POWER:
1219 //べき乗演算(浮動小数点演算のみ)
1220 if(!Calc_Power(type_stack,&sp)) goto error;
1221 break;
1222 case CALC_AS:
1223 //キャスト
1224 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1225 break;
1226 case CALC_BYVAL:
1227 //ポインタ型→参照型
1228 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1229 //ポインタ型ではないとき
1230 SetError( 3, NULL, cp );
1231 goto error;
1232 }
1233
1234 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1235
1236 break;
1237
1238 default:
1239 SetError(300,NULL,cp);
1240 goto error;
1241 }
1242 }
1243
1244 if(bError) goto error;
1245
1246 if(sp!=1){
1247 SetError(1,NULL,cp);
1248 goto error;
1249 }
1250
1251 if(bLiteralCalculation){
1252 SetError();
1253 }
1254 else{
1255 //右辺値が数値の定数式ではないとき
1256 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1257 }
1258
1259 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1260
1261 if(IsRealNumberType(type_stack[0]))
1262 *pReg=pobj_reg->UnlockXmmReg();
1263 else
1264 *pReg=pobj_reg->UnlockReg();
1265
1266
1267 resultType.SetType( type_stack[0], index_stack[0] );
1268
1269 bool isSuccessful = true;
1270 goto finish;
1271
1272
1273
1274 //////////////////
1275 // エラー処理
1276 //////////////////
1277
1278error:
1279
1280 isSuccessful = false;
1281 goto finish;
1282
1283
1284
1285
1286finish:
1287
1288 for(i=0;i<pnum;i++){
1289 if(values[i]) HeapDefaultFree(values[i]);
1290 }
1291
1292 return isSuccessful;
1293}
1294
1295bool NumOpe( int *pReg,
1296 const char *expression,
1297 const Type &baseType,
1298 Type &resultType,
1299 BOOL *pbUseHeap )
1300{
1301 BOOL bInitRegSwitch=0;
1302 if(!pobj_reg){
1303 bInitRegSwitch=1;
1304
1305 //作業用レジスタを取得
1306 pobj_reg=new CRegister(*pReg);
1307 }
1308
1309 //エラー時の復旧用
1310 CRegister objReg_Backup;
1311 objReg_Backup=*pobj_reg;
1312
1313 *pReg = pobj_reg->GetNextReg();
1314
1315
1316 bool result = _numope( pReg, expression, baseType, resultType, pbUseHeap );
1317
1318
1319 if( !result )
1320 {
1321 *pobj_reg=objReg_Backup;
1322 }
1323
1324 if(bInitRegSwitch){
1325 //整合性をチェック(バグ回避)
1326 if( result )
1327 {
1328 pobj_reg->bug_check();
1329 }
1330
1331 //作業レジスタを解放
1332 delete pobj_reg;
1333 pobj_reg=0;
1334 }
1335
1336 return result;
1337}
Note: See TracBrowser for help on using the repository browser.