Top > C++ > AngelScript > フォーラムメモ

フォーラムメモ Edit

自分自身のプロパティアクセサを呼び出すとフリーズ Edit

  • ライブラリバージョン : r564
コールトレース
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
	GameProject.exe!asCArray<asCScriptFunction *>::operator[](unsigned int index=0)  Line 147 + 0x6 Bytes	C++
 	GameProject.exe!asCContext::CallInterfaceMethod(asCScriptFunction * func=0x0a8e1058)  Line 1254 + 0x15 Bytes	C++
 	GameProject.exe!asCContext::ExecuteNext()  Line 2790	C++
 	GameProject.exe!asCContext::Execute()  Line 1004 + 0x8 Bytes	C++
 	GameProject.exe!base::ags::ContextHandle::execute()  Line 104 + 0x23 Bytes	C++
 	GameProject.exe!app::scene::SceneASTest::onSceneStart()  Line 67	C++
 	GameProject.exe!app::Application::beginSceneProcess()  Line 191 + 0x23 Bytes	C++
 	GameProject.exe!app::Application::execute()  Line 99 + 0xc Bytes	C++
 	GameProject.exe!`anonymous namespace'::t_executeApplication()  Line 50 + 0xb Bytes	C++
 	GameProject.exe!app::EntryPoint::run()  Line 73	C++
 	GameProject.exe!wmain(int __formal=1, int __formal=1)  Line 16	C++
 	GameProject.exe!__tmainCRTStartup()  Line 594 + 0x19 Bytes	C
 	GameProject.exe!wmainCRTStartup()  Line 414	C
ASコード
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
-
|
|
|
!
 
 
-
|
-
|
!
|
-
|
!
|
|
!
 
 
 
-
|
|
!
class Vector3
{
    float x;
    float y;
    float z;
};
 
class Hoge
{
    const Vector3 get_pos()const
    {
        return mPos;
    }
    const Vector3 foo()const
    {
        return pos;
    }
 
    Vector3 mPos;
};
 
 
void main()
{
    Hoge h;
    const Vector3 vec = h.foo();
}

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
-
|
|
|
!
 
 
-
|
|
|
|
!
 
 
 
-
|
|
|
|
!
 
class Vector3
{
    float x;
    float y;
    float z;
};
 
class Hoge
{
    const Vector3 get_pos() { return mPos; }
    const Vector3 foo() { return pos;  }
    const Vector3 zoo() { return get_pos(); }
    Vector3 mPos;
};
 
 
void main()
{
    Hoge h;
    Vector3 vec;
    vec = h.zoo(); // ok
    vec = h.foo(); // runtime exception
}

__Hoge_foo.txt

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
Temps: 1
 
    0   0 *    PUSH     1
    1   1 *    PshV4    v0
    2   2 *    CALLSYS  17           (void _builtin_object_::_beh_4_())
- 11,27 -
    4   1 *    SUSPEND
    5   1 *    PSF      v0
    6   2 *    CALLINTF 86           (const Vector3 Hoge::get_pos())
    8   1 *    STOREOBJ v1
    9   1 *    LOADOBJ  v1
   10   1 * 0:
   10   1 *    FREE     v0, 11276368
   12   0 *    RET      1

__Hoge_zoo.txt

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
Temps: 1
 
    0   0 *    PUSH     1
    1   1 *    PshV4    v0
    2   2 *    CALLSYS  17           (void _builtin_object_::_beh_4_())
- 12,27 -
    4   1 *    SUSPEND
    5   1 *    PshV4    v0
    6   2 *    CALLINTF 86           (const Vector3 Hoge::get_pos())
    8   1 *    STOREOBJ v1
    9   1 *    LOADOBJ  v1
   10   1 * 0:
   10   1 *    FREE     v0, 11276368
   12   0 *    RET      1

opAssignを定義するとコンパイル時にAssert Edit

  • ライブラリバージョン : 2.18.1
エラーメッセージ
Assertion failed: tempVariables.GetLength() == 0, file ..\..\source\as_compiler.cpp, line 643
コールトレース
  0
  1
  2
  3
 	msvcr80d.dll!_wassert(const wchar_t * expr=0x007013cc, const wchar_t * filename=0x00701174, unsigned int lineno=643)  行 212	C
 	GameProject.exe!asCCompiler::CompileStatementBlock(asCScriptNode * block=0x0a8c1640, bool ownVariableScope=false, bool * hasReturn=0x0012b2e3, asCByteCode * bc=0x0012b2a0)  行 643 + 0x29 バイト	C++
 	GameProject.exe!asCCompiler::CompileFunction(asCBuilder * builder=0x0a8e2b08, asCScriptCode * script=0x0a8e2800, asCScriptNode * func=0x0a8e2878, asCScriptFunction * outFunc=0x0a8e3c10)  行 324	C++
 	GameProject.exe!asCBuilder::CompileFunctions()  行 524	C++
 	GameProject.exe!asCBuilder::Build()  行 184	C++
ASコード
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
-
|
|
|
-
|
!
|
|
-
|
|
!
!
 
 
-
|
!
class Hoge
{
    int mValue;
    
    Hoge()
    {
        mValue = 0;
    }
    
    Hoge@ opAssign(const Hoge &in aObj)
    {
        mValue = aObj.mValue;
        return @this;
    }
};
 
void main()
{
    Hoge a = Hoge();
}

デストラクタが呼ばれない Edit

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 
 
 
 
-
!
 
 
-
|
-
|
!
|
-
|
!
|
!
 
 
-
|
-
|
!
|
-
|
!
|
!
 
 
-
|
-
|
!
-
|
!
|
|
!
 
 
-
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//-----------------------------------------------------------
// script code
 
class ObjType
{
};
 
class HaveObj
{
    HaveObj()
    {
        Print( "HaveObj::ctor\n" );
    }
    ~HaveObj()
    {
        Print( "HaveObj::dtor\n" );
    }
    ObjType o;
};
 
class HaveHandle
{
    HaveHandle()
    {
        Print( "HaveHandle::ctor\n" );
    }
    ~HaveHandle()
    {
        Print( "HaveHandle::dtor\n" );
    }
    ObjType@ o;
};
 
void testCase1()
{
    Print( "testCase1 start\n" );
    {
        HaveObj o;
    }// call o.~HaveObj();
    {
        HaveHandle o;
    }// not call o.~HaveHandle();
    
    Print( "testCase1 end\n" );
} 
 
void main()
{
    testCase1();
}
 
 
//-----------------------------------------------------------
 
 
//-----------------------------------------------------------
// output
 
testCase1 start
HaveObj::ctor
HaveObj::dtor
HaveHandle::ctor
testCase1 end
 
 
//-----------------------------------------------------------

回答
As with any language with automatic memory management, it can be hard to predict when the destructor is called.

In your case you have created a situation where the ordinary reference counting is not enough to control the life time of the objects, so the garbage collector is notified to keep a watch on the object instance. However, the garbage collector is not invoked automatically by the script engine (so that the application will have full control of when that is done). This means that unless you manually call the GC, the object will only be destroyed when you release the script engine.

配列を使った循環参照状態を記述するとメモリリーク Edit

  • ライブラリバージョン : r575
C++コード
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 
 
 
-
|
|
|
|
-
|
|
!
|
|
-
|
|
!
!
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
 
//-----------------------------------------------------------
// C++ source code
namespace
{
    // alloc counter
    int t_allocCount = 0;
    // alloc function
    void* t_alloc( const size_t aSize )
    {
        ++t_allocCount;
        return std::malloc( aSize );
    }
    // free cuntion
    void t_free( void* aPtr )
    {
        std::free( aPtr );
        --t_allocCount;
    }
}
 
int main(int argc, char **argv)
{
    // set allocator
    asSetGlobalMemoryFunctions( t_alloc , t_free );
 
    // Create the script engine
    asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
 
    // Compile
    asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
    mod->AddScriptSection("script", 
        "class Hoge"
        "{"
        "    Hoge(){}"
        "    Hoge(HogeManager&){}"
        "};"
        "class HogeManager"
        "{"
        "    Hoge[] hoges;"
        "};"
        , 0);
    mod->Build();
 
    // Release engine
    engine->Release();
 
    // check
    assert( t_allocCount == 0 );
}
対処
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
 
 
 
 
 
 
 
 
// as_scriptengine.cpp L490付近
 
    GarbageCollect(asGC_FULL_CYCLE);
    FreeUnusedGlobalProperties();
    ClearUnusedTypes();
 
        // もう一度,GCを走らせる
    GarbageCollect(asGC_FULL_CYCLE);

enumの文字列かぶりで無限ループ Edit

  • ライブラリバージョン : r575
スクリプトコード
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
 
-
|
|
!
 
enum Kind
{
    Kind_A
    , Kind_A // This code gives name conflict error and infinite loop.
};

asGC_ONE_STEPは想定した動きになっているのか Edit

  • ライブラリバージョン : r586
code
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
-
|
!
|
|
-
|
|
|
|
|
!
|
|
|
!
|
|
|
|
!
void main()
{
    // Create the script engine
    asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
 
    // Register Function
    RegisterScriptString(engine);
    engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString_Generic), asCALL_GENERIC);
 
    // Compile
    asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
    mod->AddScriptSection("script", 
        "class Obj{};"
        "class Hoge"
        "{"
        "    Hoge(){ Print(\"ctor\\n\"); }"
        "    ~Hoge(){ Print(\"dtor\\n\"); }"
        "    Obj@ obj;"
        "};"
        "void main()"
        "{"
        "    Hoge hoge;"
        "};"
        , 0);
    mod->Build();
 
    // Context Create
    asIScriptContext *ctx = engine->CreateContext();
 
    // Loop
    while ( true )
    {
        // Execute
        printf("----- execute\n");
        ctx->Prepare(mod->GetFunctionIdByDecl("void main()"));
        ctx->Execute();
 
        // GC
        const int GC_STEP_COUNT_PER_FRAME = 10000;
        for ( int i = 0; i < GC_STEP_COUNT_PER_FRAME; ++i )
        {
            engine->GarbageCollect(asGC_ONE_STEP);
        }
        
        // Check status
        {
            asUINT currentSize = asUINT();
            asUINT totalDestroyed = asUINT();
            asUINT totalDetected = asUINT();
            engine->GetGCStatistics(&currentSize , &totalDestroyed , &totalDetected );
            printf("(%lu,%lu,%lu)\n" , currentSize , totalDestroyed , totalDetected );
        }
 
        // Wait to input key
        while(!getch()){}
    }
 
    // Release 
    ctx->Release();
    engine->Release();
}
output
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
----- execute
ctor
dtor
(8,1,0)
----- execute
ctor
(9,1,0)
----- execute
ctor
(10,1,0)
----- execute
ctor
(11,1,0)
----- execute
ctor
(12,1,0)
----- execute
ctor
(13,1,0)
----- execute
ctor
(14,1,0)

as_restore.cppの修正箇所 Edit

revision
r589
Not work on Big Endian Environment(L1398,L1410,L1451,L1473,L1488)
すべてを展開すべてを収束
  1
  2
  3
  4
 
 
 
 
// src
asWORD w = (asWORD)(tmp[0]>>16);
// fixed
asWORD w = *(((asWORD*)tmp)+1);
 
Not work on Big Endian Environment(L1587,L1600,L1637,L1661,L1678,L1727)
すべてを展開すべてを収束
  1
  2
  3
  4
 
 
 
 
// src
*bc += asDWORD(w)<<16;
// fixed
*(((asWORD*)bc)+1) = w;
miss spell(L1497)
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
 
 
 
 
 
 
// src
asDWORD dw = tmp[2];
WRITE_NUM(w);
// fixed
asDWORD dw = tmp[2];
WRITE_NUM(dw);
miss spell(L1642,L1666,L1683)
すべてを展開すべてを収束
  1
  2
  3
  4
 
 
 
 
// src
*(WORD*)bc = w;
// fixed
*(asWORD*)bc = w;
miss spell(L1646)
すべてを展開すべてを収束
  1
  2
  3
  4
 
 
 
 
// src
*(((WORD*)bc)+1) = w;
// fixed
*(((asWORD*)bc)+1) = w;

テンプレートのメソッドを呼ぶスクリプトコードをSaveByteCode&LoadByteCodeすると落ちる Edit

リビジョン
r589
script code
すべてを展開すべてを収束
  1
  2
  3
  4
  5
 
-
|
|
!
void main()
{
    array< int > intArray = {0,1,2};
    uint tmp = intArray.length(); // program stoped while module->LoadByteCode() Processing
};
freeze code pos
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 
 
 
 
-
|
|
|
!
// as_restore.cpp L1937
else if( c == asBC_CALL ||
         c == asBC_CALLINTF ||
         c == asBC_CALLSYS )
{
    // Translate the index to the func id
    int *fid = (int*)&bc[n+1];
    *fid = FindFunction(*fid)->id; // null pointer access
}

fix patch Edit

as_restore.cpp
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
 
-
|
|
|
|
-
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
-
|
|
|
|
!
!
|
-
|
|
|
!
|
-
|
|
|
!
!
|
-
|
|
!
!
 
 
 
-
|
|
|
|
-
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
!
|
-
!
|
-
|
!
|
|
|
|
!
|
-
|
|
|
|
|
|
|
!
!
|
-
|
|
|
|
|
|
-
|
-
|
|
!
!
|
|
|
!
|
-
|
|
|
|
|
-
|
|
|
|
|
|
!
|
-
|
!
|
-
|
!
|
|
!
|
-
|
|
|
!
|
|
!
void asCRestore::WriteObjectType(asCObjectType* ot) 
{
    char ch;
 
    // Only write the object type name
    if( ot )
    {
        // Check for template instances/specializations
        if( ot->templateSubType.GetTokenType() != ttUnrecognizedToken &&
            ot != engine->defaultArrayObjectType )
        {
            ch = 'a';
            WRITE_NUM(ch);
 
            if( ot->templateSubType.IsObject() )
            {
                ch = 's';
                WRITE_NUM(ch);
                WriteObjectType(ot->templateSubType.GetObjectType());
 
                if( ot->templateSubType.IsObjectHandle() )
                    ch = 'h';
                else
                    ch = 'o';
                
                WRITE_NUM(ch);
#if 1
                ch = 'o';
                WRITE_NUM(ch);
                WriteString(&ot->name);
#endif
            }
            else
            {
                ch = 't';
                WRITE_NUM(ch);
                eTokenType t = ot->templateSubType.GetTokenType();
                WRITE_NUM(t);
            }
        }
        else if( ot->flags & asOBJ_TEMPLATE_SUBTYPE )
        {
            ch = 's';
            WRITE_NUM(ch);
            WriteString(&ot->name);
        }
        else
        {
            ch = 'o';
            WRITE_NUM(ch);
            WriteString(&ot->name);
        }
    }
    else
    {
        ch = '\0';
        WRITE_NUM(ch);
    }
}
 
 
asCObjectType* asCRestore::ReadObjectType() 
{
    asCObjectType *ot;
    char ch;
    READ_NUM(ch);
    if( ch == 'a' )
    {
        READ_NUM(ch);
        if( ch == 's' )
        {
#if 0
            ot = ReadObjectType();
            asCDataType dt = asCDataType::CreateObject(ot, false);
 
            READ_NUM(ch);
            if( ch == 'h' )
                dt.MakeHandle(true);
 
            dt.MakeArray(engine);
            ot = dt.GetObjectType();
            
            asASSERT(ot);
#else
            asCObjectType* subOT = ReadObjectType();
            asCDataType dt = asCDataType::CreateObject(subOT, false);
            READ_NUM(ch);
            if ( ch == 'h' )
            {
                dt.MakeHandle(true);
            }
            else if ( ch == 'o' )
            {
            }
            else
            {
                assert(false);
            }
            asCObjectType* tmplOT = ReadObjectType();
            dt.MakeTemplateInstanceType(engine,tmplOT);
            ot = dt.GetObjectType();
#endif
        }
        else
        {
            eTokenType tokenType;
            READ_NUM(tokenType);
            asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
            dt.MakeArray(engine);
            ot = dt.GetObjectType();
            
            asASSERT(ot);
        }
    }
    else if( ch == 's' )
    {
        // Read the name of the template subtype
        asCString typeName;
        ReadString(&typeName);
 
        // Find the template subtype
        for( asUINT n = 0; n < engine->templateSubTypes.GetLength(); n++ )
        {
            if( engine->templateSubTypes[n] && engine->templateSubTypes[n]->name == typeName )
            {
                ot = engine->templateSubTypes[n];
                break;
            }
        }
 
        // TODO: Should give a friendly error in case the template type isn't found
        asASSERT(ot);
    }
    else if( ch == 'o' )
    {
        // Read the object type name
        asCString typeName;
        ReadString(&typeName);
 
        if( typeName.GetLength() && typeName != "_builtin_object_" && typeName != "_builtin_function_" )
        {
            // Find the object type
            ot = module->GetObjectType(typeName.AddressOf());
            if( !ot )
                ot = engine->GetObjectType(typeName.AddressOf());
            
            asASSERT(ot);
        }
        else if( typeName == "_builtin_object_" )
        {
            ot = &engine->scriptTypeBehaviours;
        }
        else if( typeName == "_builtin_function_" )
        {
            ot = &engine->functionBehaviours;
        }
        else
            assert( false );
    }
    else
    {
        // No object type
        assert( ch == '\0' );
        ot = 0;
    }
 
    return ot;
}
as_datatype.h
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
 
 
 
 
 
 
 
 
    int MakeHandle(bool b, bool acceptHandleForScope = false);
    int MakeArray(asCScriptEngine *engine);
    int MakeReference(bool b);
    int MakeReadOnly(bool b);
    int MakeHandleToConst(bool b);
#if 1
    int MakeTemplateInstanceType(asCScriptEngine *engine,asCObjectType*);
#endif
as_datatype.cpp
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
!
 
#if 1
int asCDataType::MakeTemplateInstanceType(asCScriptEngine *engine,asCObjectType* templateOT)
{
    bool tmpIsReadOnly = isReadOnly;
    isReadOnly = false;
    asCObjectType *at = engine->GetTemplateInstanceType(templateOT, *this);
    isReadOnly = tmpIsReadOnly;
 
    isObjectHandle = false;
    isConstHandle = false;
    
    objectType = at;
    tokenType = ttIdentifier;
 
    return 0;
}
#endif

as_restore.cppの修正箇所 その2 Edit

r594
Not work on Big Endian Environment(L1580,L1615,L1624,L1699,L1710)

すべてを展開すべてを収束
  1
  2
  3
  4
  5
 
 
 
 
 
// src
*bc++ = b;
// fixed
*(asBYTE*)(bc) = b;
++bc;

Not work on Big Endian Environment(L1600.L1637,L1661,L1678,L1727)

すべてを展開すべてを収束
  1
  2
  3
  4
 
 
 
 
// src
*bc = b;
// fixed
*(asBYTE*)(bc) = b;

load byte code failed Edit

Revision
r595

Assertion failed at loading byte code.

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
 
 
 
-
|
!
// Succeed case
class Hoge {};
class HogeManager
{
    array< Hoge >@ hogeArray;
};
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
 
 
-
|
!
 
// Failed case
class HogeManager
{
    array< Hoge >@ hogeArray;
};
class Hoge {};
Message
Assertion failed: ot, file ..\..\source\as_restore.cpp, line 1244

load byte code failed part2 Edit

Revision
r609

Assertion failed at loading byte code.

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 
 
-
|
-
|
!
!
 
// Failed case
class HogeManager
{
    HogeManager()
    {
        array< Hoge >@ hogeArray;
    }
};
class Hoge {};
Message
Assertion failed: ot, file ..\..\source\as_restore.cpp, line 1299

memory leak part2 Edit

Revision
r604

Add 'array' object method

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 
 
-
|
!
 
-
|
|
|
!
// scriptarray.cpp
namespace
{
    void t_hoge(asIScriptGeneric*){}    
}
void RegisterScriptArray_Generic(asIScriptEngine *engine)
{
    ...
    r = engine->RegisterObjectMethod("array<T>", "void hoge(const T&in)" , asFUNCTION(t_hoge), asCALL_GENERIC); assert( r >= 0 );
    
}

main.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 
 
-
|
|
|
|
-
|
|
!
|
|
-
|
|
!
!
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
//-----------------------------------------------------------
// C++ source code
namespace
{
    // alloc counter
    int t_allocCount = 0;
    // alloc function
    void* t_alloc( const size_t aSize )
    {
        ++t_allocCount;
        return std::malloc( aSize );
    }
    // free cuntion
    void t_free( void* aPtr )
    {
        std::free( aPtr );
        --t_allocCount;
    }
}
 
int main(int argc, char **argv)
{
    // set allocator
    asSetGlobalMemoryFunctions( t_alloc , t_free );
 
    // Create the script engine
    asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
 
    // Register array class
    RegisterScriptArray_Generic(engine);
 
    // Compile
    asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
    mod->AddScriptSection("script", 
        "class Hoge"
        "{"
        "    HogeManager@ hogeManager;"
        "};"
        "class HogeManager"
        "{"
        "    array< Hoge >@ hoges;"
        "};"
        , 0);
    mod->Build();
 
    // Release engine
    engine->Release();
 
    // check
    assert( t_allocCount == 0 ); // assertion failed
 
    return 0;
}

load byte code failed part3 Edit

Revision
r609
Script Code
すべてを展開すべてを収束
  1
  2
  3
  4
  5
 
 
-
|
!
array< ColorKind > COLOR_KIND_TABLE = { ColorKind_Red };
enum ColorKind
{
    ColorKind_Red
};
Call stack trace
Maybe null pointer access.
msvc8.exe!asCRestore::TranslateFunction(asCScriptFunction * func=0x003ed990) Line 2011 + 0x11 Byte C++
msvc8.exe!asCRestore::Restore() Line 358 C++
msvc8.exe!asCModule::LoadByteCode(asIBinaryStream * in=0x00ad7018) Line 1237 + 0xb Byte C++

load byte code failed part4 Edit

Revision
r613
Script Code
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
 
 
 
-
|
|
|
!
interface IObj {};
class Hoge : IObj {};
void main()
{
    Hoge h;
    IObj@ objHandle = h;
    Hoge@ hogeHandle = cast< Hoge@ >( objHandle );
};

Crash at as_context.cpp L2866.

build failed Edit

Revision
r614
ScriptCode
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 
 
-
|
!
 
-
|
-
|
|
|
!
|
!
class Obj {};
class Hoge
{
    const Obj obj()const { return Obj(); }
};
class Foo
{
    Foo()
    {
        Hoge h;
        Obj tmpObj = h.obj(); /* OK */
        mObj = h.obj(); /* Build failed */
    }
    Obj mObj;
};

リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Mon, 05 Jul 2010 20:47:41 JST (5043d)