void Script::PushArgument(const String &sString) { if (m_pAngelScriptContext) { CScriptString *pCScriptString = new CScriptString(sString.GetASCII(), sString.GetLength()); m_pAngelScriptContext->SetArgObject(m_nCurrentArgument++, pCScriptString); pCScriptString->Release(); // Destroy our CScriptString instance } }
bool Test() { bool fail = false; COutStream out; asIScriptEngine *engine = 0; asIScriptModule *mod = 0; int r; fail = Test2() || fail; engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString(engine); RegisterScriptStringUtils(engine); engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(PrintString), asCALL_GENERIC); engine->RegisterGlobalFunction("void set(string@)", asFUNCTION(SetString), asCALL_GENERIC); engine->RegisterGlobalFunction("void set2(string@&in)", asFUNCTION(SetString2), asCALL_GENERIC); engine->RegisterGlobalFunction("const string &getconststringref()", asFUNCTION(GetConstStringRef), asCALL_GENERIC); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); // Test index operator for temp strings r = engine->ExecuteString(0, "assert('abc'[0] == 97)"); if( r != asEXECUTION_FINISHED ) fail = true; r = engine->ExecuteString(0, "assert(string('abc')[0] == 97)"); if( r != asEXECUTION_FINISHED ) fail = true; r = engine->ExecuteString(0, "string a = 'abc'; assert(a[0] == 97)"); if( r != asEXECUTION_FINISHED ) fail = true; // Test string copy constructor r = engine->ExecuteString(0, "string tst(getconststringref()); print(tst);"); if( r != asEXECUTION_FINISHED ) fail = true; if( printOutput != "test" ) fail = true; printOutput = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0); mod->Build(); engine->ExecuteString(0, "testString()"); if( printOutput != "hello Ida" ) { fail = true; printf("%s: Failed to print the correct string\n", TESTNAME); } engine->ExecuteString(0, "string s = \"test\\\\test\\\\\""); // Verify that it is possible to use the string in constructor parameters printOutput = ""; engine->ExecuteString(0, "string a; a = 1; print(a);"); if( printOutput != "1" ) fail = true; printOutput = ""; engine->ExecuteString(0, "string a; a += 1; print(a);"); if( printOutput != "1" ) fail = true; printOutput = ""; engine->ExecuteString(0, "string a = \"a\" + 1; print(a);"); if( printOutput != "a1" ) fail = true; printOutput = ""; engine->ExecuteString(0, "string a = 1 + \"a\"; print(a);"); if( printOutput != "1a" ) fail = true; printOutput = ""; engine->ExecuteString(0, "string a = 1; print(a);"); if( printOutput != "1" ) fail = true; printOutput = ""; engine->ExecuteString(0, "print(\"a\" + 1.2)"); if( printOutput != "a1.2") fail = true; printOutput = ""; engine->ExecuteString(0, "print(1.2 + \"a\")"); if( printOutput != "1.2a") fail = true; // Passing a handle to a function printOutput = ""; engine->ExecuteString(0, "string a; set(@a); print(a);"); if( printOutput != "Handle to a string" ) fail = true; // Implicit conversion to handle printOutput = ""; engine->ExecuteString(0, "string a; set(a); print(a);"); if( printOutput != "Handle to a string" ) fail = true; // Passing a reference to a handle to the function printOutput = ""; engine->ExecuteString(0, "string a; set2(@a); print(a);"); if( printOutput != "Handle to a string" ) fail = true; // Implicit conversion to reference to a handle printOutput = ""; engine->ExecuteString(0, "string a; set2(a); print(a);"); if( printOutput != "Handle to a string" ) fail = true; printOutput = ""; engine->ExecuteString(0, "string a = \" \"; a[0] = 65; print(a);"); if( printOutput != "A" ) fail = true; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0); if( mod->Build() < 0 ) fail = true; printOutput = ""; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0); if( mod->Build() < 0 ) fail = true; engine->ExecuteString(0, "test()"); if( printOutput != "Heredoc\\x20test!" ) fail = true; CScriptString *a = new CScriptString("a"); engine->RegisterGlobalProperty("string a", a); r = engine->ExecuteString(0, "print(a == 'a' ? 't' : 'f')"); if( r != asEXECUTION_FINISHED ) { fail = true; printf("%s: ExecuteString() failed\n", TESTNAME); } a->Release(); // test new mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script5, strlen(script5), 0); if( mod->Build() < 0 ) fail = true; r = engine->ExecuteString(0, "Main()"); if( r != asEXECUTION_FINISHED ) fail = true; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0); if( mod->Build() < 0 ) fail = true; r = engine->ExecuteString(0, "Main()"); if( r != asEXECUTION_FINISHED ) fail = true; // Test character literals r = engine->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, true); assert( r >= 0 ); printOutput = ""; r = engine->ExecuteString(0, "print(\"\" + 'a')"); if( r != asEXECUTION_FINISHED ) fail = true; if( printOutput != "97" ) fail = true; printOutput = ""; r = engine->ExecuteString(0, "print(\"\" + '\\'')"); if( r != asEXECUTION_FINISHED ) fail = true; if( printOutput != "39" ) fail = true; printOutput = ""; r = engine->ExecuteString(0, "print(\"\" + '\xFF')"); if( r != asEXECUTION_FINISHED ) fail = true; if( printOutput != "255" ) fail = true; CBufferedOutStream bout; engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = engine->ExecuteString(0, "print(\"\" + '')"); if( r != -1 ) fail = true; r = engine->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, false); assert( r >= 0 ); //------------------------------------- engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("test", script7, strlen(script7), 0); mod->Build(); r = engine->ExecuteString(0, "test()"); if( r != asEXECUTION_FINISHED ) fail = true; engine->RegisterObjectType("Http", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE); engine->RegisterObjectMethod("Http","bool get(const string &in,string &out)", asFUNCTION(Get),asCALL_GENERIC); r = engine->ExecuteString(0, "Http h; string str; h.get('stringtest', str); assert(str == 'output');"); if( r != asEXECUTION_FINISHED ) fail = true; r = engine->ExecuteString(0, "Http h; string a = 'test', b; h.get('string'+a, b); assert(b == 'output');"); if( r != asEXECUTION_FINISHED ) fail = true; // Test the string utils engine->ExecuteString(0, "string str = 'abcdef'; assert(findFirst(str, 'def') == 3);"); engine->ExecuteString(0, "string str = 'abcdef'; assert(findFirstOf(str, 'feb') == 1);"); engine->ExecuteString(0, "string str = 'a|b||d'; string@[]@ array = split(str, '|'); assert(array.length() == 4); assert(array[1] == 'b');"); engine->ExecuteString(0, "string@[] array = {'a', 'b', '', 'd'}; assert(join(array, '|') == 'a|b||d');"); engine->Release(); //--------------------------------------- engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); engine->RegisterGlobalFunction("void TestFunc(int, string&)", asFUNCTION(TestFunc), asCALL_GENERIC); // CHKREF was placed incorrectly r = engine->ExecuteString(0, "TestFunc(0, 'test');"); if( r != asEXECUTION_FINISHED ) fail = true; r = engine->ExecuteString(0, "string @s; TestFunc(0, s);"); if( r != asEXECUTION_EXCEPTION ) fail = true; engine->Release(); //---------------------------------------- engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("test", script7, strlen(script7), 0); mod->Build(); r = engine->ExecuteString(0, "test()"); if( r != asEXECUTION_FINISHED ) fail = true; engine->Release(); //------------------------------------------ // Test the comparison method { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptString(engine); std::string a = "a"; std::string b = "b"; int type = engine->GetTypeIdByDecl("string"); bool c; r = engine->CompareScriptObjects(c, asBEHAVE_EQUAL, &a, &b, type); assert( r >= 0 ); if( c ) fail = true; r = engine->CompareScriptObjects(c, asBEHAVE_NOTEQUAL, &a, &b, type); assert( r >= 0 ); if( !c ) fail = true; r = engine->CompareScriptObjects(c, asBEHAVE_LESSTHAN, &a, &b, type); assert( r >= 0 ); if( !c ) fail = true; r = engine->CompareScriptObjects(c, asBEHAVE_GREATERTHAN, &a, &b, type); assert( r >= 0 ); if( c ) fail = true; r = engine->CompareScriptObjects(c, asBEHAVE_LEQUAL, &a, &b, type); assert( r >= 0 ); if( !c ) fail = true; r = engine->CompareScriptObjects(c, asBEHAVE_GEQUAL, &a, &b, type); assert( r >= 0 ); if( c ) fail = true; engine->Release(); } //----- { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); engine->RegisterGlobalFunction("void Print(string &str)",asFUNCTION(PrintRef), asCALL_GENERIC); const char *script = "string str = 'Some String'; \n" "void Update() \n" "{ \n" " Print(str); \n" "} \n"; mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script, strlen(script)); mod->Build(); CScriptString *str = (CScriptString*)mod->GetAddressOfGlobalVar(0); UNUSED_VAR(str); r = engine->ExecuteString(0, "Update()"); if( r != asEXECUTION_FINISHED ) fail = true; engine->Release(); } //------- // Multiline strings { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); engine->SetEngineProperty(asEP_ALLOW_MULTILINE_STRINGS, true); engine->RegisterGlobalFunction("void assert(bool)",asFUNCTION(Assert), asCALL_GENERIC); const char *script = "string str1 = '1\\n' '2'; \n" "string str2 = '1\n2'; \n" "assert(str1 == str2); \n"; r = engine->ExecuteString(0, script); if( r != asEXECUTION_FINISHED ) fail = true; engine->Release(); } return fail; }
bool Test() { bool fail = false; int r; COutStream out; asIScriptContext *ctx; asIScriptEngine *engine; CBufferedOutStream bout; // --------------------------------------------- engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script1, strlen(script1), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to compile the script\n", "TestAny"); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestAny()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; printf("%s: Execution failed\n", "TestAny"); } if( ctx ) ctx->Release(); engine->Release(); //-------------------------------------------------- // Verify that the GC can handle circles with any structures engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script2, strlen(script2), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to compile the script\n", "TestAny"); } ctx = engine->CreateContext(); r = ExecuteString(engine, "TestAny()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; printf("%s: Execution failed\n", "TestAny"); } if( ctx ) ctx->Release(); asUINT gcCurrentSize, gcTotalDestroyed, gcTotalDetected; engine->GetGCStatistics(&gcCurrentSize, &gcTotalDestroyed, &gcTotalDetected); engine->GarbageCollect(); engine->GetGCStatistics(&gcCurrentSize, &gcTotalDestroyed, &gcTotalDetected); if( !fail ) assert( gcCurrentSize == 8 && gcTotalDestroyed == 8 && gcTotalDetected == 7 ); engine->Release(); //------------------------------------------------------- // Don't allow const handle to retrieve() engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script3, strlen(script3), 0); engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to Build()\n", "TestAny"); } if( bout.buffer != "TestAny (5, 1) : Info : Compiling void TestAny()\n" "TestAny (9, 15) : Warning : Argument cannot be assigned. Output will be discarded.\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } engine->Release(); //-------------------------------------------------------- // Make sure it is possible to pass any to the application engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); RegisterScriptString_Generic(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 ); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("TestAny", script4, strlen(script4), 0); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); r = mod->Build(); if( r < 0 ) { TEST_FAILED; printf("%s: Failed to compile\n", "TestAny"); } r = ExecuteString(engine, "TestAny()", mod); if( r != asEXECUTION_FINISHED ) { TEST_FAILED; printf("%s: Failed to execute\n", "TestAny"); } if( myAny ) { int typeId = myAny->GetTypeId(); if( !(typeId & asTYPEID_OBJHANDLE) ) TEST_FAILED; if( (typeId & asTYPEID_MASK_OBJECT) != asTYPEID_APPOBJECT ) TEST_FAILED; const char *decl = engine->GetTypeDeclaration(typeId); if( (decl == 0) || (strcmp(decl, "string@") != 0) ) { TEST_FAILED; printf("%s: Failed to return the correct type\n", "TestAny"); } int typeId2 = engine->GetTypeIdByDecl("string@"); if( typeId != typeId2 ) { TEST_FAILED; printf("%s: Failed to return the correct type\n", "TestAny"); } CScriptString *str = 0; myAny->Retrieve((void*)&str, typeId); if( str->buffer != "test" ) { TEST_FAILED; printf("%s: Failed to set the string correctly\n", "TestAny"); } if( str ) str->Release(); myAny->Release(); myAny = 0; } else TEST_FAILED; //-------------------------------------- // Make sure the any type can store primitives as well r = ExecuteString(engine, "any a; a.store(1); int b; a.retrieve(b); Assert(b == 1);"); if( r != asEXECUTION_FINISHED ) TEST_FAILED; engine->Release(); { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterScriptMath3D(engine); RegisterScriptAny(engine); engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC); mod = engine->GetModule(0, asGM_ALWAYS_CREATE); const char *script = "void main() \n" "{ \n" " any storage; \n" " storage.store(vector3(1,1,1)); \n" "} \n"; mod->AddScriptSection("script", script); r = mod->Build(); if( r < 0 ) TEST_FAILED; ctx = engine->CreateContext(); r = ExecuteString(engine, "main()", mod, ctx); if( r != asEXECUTION_FINISHED ) { if( r == asEXECUTION_EXCEPTION ) PrintException(ctx); TEST_FAILED; } ctx->Release(); engine->Release(); } // Success return fail; }
bool TestException() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); COutStream out; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_GENERIC); asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "int a = 0;\na = 10/a;", 0, ctx); // Throws an exception if( r == asEXECUTION_EXCEPTION ) { int func = ctx->GetExceptionFunction(); int line = ctx->GetExceptionLineNumber(); const char *desc = ctx->GetExceptionString(); const asIScriptFunction *function = engine->GetFunctionById(func); if( strcmp(function->GetName(), "ExecuteString") != 0 ) { printf("%s: Exception function name is wrong\n", TESTNAME); TEST_FAILED; } if( strcmp(function->GetDeclaration(), "void ExecuteString()") != 0 ) { printf("%s: Exception function declaration is wrong\n", TESTNAME); TEST_FAILED; } if( line != 2 ) { printf("%s: Exception line number is wrong\n", TESTNAME); TEST_FAILED; } if( strcmp(desc, "Divide by zero") != 0 ) { printf("%s: Exception string is wrong\n", TESTNAME); TEST_FAILED; } } else { printf("%s: Failed to raise exception\n", TESTNAME); TEST_FAILED; } ctx->Release(); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script1, strlen(script1)); mod->Build(); r = ExecuteString(engine, "A a; a.Test(\"test\");", mod); if( r != asEXECUTION_EXCEPTION ) { TEST_FAILED; } // A test to validate Unprepare without execution { asIObjectType *type = mod->GetObjectTypeByIndex(0); int funcId = type->GetMethodIdByDecl("void Test(string c)"); ctx = engine->CreateContext(); ctx->Prepare(funcId); asIScriptContext *obj = (asIScriptContext*)engine->CreateScriptObject(type->GetTypeId()); ctx->SetObject(obj); // Just sets the address CScriptString *str = new CScriptString(); ctx->SetArgObject(0, str); // Makes a copy of the object str->Release(); ctx->Unprepare(); // Must release the string argument, but not the object ctx->Release(); obj->Release(); } // A test to verify behaviour when exception occurs in script class constructor const char *script2 = "class SomeClassA \n" "{ \n" " int A; \n" " \n" " ~SomeClassA() \n" " { \n" " print('destruct'); \n" " } \n" "} \n" "class SomeClassB \n" "{ \n" " SomeClassA@ nullptr; \n" " SomeClassB(SomeClassA@ aPtr) \n" " { \n" " this.nullptr.A=100; // Null pointer access. After this class a is destroyed. \n" " } \n" "} \n" "void test() \n" "{ \n" " SomeClassA a; \n" " SomeClassB(a); \n" "} \n"; mod->AddScriptSection("script2", script2); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "test()", mod); if( r != asEXECUTION_EXCEPTION ) { TEST_FAILED; } engine->GarbageCollect(); engine->Release(); // Success return fail; }
bool TestException() { bool fail = false; int r; asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); COutStream out; engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); RegisterScriptString(engine); engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_GENERIC); asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "int a = 0;\na = 10/a;", 0, ctx); // Throws an exception if( r == asEXECUTION_EXCEPTION ) { int line = ctx->GetExceptionLineNumber(); const char *desc = ctx->GetExceptionString(); const asIScriptFunction *function = ctx->GetExceptionFunction(); if( strcmp(function->GetName(), "ExecuteString") != 0 ) { PRINTF("%s: Exception function name is wrong\n", TESTNAME); TEST_FAILED; } if( strcmp(function->GetDeclaration(), "void ExecuteString()") != 0 ) { PRINTF("%s: Exception function declaration is wrong\n", TESTNAME); TEST_FAILED; } if( line != 2 ) { PRINTF("%s: Exception line number is wrong\n", TESTNAME); TEST_FAILED; } if( strcmp(desc, "Divide by zero") != 0 ) { PRINTF("%s: Exception string is wrong\n", TESTNAME); TEST_FAILED; } } else { PRINTF("%s: Failed to raise exception\n", TESTNAME); TEST_FAILED; } ctx->Release(); asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE); mod->AddScriptSection("script", script1, strlen(script1)); mod->Build(); r = ExecuteString(engine, "A a; a.Test(\"test\");", mod); if( r != asEXECUTION_EXCEPTION ) { TEST_FAILED; } // A test to validate Unprepare without execution { asITypeInfo *type = mod->GetObjectTypeByIndex(0); asIScriptFunction *func = type->GetMethodByDecl("void Test(string c)"); ctx = engine->CreateContext(); ctx->Prepare(func); asIScriptContext *obj = (asIScriptContext*)engine->CreateScriptObject(type); ctx->SetObject(obj); // Just sets the address CScriptString *str = new CScriptString(); ctx->SetArgObject(0, str); // Makes a copy of the object str->Release(); ctx->Unprepare(); // Must release the string argument, but not the object ctx->Release(); obj->Release(); } // Another test to validate Unprepare without execution { asITypeInfo *type = mod->GetObjectTypeByIndex(0); // Get the real method, not the virtual method asIScriptFunction *func = type->GetMethodByDecl("void Test(string c)", false); ctx = engine->CreateContext(); ctx->Prepare(func); // Don't set the object, nor the arguments ctx->Unprepare(); ctx->Release(); } // A test to verify behaviour when exception occurs in script class constructor const char *script2 = "class SomeClassA \n" "{ \n" " int A; \n" " \n" " ~SomeClassA() \n" " { \n" " print('destruct'); \n" " } \n" "} \n" "class SomeClassB \n" "{ \n" " SomeClassA@ nullptr; \n" " SomeClassB(SomeClassA@ aPtr) \n" " { \n" " this.nullptr.A=100; // Null pointer access. After this class a is destroyed. \n" " } \n" "} \n" "void test() \n" "{ \n" " SomeClassA a; \n" " SomeClassB(a); \n" "} \n"; mod->AddScriptSection("script2", script2); r = mod->Build(); if( r < 0 ) TEST_FAILED; r = ExecuteString(engine, "test()", mod); if( r != asEXECUTION_EXCEPTION ) { TEST_FAILED; } engine->GarbageCollect(); engine->Release(); // Problem reported by Philip Bennefall { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterStdString(engine); RegisterScriptArray(engine, true); mod = engine->GetModule("test", asGM_ALWAYS_CREATE); mod->AddScriptSection("test", "string post_score(string url, string channel, string channel_password, int score, string name, string email, string country) \n" "{ \n" " string[] list={'something'}; \n" " return list[1]; \n" "} \n" "void main() \n" "{ \n" " string result=post_score('hello', 'palacepunchup', 'anka', -1, 'Philip', '*****@*****.**', 'Sweden'); \n" "}\n"); r = mod->Build(); if( r < 0 ) TEST_FAILED; asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "main()", mod, ctx); if( r != asEXECUTION_EXCEPTION ) TEST_FAILED; if( string(ctx->GetExceptionString()) != "Index out of bounds" ) TEST_FAILED; if( string(ctx->GetExceptionFunction()->GetName()) != "post_score" ) TEST_FAILED; ctx->Release(); engine->Release(); } // Test exception within default constructor { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); RegisterStdString(engine); mod = engine->GetModule("test", asGM_ALWAYS_CREATE); mod->AddScriptSection("test", "class Test { \n" " string mem = 'hello'; \n" " int a = 0; \n" " int b = 10/a; \n" "}\n"); r = mod->Build(); if( r < 0 ) TEST_FAILED; asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "Test t;", mod, ctx); if( r != asEXECUTION_EXCEPTION ) TEST_FAILED; if( string(ctx->GetExceptionString()) != "Divide by zero" ) { PRINTF("%s\n", ctx->GetExceptionString()); TEST_FAILED; } if( string(ctx->GetExceptionFunction()->GetName()) != "Test" ) TEST_FAILED; ctx->Release(); engine->Release(); } // Test exception in for-condition // http://www.gamedev.net/topic/638128-bug-with-show-code-line-after-null-pointer-exception-and-for/ { engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); mod = engine->GetModule("test", asGM_ALWAYS_CREATE); mod->AddScriptSection("test", "class A\n" "{\n" " int GetCount(){ return 10; }\n" "}\n" "void startGame()\n" "{\n" " A @a = null;\n" " for( int i=0; i < a.GetCount(); i++ )\n" " {\n" " int some_val;\n" " }\n" "}\n"); r = mod->Build(); if( r < 0 ) TEST_FAILED; asIScriptContext *ctx = engine->CreateContext(); r = ExecuteString(engine, "startGame();", mod, ctx); if( r != asEXECUTION_EXCEPTION ) TEST_FAILED; if( string(ctx->GetExceptionString()) != "Null pointer access" ) { PRINTF("%s\n", ctx->GetExceptionString()); TEST_FAILED; } if( string(ctx->GetExceptionFunction()->GetName()) != "startGame" ) TEST_FAILED; if( ctx->GetExceptionLineNumber() != 8 ) TEST_FAILED; ctx->Release(); engine->Release(); } // Test exception handler with thiscall // http://www.gamedev.net/topic/665587-angelscript-ios-x64/ { asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL); mod = engine->GetModule("test", asGM_ALWAYS_CREATE); mod->AddScriptSection("test", "class SomeClass \n" "{ \n" " float some_value; \n" "} \n" "SomeClass @obj; \n" "void test() \n" "{\n" " obj.some_value = 3.14f; \n" "}\n"); r = mod->Build(); if( r < 0 ) TEST_FAILED; ExceptionHandler handler; asIScriptContext *ctx = engine->CreateContext(); ctx->SetExceptionCallback(asMETHOD(ExceptionHandler, Callback), &handler, asCALL_THISCALL); ctx->Prepare(mod->GetFunctionByName("test")); r = ctx->Execute(); if( r != asEXECUTION_EXCEPTION ) TEST_FAILED; ctx->Release(); if( handler.ok == false ) TEST_FAILED; engine->Release(); } // Success return fail; }