Changeset 435 in dev


Ignore:
Timestamp:
Mar 15, 2008, 1:20:13 PM (16 years ago)
Author:
dai_9181
Message:

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

Location:
trunk/abdev
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/abdev/BasicCompiler32/CParameter.cpp

    r331 r435  
    6565                //変数ではないとき
    6666                Type calcType;
    67                 NumOpe( Parms[i2], dummyType, calcType );
     67                BOOL bUseHeap;
     68                NumOpe( Parms[i2], dummyType, calcType, &bUseHeap );
    6869                //↑ここでスタックに積む
    6970
     
    8586                    i2);
    8687
    87                 if( result ){
     88                if( result && bUseHeap ){
    8889                    useTempParameters[i2] = true;
    8990                    useTempObject = true;
  • trunk/abdev/BasicCompiler32/Compile_Calc.cpp

    r415 r435  
    646646
    647647    SetVariableFromEax(varType,calcType.GetBasicType(),&VarRelativeVar);
    648 }
     648
     649
     650    // コード生成過程で発生した構造体の一時メモリを破棄する
     651    compiler.codeGenerator.op_FreeTempStructure();
     652}
  • trunk/abdev/BasicCompiler32/Compile_CallProc.cpp

    r420 r435  
    289289            if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
    290290            else{
    291                 bool isLiteral;
     291                bool isLiteral, isNeedHeapFreeStructure = false;
    292292                Type baseType( DEF_OBJECT, *pUserProc->GetParentClassPtr() ) , resultType;
    293                 if( !TermOpe( ObjectName, baseType, resultType, isLiteral, NULL, NULL, false, !pMethod->IsConst() ) )
     293                if( !TermOpe( ObjectName, baseType, resultType, isLiteral, isNeedHeapFreeStructure, NULL, false, !pMethod->IsConst() ) )
    294294                {
    295295                    return false;
     296                }
     297                if( !resultType.IsObject() )
     298                {
     299                    SetError();
    296300                }
    297301
  • trunk/abdev/BasicCompiler32/Compile_Statement.cpp

    r424 r435  
    9191
    9292    Type resultType;
    93     bool isLiteral;
    94     BOOL bUseHeap;
    95     bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, NULL, true );
     93    bool isLiteral, isNeedHeapFreeStructure = false;
     94    bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, true );
    9695    if( result ){
    9796
  • trunk/abdev/BasicCompiler32/MakePeHdr.cpp

    r422 r435  
    3333    *pSub_System_GC_malloc_ForObjectPtr,
    3434    *pSub_System_GC_free_for_SweepingDelete,
     35    *pSub_System_AddNeedFreeTempStructure,
     36    *pSub_System_FreeTempStructure,
    3537    *pSubStaticMethod_System_TypeBase_InitializeUserTypes,
    3638    *pSubStaticMethod_System_TypeBase_InitializeUserTypesForBaseType,
     
    273275    if( pSub_System_GC_free_for_SweepingDelete = GetSubHash( "_System_GC_free_for_SweepingDelete",1 ) )
    274276        pSub_System_GC_free_for_SweepingDelete->Using();
     277
     278    if( pSub_System_AddNeedFreeTempStructure = GetSubHash( "_System_AddNeedFreeTempStructure",1 ) )
     279    {
     280        pSub_System_AddNeedFreeTempStructure->Using();
     281    }
     282    if( pSub_System_FreeTempStructure = GetSubHash( "_System_FreeTempStructure",1 ) )
     283    {
     284        pSub_System_FreeTempStructure->Using();
     285    }
    275286
    276287    if( pSubStaticMethod_System_TypeBase_InitializeUserTypes = GetSubHash( "ActiveBasic.Core._System_TypeBase.InitializeUserTypes",1 ) ){
  • trunk/abdev/BasicCompiler32/NumOpe.cpp

    r429 r435  
    140140    return true;
    141141}
    142 bool TermMemberOpe( const Type &leftType, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool &isVariable, RELATIVE_VAR &relativeVar )
     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 )
    143143{
    144144    const CClass &objClass = leftType.GetClass();
     
    222222        // メンバが見つかったとき
    223223
     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
    224236        //オブジェクトポインタをecxにコピー
    225237        compiler.codeGenerator.op_mov_RR( REG_ECX, useReg );
     
    271283                bool dummyIsVariable;
    272284                RELATIVE_VAR dummyRelativeVar;
    273                 TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, methodName, dummyIsVariable, dummyRelativeVar );
     285                TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, methodName, dummyIsVariable, dummyRelativeVar );
    274286
    275287                // 戻り値のオブジェクトインスタンスのインデクサを呼び出す
     
    278290                sprintf( temp2, "%s.%s", termLeft, methodName );
    279291                Type classType = resultType;
    280                 return TermMemberOpe( classType, baseType, resultType, termFull, temp2, temporary, isVariable, relativeVar );
     292                return TermMemberOpe( classType, isNeedHeapFreeStructure, baseType, resultType, termFull, temp2, temporary, isVariable, relativeVar );
    281293            }
    282294
     
    336348    return false;
    337349}
    338 bool _TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool *pIsClassName, bool isProcedureCallOnly, bool &isVariable, RELATIVE_VAR &relativeVar, bool isWriteAccess )
     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 )
    339351{
    340352    char parameter[VN_SIZE];
     
    377389        }
    378390
    379         if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, &isClassName ) ){
     391        if( !TermOpe( termLeft, baseType, leftType, isLiteral, isNeedHeapFreeStructure, &isClassName ) ){
    380392            goto globalArea;
    381393        }
     
    395407        }
    396408
    397         return TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, member, isVariable, relativeVar );
     409        return TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, member, isVariable, relativeVar );
    398410    }
    399411globalArea:
     
    492504
    493505
    494             if(resultType.IsStruct()){
     506            if(resultType.IsStruct())
     507            {
    495508                //構造体が戻ったときはヒープ領域にインスタンスが格納されている
    496509                //※後にfreeする必要あり
    497510                // TODO: 解放はGCに任せる
    498                 *pbUseHeap = 1;
     511                isNeedHeapFreeStructure = true;
    499512            }
    500513
     
    603616
    604617
    605         if(resultType.IsStruct()){
     618        if(resultType.IsStruct())
     619        {
    606620            //構造体が戻ったときはヒープ領域にインスタンスが格納されている
    607621            //※後にfreeする必要あり
    608622            // TODO: 解放はGCに任せる
    609             *pbUseHeap = 1;
     623            isNeedHeapFreeStructure = true;
    610624        }
    611625
     
    623637}
    624638
    625 bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool *pIsClassName, bool isProcedureCallOnly, bool isWriteAccess )
     639bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool isWriteAccess )
    626640{
    627641    RELATIVE_VAR relativeVar;
    628642    bool isVariable = false;
    629     bool result = _TermOpe( term, baseType, resultType, isLiteral, pbUseHeap, pIsClassName, isProcedureCallOnly, isVariable, relativeVar, isWriteAccess );
     643    bool result = _TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructure, pIsClassName, isProcedureCallOnly, isVariable, relativeVar, isWriteAccess );
    630644
    631645    if( isVariable )
     
    641655bool TermOpeOnlyVariable( const char *term, Type &resultType, RELATIVE_VAR &relativeVar, bool isWriteAccess )
    642656{
    643     bool isLiteral, isVariable = false;
    644     bool result = _TermOpe( term, Type(), resultType, isLiteral, NULL, NULL, false, isVariable, relativeVar, isWriteAccess );
     657    bool isLiteral, isVariable = false, isNeedHeapFreeStructure = false;
     658    bool result = _TermOpe( term, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, false, isVariable, relativeVar, isWriteAccess );
    645659
    646660    if( !isVariable )
     
    823837    bool isNothing_stack[255];
    824838    LONG_PTR index_stack[255];
    825     BOOL bUseHeap[255];
     839    bool isNeedHeapFreeStructureStack[255];
    826840    _int64 i64data;
    827841    for(i=0,sp=0;i<pnum;i++){
     
    845859                else{
    846860                    //オーバーロードされたオペレータを呼び出す
    847                     i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
     861                    i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,isNeedHeapFreeStructureStack,sp);
    848862                    if(i2==0){
    849863                        if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
     
    867881                index_stack[sp]=-1;
    868882                isNothing_stack[sp] = false;
    869                 bUseHeap[sp]=0;
     883                isNeedHeapFreeStructureStack[sp] = false;
    870884
    871885                char *term;
     
    954968
    955969                    bool isLiteral;
    956                     if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
     970                    if( TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructureStack[sp] ) ){
    957971                        if(resultType.IsNull()){
    958972                            //戻り値が存在しないとき
     
    12601274    }
    12611275
    1262     if(pbUseHeap) *pbUseHeap=bUseHeap[0];
     1276    if(pbUseHeap) *pbUseHeap = isNeedHeapFreeStructureStack[0];
    12631277
    12641278    resultType.SetType( type_stack[0], index_stack[0] );
  • trunk/abdev/BasicCompiler32/Opcode.h

    r424 r435  
    6565             Type &resultType,
    6666             bool &isLiteral,
    67              BOOL *pbUseHeap,
     67             bool &isNeedHeapFreeStructure,
    6868             bool *pIsClassName = NULL,
    6969             bool isProcedureCallOnly = false,
     
    222222//OperatorProc.cpp
    223223void FreeTempObject(int reg,const CClass *pobj_c);
    224 int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,BOOL *bUseHeap,int &sp);
     224int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,bool isNeedHeapFreeStructureStack[],int &sp);
    225225void CallCastOperatorProc(Type &calcType,BOOL bCalcUseHeap,const Type &toType);
    226226void CallIndexerGetterProc( const Type &classType, const char *ObjectName, char *Parameter,Type &resultType, DWORD dwProcFlags = 0 );
  • trunk/abdev/BasicCompiler32/OperatorProc.cpp

    r424 r435  
    2626}
    2727
    28 int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,BOOL *bUseHeap,int &sp)
     28int CallOperatorProc(int idCalc, const Type &baseType, int *type_stack, LONG_PTR *index_stack,bool isNeedHeapFreeStructureStack[],int &sp)
    2929{
    3030    Type leftType( type_stack[sp-2], index_stack[sp-2] );
     
    9595        if( pUserProc->RealParams()[1]->IsStruct() &&pUserProc->RealParams()[1]->IsRef() == false ){
    9696            //一時オブジェクトはメソッド内で破棄される
    97             bUseHeap[sp-1]=0;
     97            isNeedHeapFreeStructureStack[sp-1] = false;
    9898        }
    9999    }
     
    140140
    141141    //ヒープ解放用に退避
    142     if(bUseHeap[sp-1]){
     142    if(isNeedHeapFreeStructureStack[sp-1]){
    143143        //mov esi,eax
    144144        compiler.codeGenerator.op_mov_RR(REG_ESI,REG_EAX);
    145145    }
    146     if(bUseHeap[sp-2]){
     146    if(isNeedHeapFreeStructureStack[sp-2]){
    147147        //mov edi,ecx
    148148        compiler.codeGenerator.op_mov_RR(REG_EDI,REG_ECX);
     
    198198    }
    199199
    200     if(bUseHeap[sp-1]){
     200    if(isNeedHeapFreeStructureStack[sp-1]){
    201201        FreeTempObject(REG_ESI,(CClass *)index_stack[sp-1]);
    202202    }
    203     if(bUseHeap[sp-2]){
     203    if(isNeedHeapFreeStructureStack[sp-2]){
    204204        FreeTempObject(REG_EDI,(CClass *)index_stack[sp-2]);
    205205    }
     
    209209    index_stack[sp-1]=pUserProc->ReturnType().GetIndex();
    210210
    211     if( pUserProc->ReturnType().IsStruct() ){
     211    if( pUserProc->ReturnType().IsStruct() )
     212    {
    212213        //構造体が戻ったときはヒープ領域にインスタンスが格納されている
    213214        //※後にfreeする必要あり
    214         bUseHeap[sp-1]=1;
    215     }
    216     else bUseHeap[sp-1]=0;
     215        isNeedHeapFreeStructureStack[sp-1] = true;
     216    }
     217    else
     218    {
     219        isNeedHeapFreeStructureStack[sp-1] = false;
     220    }
    217221
    218222    return 1;
     
    222226    int type_stack[10];
    223227    LONG_PTR index_stack[10];
    224     BOOL array_bUseHeap[10];
     228    bool array_bUseHeap[10];
    225229    int sp=2;
    226230
  • trunk/abdev/BasicCompiler_Common/Compile.cpp

    r424 r435  
    457457        case COM_LET:
    458458            OpcodeCalc(Command+2);
     459
    459460            break;
    460461        default:
    461462            OpcodeOthers(Command);
     463
     464            // コード生成過程で発生した構造体の一時メモリを破棄する
     465            compiler.codeGenerator.op_FreeTempStructure();
     466
    462467            break;
    463468    }
  • trunk/abdev/BasicCompiler_Common/include/CodeGenerator.h

    r370 r435  
    198198    std::vector<long> continueCodePositions;
    199199
     200    // コンパイル中のステップにおいて、構造体の一時オブジェクトの解放が必要かどうか
     201    bool isNeedFreeTempStructureInCurrentStep;
     202
    200203public:
    201204
     
    215218    CodeGenerator()
    216219        : pNativeCode( 0 )
     220        , isNeedFreeTempStructureInCurrentStep( false )
    217221    {
    218222    }
     
    294298    void op_jmp_exitsub();
    295299    void op_jmp_goto_schedule( const std::string &name, int lineNum, int sourceCodePos );
     300    void op_AddNeedFreeTempStructure( int reg );
     301    void op_FreeTempStructure();
    296302
    297303
  • trunk/abdev/BasicCompiler_Common/src/CommonCodeGenerator.cpp

    r357 r435  
    304304    pNativeCode->Put( (long)0 );
    305305}
     306
     307void CodeGenerator::op_AddNeedFreeTempStructure( int reg )
     308{
     309#ifdef _AMD64_
     310    //////////////////////////////////////////////////////
     311    /////    レジスタ資源のバックアップ
     312    {   BACKUP_REGISTER_RESOURCE
     313    //////////////////////////////////////////////////////
     314
     315    //mov rcx,reg
     316    compiler.codeGenerator.op_mov_RR( REG_RCX, reg );
     317
     318    //call _System_AddNeedFreeTempStructure
     319    extern const UserProc *pSub_System_AddNeedFreeTempStructure;
     320    compiler.codeGenerator.op_call( pSub_System_AddNeedFreeTempStructure );
     321
     322    /////////////////////////////////////////////
     323    //////   レジスタ資源を復元
     324        RESTORE_REGISTER_RESOURCE
     325    }////////////////////////////////////////////
     326#else
     327
     328    //push useReg(引き続き利用するため、退避しておく)
     329    compiler.codeGenerator.op_push( reg );
     330
     331    //push useReg
     332    compiler.codeGenerator.op_push( reg );
     333
     334    //call _System_AddNeedFreeTempStructure
     335    extern const UserProc *pSub_System_AddNeedFreeTempStructure;
     336    compiler.codeGenerator.op_call( pSub_System_AddNeedFreeTempStructure );
     337
     338    //pop useReg(復元する)
     339    compiler.codeGenerator.op_pop( reg );
     340#endif
     341
     342    isNeedFreeTempStructureInCurrentStep = true;
     343}
     344void CodeGenerator::op_FreeTempStructure()
     345{
     346    if( !isNeedFreeTempStructureInCurrentStep )
     347    {
     348        // 解放の必要はない
     349        return;
     350    }
     351
     352    // call _System_FreeTempStructure
     353    extern const UserProc *pSub_System_FreeTempStructure;
     354    op_call( pSub_System_FreeTempStructure );
     355
     356    isNeedFreeTempStructureInCurrentStep = false;
     357}
Note: See TracChangeset for help on using the changeset viewer.