source: dev/trunk/ab5.0/abdev/compiler_x64/NumOpe.cpp@ 581

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

[522][527]を64bit版にマージ。

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