Просмотр исходного кода

Fix bugs on 64bit archs.
Добавил преобразование объектов в строку через глобальный метод ToString.
Добавил документацию.
Дополнил тесты.
Убрал баг при поиске локальных переменных.
Убрал табуляции.

Fix work with General calling convention.
Add ability to save debug info in compiled sript's bytecode.
Add option `-nostrip` for Scriptompiler.

Aleksandr Orefkov 3 лет назад
Родитель
Сommit
8836e82f2b

+ 3 - 1
Docs/Reference.dox

@@ -731,6 +731,7 @@ The placeholders in a format string are generally defined as {[NumberOrName][%fo
 If a number is specified for insertion, then it indicates the number among the passed parameters.
 If a number is specified for insertion, then it indicates the number among the passed parameters.
 If a name is given, then a variable with the given name is searched in the order: local variables, class members (if the method is called inside a class method), global variables.
 If a name is given, then a variable with the given name is searched in the order: local variables, class members (if the method is called inside a class method), global variables.
 You can also use the name "this" inside class methods. If neither number nor name is specified, the next parameter in order is taken.
 You can also use the name "this" inside class methods. If neither number nor name is specified, the next parameter in order is taken.
+Searching by local variable names only works in scripts built from source code or from bytecode with debug information preserved. To save debugging information, run the ScriptCompiler with the -nostrip option.
 If the passed paramter or founded variable is an object, it is converted to a string as follows - the object method is searched for "String ToString()const", then "String opImplConv()const", then "String toString()const"
 If the passed paramter or founded variable is an object, it is converted to a string as follows - the object method is searched for "String ToString()const", then "String opImplConv()const", then "String toString()const"
 and finally the global method "String ToString(const ObjectTypeName&in)".
 and finally the global method "String ToString(const ObjectTypeName&in)".
 If one of the methods is found, then it is called and its result is used. If no functions are found, the "[object ObjectTypeName ObjectAddress]" is returned.
 If one of the methods is found, then it is called and its result is used. If no functions are found, the "[object ObjectTypeName ObjectAddress]" is returned.
@@ -3648,12 +3649,13 @@ Compiles AngelScript file(s) to binary bytecode for faster loading. Can also dum
 Usage:
 Usage:
 
 
 \verbatim
 \verbatim
-ScriptCompiler <input file> [resource path for includes]
+ScriptCompiler <input file> [resource path for includes] [-nostrip]
 ScriptCompiler -dumpapi <Doxygen output file> [C header output file]
 ScriptCompiler -dumpapi <Doxygen output file> [C header output file]
 
 
 \endverbatim
 \endverbatim
 
 
 The output files are saved with the extension .asc (compiled AngelScript.) binary files are not automatically loaded instead of the text format (.as) script files, instead resource requests and resource references in objects need to point to the compiled files. In a final build of an application it may be convenient to simply replace the text format script files with the compiled scripts.
 The output files are saved with the extension .asc (compiled AngelScript.) binary files are not automatically loaded instead of the text format (.as) script files, instead resource requests and resource references in objects need to point to the compiled files. In a final build of an application it may be convenient to simply replace the text format script files with the compiled scripts.
+By default, debugging information about local variable names is removed from the bytecode. If you use string formatting with local variable names in placeholders, you need to add the -nostrip option when you run the compiler.
 
 
 The script API dump mode can be used to replace the 'ScriptAPI.dox' file in the 'Docs' directory. If the output file name is not provided then the script API would be dumped to standard output (console) instead.
 The script API dump mode can be used to replace the 'ScriptAPI.dox' file in the 'Docs' directory. If the output file name is not provided then the script API would be dumped to standard output (console) instead.
 
 

+ 17 - 7
Source/Tools/ScriptCompiler/ScriptCompiler.cpp

@@ -24,7 +24,7 @@
 
 
 using namespace Urho3D;
 using namespace Urho3D;
 
 
-void CompileScript(Context* context, const String& fileName);
+void CompileScript(Context* context, const String& fileName, bool stripDebugSymbols);
 
 
 int main(int argc, char** argv)
 int main(int argc, char** argv)
 {
 {
@@ -39,7 +39,7 @@ int main(int argc, char** argv)
     String outputFile;
     String outputFile;
 
 
     if (arguments.Size() < 1)
     if (arguments.Size() < 1)
-        ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes]\n"
+        ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes] [-nostrip]\n"
                   "       ScriptCompiler -dumpapi <source tree> <Doxygen output file> [C header output file]");
                   "       ScriptCompiler -dumpapi <source tree> <Doxygen output file> [C header output file]");
     else
     else
     {
     {
@@ -96,20 +96,30 @@ int main(int argc, char** argv)
 
 
         auto* cache = context->GetSubsystem<ResourceCache>();
         auto* cache = context->GetSubsystem<ResourceCache>();
 
 
+        bool stripDebugSymbols = true;
+        for (int idx = arguments.Size() - 1; idx > 0; idx--)
+        {
+            if (arguments[idx] == "-nostrip")
+            {
+                stripDebugSymbols = false;
+                break;
+            }
+        }
+
         // Add resource path to be able to resolve includes
         // Add resource path to be able to resolve includes
-        if (arguments.Size() > 1)
+        if (arguments.Size() > 1 && arguments[1] != "-nostrip")
             cache->AddResourceDir(arguments[1]);
             cache->AddResourceDir(arguments[1]);
         else
         else
             cache->AddResourceDir(cache->GetPreferredResourceDir(path));
             cache->AddResourceDir(cache->GetPreferredResourceDir(path));
 
 
         if (!file.StartsWith("*"))
         if (!file.StartsWith("*"))
-            CompileScript(context, outputFile);
+            CompileScript(context, outputFile, stripDebugSymbols);
         else
         else
         {
         {
             Vector<String> scriptFiles;
             Vector<String> scriptFiles;
             context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false);
             context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false);
             for (unsigned i = 0; i < scriptFiles.Size(); ++i)
             for (unsigned i = 0; i < scriptFiles.Size(); ++i)
-                CompileScript(context, path + scriptFiles[i]);
+                CompileScript(context, path + scriptFiles[i], stripDebugSymbols);
         }
         }
     }
     }
     else
     else
@@ -134,7 +144,7 @@ int main(int argc, char** argv)
     return EXIT_SUCCESS;
     return EXIT_SUCCESS;
 }
 }
 
 
-void CompileScript(Context* context, const String& fileName)
+void CompileScript(Context* context, const String& fileName, bool stripDebugSymbols)
 {
 {
     PrintLine("Compiling script file " + fileName);
     PrintLine("Compiling script file " + fileName);
 
 
@@ -152,5 +162,5 @@ void CompileScript(Context* context, const String& fileName)
     if (!outFile.IsOpen())
     if (!outFile.IsOpen())
         ErrorExit("Failed to open output file " + fileName);
         ErrorExit("Failed to open output file " + fileName);
 
 
-    script.SaveByteCode(outFile);
+    script.SaveByteCode(outFile, stripDebugSymbols);
 }
 }

+ 73 - 25
Source/Urho3D/AngelScript/Manual_Container.cpp

@@ -460,7 +460,30 @@ static String format_argsA(const String& pattern, void* a1, int i1, void* a2, in
     return formatString(pattern, 10, ua);
     return formatString(pattern, 10, ua);
 }
 }
 
 
-
+#ifdef AS_MAX_PORTABILITY
+static void String_Format_gen(asIScriptGeneric* gen)
+{
+    int argsCount = gen->GetArgCount();
+    Vector<as_unkn_arg> args(argsCount);
+    for (int i = 0; i < argsCount; i++)
+    {
+        args[i].typeId = gen->GetArgTypeId(i);
+        args[i].val = gen->GetArgAddress(i);
+    }
+    *static_cast<String*>(gen->GetAddressOfReturnLocation()) = formatString(*static_cast<String*>(gen->GetObject()), argsCount, args.Buffer());
+}
+static void Format_String_gen(asIScriptGeneric* gen)
+{
+    int argsCount = gen->GetArgCount();
+    Vector<as_unkn_arg> args(argsCount - 1);
+    for (int i = 1; i < argsCount; i++)
+    {
+        args[i - 1].typeId = gen->GetArgTypeId(i);
+        args[i - 1].val = gen->GetArgAddress(i);
+    }
+    *static_cast<String*>(gen->GetAddressOfReturnLocation()) = formatString(*static_cast<String*>(gen->GetArgAddress(0)), argsCount - 1, args.Buffer());
+}
+#endif
 
 
 // This function is called after ASRegisterGenerated()
 // This function is called after ASRegisterGenerated()
 void ASRegisterManualLast_Container(asIScriptEngine* engine)
 void ASRegisterManualLast_Container(asIScriptEngine* engine)
@@ -484,30 +507,55 @@ void ASRegisterManualLast_Container(asIScriptEngine* engine)
     engine->RegisterObjectMethod("String", "String& opAssign(bool)", AS_FUNCTION_OBJLAST(StringAssignBool), AS_CALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "String& opAssign(bool)", AS_FUNCTION_OBJLAST(StringAssignBool), AS_CALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "String opAdd(bool) const", AS_FUNCTION_OBJLAST(StringAddBool), AS_CALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "String opAdd(bool) const", AS_FUNCTION_OBJLAST(StringAddBool), AS_CALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "String opAdd_r(bool) const", AS_FUNCTION_OBJLAST(StringAddBoolReverse), AS_CALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "String opAdd_r(bool) const", AS_FUNCTION_OBJLAST(StringAddBoolReverse), AS_CALL_CDECL_OBJLAST);
-
-    engine->RegisterObjectMethod("String", "String f()const", asFUNCTION(format_args0), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0)const", asFUNCTION(format_args1), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1)const", asFUNCTION(format_args2), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2)const", asFUNCTION(format_args3), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3)const", asFUNCTION(format_args4), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4)const", asFUNCTION(format_args5), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5)const",asFUNCTION(format_args6), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6)const", asFUNCTION(format_args7), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7)const", asFUNCTION(format_args8), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8)const", asFUNCTION(format_args9), asCALL_CDECL_OBJFIRST);
-    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8,?&in a9)const",asFUNCTION(format_argsA), asCALL_CDECL_OBJFIRST);
-
-    engine->RegisterGlobalFunction("String format(const String&in pattern)", asFUNCTION(format_args0), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0)", asFUNCTION(format_args1), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1)", asFUNCTION(format_args2), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2)", asFUNCTION(format_args3), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3)", asFUNCTION(format_args4), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4)", asFUNCTION(format_args5), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5)", asFUNCTION(format_args6), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6)", asFUNCTION(format_args7), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7)", asFUNCTION(format_args8), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8)", asFUNCTION(format_args9), asCALL_CDECL);
-    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8,?&in a9)", asFUNCTION(format_argsA), asCALL_CDECL);
+#ifndef AS_MAX_PORTABILITY
+    engine->RegisterObjectMethod("String", "String f()const", AS_FUNCTION_OBJFIRST(format_args0), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0)const", AS_FUNCTION_OBJFIRST(format_args1), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1)const", AS_FUNCTION_OBJFIRST(format_args2), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2)const", AS_FUNCTION_OBJFIRST(format_args3), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3)const", AS_FUNCTION_OBJFIRST(format_args4), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4)const", AS_FUNCTION_OBJFIRST(format_args5), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5)const",AS_FUNCTION_OBJFIRST(format_args6), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6)const", AS_FUNCTION_OBJFIRST(format_args7), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7)const", AS_FUNCTION_OBJFIRST(format_args8), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8)const", AS_FUNCTION_OBJFIRST(format_args9), AS_CALL_CDECL_OBJFIRST);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8,?&in a9)const",AS_FUNCTION_OBJFIRST(format_argsA), AS_CALL_CDECL_OBJFIRST);
+
+    engine->RegisterGlobalFunction("String format(const String&in pattern)", AS_FUNCTION(format_args0), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0)", AS_FUNCTION(format_args1), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1)", AS_FUNCTION(format_args2), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2)", AS_FUNCTION(format_args3), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3)", AS_FUNCTION(format_args4), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4)", AS_FUNCTION(format_args5), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5)", AS_FUNCTION(format_args6), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6)", AS_FUNCTION(format_args7), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7)", AS_FUNCTION(format_args8), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8)", AS_FUNCTION(format_args9), AS_CALL_CDECL);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8,?&in a9)", AS_FUNCTION(format_argsA), AS_CALL_CDECL);
+#else
+    engine->RegisterObjectMethod("String", "String f()const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+    engine->RegisterObjectMethod("String", "String f(?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8,?&in a9)const", asFUNCTION(String_Format_gen), asCALL_GENERIC);
+
+    engine->RegisterGlobalFunction("String format(const String&in pattern)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+    engine->RegisterGlobalFunction("String format(const String&in pattern,?&in a0,?&in a1,?&in a2,?&in a3,?&in a4,?&in a5,?&in a6,?&in a7,?&in a8,?&in a9)", asFUNCTION(Format_String_gen), asCALL_GENERIC);
+#endif
 }
 }
 
 
 }
 }

+ 2 - 2
Source/Urho3D/AngelScript/ScriptFile.cpp

@@ -577,13 +577,13 @@ asIScriptObject* ScriptFile::CreateObject(const String& className, bool useInter
     return obj;
     return obj;
 }
 }
 
 
-bool ScriptFile::SaveByteCode(Serializer& dest)
+bool ScriptFile::SaveByteCode(Serializer& dest, bool stripDebugInfo)
 {
 {
     if (compiled_)
     if (compiled_)
     {
     {
         dest.WriteFileID("ASBC");
         dest.WriteFileID("ASBC");
         ByteCodeSerializer serializer = ByteCodeSerializer(dest);
         ByteCodeSerializer serializer = ByteCodeSerializer(dest);
-        return scriptModule_->SaveByteCode(&serializer, true) >= 0;
+        return scriptModule_->SaveByteCode(&serializer, stripDebugInfo) >= 0;
     }
     }
     else
     else
         return false;
         return false;

+ 1 - 1
Source/Urho3D/AngelScript/ScriptFile.h

@@ -82,7 +82,7 @@ public:
     /// Create a script object. Optionally search for the first class in the module that implements the specified interface.
     /// Create a script object. Optionally search for the first class in the module that implements the specified interface.
     asIScriptObject* CreateObject(const String& className, bool useInterface = false);
     asIScriptObject* CreateObject(const String& className, bool useInterface = false);
     /// Save the script bytecode. Return true if successful.
     /// Save the script bytecode. Return true if successful.
-    bool SaveByteCode(Serializer& dest);
+    bool SaveByteCode(Serializer& dest, bool stripDebugInfo = true);
 
 
     /// Return script module.
     /// Return script module.
     asIScriptModule* GetScriptModule() const { return scriptModule_; }
     asIScriptModule* GetScriptModule() const { return scriptModule_; }