source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Var.cpp @ 538

Last change on this file since 538 was 538, checked in by dai_9181, 15 years ago

pCompilingMethodを排除。

File size: 35.4 KB
Line 
1#include "stdafx.h"
2
3#include <LexicalScope.h>
4#include <CodeGenerator.h>
5#include <Compiler.h>
6#include <Variable.h>
7
8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
11//変数
12// TODO: xml未完成
13int AllLocalVarSize;
14
15using namespace ActiveBasic::Compiler;
16
17void SetRelativeOffset( Type &resultType, RELATIVE_VAR *pRelativeVar,const char *lpPtrOffset){
18    PushLongVariable(pRelativeVar);
19
20    Type type;
21    NumOpe( lpPtrOffset, Type(), type );
22    ChangeTypeToLong( type.GetBasicType() );
23
24    //pop ebx
25    compiler.codeGenerator.op_pop(REG_EBX);
26
27    if( resultType.PtrLevel() ){
28        resultType.PtrLevelDown();
29
30        int typeSize = resultType.GetSize();
31        if(typeSize>=2){
32            //imul ebx,i2
33            compiler.codeGenerator.op_imul_RV( REG_EBX, typeSize );
34        }
35    }
36    else{
37        //エラー
38        compiler.errorMessenger.Output(1,NULL,cp);
39        return;
40    }
41
42    //pop ecx
43    compiler.codeGenerator.op_pop(REG_ECX);
44
45    //add ecx,ebx
46    compiler.codeGenerator.op_add_RR( REG_ECX, REG_EBX );
47}
48void SetRelativeOffset( RELATIVE_VAR &relativeVar ){
49    if(relativeVar.dwKind==VAR_DIRECTMEM){
50        //mov ecx,dword ptr[ecx]
51        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, 0, MOD_BASE );
52    }
53    else{
54        //直接参照に切り替え
55        SetVarPtrToEax(&relativeVar);
56        relativeVar.dwKind=VAR_DIRECTMEM;
57
58        //mov ecx,dword ptr[eax]
59        compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
60    }
61}
62bool GetArrayOffset(const Subscripts &subscripts,char *array, const Type &type){
63    extern HANDLE hHeap;
64    int i,i2,i3,i4;
65    char temporary[VN_SIZE],*pParm[MAX_PARMS];
66
67    for(i=0,i2=0,i3=0;;i++,i2++){
68        if(array[i]=='('){
69            i4=GetStringInPare(temporary+i2,array+i);
70            i+=i4-1;
71            i2+=i4-1;
72            continue;
73        }
74        if(array[i]=='['){
75            i4=GetStringInBracket(temporary+i2,array+i);
76            i+=i4-1;
77            i2+=i4-1;
78            continue;
79        }
80        if(array[i]==','||array[i]=='\0'){
81            if( i3 >= (int)subscripts.size() )
82            {
83                for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
84                return 0;
85            }
86
87            temporary[i2]=0;
88
89            pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
90            lstrcpy(pParm[i3],temporary);
91
92            i3++;
93
94            if(array[i]=='\0'){
95                if( i3 < (int)subscripts.size() )
96                {
97                    for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
98                    return 0;
99                }
100                break;
101            }
102
103            i2=-1;
104            continue;
105        }
106        temporary[i2]=array[i];
107    }
108
109    //push ecx
110    compiler.codeGenerator.op_push(REG_ECX);
111
112    //push 0
113    compiler.codeGenerator.op_push_V(0);
114
115    for(i=i3-1;i>=0;i--){
116        Type tempType;
117        bool isNeedHeapFreeStructure;
118        NumOpe( pParm[i], Type( DEF_LONG ), tempType, &isNeedHeapFreeStructure );
119        if( tempType.IsObject() )
120        {
121            //キャスト演算子のオーバーロードに対応する
122            CallCastOperatorProc(
123                tempType,
124                isNeedHeapFreeStructure, Type(DEF_LONG) );
125            tempType.SetBasicType( DEF_LONG );
126        }
127        ChangeTypeToLong( tempType.GetBasicType() );
128
129        //pop eax
130        compiler.codeGenerator.op_pop(REG_EAX);
131
132        for( i2=i+1, i4=1; i2<i3; i2++ )
133        {
134            i4*=subscripts[i2]+1;
135        }
136
137        //imul eax,i4
138        compiler.codeGenerator.op_imul_RV( REG_EAX, i4 );
139
140        //add dword ptr[esp],eax
141        compiler.codeGenerator.PutOld(
142            (char)0x01,
143            (char)0x04,
144            (char)0x24
145        );
146
147        HeapDefaultFree(pParm[i]);
148    }
149
150    //pop eax
151    compiler.codeGenerator.op_pop(REG_EAX);
152
153    //imul eax,TypeSize
154    compiler.codeGenerator.op_imul_RV( REG_EAX, type.GetSize() );
155
156    //pop ecx
157    compiler.codeGenerator.op_pop(REG_ECX);
158
159    //add ecx,eax
160    compiler.codeGenerator.op_add_RR( REG_ECX, REG_EAX );
161
162    return 1;
163}
164bool _member_offset(bool isErrorEnabled, bool isWriteAccess, const Type &classType, const char *member, RELATIVE_VAR *pRelativeVar, Type &resultType, BOOL bPrivateAccess)
165{
166    const CClass &objClass = classType.GetClass();
167
168    //////////////////////////////////////
169    // クラス、配列の構成要素を解析する
170    //////////////////////////////////////
171
172    char VarName[VN_SIZE];      //変数名
173    char array[VN_SIZE];        //第1次配列
174    char lpPtrOffset[VN_SIZE];  //第2次配列
175    char NestMember[VN_SIZE];   //入れ子メンバ
176    ReferenceKind refType;
177    lstrcpy(VarName,member);
178    if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false;
179
180
181    ////////////////////////////
182    // メンバオフセットを取得
183    ////////////////////////////
184
185    const CMember *pMember = objClass.FindDynamicMember( VarName );
186    if( !pMember )
187    {
188        if(isErrorEnabled) compiler.errorMessenger.Output(103,VarName,cp);
189        return false;
190    }
191
192    int offset = objClass.GetMemberOffset( VarName );
193
194
195    //アクセシビリティをチェック
196    if( compiler.IsCompilingClass() && &objClass == &compiler.GetCompilingClass() ){
197        //同一クラスオブジェクトの場合はプライベートアクセスを容認する
198        if(pMember->IsNoneAccess()){
199            if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp);
200            return false;
201        }
202    }
203    else{
204        if((bPrivateAccess==0&&pMember->IsPrivate())||
205            pMember->IsNoneAccess()){
206            if(isErrorEnabled) compiler.errorMessenger.Output(107,VarName,cp);
207            return false;
208        }
209        else if(bPrivateAccess==0&&pMember->IsProtected()){
210            if(isErrorEnabled) compiler.errorMessenger.Output(108,VarName,cp);
211            return false;
212        }
213    }
214
215    //Const定義の場合は書き込みアクセスを制限する
216    //※コンストラクタをコンパイル中の場合は例外的に許可する
217    if( pMember->IsConst() &&       //定数メンバである
218        isWriteAccess &&                            //書き込みアクセスを要求されている
219        objClass.IsCompilingConstructor() == false  //コンストラクタ コンパイル中を除く
220        ){
221            //Const定義の変数に書き込みアクセスをしようとした場合
222            compiler.errorMessenger.Output(61,VarName,cp);
223    }
224
225    resultType = pMember->GetType();
226
227    // 型パラメータを解決
228    ResolveFormalGenericTypeParameter( resultType, classType );
229
230
231    //ポインタ変数の場合
232    if( resultType.IsPointer() ){
233        if( pMember->GetSubscripts().size() == 0 ){
234            lstrcpy(lpPtrOffset,array);
235            array[0]=0;
236        }
237    }
238    else{
239        if(lpPtrOffset[0]){
240            if(isErrorEnabled) compiler.errorMessenger.Output(16,member,cp);
241            return false;
242        }
243    }
244
245    if(offset){
246        //add ecx,offset
247        compiler.codeGenerator.op_add_RV( REG_ECX, offset );
248    }
249
250    if(array[0]){
251        //配列オフセット
252        if(!GetArrayOffset(pMember->GetSubscripts(),array,pMember->GetType())){
253            if(isErrorEnabled) compiler.errorMessenger.Output(14,member,cp);
254            return false;
255        }
256    }
257    else if( pMember->GetSubscripts().size() > 0 ){
258        resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
259    }
260
261    if(NestMember[0]){
262        //入れ子構造の場合
263
264        if( resultType.IsObject() || resultType.IsStruct() ){
265            if( refType != RefDot ){
266                if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
267                return false;
268            }
269
270            if( resultType.IsObject() ){
271                // 参照内容へのポインタを抽出
272                SetRelativeOffset( *pRelativeVar );
273            }
274        }
275        else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
276            //構造体ポインタ型メンバ変数
277
278            if(lpPtrOffset[0]){
279                //pObj[n].member
280                if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() )
281                    && refType != RefDot ){
282                        if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
283                        return false;
284                }
285
286                //直接参照に切り替え
287                SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
288                pRelativeVar->dwKind=VAR_DIRECTMEM;
289
290                lpPtrOffset[0]=0;
291            }
292            else{
293                //pObj->member
294                if( ( resultType.IsObjectPtr() || resultType.IsStructPtr() )
295                    && refType != RefPointer ){
296                        if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
297                        return false;
298                }
299
300                SetRelativeOffset( *pRelativeVar );
301            }
302        }
303        else if( resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_OBJECT,2)
304            || resultType.GetBasicType() == MAKE_PTR_TYPE(DEF_STRUCT,2)){
305            //構造体ポインタのポインタ型メンバ変数
306
307            if(lpPtrOffset[0]){
308                //ppObj[n]->member
309                if( refType != RefPointer ){
310                    if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
311                    return false;
312                }
313
314                //直接参照に切り替え
315                SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
316                pRelativeVar->dwKind=VAR_DIRECTMEM;
317
318                lpPtrOffset[0]=0;
319
320                //mov ecx,dword ptr[ecx]
321                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_ECX, 0, MOD_BASE );
322            }
323            else{
324                if(isErrorEnabled) compiler.errorMessenger.Output(104,member,cp);
325                return false;
326            }
327        }
328
329        if(!_member_offset(
330            isErrorEnabled,
331            isWriteAccess,
332            pMember->GetType(),
333            NestMember,
334            pRelativeVar,
335            resultType,
336            0)) return false;
337    }
338
339    if(lpPtrOffset[0]){
340        SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
341        pRelativeVar->dwKind=VAR_DIRECTMEM;
342    }
343
344    return true;
345}
346
347int LocalVar_ThisPtrOffset;
348void SetThisPtrToReg(int reg){
349    //自身のオブジェクトのThisポインタをregにコピー
350
351    RELATIVE_VAR RelativeVar;
352    RelativeVar.dwKind=VAR_LOCAL;
353    RelativeVar.bOffsetOffset=0;
354    RelativeVar.offset=-LocalVar_ThisPtrOffset;
355
356    SetReg_WholeVariable(Type(DEF_PTR_VOID),&RelativeVar,reg);
357}
358
359bool GetVarOffset(bool isErrorEnabled,bool isWriteAccess,const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType, Subscripts *pResultSubscripts ){
360    char variable[VN_SIZE];
361
362    if(NameBuffer[0]=='.'){
363        GetWithName(variable);
364        lstrcat(variable,NameBuffer);
365    }
366    else lstrcpy(variable,NameBuffer);
367
368    // 名前空間を分離
369    char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE];
370    compiler.GetObjectModule().meta.GetNamespaces().SplitNamespace( variable, namespaceStr, simpleName );
371
372    // 先頭オブジェクトまたはクラス名と入れ子メンバに分割
373    ReferenceKind refType;
374    char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
375    GetVarFormatString(simpleName,array,lpPtrOffset,member,refType);
376
377    // 名前空間を分離していた場合は結合
378    char VarName[VN_SIZE];
379    if( namespaceStr[0] ){
380        sprintf( VarName, "%s.%s", namespaceStr, simpleName );
381    }
382    else{
383        lstrcpy( VarName, simpleName );
384    }
385
386    const Subscripts *pSubscripts;
387    bool bConst = false;
388
389
390    if( compiler.IsLocalAreaCompiling() ){
391        //////////////////
392        // ローカル変数
393        //////////////////
394
395        const Variable *pVar = compiler.GetCompilingUserProc().GetLocalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ) );
396        if( pVar ){
397            //ポインタ変数の場合
398            if( pVar->GetType().IsPointer() ){
399                if( !pVar->IsArray() ){
400                    lstrcpy(lpPtrOffset,array);
401                    array[0]=0;
402                }
403            }
404            else{
405                if(lpPtrOffset[0]){
406                    compiler.errorMessenger.Output(16,variable,cp);
407                    pRelativeVar->dwKind=NON_VAR;
408                    return false;
409                }
410            }
411
412            pRelativeVar->offset=-pVar->GetOffsetAddress();
413            pRelativeVar->bOffsetOffset=0;
414            if( pVar->IsRef() ){
415                // 参照型
416                pRelativeVar->dwKind = VAR_REFLOCAL;
417            }
418            else pRelativeVar->dwKind=VAR_LOCAL;
419            resultType = pVar->GetType();
420            pSubscripts = &pVar->GetSubscripts();
421            bConst = pVar->IsConst();
422
423
424            /////////////////////////////////////////////////////////
425            // ☆★☆ ジェネリクスサポート ☆★☆
426
427            if( resultType.IsTypeParameter() )
428            {
429                // 型パラメータだったとき
430
431                int ptrLevel = PTR_LEVEL( resultType.GetBasicType() );
432
433                // 制約クラス(指定されていないときはObjectクラス)にセットする
434                resultType.SetBasicType( DEF_OBJECT );
435
436                for( int i=0; i<ptrLevel; i++ )
437                {
438                    resultType.PtrLevelUp();
439                }
440            }
441
442            //
443            /////////////////////////////////////////////////////////
444
445            goto ok;
446        }
447    }
448
449    if( compiler.IsCompilingClass() ){
450        //////////////////////
451        // クラスメンバの参照
452        //////////////////////
453
454        if(lstrcmpi(variable,"This")==0){
455            //Thisオブジェクト
456
457            //Thisポインタをecxにコピー
458            SetThisPtrToReg(REG_ECX);
459
460            pRelativeVar->dwKind=VAR_DIRECTMEM;
461
462            resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() );
463            return true;
464        }
465
466        if(memicmp(variable,"This.",5)==0){
467            //Thisオブジェクトのメンバを参照するとき
468            SlideString(variable+5,-5);
469            lstrcpy(VarName,variable);
470        }
471        else{
472            //クラス内の動的メンバを参照するとき(通常)
473
474            if( !compiler.GetCompilingClass().HasDynamicMember( VarName ) )
475            {
476                goto NonClassMember;
477            }
478        }
479
480        //Const修飾子のメソッド内でメンバ書き込みアクセスが発生したとき
481        //(コンストラクタ、デストラクタ内を除く)
482        const CMethod *pMethod = &compiler.GetCompilingUserProc().GetMethod();
483        if( isWriteAccess &&
484            pMethod->IsConst() &&
485            compiler.GetCompilingClass().IsCompilingConstructor() == false &&
486            compiler.GetCompilingClass().IsCompilingDestructor() == false
487            ){
488                compiler.errorMessenger.Output(131, NULL, cp );
489        }
490
491        /////////////////////////////
492        // thisポインタをecxにセット
493
494        //Thisポインタをecxにコピー
495        SetThisPtrToReg(REG_ECX);
496
497        pRelativeVar->dwKind=VAR_DIRECTMEM;
498        if(!_member_offset(
499            isErrorEnabled,
500            isWriteAccess,
501            Type( DEF_OBJECT, compiler.GetCompilingClass() ),
502            variable,
503            pRelativeVar,
504            resultType,1)) return false;
505        return true;
506    }
507
508NonClassMember:
509
510    {
511        const Variable *pVar;
512
513        //////////////////////////
514        // 静的ローカル変数
515        // ※"Static.Object.Method.Variable"
516        //////////////////////////
517
518        char temporary[VN_SIZE];
519        if( compiler.IsLocalAreaCompiling() ){
520            GetNowStaticVarFullName(VarName,temporary);
521
522            pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temporary ) );
523            if( pVar ){
524                goto GlobalOk;
525            }
526        }
527
528
529        //////////////////////////
530        // クラスの静的メンバ
531        //////////////////////////
532
533        if(member[0]){
534            lstrcpy(temporary,member);
535
536            // TODO: 名前空間を考慮したコードになっていない
537
538            char tempMember[VN_SIZE];
539            char tempArray[VN_SIZE];
540            {
541                ReferenceKind refType;
542                GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember, refType );
543            }
544
545            int typeDefIndex = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( VarName );
546            if( typeDefIndex != -1 ){
547                // TypeDef後の型名だったとき
548                lstrcpy( VarName, compiler.GetObjectModule().meta.GetTypeDefs()[typeDefIndex].GetBaseName().c_str() );
549            }
550
551            char temp2[VN_SIZE];
552            sprintf(temp2,"%s.%s",VarName,temporary);
553            pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
554            if( pVar ){
555                lstrcpy(member,tempMember);
556                lstrcpy(array,tempArray);
557                goto GlobalOk;
558            }
559        }
560
561        if( compiler.IsCompilingClass() ){
562            //自身のクラスから静的メンバを参照する場合
563            char temp2[VN_SIZE];
564            sprintf(temp2,"%s.%s",compiler.GetCompilingClass().GetName().c_str(),VarName);
565            pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( temp2 ) );
566            if( pVar ){
567                goto GlobalOk;
568            }
569        }
570
571        /////////////////////
572        // グローバル変数
573        /////////////////////
574
575        pVar = compiler.GetObjectModule().meta.GetGlobalVars().BackSearch( LexicalAnalyzer::FullNameToSymbol( VarName ) );
576        if( pVar ){
577            goto GlobalOk;
578        }
579
580        if(isErrorEnabled) compiler.errorMessenger.Output(3,variable,cp);
581        pRelativeVar->dwKind=NON_VAR;
582        return false;
583
584
585
586GlobalOk:
587        //ポインタ変数の場合
588        if( pVar->GetType().IsPointer() ){
589            if( !pVar->IsArray() ){
590                lstrcpy(lpPtrOffset,array);
591                array[0]=0;
592            }
593        }
594        else{
595            if(lpPtrOffset[0]){
596                compiler.errorMessenger.Output(16,variable,cp);
597                pRelativeVar->dwKind=NON_VAR;
598                return false;
599            }
600        }
601
602        pRelativeVar->offset=pVar->GetOffsetAddress();
603        pRelativeVar->bOffsetOffset=0;
604        if( pVar->IsRef() ){
605            // 参照型
606            pRelativeVar->dwKind = VAR_REFGLOBAL;
607        }
608        else pRelativeVar->dwKind=VAR_GLOBAL;
609        resultType = pVar->GetType();
610        pSubscripts=&pVar->GetSubscripts();
611        bConst = pVar->IsConst();
612    }
613
614
615
616ok:
617
618    if( bConst && isWriteAccess ){
619        //Const定義の変数に書き込みアクセスをしようとした場合
620        if( resultType.IsObject() ){
621            //オブジェクト定数
622            compiler.errorMessenger.Output(130, VarName, cp );
623        }
624        else{
625            //一般のConst変数
626            compiler.errorMessenger.Output(61,VarName,cp);
627        }
628    }
629
630    if( array[0] == 0 && pSubscripts->size() > 0 ){
631        //配列の先頭ポインタを示す場合
632        resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
633
634        if( pResultSubscripts )
635        {
636            (*pResultSubscripts) = *pSubscripts;
637        }
638        return true;
639    }
640
641    if(array[0]||member[0]){
642        //xor ecx,ecx(ecxを0に初期化する)
643        //※ecxは変数ベースアドレスからの相対オフセットを示す
644        compiler.codeGenerator.op_zero_reg(REG_ECX);
645
646        pRelativeVar->bOffsetOffset=1;
647    }
648    if(array[0]){
649        if(!GetArrayOffset(*pSubscripts,array,resultType)){
650            compiler.errorMessenger.Output(14,variable,cp);
651            pRelativeVar->dwKind=NON_VAR;
652            return false;
653        }
654    }
655    if(member[0]){
656        if( resultType.IsObject() || resultType.IsStruct() ){
657            //実態オブジェクトのメンバを参照(obj.member)
658            if( refType != RefDot ){
659                compiler.errorMessenger.Output(104,VarName,cp);
660                pRelativeVar->dwKind=NON_VAR;
661                return false;
662            }
663
664            if( resultType.IsObject() ){
665                // 参照内容へのポインタを抽出
666                SetRelativeOffset( *pRelativeVar );
667            }
668        }
669        else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
670            //ポインタオブジェクトが示すメンバを参照
671            if(lpPtrOffset[0]){
672                //pObj[n].member
673                if( refType != RefDot ){
674                    compiler.errorMessenger.Output(104,VarName,cp);
675                    pRelativeVar->dwKind=NON_VAR;
676                    return false;
677                }
678                SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
679                pRelativeVar->dwKind=VAR_DIRECTMEM;
680            }
681            else{
682                //pObj->member
683                if( refType != RefPointer ){
684                    compiler.errorMessenger.Output(104,VarName,cp);
685                    pRelativeVar->dwKind=NON_VAR;
686                    return false;
687                }
688
689                SetVarPtrToEax(pRelativeVar);
690                pRelativeVar->dwKind=VAR_DIRECTMEM;
691
692                //mov ecx,dword ptr[eax]
693                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
694            }
695        }
696        else if( resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_OBJECT,2) || resultType.GetBasicType()==MAKE_PTR_TYPE(DEF_STRUCT,2)){
697            //ポインタオブジェクトが示すメンバを参照
698            if(lpPtrOffset[0]){
699                //ppObj[n]->member
700                if( refType != RefPointer ){
701                    compiler.errorMessenger.Output(104,VarName,cp);
702                    pRelativeVar->dwKind=NON_VAR;
703                    return false;
704                }
705
706                SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
707                pRelativeVar->dwKind=VAR_DIRECTMEM;
708
709
710                SetVarPtrToEax(pRelativeVar);
711
712                //mov ecx,dword ptr[eax]
713                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
714            }
715            else{
716                compiler.errorMessenger.Output(104,VarName,cp);
717                pRelativeVar->dwKind=NON_VAR;
718                return false;
719            }
720        }
721        else{
722            compiler.errorMessenger.Output(102,VarName,cp);
723            pRelativeVar->dwKind=NON_VAR;
724            return false;
725        }
726
727        Type classType( resultType );
728
729        if(!_member_offset(
730            isErrorEnabled,
731            isWriteAccess,
732            classType,
733            member,pRelativeVar,resultType,0)) return false;
734
735        return true;
736    }
737
738    if(lpPtrOffset[0]){
739        SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
740        pRelativeVar->dwKind=VAR_DIRECTMEM;
741    }
742
743    return true;
744}
745
746bool SetInitGlobalData(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
747    int i2,i3;
748    char temporary[VN_SIZE];
749    char InitBuf[VN_SIZE];
750    lstrcpy( InitBuf, lpszInitBuf );
751
752    if(InitBuf[0]=='['){
753        SlideString(InitBuf+1,-1);
754        InitBuf[lstrlen(InitBuf)-1]=0;
755
756        int typeSize = type.GetSize();
757
758        if( subscripts.size() > 0 ){
759            Subscripts nestSubscripts;
760            for( int i=1; i<(int)subscripts.size(); i++ )
761            {
762                nestSubscripts.push_back( subscripts[i] );
763            }
764
765            typeSize*=JumpSubScripts( nestSubscripts );
766            {
767                int i=0;
768                i2=0;
769                while(1){
770                    if( subscripts[0] < i2 ){
771                        compiler.errorMessenger.Output(41,0,cp);
772                        return 0;
773                    }
774                    i=GetOneParameter(InitBuf,i,temporary);
775                    if(!SetInitGlobalData(
776                        offset+i2*typeSize,
777                        type,
778                        nestSubscripts,
779                        temporary)) return false;
780                    i2++;
781                    if(InitBuf[i]=='\0') break;
782                }
783            }
784            return true;
785        }
786
787        if(type.IsStruct()){
788            const CClass &objClass = type.GetClass();
789
790            int i = 0;
791            BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
792                if(InitBuf[i]=='\0'){
793                    compiler.errorMessenger.Output(41,0,cp);
794                    return false;
795                }
796
797                i=GetOneParameter(InitBuf,i,temporary);
798
799                i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
800
801                if(!SetInitGlobalData(offset+i3,
802                    pMember->GetType(),
803                    pMember->GetSubscripts(),
804                    temporary)) return false;
805            }
806            return true;
807        }
808
809        compiler.errorMessenger.Output(41,0,cp);
810        return false;
811    }
812
813
814    ///////////////////////////////////////
815    // 単発式([]で囲まれていない)
816    ///////////////////////////////////////
817
818    if( subscripts.size() > 0 ){
819        compiler.errorMessenger.Output(41,0,cp);
820        return false;
821    }
822
823    double dbl;
824    _int64 i64data;
825    Type calcType;
826
827    if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
828        //動的データだった場合
829        return false;
830    }
831    if( calcType.IsReal() ){
832        memcpy(&dbl,&i64data,sizeof(double));
833        i64data=(_int64)dbl;
834    }
835    else dbl=(double)i64data;
836
837    //型チェック
838    CheckDifferentType(
839        type,
840        calcType,
841        0,0);
842
843    if( type.IsDouble() ){
844        compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
845            offset,
846            (const char *)&dbl,
847            sizeof(double)
848        );
849    }
850    else if( type.IsSingle() ){
851        float flt = (float)dbl;
852        compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
853            offset,
854            (const char *)&flt,
855            sizeof(float)
856        );
857    }
858    else if( type.Is64() ){
859        compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
860            offset,
861            (const char *)&i64data,
862            sizeof(_int64)
863        );
864    }
865    else if( type.IsLong() || type.IsDWord() || type.IsPointer() ){
866        if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
867        {
868            //文字列定数のとき
869
870            char *temp;
871            temp=(char *)i64data;
872            i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
873            HeapDefaultFree(temp);
874
875            //mov eax,DataPos
876            compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
877
878            //mov dword ptr[offset],eax
879            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, 0, offset, MOD_DISP32, Schedule::GlobalVar );
880        }
881        else{
882            long l = (long)i64data;
883            compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
884                offset,
885                (const char *)&l,
886                sizeof(long)
887            );
888        }
889    }
890    else if( type.IsWord() || type.IsInteger() ){
891        short s = (short)i64data;
892        compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
893            offset,
894            (const char *)&s,
895            sizeof(short)
896        );
897    }
898    else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
899        char c = (char)i64data;
900        compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.Overwrite(
901            offset,
902            (const char *)&c,
903            sizeof(char)
904        );
905    }
906
907    return true;
908}
909bool InitLocalVar(int offset,const Type &type,const Subscripts &subscripts,const char *lpszInitBuf){
910    int i2,i3;
911    char temporary[VN_SIZE];
912    char InitBuf[VN_SIZE];
913    lstrcpy( InitBuf, lpszInitBuf );
914
915    if(InitBuf[0]=='['){
916        SlideString(InitBuf+1,-1);
917        InitBuf[lstrlen(InitBuf)-1]=0;
918
919        int typeSize = type.GetSize();
920
921        if( subscripts.size() > 0 ){
922            Subscripts nestSubscripts;
923            for( int i=1; i<(int)subscripts.size(); i++ )
924            {
925                nestSubscripts.push_back( subscripts[i] );
926            }
927
928            typeSize*=JumpSubScripts( nestSubscripts );
929            {
930                int i=0;
931                i2=0;
932                while(1){
933                    if( subscripts[0] < i2 ){
934                        compiler.errorMessenger.Output(41,0,cp);
935                        return 0;
936                    }
937                    i=GetOneParameter(InitBuf,i,temporary);
938                    if(!InitLocalVar(
939                        offset+i2*typeSize,
940                        type,
941                        nestSubscripts,
942                        temporary)) return false;
943                    i2++;
944                    if(InitBuf[i]=='\0') break;
945                }
946            }
947            return true;
948        }
949
950        if(type.IsStruct()){
951            const CClass &objClass = type.GetClass();
952
953            int i = 0;
954            BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
955                if(InitBuf[i]=='\0'){
956                    compiler.errorMessenger.Output(41,0,cp);
957                    return false;
958                }
959
960                i=GetOneParameter(InitBuf,i,temporary);
961
962                i3=objClass.GetMemberOffset( pMember->GetName().c_str() );
963
964                if(!InitLocalVar(offset+i3,
965                    pMember->GetType(),
966                    pMember->GetSubscripts(),
967                    temporary)) return false;
968
969                if(InitBuf[i]=='\0') break;
970            }
971            return true;
972        }
973
974        compiler.errorMessenger.Output(41,0,cp);
975        return false;
976    }
977
978
979    ///////////////////////////////////////
980    // 単発式([]で囲まれていない)
981    ///////////////////////////////////////
982
983    if( subscripts.size() > 0 ){
984        compiler.errorMessenger.Output(41,0,cp);
985        return false;
986    }
987
988    double dbl;
989    _int64 i64data;
990    Type calcType;
991
992    if( !StaticCalculation(false, InitBuf,type.GetBasicType(),&i64data,calcType) ){
993        //動的データだった場合
994        return false;
995    }
996    if( calcType.IsReal() ){
997        memcpy(&dbl,&i64data,sizeof(double));
998        i64data=(_int64)dbl;
999    }
1000    else dbl=(double)i64data;
1001
1002    //型チェック
1003    CheckDifferentType(
1004        type,
1005        calcType,
1006        0,0);
1007
1008    if( type.IsDouble() ){
1009        //mov eax,HILONG(dbl)
1010        compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&dbl))+4) );
1011
1012        //mov dword ptr[ebp+offset+sizeof(long)],eax
1013        compiler.codeGenerator.localVarPertialSchedules.push_back(
1014            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1015        );
1016
1017        //mov eax,LOLONG(dbl)
1018        compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&dbl) );
1019
1020        //mov dword ptr[ebp+offset],eax
1021        compiler.codeGenerator.localVarPertialSchedules.push_back(
1022            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1023        );
1024    }
1025    else if( type.IsSingle() ){
1026        float flt;
1027        flt=(float)dbl;
1028
1029        //mov eax,InitValue
1030        compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)&flt );
1031
1032        //mov dword ptr[ebp+offset],eax
1033        compiler.codeGenerator.localVarPertialSchedules.push_back(
1034            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1035        );
1036    }
1037    else if( type.Is64() ){
1038        //mov eax,HILONG(i64data)
1039        compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(((char *)(&i64data))+4) );
1040
1041        //mov dword ptr[ebp+offset+sizeof(long)],eax
1042        compiler.codeGenerator.localVarPertialSchedules.push_back(
1043            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset+sizeof(long), MOD_BASE_DISP32, Schedule::None, true )
1044        );
1045
1046        //mov eax,LOLONG(i64data)
1047        compiler.codeGenerator.op_mov_RV( REG_EAX, *(long *)(&i64data) );
1048
1049        //mov dword ptr[ebp+offset],eax
1050        compiler.codeGenerator.localVarPertialSchedules.push_back(
1051            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1052        );
1053    }
1054    else if( type.IsDWord() || type.IsLong() || type.IsPointer() ){
1055        if( type.GetBasicType() == typeOfPtrChar && calcType.GetIndex() == LITERAL_STRING )
1056        {
1057            //文字列定数のとき
1058
1059            char *temp;
1060            temp=(char *)i64data;
1061            i2=compiler.GetObjectModule().dataTable.AddString(temp,lstrlen(temp));
1062            HeapDefaultFree(temp);
1063
1064            //mov eax,DataPos
1065            compiler.codeGenerator.op_mov_RV( REG_EAX, i2, Schedule::DataTable );
1066        }
1067        else{
1068            //mov eax,InitValue
1069            compiler.codeGenerator.op_mov_RV( REG_EAX, (long)i64data );
1070        }
1071
1072        //mov dword ptr[ebp+offset],eax
1073        compiler.codeGenerator.localVarPertialSchedules.push_back(
1074            compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_EBP, offset, MOD_BASE_DISP32, Schedule::None, true )
1075        );
1076    }
1077    else if( type.IsWord() || type.IsInteger() ){
1078        //mov word ptr[ebp+offset],InitValue
1079        compiler.codeGenerator.localVarPertialSchedules.push_back(
1080            compiler.codeGenerator.op_mov_MV( sizeof(short), REG_EBP, offset, Schedule::None, true, (long)i64data )
1081        );
1082    }
1083    else if( type.IsSByte() || type.IsByte() || type.IsBoolean() ){
1084        //mov byte ptr[ebp+offset],InitValue
1085        compiler.codeGenerator.localVarPertialSchedules.push_back(
1086            compiler.codeGenerator.op_mov_MV( sizeof(char), REG_EBP, offset, Schedule::None, true, (long)i64data )
1087        );
1088    }
1089
1090    return true;
1091}
1092
1093void dim( char *VarName, const Subscripts &subscripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlags){
1094    if( compiler.IsGlobalAreaCompiling() ){
1095        /////////////////////////
1096        // グローバル変数
1097        /////////////////////////
1098
1099        AddGlobalVariable(VarName,subscripts,type,InitBuf,ConstractParameter,dwFlags);
1100    }
1101    else{
1102        /////////////////
1103        // ローカル変数
1104        /////////////////
1105
1106        if( compiler.GetCompilingUserProc().GetLocalVars().DuplicateCheck( LexicalAnalyzer::FullNameToSymbol( VarName ) ) ){
1107            //2重定義のエラー
1108            compiler.errorMessenger.Output(15,VarName,cp);
1109            return;
1110        }
1111
1112        bool isConst = ( dwFlags & DIMFLAG_CONST ) ? true:false;
1113
1114        Variable *pVar = new Variable( VarName, type, isConst, false, ConstractParameter, false );
1115
1116        if( subscripts.size() > 0 ){
1117            //配列あり
1118            pVar->SetArray( subscripts );
1119        }
1120
1121        //レキシカルスコープ
1122        pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1123        pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1124        pVar->isLiving = true;
1125
1126        //エラー用
1127        pVar->source_code_address=cp;
1128
1129        // 変数を追加
1130        compiler.GetCompilingUserProc().GetLocalVars().push_back( pVar );
1131
1132        //アラインメントを考慮
1133        if( pVar->GetType().IsStruct() ){
1134            int alignment = pVar->GetType().GetClass().GetFixedAlignment();
1135
1136            if( alignment ){
1137                if( AllLocalVarSize % alignment ){
1138                    AllLocalVarSize += alignment - (AllLocalVarSize % alignment);
1139                }
1140            }
1141
1142            if( alignment == PTR_SIZE*2 ){
1143                // ポインタに要するサイズよりも一回り大きなアラインメントが指定されているとき
1144                // (例:CONTEXT構造体など)
1145                // 呼び出し側のオフセットズレを考慮する
1146
1147                if( 0 == ( compiler.GetCompilingUserProc().RealParams().GetMemorySize() + PTR_SIZE /* ret分 */ ) % alignment ){
1148                    AllLocalVarSize += PTR_SIZE;
1149                }
1150            }
1151        }
1152
1153        AllLocalVarSize += pVar->GetMemorySize();
1154        pVar->SetOffsetAddress( AllLocalVarSize );
1155
1156        //レキシカルスコープ
1157        pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
1158        pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
1159        pVar->isLiving = true;
1160
1161        if(InitBuf[0]){
1162            //初期代入時のみ、書き込みアクセスを許可する
1163            if( isConst ){
1164                pVar->ConstOff();
1165            }
1166
1167            int result = 0;
1168            if( !pVar->GetType().IsObject() ){
1169                result = InitLocalVar(-pVar->GetOffsetAddress(),
1170                    pVar->GetType(),
1171                    pVar->GetSubscripts(),
1172                    InitBuf);
1173            }
1174
1175            if(!result){
1176                //動的な式だった場合は代入演算を行う
1177                char temporary[8192];
1178                sprintf(temporary,"%s=%s",VarName,InitBuf);
1179                OpcodeCalc(temporary);
1180            }
1181
1182            if( isConst ){
1183                pVar->ConstOn();
1184            }
1185        }
1186        else{
1187            //push 0
1188            compiler.codeGenerator.op_push_V(0);
1189
1190            //push VarSize
1191            compiler.codeGenerator.op_push_V( pVar->GetMemorySize() );
1192
1193            //mov eax,ebp
1194            compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EBP );
1195
1196            //add eax,offset
1197            compiler.codeGenerator.localVarPertialSchedules.push_back(
1198                compiler.codeGenerator.op_add_RV( REG_EAX, -pVar->GetOffsetAddress(), Schedule::None, true )
1199            );
1200
1201            //push eax
1202            compiler.codeGenerator.op_push(REG_EAX);
1203
1204            //call FillMemory
1205            compiler.codeGenerator.op_call( GetDeclareHash("FillMemory") );
1206        }
1207    }
1208
1209    //New呼び出し
1210    if( type.IsObject()
1211        && !type.IsInterface() &&  !type.IsComInterface()
1212        &&(dwFlags&DIMFLAG_NONCALL_CONSTRACTOR)==0
1213        &&InitBuf[0]=='\0')
1214    {
1215        char objectSize[255];
1216        if( subscripts.size() == 0 ){
1217            objectSize[0] = 0;
1218        }
1219        else{
1220            if( subscripts.size() > 1 ){
1221                compiler.errorMessenger.Output(300,NULL,cp);
1222            }
1223            sprintf( objectSize, "%d", subscripts[0] );
1224        }
1225        Operator_New( type.GetClass(), objectSize, ConstractParameter, type );
1226
1227        //pop eax
1228        compiler.codeGenerator.op_pop( REG_EAX );
1229
1230        RELATIVE_VAR RelativeVar;
1231        GetVarOffset( true, false, VarName, &RelativeVar, Type() );
1232        if( RelativeVar.dwKind == VAR_DIRECTMEM ){
1233            compiler.errorMessenger.OutputFatalError();
1234        }
1235        SetVariableFromEax( Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr() ), DEF_OBJECT, &RelativeVar );
1236    }
1237}
1238
1239void SetVarPtrToEax(RELATIVE_VAR *pRelativeVar){
1240    if(pRelativeVar->dwKind==VAR_GLOBAL){
1241        if(pRelativeVar->bOffsetOffset){
1242            //lea eax,dword ptr[ecx+offset]
1243            compiler.codeGenerator.op_lea_RM( REG_EAX, REG_ECX, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
1244        }
1245        else{
1246            //mov eax,offset
1247            compiler.codeGenerator.op_mov_RV( REG_EAX, pRelativeVar->offset, Schedule::GlobalVar );
1248        }
1249    }
1250    else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
1251        if(pRelativeVar->bOffsetOffset){
1252            //mov eax,ecx
1253            compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1254
1255            //add eax,dword ptr[offset]
1256            compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1257        }
1258        else{
1259            //mov eax,dword ptr[offset]
1260            compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_NON, (int)pRelativeVar->offset, MOD_DISP32, Schedule::GlobalVar );
1261        }
1262    }
1263    else if(pRelativeVar->dwKind==VAR_LOCAL){
1264        if(pRelativeVar->bOffsetOffset){
1265            //add ecx,offset
1266            compiler.codeGenerator.localVarPertialSchedules.push_back(
1267                compiler.codeGenerator.op_add_RV( REG_ECX, pRelativeVar->offset, Schedule::None, true )
1268            );
1269
1270            //lea eax,dword ptr[ebp+ecx]
1271            compiler.codeGenerator.PutOld(
1272                (char)0x8D,
1273                (char)0x44,
1274                (char)0x0D,
1275                (char)0x00
1276            );
1277        }
1278        else{
1279            //lea eax,dword ptr[ecx+offset]
1280            compiler.codeGenerator.localVarPertialSchedules.push_back(
1281                compiler.codeGenerator.op_lea_RM( REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1282            );
1283        }
1284    }
1285    else if(pRelativeVar->dwKind==VAR_REFLOCAL){
1286        if(pRelativeVar->bOffsetOffset){
1287            //mov eax,ecx
1288            compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1289
1290            //add eax,dword ptr[ebp+offset]
1291            compiler.codeGenerator.localVarPertialSchedules.push_back(
1292                compiler.codeGenerator.op_add_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1293            );
1294        }
1295        else{
1296            //mov eax,dword ptr[ebp+offset]
1297            compiler.codeGenerator.localVarPertialSchedules.push_back(
1298                compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EBP, pRelativeVar->offset, MOD_BASE_DISP32, Schedule::None, true )
1299            );
1300        }
1301    }
1302    else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
1303        //mov eax,ecx
1304        compiler.codeGenerator.op_mov_RR( REG_EAX, REG_ECX );
1305    }
1306}
1307void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar){
1308    if( reg != REG_EAX ){
1309        compiler.errorMessenger.OutputFatalError();
1310        //TODO: 未完成
1311    }
1312    SetVarPtrToEax( pRelativeVar );
1313}
1314
1315bool Compile_AddGlobalRootsForGc(){
1316    const UserProc *pUserProc_AddGlobalRootPtr = GetClassMethod( "_System_CGarbageCollection", "AddGlobalRootPtr" );
1317    if( !pUserProc_AddGlobalRootPtr ){
1318        compiler.errorMessenger.Output(3, "_System_CGarbageCollection.AddGlobalRootPtr", -1 );
1319        return false;
1320    }
1321
1322    BOOST_FOREACH( const Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
1323        if( pVar->GetType().IsObject() || pVar->GetType().IsPointer() || pVar->GetType().IsStruct() ){
1324            // オブジェクトまたはポインタだったとき
1325            // ※構造体も含む(暫定対応)
1326
1327            // 変数領域に要するLONG_PTR単位の個数を引き渡す
1328            compiler.codeGenerator.op_push_V( pVar->GetMemorySize()/PTR_SIZE );
1329
1330
1331            /////////////////////////////
1332            // ルートポインタを引き渡す
1333
1334            //mov eax,offset
1335            compiler.codeGenerator.op_mov_RV(REG_EAX,(int)pVar->GetOffsetAddress(), Schedule::GlobalVar );
1336
1337            //push eax
1338            compiler.codeGenerator.op_push( REG_EAX );
1339
1340            //
1341            /////////////////////////////
1342
1343
1344            /////////////////////////////
1345            // Thisポインタを引き渡す
1346
1347            SetThisPtrToReg(REG_EAX);
1348
1349            //push eax
1350            compiler.codeGenerator.op_push( REG_EAX );
1351
1352            //
1353            /////////////////////////////
1354
1355
1356            // call AddGlobalRootPtr
1357            compiler.codeGenerator.op_call( pUserProc_AddGlobalRootPtr );
1358        }
1359    }
1360
1361    return true;
1362}
Note: See TracBrowser for help on using the repository browser.