source: dev/trunk/abdev/BasicCompiler32/NumOpe.cpp@ 435

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

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

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