bool Test() { bool fail = false; int r = 0; COutStream out; // TODO: Preprocessor directives should be alone on the line asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); // Test the parse token method asETokenClass t = engine->ParseToken("!is"); if( t != asTC_KEYWORD ) fail = true; // Compile a script with meta data strings CScriptBuilder builder; builder.DefineWord("COMPILE"); r = builder.BuildScriptFromMemory(engine, 0, script); #if AS_PROCESS_METADATA == 1 if( r < 0 ) fail = true; int funcId = engine->GetModule(0)->GetFunctionIdByName("func1"); string metadata = builder.GetMetadataStringForFunc(funcId); if( metadata != " my meta data test " ) fail = true; funcId = engine->GetModule(0)->GetFunctionIdByName("func2"); metadata = builder.GetMetadataStringForFunc(funcId); if( metadata != " test['hello'] " ) fail = true; int typeId = engine->GetModule(0)->GetTypeIdByDecl("MyClass"); metadata = builder.GetMetadataStringForType(typeId); if( metadata != " myclass " ) fail = true; typeId = engine->GetModule(0)->GetTypeIdByDecl("MyIntf"); metadata = builder.GetMetadataStringForType(typeId); if( metadata != " myintf " ) fail = true; int varIdx = engine->GetModule(0)->GetGlobalVarIndexByName("g_var"); metadata = builder.GetMetadataStringForVar(varIdx); if( metadata != " init " ) fail = true; varIdx = engine->GetModule(0)->GetGlobalVarIndexByName("g_obj"); metadata = builder.GetMetadataStringForVar(varIdx); if( metadata != " var of type myclass " ) fail = true; #endif engine->Release(); return fail; }
bool ScriptManager::loadFromMemory(const std::string& name, const void* data, size_t len, ScriptType type) { std::string lower; std::transform(name.begin(), name.end(), std::back_inserter(lower), ::tolower); if (type == Type_Autodetect) { if (lower.substr(lower.size() - 4) == ".asb") type = Type_Bytecode; else if (lower.substr(lower.size() - 3) == ".as") type = Type_Text; else return false; } bool reload = mScripts.count(lower) > 0; std::list<asIScriptObject*> changes; asIScriptModule* module = mEngine->GetModule(lower.c_str(), asGM_ONLY_IF_EXISTS); CSerializer serial; if (reload && module) { for (auto& reg : mSerializers) serial.AddUserType(reg.second(), reg.first); for (auto it = mChangeNotice.begin(); it != mChangeNotice.end();) { if (it->second.WeakRef->Get()) { it->second.WeakRef->Release(); it = mChangeNotice.erase(it); continue; } auto* obj = it->first; if (obj->GetObjectType()->GetModule() == module) { serial.AddExtraObjectToStore(obj); changes.push_back(it->first); } ++it; } serial.Store(module); } BytecodeStore bcode; if (type == Type_Text) { static const char* scratchName = "!!ScratchSpace!!"; CScriptBuilder builder; for (auto& def : mDefines) builder.DefineWord(def.c_str()); builder.StartNewModule(mEngine, scratchName); for (auto& callback : mPreLoadCallbacks) if (!callback.second(builder.GetModule())) { mEngine->DiscardModule(scratchName); return false; } builder.AddSectionFromMemory(lower.c_str(), (const char*)data, len); int r = builder.BuildModule(); if (r < 0) { #ifndef NDEBUG puts(ASException::GetMessage(r)); #endif return false; } #ifdef NDEBUG builder.GetModule()->SaveByteCode(&bcode, true); #else builder.GetModule()->SaveByteCode(&bcode, false); #endif mEngine->DiscardModule(scratchName); } else { bcode = BytecodeStore((const char*)data, len); } if (module) module->Discard(); module = mEngine->GetModule(lower.c_str(), asGM_ALWAYS_CREATE); // FIXME? Preload callbacks can not act on bytecode anyway /* if (type == Type_Bytecode) for (auto& callback : mPreLoadCallbacks) if (!callback.second(module)) { module->Discard(); return false; } */ int r = module->LoadByteCode(&bcode); if (r < 0) { module->Discard(); return false; } module->BindAllImportedFunctions(); if (mScripts.count(lower) == 0) { mScripts[lower].Name = name; mScripts[lower].DirectLoad = true; } if (reload) { serial.Restore(module); for (auto& it : changes) { auto* newObj = (asIScriptObject*)serial.GetPointerToRestoredObject(it); auto notice = mChangeNotice[it]; mChangeNotice.erase(it); notice.WeakRef->Release(); notice.Callback(newObj); } mEngine->GarbageCollect(asGC_FULL_CYCLE); } return true; }
bool Test() { bool fail = false; int r = 0; COutStream out; CBufferedOutStream bout; // TODO: Preprocessor directives should be alone on the line asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION); RegisterScriptArray(engine, true); engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL); if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") ) RegisterScriptMathComplex(engine); else engine->RegisterObjectType("complex", 4, asOBJ_VALUE | asOBJ_POD); // Test the parse token method asETokenClass t = engine->ParseToken("!is"); if( t != asTC_KEYWORD ) TEST_FAILED; // Compile a script with meta data strings CScriptBuilder builder; builder.DefineWord("COMPILE"); r = builder.StartNewModule(engine, 0); r = builder.AddSectionFromMemory("", script); r = builder.BuildModule(); #if AS_PROCESS_METADATA == 1 if( r < 0 ) TEST_FAILED; asIScriptFunction *func = engine->GetModule(0)->GetFunctionByName("func1"); string metadata = builder.GetMetadataStringForFunc(func); if( metadata != " my meta data test " ) TEST_FAILED; func = engine->GetModule(0)->GetFunctionByName("func2"); metadata = builder.GetMetadataStringForFunc(func); if( metadata != " test['hello'] " ) TEST_FAILED; engine->GetModule(0)->SetDefaultNamespace("NS"); func = engine->GetModule(0)->GetFunctionByName("func"); metadata = builder.GetMetadataStringForFunc(func); if( metadata != "func" ) TEST_FAILED; engine->GetModule(0)->SetDefaultNamespace(""); int typeId = engine->GetModule(0)->GetTypeIdByDecl("MyClass"); metadata = builder.GetMetadataStringForType(typeId); if( metadata != " myclass " ) TEST_FAILED; typeId = engine->GetModule(0)->GetTypeIdByDecl("NS::Class"); metadata = builder.GetMetadataStringForType(typeId); if( metadata != "class" ) TEST_FAILED; typeId = engine->GetModule(0)->GetTypeIdByDecl("MyClass2"); metadata = builder.GetMetadataStringForTypeProperty(typeId, 0); if( metadata != " edit " ) TEST_FAILED; metadata = builder.GetMetadataStringForTypeProperty(typeId, 1); if( metadata != " noedit " ) TEST_FAILED; metadata = builder.GetMetadataStringForTypeProperty(typeId, 2); if( metadata != " edit,c " ) TEST_FAILED; asIObjectType *type = engine->GetObjectTypeById(typeId); if( type == 0 ) TEST_FAILED; else { metadata = builder.GetMetadataStringForTypeMethod(typeId, type->GetMethodByName("get_prop")); if( metadata != " prop " ) TEST_FAILED; metadata = builder.GetMetadataStringForTypeMethod(typeId, type->GetMethodByName("set_prop")); if( metadata != " prop " ) TEST_FAILED; } typeId = engine->GetModule(0)->GetTypeIdByDecl("MyIntf"); metadata = builder.GetMetadataStringForType(typeId); if( metadata != " myintf " ) TEST_FAILED; int varIdx = engine->GetModule(0)->GetGlobalVarIndexByName("g_var"); metadata = builder.GetMetadataStringForVar(varIdx); if( metadata != " init " ) TEST_FAILED; varIdx = engine->GetModule(0)->GetGlobalVarIndexByName("g_obj"); metadata = builder.GetMetadataStringForVar(varIdx); if( metadata != " var of type myclass " ) TEST_FAILED; #endif // http://www.gamedev.net/topic/624445-cscriptbuilder-asset-string-subscript-out-of-range/ { bout.buffer = ""; CScriptBuilder builder; builder.StartNewModule(engine, "mod"); builder.AddSectionFromMemory("", "#"); engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL); r = builder.BuildModule(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != " (1, 1) : Error : Unexpected token '<unrecognized token>'\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } } // Add a script section from memory with length { engine->SetMessageCallback(asMETHOD(COutStream, Callback), &bout, asCALL_THISCALL); CScriptBuilder builder; builder.StartNewModule(engine, "mod"); builder.AddSectionFromMemory("", "void func() {} $#", 14); r = builder.BuildModule(); if( r < 0 ) TEST_FAILED; } // http://www.gamedev.net/topic/631848-cscriptbuilder-bug/ { bout.buffer = ""; CScriptBuilder builder; builder.StartNewModule(engine, "mod"); builder.AddSectionFromMemory("", "class "); engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL); r = builder.BuildModule(); if( r >= 0 ) TEST_FAILED; if( bout.buffer != " (1, 7) : Error : Expected identifier\n" " (1, 7) : Error : Instead found '<end of file>'\n" " (1, 7) : Error : Expected '{'\n" " (1, 7) : Error : Instead found '<end of file>'\n" ) { printf("%s", bout.buffer.c_str()); TEST_FAILED; } } engine->Release(); return fail; }
static void RegisterDefinedWords(const std::vector<gs2d::str_type::string>& definedWords, CScriptBuilder& builder, const bool isTesting) { #if defined(_DEBUG) || defined(DEBUG) builder.DefineWord("DEBUG"); #endif #ifdef ANDROID builder.DefineWord("ANDROID"); #endif #ifdef APPLE_IOS builder.DefineWord("APPLE_IOS"); #endif #ifdef MACOSX builder.DefineWord("MACOSX"); #endif #ifdef WIN32 builder.DefineWord("WINDOWS"); #endif #ifdef LINUX builder.DefineWord("LINUX"); #endif #if defined(APPLE_IOS) || defined(ANDROID) builder.DefineWord("MOBILE"); builder.DefineWord("MOBILE_DEVICE"); builder.DefineWord("HANDHELD"); builder.DefineWord("HANDHELD_DEVICE"); #endif #if defined(WIN32) || defined(MACOSX) || defined(LINUX) builder.DefineWord("DESKTOP"); #endif if (isTesting) { builder.DefineWord("TESTING"); } // register custom words (defined in the app.enml) for (std::size_t t = 0; t < definedWords.size(); t++) { builder.DefineWord(definedWords[t].c_str()); } }