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

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

関数の戻り値の構造体など、一時メモリに保持された構造体のメンバに直接アクセスした場合、その一時メモリの解放が正常に行われないバグを修正(64bit版も修正した)。

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