From 4697cd3fb18bcf312cd01e25f238b402c41b2e09 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 2 Jun 2020 14:38:07 +0900 Subject: [PATCH 1/5] add useNashorn flag --- src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt b/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt index a57db5d7..a634b70d 100644 --- a/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt +++ b/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt @@ -29,6 +29,12 @@ object MainConfig { true, "caches compiled script and executed environment") + @JvmField + val useNashorn = config.getBoolean( + "useNashorn", categoryModelLoading, + true, + "use nashorn to execute script (cachedScripts never enabled)") + @JvmField val reduceConstructModelLog = config.getBoolean( "reduceConstructModelLog", categoryModelLoading, From bb4006cfcc6d2ffc625cc3fc49bb28d8d3b417b4 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 2 Jun 2020 15:58:10 +0900 Subject: [PATCH 2/5] add scriptingMode flag --- patches/rtm.patch | 36 +++++------ src/main/java/com/anatawa12/fixRtm/FixRtm.kt | 3 +- .../anatawa12/fixRtm/asm/config/MainConfig.kt | 62 ++++++++++++++++--- 3 files changed, 72 insertions(+), 29 deletions(-) diff --git a/patches/rtm.patch b/patches/rtm.patch index 04fa36d3..69db0886 100644 --- a/patches/rtm.patch +++ b/patches/rtm.patch @@ -895,7 +895,7 @@ index 0a49c17..d210f43 100644 .stack use locals .end stack diff --git a/mods/rtm.deobf.jar.src.processed/jp/ngt/rtm/modelpack/modelset/ModelSetBase.jasm b/src/main/rtm/jp/ngt/rtm/modelpack/modelset/ModelSetBase.jasm -index c1621a2..bfa23df 100644 +index c1621a2..ef1f288 100644 --- a/mods/rtm.deobf.jar.src.processed/jp/ngt/rtm/modelpack/modelset/ModelSetBase.jasm +++ b/src/main/rtm/jp/ngt/rtm/modelpack/modelset/ModelSetBase.jasm @@ -80,22 +80,35 @@ L_0000: @@ -910,18 +910,18 @@ index c1621a2..bfa23df 100644 checkcast jp/ngt/rtm/modelpack/cfg/ModelConfig getfield jp/ngt/rtm/modelpack/cfg/ModelConfig/serverScriptPath Ljava/lang/String; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifDisabled (Ljava/lang/String;)V + invokevirtual jp/ngt/rtm/modelpack/ModelPackManager/getScript (Ljava/lang/String;)Ljava/lang/String; invokestatic jp/ngt/ngtlib/io/ScriptUtil/doScript (Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifEnabled (Ljava/lang/String;)V + + invokestatic com/anatawa12/fixRtm/scripting/FIXScriptUtil/getScriptAndDoScript (Ljp/ngt/rtm/modelpack/ModelPackManager;Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/whatever (Ljava/lang/String;)V + putfield jp/ngt/rtm/modelpack/modelset/ModelSetBase/serverSE Ljavax/script/ScriptEngine; @@ -946,18 +946,18 @@ index c1621a2..bfa23df 100644 checkcast jp/ngt/rtm/modelpack/cfg/ModelConfig getfield jp/ngt/rtm/modelpack/cfg/ModelConfig/serverScriptPath Ljava/lang/String; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifDisabled (Ljava/lang/String;)V + invokevirtual jp/ngt/rtm/modelpack/ModelPackManager/getScript (Ljava/lang/String;)Ljava/lang/String; invokestatic jp/ngt/ngtlib/io/ScriptUtil/doScript (Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifEnabled (Ljava/lang/String;)V + + invokestatic com/anatawa12/fixRtm/scripting/FIXScriptUtil/getScriptAndDoScript (Ljp/ngt/rtm/modelpack/ModelPackManager;Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/whatever (Ljava/lang/String;)V + putfield jp/ngt/rtm/modelpack/modelset/ModelSetBase/serverSE Ljavax/script/ScriptEngine; @@ -980,18 +980,18 @@ index c1621a2..bfa23df 100644 checkcast jp/ngt/rtm/modelpack/cfg/ModelConfig getfield jp/ngt/rtm/modelpack/cfg/ModelConfig/guiScriptPath Ljava/lang/String; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifDisabled (Ljava/lang/String;)V + invokevirtual jp/ngt/rtm/modelpack/ModelPackManager/getScript (Ljava/lang/String;)Ljava/lang/String; invokestatic jp/ngt/ngtlib/io/ScriptUtil/doScript (Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifEnabled (Ljava/lang/String;)V + + invokestatic com/anatawa12/fixRtm/scripting/FIXScriptUtil/getScriptAndDoScript (Ljp/ngt/rtm/modelpack/ModelPackManager;Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/whatever (Ljava/lang/String;)V + putfield jp/ngt/rtm/modelpack/modelset/ModelSetBase/guiSE Ljavax/script/ScriptEngine; @@ -1005,7 +1005,7 @@ index c1621a2..bfa23df 100644 getfield jp/ngt/rtm/modelpack/cfg/ModelConfig/guiTexture Ljava/lang/String; invokevirtual jp/ngt/rtm/modelpack/ModelPackManager/getResource (Ljava/lang/String;)Lnet/minecraft/util/ResourceLocation; diff --git a/mods/rtm.deobf.jar.src.processed/jp/ngt/rtm/modelpack/modelset/ModelSetVehicleBase.jasm b/src/main/rtm/jp/ngt/rtm/modelpack/modelset/ModelSetVehicleBase.jasm -index e05f400..c53b685 100644 +index e05f400..1418cc5 100644 --- a/mods/rtm.deobf.jar.src.processed/jp/ngt/rtm/modelpack/modelset/ModelSetVehicleBase.jasm +++ b/src/main/rtm/jp/ngt/rtm/modelpack/modelset/ModelSetVehicleBase.jasm @@ -192,22 +192,35 @@ L_0068: @@ -1020,18 +1020,18 @@ index e05f400..c53b685 100644 invokevirtual jp/ngt/rtm/modelpack/modelset/ModelSetVehicleBase/getConfig ()Ljp/ngt/rtm/modelpack/cfg/VehicleBaseConfig; getfield jp/ngt/rtm/modelpack/cfg/VehicleBaseConfig/soundScriptPath Ljava/lang/String; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifDisabled (Ljava/lang/String;)V + invokevirtual jp/ngt/rtm/modelpack/ModelPackManager/getScript (Ljava/lang/String;)Ljava/lang/String; invokestatic jp/ngt/ngtlib/io/ScriptUtil/doScript (Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifEnabled (Ljava/lang/String;)V + + invokestatic com/anatawa12/fixRtm/scripting/FIXScriptUtil/getScriptAndDoScript (Ljp/ngt/rtm/modelpack/ModelPackManager;Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/whatever (Ljava/lang/String;)V + putfield jp/ngt/rtm/modelpack/modelset/ModelSetVehicleBase/soundSE Ljavax/script/ScriptEngine; @@ -1392,7 +1392,7 @@ index 283bb01..efd8f8d 100644 invokespecial java/lang/RuntimeException/ (Ljava/lang/String;Ljava/lang/Throwable;)V athrow diff --git a/mods/rtm.deobf.jar.src.processed/jp/ngt/rtm/render/RTMRenderers.jasm b/src/main/rtm/jp/ngt/rtm/render/RTMRenderers.jasm -index 7cd3941..49f40d0 100644 +index 7cd3941..be222d2 100644 --- a/mods/rtm.deobf.jar.src.processed/jp/ngt/rtm/render/RTMRenderers.jasm +++ b/src/main/rtm/jp/ngt/rtm/render/RTMRenderers.jasm @@ -20,30 +20,48 @@ L_0005: @@ -1407,7 +1407,7 @@ index 7cd3941..49f40d0 100644 .var 0 is par1 Lnet/minecraft/util/ResourceLocation; from L_0000 to L_0029 .var 1 is args "[Ljava/lang/String;" from L_0000 to L_0029 + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifDisabled (Ljava/lang/String;)V + getstatic jp/ngt/rtm/modelpack/ModelPackManager/INSTANCE Ljp/ngt/rtm/modelpack/ModelPackManager; @@ -1421,7 +1421,7 @@ index 7cd3941..49f40d0 100644 aload 2 invokestatic jp/ngt/ngtlib/io/ScriptUtil/doScript (Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/ifEnabled (Ljava/lang/String;)V + + aconst_null @@ -1431,7 +1431,7 @@ index 7cd3941..49f40d0 100644 + invokevirtual net/minecraft/util/ResourceLocation/toString ()Ljava/lang/String; + invokestatic com/anatawa12/fixRtm/scripting/FIXScriptUtil/getScriptAndDoScript (Ljava/lang/String;)Ljavax/script/ScriptEngine; + -+ ldc "cachedScripts" ++ ldc "useOurScripting" + invokestatic com/anatawa12/fixRtm/asm/Preprocessor/whatever (Ljava/lang/String;)V + astore 3 diff --git a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt index 41baf074..d977b3cf 100644 --- a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt +++ b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt @@ -4,7 +4,6 @@ import com.anatawa12.fixRtm.asm.config.MainConfig import com.anatawa12.fixRtm.asm.config.MainConfig.changeTestTrainTextureEnabled import com.anatawa12.fixRtm.io.FIXFileLoader import com.anatawa12.fixRtm.network.NetworkHandler -import com.anatawa12.fixRtm.ngtlib.renderer.model.CachedPolygonModel import com.anatawa12.fixRtm.rtm.modelpack.modelset.dummies.* import com.anatawa12.fixRtm.scripting.ExecutedScriptCache import com.anatawa12.fixRtm.scripting.PrimitiveJavaHelper @@ -48,7 +47,7 @@ object FixRtm { NativeJavaObject.canConvert(0, Object::class.java)// load RhinoHooks.load()// load FIXFileLoader.load() // init - if (MainConfig.cachedScripts) { + if (MainConfig.useOurScripting) { ExecutedScriptCache.load()// init loadFIXScriptUtil()// init PrimitiveJavaHelper.load()// init diff --git a/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt b/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt index a634b70d..b26577c2 100644 --- a/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt +++ b/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt @@ -1,6 +1,9 @@ package com.anatawa12.fixRtm.asm.config +import com.anatawa12.fixRtm.Loggers +import net.minecraftforge.common.config.Config import net.minecraftforge.common.config.Configuration +import net.minecraftforge.fml.common.FMLLog import net.minecraftforge.fml.common.Loader object MainConfig { @@ -23,17 +26,41 @@ object MainConfig { true, "caches obj, mqo model.") - @JvmField - val cachedScripts = config.getBoolean( - "cachedScriptsEnabled", categoryModelLoading, - true, - "caches compiled script and executed environment") + private val scriptingModeStr = config.getString( + "scriptingMode", categoryModelLoading, + "use-default", + "scripting mode. the value is one of the list below:\n" + + "cache-with-rhino : the fastest mode but not stable. some script may make error.\n" + + "better-with-nashorn : same runtime as RTM but a little faster than RTM.\n" + + "use-rtm-normal : same as RTM. this is the slowest mode.\n" + + "use-default : use default mode.\n") + + val scriptingMode: ScriptingMode + + init { + val cachedScriptsEnabled = config.getCategory(categoryModelLoading).remove("cachedScriptsEnabled") + if (cachedScriptsEnabled != null) { // cachedScriptsEnabledがある + val categoryModelLoadingProp = config.getCategory("scriptingMode").get(categoryModelLoading)!! + if (categoryModelLoadingProp.string.toLowerCase() == ScriptingMode.defaultConfigValue) { // scriptingModeがuse default + if (!cachedScriptsEnabled.boolean) { // cached scriptがdisable + categoryModelLoadingProp.setValue(ScriptingMode.BetterWithNashorn.configValue) + } + } + } + var scriptingMode = ScriptingMode.getByConfigValue(scriptingModeStr.toLowerCase()) + if (scriptingMode == null) { + if (scriptingModeStr.toLowerCase() == ScriptingMode.defaultConfigValue) { + scriptingMode = ScriptingMode.default + } else { + Loggers.getLogger("Config").fatal("your scriptingMode is not valid so we use default.") + scriptingMode = ScriptingMode.default + } + } + this.scriptingMode = scriptingMode + } @JvmField - val useNashorn = config.getBoolean( - "useNashorn", categoryModelLoading, - true, - "use nashorn to execute script (cachedScripts never enabled)") + val useOurScripting = scriptingMode != ScriptingMode.UseRtmNormal @JvmField val reduceConstructModelLog = config.getBoolean( @@ -76,4 +103,21 @@ object MainConfig { config.save() } } + + enum class ScriptingMode(val configValue: String) { + CacheWithRhino("cache-with-rhino"), + BetterWithNashorn("better-with-nashorn"), + UseRtmNormal("use-rtm-normal"), + ; + + companion object { + private val byConfigValue = values().associateBy { it.configValue } + + fun getByConfigValue(value: String) = byConfigValue[value] + + val default = CacheWithRhino + + const val defaultConfigValue = "use-default" + } + } } From 4042cc8cd9016beff782d3f9bf2c79d1432c7837 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 2 Jun 2020 17:01:24 +0900 Subject: [PATCH 3/5] move classes for rhino --- src/main/java/com/anatawa12/fixRtm/FixRtm.kt | 4 +- .../anatawa12/fixRtm/asm/RhinoTransformer.kt | 40 +++++++-------- .../anatawa12/fixRtm/asm/config/MainConfig.kt | 2 +- .../fixRtm/scripting/FIXScriptUtil.kt | 12 +++-- .../fixRtm/scripting/ScriptImporter.kt | 50 +------------------ .../scripting/{ => rhino}/CodeGenHooks.kt | 7 ++- .../FIXRhinoScriptEngine.kt} | 5 +- .../rhino/ImportScriptRhinoFunctionImpl.kt | 50 +++++++++++++++++++ .../{ => rhino}/PrimitiveJavaHelper.kt | 7 +-- .../scripting/{ => rhino}/RhinoHooks.kt | 6 +-- .../{ => rhino}/ScriptCompiledClassCache.kt | 2 +- .../fixRtm/scripting/{ => rhino}/Util.kt | 2 +- .../scripting/{ => rhino}/inRhinoPackage.kt | 0 13 files changed, 96 insertions(+), 91 deletions(-) rename src/main/java/com/anatawa12/fixRtm/scripting/{ => rhino}/CodeGenHooks.kt (97%) rename src/main/java/com/anatawa12/fixRtm/scripting/{FIXScriptEngine.kt => rhino/FIXRhinoScriptEngine.kt} (94%) create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/rhino/ImportScriptRhinoFunctionImpl.kt rename src/main/java/com/anatawa12/fixRtm/scripting/{ => rhino}/PrimitiveJavaHelper.kt (90%) rename src/main/java/com/anatawa12/fixRtm/scripting/{ => rhino}/RhinoHooks.kt (97%) rename src/main/java/com/anatawa12/fixRtm/scripting/{ => rhino}/ScriptCompiledClassCache.kt (98%) rename src/main/java/com/anatawa12/fixRtm/scripting/{ => rhino}/Util.kt (82%) rename src/main/java/com/anatawa12/fixRtm/scripting/{ => rhino}/inRhinoPackage.kt (100%) diff --git a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt index d977b3cf..660707bc 100644 --- a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt +++ b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt @@ -6,8 +6,8 @@ import com.anatawa12.fixRtm.io.FIXFileLoader import com.anatawa12.fixRtm.network.NetworkHandler import com.anatawa12.fixRtm.rtm.modelpack.modelset.dummies.* import com.anatawa12.fixRtm.scripting.ExecutedScriptCache -import com.anatawa12.fixRtm.scripting.PrimitiveJavaHelper -import com.anatawa12.fixRtm.scripting.RhinoHooks +import com.anatawa12.fixRtm.scripting.rhino.PrimitiveJavaHelper +import com.anatawa12.fixRtm.scripting.rhino.RhinoHooks import com.anatawa12.fixRtm.scripting.loadFIXScriptUtil import jp.ngt.ngtlib.NGTCore import jp.ngt.rtm.RTMCore diff --git a/src/main/java/com/anatawa12/fixRtm/asm/RhinoTransformer.kt b/src/main/java/com/anatawa12/fixRtm/asm/RhinoTransformer.kt index 8b79cf5c..64e5e561 100644 --- a/src/main/java/com/anatawa12/fixRtm/asm/RhinoTransformer.kt +++ b/src/main/java/com/anatawa12/fixRtm/asm/RhinoTransformer.kt @@ -1,24 +1,24 @@ package com.anatawa12.fixRtm.asm -import com.anatawa12.fixRtm.scripting.CodeGenHooks.ClassCompiler_compileToClassFiles_desc -import com.anatawa12.fixRtm.scripting.CodeGenHooks.ClassCompiler_compileToClassFiles_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.ClassCompiler_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.CodeGenHooks_implDecompile_desc -import com.anatawa12.fixRtm.scripting.CodeGenHooks.CodeGenHooks_implDecompile_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.CodeGenHooks_internal -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_generateNativeFunctionOverrides_desc -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_generateNativeFunctionOverrides_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_internal -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_scriptOrFnNodes_desc -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_scriptOrFnNodes_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_sourceString_desc -import com.anatawa12.fixRtm.scripting.CodeGenHooks.Codegen_sourceString_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.NativeFunction_decompile_desc -import com.anatawa12.fixRtm.scripting.CodeGenHooks.NativeFunction_decompile_name -import com.anatawa12.fixRtm.scripting.CodeGenHooks.NativeFunction_name -import com.anatawa12.fixRtm.scripting.PrimitiveJavaHelper -import com.anatawa12.fixRtm.scripting.RhinoHooks +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.ClassCompiler_compileToClassFiles_desc +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.ClassCompiler_compileToClassFiles_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.ClassCompiler_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.CodeGenHooks_implDecompile_desc +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.CodeGenHooks_implDecompile_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.CodeGenHooks_internal +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_generateNativeFunctionOverrides_desc +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_generateNativeFunctionOverrides_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_internal +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_scriptOrFnNodes_desc +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_scriptOrFnNodes_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_sourceString_desc +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.Codegen_sourceString_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.NativeFunction_decompile_desc +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.NativeFunction_decompile_name +import com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks.NativeFunction_name +import com.anatawa12.fixRtm.scripting.rhino.PrimitiveJavaHelper +import com.anatawa12.fixRtm.scripting.rhino.RhinoHooks import net.minecraft.launchwrapper.IClassTransformer import org.objectweb.asm.* import org.objectweb.asm.Opcodes.* @@ -346,7 +346,7 @@ class RhinoTransformer : IClassTransformer { companion object { const val NativeJavaObject_name = "org.mozilla.javascript.NativeJavaObject" const val NativeJavaObject_internal = "org/mozilla/javascript/NativeJavaObject" - const val CoerceTypeImplFailed_internal = "com/anatawa12/fixRtm/scripting/CoerceTypeImplFailed" + const val CoerceTypeImplFailed_internal = "com/anatawa12/fixRtm/scripting/rhino/CoerceTypeImplFailed" const val IdScriptableObject_internal = "org/mozilla/javascript/IdScriptableObject" const val Scriptable_internal = "org/mozilla/javascript/Scriptable" const val Scriptable_NOT_FOUND_name = "NOT_FOUND" diff --git a/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt b/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt index b26577c2..2ac40ed1 100644 --- a/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt +++ b/src/main/java/com/anatawa12/fixRtm/asm/config/MainConfig.kt @@ -40,7 +40,7 @@ object MainConfig { init { val cachedScriptsEnabled = config.getCategory(categoryModelLoading).remove("cachedScriptsEnabled") if (cachedScriptsEnabled != null) { // cachedScriptsEnabledがある - val categoryModelLoadingProp = config.getCategory("scriptingMode").get(categoryModelLoading)!! + val categoryModelLoadingProp = config.getCategory(categoryModelLoading).get("scriptingMode")!! if (categoryModelLoadingProp.string.toLowerCase() == ScriptingMode.defaultConfigValue) { // scriptingModeがuse default if (!cachedScriptsEnabled.boolean) { // cached scriptがdisable categoryModelLoadingProp.setValue(ScriptingMode.BetterWithNashorn.configValue) diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt b/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt index fb237f8c..80b93929 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt @@ -6,6 +6,10 @@ import com.anatawa12.fixRtm.caching.ModelPackBasedCache import com.anatawa12.fixRtm.fixCacheDir import com.anatawa12.fixRtm.io.FIXFileLoader import com.anatawa12.fixRtm.io.FIXModelPack +import com.anatawa12.fixRtm.scripting.rhino.FIXRhinoScriptEngine +import com.anatawa12.fixRtm.scripting.rhino.ImportScriptRhinoFunctionImpl +import com.anatawa12.fixRtm.scripting.rhino.ScriptCompiledClassCache +import com.anatawa12.fixRtm.scripting.rhino.usingContext import com.anatawa12.fixRtm.utils.DigestUtils import jp.ngt.rtm.modelpack.ModelPackManager import net.minecraft.util.ResourceLocation @@ -19,7 +23,7 @@ val baseScope = usingContext { it.initStandardObjects(scope) - ScriptImporter.init(scope) + ImportScriptRhinoFunctionImpl.init(scope) scope.sealObject() @@ -59,17 +63,17 @@ fun ModelPackManager.getScriptAndDoScript(fileName: String): ScriptEngine { // first, try cache getScriptAndDoScriptByCache(filePath, resource.pack, dependencies)?.let { scope -> - val engine = FIXScriptEngine() + val engine = FIXRhinoScriptEngine() engine.scope = scope return engine } // then evalute - val engine = FIXScriptEngine() + val engine = FIXRhinoScriptEngine() usingContext { cx -> val scope = makeNewScope() - val script = ScriptImporter.makeScript(filePath, scriptStr, resource.pack) + val script = ImportScriptRhinoFunctionImpl.makeScript(filePath, scriptStr, resource.pack) script.exec(cx, scope) diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/ScriptImporter.kt b/src/main/java/com/anatawa12/fixRtm/scripting/ScriptImporter.kt index 8afe6484..0da925ad 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/ScriptImporter.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/ScriptImporter.kt @@ -1,37 +1,14 @@ package com.anatawa12.fixRtm.scripting import com.anatawa12.fixRtm.io.FIXFileLoader -import com.anatawa12.fixRtm.io.FIXModelPack -import com.anatawa12.fixRtm.io.FIXResource -import net.minecraft.client.resources.IResource import net.minecraft.util.ResourceLocation -import org.mozilla.javascript.* +import org.mozilla.javascript.ScriptRuntime import java.util.concurrent.ConcurrentHashMap object ScriptImporter { const val importScriptFunctionName = "__\$\$fixrtm_internal_function_importScript\$\$__" - private val importScriptFunction = ImportScriptFunctionImpl as BaseFunction - - fun importScript(cx: Context, name: String, scope: Scriptable) { - val script = getScript(name) - script.exec(cx, scope) - } - - fun getScript(name: String): Script { - val resourceLocation = ResourceLocation(name) - val resource = FIXFileLoader.getResource(resourceLocation) - val script = resource.inputStream.reader().use { it.readText() } - return makeScript(resourceLocation, script, resource.pack) - } - - fun makeScript(location: ResourceLocation, script: String, pack: FIXModelPack? = null): Script { - val script = preprocessScript(script) - val name = if (pack != null) "$location(${pack.file.name})" else "$location" - return ScriptCompiledClassCache.compile(script, name) - } - private val allDependenceScripts = ConcurrentHashMap>() fun getAllDependenceScripts(name: String): Map { @@ -59,29 +36,4 @@ object ScriptImporter { """;$importScriptFunctionName("${ScriptRuntime.escapeString(result.groupValues[1])}");""" } } - - - private object ImportScriptFunctionImpl : BaseFunction() { - override fun call(cx: Context, scope: Scriptable, thisObj: Scriptable, args: Array): Any? { - if (args.size != 1) - ScriptRuntime.typeError("invalid arguments: argument length must be 1") - val name = ScriptRuntime.toString(args[0]) - - importScript(cx, name, scope) - - return Undefined.instance - } - - override fun getFunctionName(): String = importScriptFunctionName - } - - fun init(scope: ScriptableObject) { - usingContext { cx -> - scope.defineProperty( - importScriptFunction.functionName, - importScriptFunction, - ScriptableObject.READONLY or ScriptableObject.DONTENUM - ) - } - } } diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/CodeGenHooks.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/CodeGenHooks.kt similarity index 97% rename from src/main/java/com/anatawa12/fixRtm/scripting/CodeGenHooks.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/CodeGenHooks.kt index 962c2455..66a3ac07 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/CodeGenHooks.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/CodeGenHooks.kt @@ -1,6 +1,5 @@ -package com.anatawa12.fixRtm.scripting +package com.anatawa12.fixRtm.scripting.rhino -import org.mozilla.classfile.ByteCode import org.mozilla.classfile.ByteCode.* import org.mozilla.classfile.ClassFileWriter import org.mozilla.classfile.ClassFileWriter.classNameToSignature @@ -95,8 +94,8 @@ object CodeGenHooks { const val NativeFunction_decompile_name = "decompile" const val NativeFunction_decompile_desc = "(II)L${"java/lang/String"};" - const val CodeGenHooks_name = "com.anatawa12.fixRtm.scripting.CodeGenHooks" - const val CodeGenHooks_internal = "com/anatawa12/fixRtm/scripting/CodeGenHooks" + const val CodeGenHooks_name = "com.anatawa12.fixRtm.scripting.rhino.CodeGenHooks" + const val CodeGenHooks_internal = "com/anatawa12/fixRtm/scripting/rhino/CodeGenHooks" const val CodeGenHooks_implDecompile_name = "implDecompile" const val CodeGenHooks_implDecompile_desc = "(L${"org/mozilla/classfile/ClassFileWriter"};[L${"org/mozilla/javascript/ast/ScriptNode"};L${"java/lang/String"};)V" diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptEngine.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/FIXRhinoScriptEngine.kt similarity index 94% rename from src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptEngine.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/FIXRhinoScriptEngine.kt index 30d9308e..4a70a498 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptEngine.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/FIXRhinoScriptEngine.kt @@ -1,12 +1,11 @@ -package com.anatawa12.fixRtm.scripting +package com.anatawa12.fixRtm.scripting.rhino import org.mozilla.javascript.Function -import org.mozilla.javascript.NativeObject import org.mozilla.javascript.ScriptableObject import java.io.Reader import javax.script.* -class FIXScriptEngine : ScriptEngine, Invocable { +class FIXRhinoScriptEngine : ScriptEngine, Invocable { lateinit var scope: ScriptableObject override fun createBindings(): Bindings { diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/rhino/ImportScriptRhinoFunctionImpl.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/ImportScriptRhinoFunctionImpl.kt new file mode 100644 index 00000000..a73c129c --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/ImportScriptRhinoFunctionImpl.kt @@ -0,0 +1,50 @@ +package com.anatawa12.fixRtm.scripting.rhino + +import com.anatawa12.fixRtm.io.FIXFileLoader +import com.anatawa12.fixRtm.io.FIXModelPack +import com.anatawa12.fixRtm.scripting.ScriptImporter +import net.minecraft.util.ResourceLocation +import org.mozilla.javascript.* + + +object ImportScriptRhinoFunctionImpl : BaseFunction() { + fun getScript(name: String): Script { + val resourceLocation = ResourceLocation(name) + val resource = FIXFileLoader.getResource(resourceLocation) + val script = resource.inputStream.reader().use { it.readText() } + return makeScript(resourceLocation, script, resource.pack) + } + + fun makeScript(location: ResourceLocation, script: String, pack: FIXModelPack? = null): Script { + val script = ScriptImporter.preprocessScript(script) + val name = if (pack != null) "$location(${pack.file.name})" else "$location" + return ScriptCompiledClassCache.compile(script, name) + } + + fun importScript(cx: Context, name: String, scope: Scriptable) { + val script = getScript(name) + script.exec(cx, scope) + } + + override fun call(cx: Context, scope: Scriptable, thisObj: Scriptable, args: Array): Any? { + if (args.size != 1) + ScriptRuntime.typeError("invalid arguments: argument length must be 1") + val name = ScriptRuntime.toString(args[0]) + + importScript(cx, name, scope) + + return Undefined.instance + } + + override fun getFunctionName(): String = ScriptImporter.importScriptFunctionName + + fun init(scope: ScriptableObject) { + usingContext { cx -> + scope.defineProperty( + ImportScriptRhinoFunctionImpl.functionName, + ImportScriptRhinoFunctionImpl, + ScriptableObject.READONLY or ScriptableObject.DONTENUM + ) + } + } +} diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/PrimitiveJavaHelper.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt similarity index 90% rename from src/main/java/com/anatawa12/fixRtm/scripting/PrimitiveJavaHelper.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt index c5cf4c67..3908c26f 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/PrimitiveJavaHelper.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt @@ -1,10 +1,11 @@ -package com.anatawa12.fixRtm.scripting +package com.anatawa12.fixRtm.scripting.rhino +import com.anatawa12.fixRtm.scripting.baseScope import org.mozilla.javascript.* @Suppress("FunctionName") object PrimitiveJavaHelper { - const val internalClassName = "com/anatawa12/fixRtm/scripting/PrimitiveJavaHelper" + const val internalClassName = "com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper" const val NativeString_name = "org.mozilla.javascript.NativeString" const val NativeString_internal = "org/mozilla/javascript/NativeString" @@ -25,7 +26,7 @@ object PrimitiveJavaHelper { private fun wrapFunctionForString(scriptable: Any?): Any? { if (scriptable is NativeJavaMethod) - return FixRTMWrappedFunction(scriptable, ::getStringInstance) + return FixRTMWrappedFunction(scriptable, PrimitiveJavaHelper::getStringInstance) else return scriptable } diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/RhinoHooks.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoHooks.kt similarity index 97% rename from src/main/java/com/anatawa12/fixRtm/scripting/RhinoHooks.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoHooks.kt index e77f847f..c78381f4 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/RhinoHooks.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoHooks.kt @@ -1,4 +1,4 @@ -package com.anatawa12.fixRtm.scripting +package com.anatawa12.fixRtm.scripting.rhino import org.mozilla.javascript.* @@ -8,8 +8,8 @@ object CoerceTypeImplFailed * hooks used from Rhino by transformer */ object RhinoHooks { - const val className = "com.anatawa12.fixRtm.scripting.RhinoHooks" - const val internalClassName = "com/anatawa12/fixRtm/scripting/RhinoHooks" + const val className = "com.anatawa12.fixRtm.scripting.rhino.RhinoHooks" + const val internalClassName = "com/anatawa12/fixRtm/scripting/rhino/RhinoHooks" const val coerceTypeImpl_name = "coerceTypeImpl" const val coerceTypeImpl_desc = "(L${"java/lang/Class"};L${"java/lang/Object"};)L${"java/lang/Object"};" diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/ScriptCompiledClassCache.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/ScriptCompiledClassCache.kt similarity index 98% rename from src/main/java/com/anatawa12/fixRtm/scripting/ScriptCompiledClassCache.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/ScriptCompiledClassCache.kt index 0b8b2016..082a2a87 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/ScriptCompiledClassCache.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/ScriptCompiledClassCache.kt @@ -1,4 +1,4 @@ -package com.anatawa12.fixRtm.scripting +package com.anatawa12.fixRtm.scripting.rhino import com.anatawa12.fixRtm.Loggers import com.anatawa12.fixRtm.fixCacheDir diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/Util.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/Util.kt similarity index 82% rename from src/main/java/com/anatawa12/fixRtm/scripting/Util.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/Util.kt index 71b1c4f4..3acada86 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/Util.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/Util.kt @@ -1,4 +1,4 @@ -package com.anatawa12.fixRtm.scripting +package com.anatawa12.fixRtm.scripting.rhino import org.mozilla.javascript.Context diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/inRhinoPackage.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/inRhinoPackage.kt similarity index 100% rename from src/main/java/com/anatawa12/fixRtm/scripting/inRhinoPackage.kt rename to src/main/java/com/anatawa12/fixRtm/scripting/rhino/inRhinoPackage.kt From ce6a43a49bbd5f3cb71c1a0faa124d26344e42c6 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Wed, 3 Jun 2020 22:20:51 +0900 Subject: [PATCH 4/5] =?UTF-8?q?FIXScriptUtil=E3=81=A7=E3=81=AE=E3=83=A9?= =?UTF-8?q?=E3=83=B3=E3=82=BF=E3=82=A4=E3=83=A0=E4=BE=9D=E5=AD=98=E3=82=92?= =?UTF-8?q?IScriptRuntime=E3=81=A7=E3=81=AA=E3=81=8F=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/anatawa12/fixRtm/FixRtm.kt | 21 ++- .../fixRtm/scripting/FIXScriptUtil.kt | 128 +++--------------- .../fixRtm/scripting/IScriptRuntime.kt | 53 ++++++++ .../scripting/rhino/PrimitiveJavaHelper.kt | 3 +- .../scripting/rhino/RhinoScriptRuntimeImpl.kt | 126 +++++++++++++++++ 5 files changed, 212 insertions(+), 119 deletions(-) create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/IScriptRuntime.kt create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoScriptRuntimeImpl.kt diff --git a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt index 660707bc..562bc1ee 100644 --- a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt +++ b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt @@ -5,10 +5,10 @@ import com.anatawa12.fixRtm.asm.config.MainConfig.changeTestTrainTextureEnabled import com.anatawa12.fixRtm.io.FIXFileLoader import com.anatawa12.fixRtm.network.NetworkHandler import com.anatawa12.fixRtm.rtm.modelpack.modelset.dummies.* -import com.anatawa12.fixRtm.scripting.ExecutedScriptCache +import com.anatawa12.fixRtm.scripting.loadFIXScriptUtil +import com.anatawa12.fixRtm.scripting.rhino.ExecutedScriptCache import com.anatawa12.fixRtm.scripting.rhino.PrimitiveJavaHelper import com.anatawa12.fixRtm.scripting.rhino.RhinoHooks -import com.anatawa12.fixRtm.scripting.loadFIXScriptUtil import jp.ngt.ngtlib.NGTCore import jp.ngt.rtm.RTMCore import net.minecraft.block.Block @@ -45,12 +45,19 @@ object FixRtm { @Mod.EventHandler fun construct(e: FMLConstructionEvent) { NativeJavaObject.canConvert(0, Object::class.java)// load - RhinoHooks.load()// load FIXFileLoader.load() // init - if (MainConfig.useOurScripting) { - ExecutedScriptCache.load()// init - loadFIXScriptUtil()// init - PrimitiveJavaHelper.load()// init + when (MainConfig.scriptingMode) { + MainConfig.ScriptingMode.CacheWithRhino -> { + loadFIXScriptUtil()// init + ExecutedScriptCache.load()// init + PrimitiveJavaHelper.load()// init + RhinoHooks.load()// load + } + MainConfig.ScriptingMode.BetterWithNashorn -> { + } + MainConfig.ScriptingMode.UseRtmNormal -> { + // nop + } } if (e.side == Side.CLIENT) registerGenerators() } diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt b/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt index 80b93929..79232fa6 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt @@ -2,139 +2,47 @@ package com.anatawa12.fixRtm.scripting -import com.anatawa12.fixRtm.caching.ModelPackBasedCache -import com.anatawa12.fixRtm.fixCacheDir +import com.anatawa12.fixRtm.asm.config.MainConfig import com.anatawa12.fixRtm.io.FIXFileLoader -import com.anatawa12.fixRtm.io.FIXModelPack -import com.anatawa12.fixRtm.scripting.rhino.FIXRhinoScriptEngine -import com.anatawa12.fixRtm.scripting.rhino.ImportScriptRhinoFunctionImpl -import com.anatawa12.fixRtm.scripting.rhino.ScriptCompiledClassCache -import com.anatawa12.fixRtm.scripting.rhino.usingContext -import com.anatawa12.fixRtm.utils.DigestUtils +import com.anatawa12.fixRtm.scripting.rhino.RhinoScriptRuntimeImpl import jp.ngt.rtm.modelpack.ModelPackManager import net.minecraft.util.ResourceLocation -import org.mozilla.javascript.ImporterTopLevel -import org.mozilla.javascript.ScriptableObject -import org.mozilla.javascript.TopLevel import javax.script.ScriptEngine -val baseScope = usingContext { - val scope = TopLevel() - - it.initStandardObjects(scope) - - ImportScriptRhinoFunctionImpl.init(scope) - - scope.sealObject() - - scope +val scriptRuntime: IScriptRuntime<*, *> = when (MainConfig.scriptingMode) { + MainConfig.ScriptingMode.CacheWithRhino -> RhinoScriptRuntimeImpl + MainConfig.ScriptingMode.BetterWithNashorn -> TODO() + MainConfig.ScriptingMode.UseRtmNormal -> IScriptRuntime.AssertingRuntime } fun loadFIXScriptUtil() {} -private fun makeNewScope(): ScriptableObject = usingContext { - it.applicationClassLoader = ScriptCompiledClassCache.Loader - - val scope = ImporterTopLevel(it, false) - scope.prototype = baseScope - return scope -} - -fun makeNewScopeWithCache(cache: ExecutedScript): ScriptableObject? { - usingContext { - ScriptCompiledClassCache.initContext(it) - return cache.getScope(baseScope) - } -} +@Suppress("unused") +fun ModelPackManager.getScriptAndDoScript(fileName: String): ScriptEngine + = com.anatawa12.fixRtm.scripting.getScriptAndDoScript(fileName) -fun makeExecutedScript(dependencies: Map, scope: ScriptableObject): ExecutedScript { - usingContext { - ScriptCompiledClassCache.initContext(it) - return ExecutedScript(dependencies, scope, baseScope) - } +@Suppress("unused") +fun getScriptAndDoScript(fileName: String): ScriptEngine { + return getScriptAndDoScript(scriptRuntime, fileName) } @Suppress("unused") -fun ModelPackManager.getScriptAndDoScript(fileName: String): ScriptEngine { +fun getScriptAndDoScript(runtime: IScriptRuntime, fileName: String): ScriptEngine { val filePath = ResourceLocation(fileName) val resource = FIXFileLoader.getResource(filePath) val scriptStr = resource.inputStream.reader().use { it.readText() } - val dependencies = makeDependenciesData(ScriptImporter.getAllDependenceScripts(filePath, scriptStr)) + val dependencies = ScriptImporter.getAllDependenceScripts(filePath, scriptStr) - // first, try cache - getScriptAndDoScriptByCache(filePath, resource.pack, dependencies)?.let { scope -> - val engine = FIXRhinoScriptEngine() - engine.scope = scope - return engine - } + runtime.getCachedEngine(filePath, resource, dependencies)?.let { return it } // then evalute - val engine = FIXRhinoScriptEngine() - usingContext { cx -> - val scope = makeNewScope() - - val script = ImportScriptRhinoFunctionImpl.makeScript(filePath, scriptStr, resource.pack) - - script.exec(cx, scope) + val script = runtime.compile(filePath, scriptStr, resource.pack) - engine.scope = scope - } + val engine = runtime.exec(script) // add to cache - ExecutedScriptCache.add(resource.pack, filePath, makeExecutedScript(dependencies, engine.scope)) + runtime.cache(resource.pack, filePath, dependencies, engine) return engine } - -fun getScriptAndDoScriptByCache(filePath: ResourceLocation, pack: FIXModelPack, dependencies: Map): ScriptableObject? { - val cache = ExecutedScriptCache.getScript(pack, filePath) ?: return null - - // verify cache - if (cache.dependencies.keys != dependencies.keys) return null - - for ((name, hash) in dependencies) { - if (!cache.dependencies[name]!!.contentEquals(hash)) return null - } - - // load cache - - val newScope = makeNewScopeWithCache(cache) - if (newScope == null) { - ExecutedScriptCache.discord(pack, filePath) - } - return newScope -} - -fun makeDependenciesData(dependencies: Map): Map { - val data = mutableMapOf() - for ((name, script) in dependencies) { - data[name.toString()] = DigestUtils.sha1(script) - } - return data -} - -@Suppress("unused") -fun getScriptAndDoScript(fileName: String): ScriptEngine = ModelPackManager.INSTANCE.getScriptAndDoScript(fileName) - -object ExecutedScriptCache { - private val cache = ModelPackBasedCache( - fixCacheDir.resolve("excluded-script"), - 0x0000 to ExecutedScript.Serializer - ) - - fun getScript(pack: FIXModelPack, filePath: ResourceLocation): ExecutedScript? { - return cache.get(pack, DigestUtils.sha1Hex(filePath.toString()), ExecutedScript.Serializer) - } - - fun add(pack: FIXModelPack, filePath: ResourceLocation, executedScript: ExecutedScript) { - cache.put(pack, DigestUtils.sha1Hex(filePath.toString()), executedScript) - } - - fun discord(pack: FIXModelPack, filePath: ResourceLocation) { - cache.discord(pack, DigestUtils.sha1Hex(filePath.toString())) - } - - fun load() {} -} - diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/IScriptRuntime.kt b/src/main/java/com/anatawa12/fixRtm/scripting/IScriptRuntime.kt new file mode 100644 index 00000000..8dfaa930 --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/IScriptRuntime.kt @@ -0,0 +1,53 @@ +package com.anatawa12.fixRtm.scripting + +import com.anatawa12.fixRtm.io.FIXModelPack +import com.anatawa12.fixRtm.io.FIXResource +import net.minecraft.util.ResourceLocation +import javax.script.ScriptEngine + +interface IScriptRuntime { + /** + * @param filePath the path of script + * @param resource [FIXResource] of the script + * @param dependencies all dependency script name and body + * @return cached [Engine] if found, returns null if cache is not found or not supported. + */ + fun getCachedEngine(filePath: ResourceLocation, resource: FIXResource, dependencies: Map): Engine? + + /** + * @param location the path of script + * @param script body of script + * @param pack model pack of the script + * @param engine the engine for which runtime compile. + */ + fun compile(location: ResourceLocation, script: String, pack: FIXModelPack? = null, engine: Engine? = null): CompiledScript { + val preprocessed = ScriptImporter.preprocessScript(script) + val name = if (pack != null) "$location(${pack.file.name})" else "$location" + return compile(preprocessed, name, engine = engine) + } + + /** + * @param script body of script + * @param fileName name of the script + * @param engine the engine for which runtime compile. + */ + fun compile(script: String, fileName: String, engine: Engine? = null): CompiledScript + + fun exec(script: CompiledScript): Engine + + fun cache(pack: FIXModelPack, filePath: ResourceLocation, dependencies: Map, engine: Engine) + + object AssertingRuntime : IScriptRuntime { + override fun getCachedEngine(filePath: ResourceLocation, resource: FIXResource, dependencies: Map): Nothing? + = throw AssertionError("IScriptRuntime should be never used") + + override fun compile(script: String, fileName: String, engine: Nothing?): Nothing + = throw AssertionError("IScriptRuntime should be never used") + + override fun exec(script: Nothing): Nothing + = throw AssertionError("IScriptRuntime should be never used") + + override fun cache(pack: FIXModelPack, filePath: ResourceLocation, dependencies: Map, engine: Nothing) + = throw AssertionError("IScriptRuntime should be never used") + } +} diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt index 3908c26f..6cd2054c 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/PrimitiveJavaHelper.kt @@ -1,6 +1,5 @@ package com.anatawa12.fixRtm.scripting.rhino -import com.anatawa12.fixRtm.scripting.baseScope import org.mozilla.javascript.* @Suppress("FunctionName") @@ -22,7 +21,7 @@ object PrimitiveJavaHelper { return wrapFunctionForString(stringObject.get(name, start)) } - private val stringObject = usingContext { NativeJavaObject(baseScope, "", null) } + private val stringObject = usingContext { NativeJavaObject(RhinoScriptRuntimeImpl.baseScope, "", null) } private fun wrapFunctionForString(scriptable: Any?): Any? { if (scriptable is NativeJavaMethod) diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoScriptRuntimeImpl.kt b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoScriptRuntimeImpl.kt new file mode 100644 index 00000000..4667413d --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/rhino/RhinoScriptRuntimeImpl.kt @@ -0,0 +1,126 @@ +package com.anatawa12.fixRtm.scripting.rhino + +import com.anatawa12.fixRtm.caching.ModelPackBasedCache +import com.anatawa12.fixRtm.fixCacheDir +import com.anatawa12.fixRtm.io.FIXModelPack +import com.anatawa12.fixRtm.io.FIXResource +import com.anatawa12.fixRtm.scripting.ExecutedScript +import com.anatawa12.fixRtm.scripting.IScriptRuntime +import com.anatawa12.fixRtm.utils.DigestUtils +import net.minecraft.util.ResourceLocation +import org.mozilla.javascript.ImporterTopLevel +import org.mozilla.javascript.Script +import org.mozilla.javascript.ScriptableObject +import org.mozilla.javascript.TopLevel + +object RhinoScriptRuntimeImpl : IScriptRuntime { + override fun getCachedEngine(filePath: ResourceLocation, resource: FIXResource, dependencies: Map): FIXRhinoScriptEngine? { + return getScriptAndDoScriptByCache(filePath, resource.pack, makeDependenciesData(dependencies)) + ?.let { scope -> FIXRhinoScriptEngine().also { it.scope = scope } } + } + + override fun compile(script: String, fileName: String, engine: FIXRhinoScriptEngine?): Script =usingContext { cx -> + return ScriptCompiledClassCache.compile(script, fileName) + } + + override fun exec(script: Script): FIXRhinoScriptEngine { + val engine = FIXRhinoScriptEngine() + usingContext { cx -> + val scope = makeNewScope() + + script.exec(cx, scope) + + engine.scope = scope + } + + return engine + } + + override fun cache(pack: FIXModelPack, filePath: ResourceLocation, dependencies: Map, engine: FIXRhinoScriptEngine) { + ExecutedScriptCache.add(pack, filePath, makeExecutedScript(makeDependenciesData(dependencies), engine.scope)) + } + + val baseScope = usingContext { + val scope = TopLevel() + + it.initStandardObjects(scope) + + ImportScriptRhinoFunctionImpl.init(scope) + + scope.sealObject() + + scope + } + + //////////////////////////////////////////////////////////////// + + private fun makeNewScope(): ScriptableObject = usingContext { + ScriptCompiledClassCache.initContext(it) + + val scope = ImporterTopLevel(it, false) + scope.prototype = baseScope + return scope + } + + private fun makeNewScopeWithCache(cache: ExecutedScript): ScriptableObject? = usingContext { + ScriptCompiledClassCache.initContext(it) + + return cache.getScope(baseScope) + } + + private fun makeExecutedScript(dependencies: Map, scope: ScriptableObject): ExecutedScript = usingContext { + ScriptCompiledClassCache.initContext(it) + + return ExecutedScript(dependencies, scope, baseScope) + } + + private fun getScriptAndDoScriptByCache(filePath: ResourceLocation, pack: FIXModelPack, dependencies: Map): ScriptableObject? { + val cache = ExecutedScriptCache.getScript(pack, filePath) ?: return null + + // verify cache + if (cache.dependencies.keys != dependencies.keys) return null + + for ((name, hash) in dependencies) { + if (!cache.dependencies[name]!!.contentEquals(hash)) return null + } + + // load cache + + val newScope = makeNewScopeWithCache(cache) + if (newScope == null) { + ExecutedScriptCache.discord(pack, filePath) + } + return newScope + } + + private fun makeDependenciesData(dependencies: Map): Map { + val data = mutableMapOf() + for ((name, script) in dependencies) { + data[name.toString()] = DigestUtils.sha1(script) + } + return data + } +} + +object ExecutedScriptCache { + private val cache = ModelPackBasedCache( + fixCacheDir.resolve("excluded-script"), + 0x0000 to ExecutedScript.Serializer + ) + + fun getScript(pack: FIXModelPack, filePath: ResourceLocation): ExecutedScript? { + return cache.get(pack, DigestUtils.sha1Hex(filePath.toString()), ExecutedScript.Serializer) + } + + fun add(pack: FIXModelPack, filePath: ResourceLocation, executedScript: ExecutedScript) { + cache.put(pack, DigestUtils.sha1Hex(filePath.toString()), executedScript) + } + + fun discord(pack: FIXModelPack, filePath: ResourceLocation) { + cache.discord(pack, DigestUtils.sha1Hex(filePath.toString())) + } + + fun load() {} +} + + From ad595cf0ab36a44e1252c2b056e10560c835ca0e Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Wed, 3 Jun 2020 22:29:15 +0900 Subject: [PATCH 5/5] =?UTF-8?q?nashorn=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=97?= =?UTF-8?q?=E3=81=9FIScriptRuntime=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/anatawa12/fixRtm/FixRtm.kt | 4 ++ .../fixRtm/scripting/FIXScriptUtil.kt | 3 +- .../nashorn/CompiledImportedScriptCache.kt | 57 +++++++++++++++ .../nashorn/FIXNashornScriptEngine.kt | 71 +++++++++++++++++++ .../ImportScriptNashornFunctionImpl.kt | 51 +++++++++++++ .../nashorn/NashornScriptRuntimeImpl.kt | 46 ++++++++++++ 6 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/nashorn/CompiledImportedScriptCache.kt create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/nashorn/FIXNashornScriptEngine.kt create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/nashorn/ImportScriptNashornFunctionImpl.kt create mode 100644 src/main/java/com/anatawa12/fixRtm/scripting/nashorn/NashornScriptRuntimeImpl.kt diff --git a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt index 562bc1ee..452ca926 100644 --- a/src/main/java/com/anatawa12/fixRtm/FixRtm.kt +++ b/src/main/java/com/anatawa12/fixRtm/FixRtm.kt @@ -6,6 +6,7 @@ import com.anatawa12.fixRtm.io.FIXFileLoader import com.anatawa12.fixRtm.network.NetworkHandler import com.anatawa12.fixRtm.rtm.modelpack.modelset.dummies.* import com.anatawa12.fixRtm.scripting.loadFIXScriptUtil +import com.anatawa12.fixRtm.scripting.nashorn.CompiledImportedScriptCache import com.anatawa12.fixRtm.scripting.rhino.ExecutedScriptCache import com.anatawa12.fixRtm.scripting.rhino.PrimitiveJavaHelper import com.anatawa12.fixRtm.scripting.rhino.RhinoHooks @@ -15,6 +16,7 @@ import net.minecraft.block.Block import net.minecraft.client.Minecraft import net.minecraft.client.resources.IReloadableResourceManager import net.minecraft.item.Item +import net.minecraft.launchwrapper.Launch import net.minecraft.util.ResourceLocation import net.minecraftforge.client.event.ModelRegistryEvent import net.minecraftforge.common.MinecraftForge @@ -54,6 +56,8 @@ object FixRtm { RhinoHooks.load()// load } MainConfig.ScriptingMode.BetterWithNashorn -> { + Launch.classLoader.addClassLoaderExclusion("jdk.nashorn.") + CompiledImportedScriptCache.load() // load } MainConfig.ScriptingMode.UseRtmNormal -> { // nop diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt b/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt index 79232fa6..b8964d8a 100644 --- a/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt +++ b/src/main/java/com/anatawa12/fixRtm/scripting/FIXScriptUtil.kt @@ -4,6 +4,7 @@ package com.anatawa12.fixRtm.scripting import com.anatawa12.fixRtm.asm.config.MainConfig import com.anatawa12.fixRtm.io.FIXFileLoader +import com.anatawa12.fixRtm.scripting.nashorn.NashornScriptRuntimeImpl import com.anatawa12.fixRtm.scripting.rhino.RhinoScriptRuntimeImpl import jp.ngt.rtm.modelpack.ModelPackManager import net.minecraft.util.ResourceLocation @@ -11,7 +12,7 @@ import javax.script.ScriptEngine val scriptRuntime: IScriptRuntime<*, *> = when (MainConfig.scriptingMode) { MainConfig.ScriptingMode.CacheWithRhino -> RhinoScriptRuntimeImpl - MainConfig.ScriptingMode.BetterWithNashorn -> TODO() + MainConfig.ScriptingMode.BetterWithNashorn -> NashornScriptRuntimeImpl MainConfig.ScriptingMode.UseRtmNormal -> IScriptRuntime.AssertingRuntime } diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/CompiledImportedScriptCache.kt b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/CompiledImportedScriptCache.kt new file mode 100644 index 00000000..44f09963 --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/CompiledImportedScriptCache.kt @@ -0,0 +1,57 @@ +package com.anatawa12.fixRtm.scripting.nashorn + +import com.anatawa12.fixRtm.utils.DigestUtils +import jdk.nashorn.api.scripting.NashornScriptEngine +import jdk.nashorn.api.scripting.NashornScriptEngineFactory +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArraySet +import javax.script.CompiledScript +import javax.script.ScriptContext + +//* +object CompiledImportedScriptCache { + private val local = ThreadLocal.withInitial { Threaded() } + private val threaded get() = local.get()!! + private val threadedByEngine = ConcurrentHashMap() + + private fun threadedByEngine(engine: NashornScriptEngine?): Threaded { + if (engine == null) return threaded + else return threadedByEngine[engine] ?: throw IllegalArgumentException("the engine is not threaded") + } + + val engineFactory = NashornScriptEngineFactory() + val engines = CopyOnWriteArraySet() + + val engine get() = threaded.engine + + fun makeCompiled(script: String, fileName: String): CompiledScript + = threaded.makeCompiled(script, fileName) + + fun makeCompiled(engine: NashornScriptEngine?, script: String, fileName: String): CompiledScript + = threadedByEngine(engine).makeCompiled(script, fileName) + + fun load() { + // load + } + + private class Threaded { + val engine = engineFactory.scriptEngine as NashornScriptEngine + + init { + engines.add(engine) + threadedByEngine[engine] = this + } + + private val compiledScripts = mutableMapOf() + + fun makeCompiled(script: String, fileName: String): CompiledScript { + engine.context.setAttribute("javax.script.filename", fileName, ScriptContext.ENGINE_SCOPE) + val compile = engine.compile(script) + compiledScripts[DigestUtils.sha1Hex(script)] = compile + engine.context.removeAttribute("javax.script.filename", ScriptContext.ENGINE_SCOPE) + return compile + } + + } +} +// */ diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/FIXNashornScriptEngine.kt b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/FIXNashornScriptEngine.kt new file mode 100644 index 00000000..0d2bd7bd --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/FIXNashornScriptEngine.kt @@ -0,0 +1,71 @@ +package com.anatawa12.fixRtm.scripting.nashorn + +import jdk.nashorn.api.scripting.NashornScriptEngine +import java.io.Reader +import javax.script.* + +class FIXNashornScriptEngine( + val baseEngine: NashornScriptEngine, + private val context: ScriptContext +) : ScriptEngine by baseEngine, Compilable, Invocable { + + override fun getFactory(): ScriptEngineFactory { + TODO("Not yet implemented") + } + + override fun setContext(context: ScriptContext) { + throw UnsupportedOperationException("setContext is not supported by FIXNashornScriptEngine") + } + + override fun eval(script: String): Any? = baseEngine.eval(script, context) + + override fun eval(reader: Reader): Any? = baseEngine.eval(reader, context) + + override fun getBindings(scope: Int): Bindings = context.getBindings(scope) + + override fun put(name: String, value: Any?) { + context.getBindings(ScriptContext.ENGINE_SCOPE)?.put(name, value) + } + + override fun get(name: String): Any? = context.getBindings(ScriptContext.ENGINE_SCOPE)?.get(name) + + override fun setBindings(bindings: Bindings?, scope: Int) { + context.setBindings(bindings, scope) + } + + override fun getContext(): ScriptContext = context + + override fun compile(script: String): CompiledScript { + val compiled = baseEngine.compile(script) + return object : CompiledScript() { + override fun eval(context: ScriptContext): Any = compiled.eval(context) + + override fun getEngine(): ScriptEngine = this@FIXNashornScriptEngine + } + } + + override fun compile(script: Reader): CompiledScript { + val compiled = baseEngine.compile(script) + return object : CompiledScript() { + override fun eval(context: ScriptContext): Any = compiled.eval(context) + + override fun getEngine(): ScriptEngine = this@FIXNashornScriptEngine + } + } + + override fun getInterface(clasz: Class): T? { + throw UnsupportedOperationException("getInterface is not supported by FIXNashornScriptEngine") + } + + override fun getInterface(thiz: Any, clasz: Class): T? { + throw UnsupportedOperationException("getInterface is not supported by FIXNashornScriptEngine") + } + + override fun invokeMethod(thiz: Any, name: String, vararg args: Any?): Any? { + return baseEngine.invokeMethod(thiz, name, *args) + } + + override fun invokeFunction(name: String, vararg args: Any?): Any? { + return baseEngine.invokeMethod(context.getBindings(ScriptContext.ENGINE_SCOPE), name, *args) + } +} diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/ImportScriptNashornFunctionImpl.kt b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/ImportScriptNashornFunctionImpl.kt new file mode 100644 index 00000000..4e99ddbc --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/ImportScriptNashornFunctionImpl.kt @@ -0,0 +1,51 @@ +package com.anatawa12.fixRtm.scripting.nashorn + +import com.anatawa12.fixRtm.io.FIXFileLoader +import jdk.nashorn.api.scripting.AbstractJSObject +import jdk.nashorn.api.scripting.NashornScriptEngine +import jdk.nashorn.api.scripting.ScriptObjectMirror +import net.minecraft.util.ResourceLocation +import javax.script.CompiledScript +import javax.script.ScriptContext +import javax.script.SimpleScriptContext + +//* +object ImportScriptNashornFunctionImpl : AbstractJSObject() { + override fun isStrictFunction(): Boolean = false + + private val ctx = SimpleScriptContext() + + private fun getCompiled(engine: NashornScriptEngine?, name: String): CompiledScript { + val resourceLocation = ResourceLocation(name) + val resource = FIXFileLoader.getResource(resourceLocation) + val script = resource.inputStream.reader().use { it.readText() } + return NashornScriptRuntimeImpl.compile(resourceLocation, script, resource.pack, + engine = engine?.let { FIXNashornScriptEngine(it, ctx) }) + } + + override fun call(thiz: Any?, vararg args: Any?): Any? { + val str = args.getOrNull(0) + + if (str !is String) throw IllegalArgumentException("argument#1 must be string") + if (thiz !is ScriptObjectMirror) throw IllegalArgumentException("this must be a scope") + + val engine = thiz.getMember("engine") as? NashornScriptEngine + + if (engine != null && engine !in CompiledImportedScriptCache.engines) + throw IllegalStateException("current engine is not current thread engine") + + val compiled = getCompiled(engine, str.toString()) + + val context = SimpleScriptContext() + context.setBindings(thiz, ScriptContext.ENGINE_SCOPE) + + return compiled.eval(context) + } + + override fun isFunction(): Boolean = true + + override fun getClassName(): String = "Function" + + override fun isArray(): Boolean = false +} +// */ diff --git a/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/NashornScriptRuntimeImpl.kt b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/NashornScriptRuntimeImpl.kt new file mode 100644 index 00000000..005b0366 --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/scripting/nashorn/NashornScriptRuntimeImpl.kt @@ -0,0 +1,46 @@ +@file:JvmName("FIXScriptUtil") + +package com.anatawa12.fixRtm.scripting.nashorn + +import com.anatawa12.fixRtm.io.FIXModelPack +import com.anatawa12.fixRtm.io.FIXResource +import com.anatawa12.fixRtm.scripting.IScriptRuntime +import com.anatawa12.fixRtm.scripting.ScriptImporter +import net.minecraft.util.ResourceLocation +import javax.script.CompiledScript +import javax.script.ScriptContext +import javax.script.SimpleScriptContext + +object NashornScriptRuntimeImpl : IScriptRuntime { + /** + * nashorn does not support executed cache so always return null. + * @return always null + */ + override fun getCachedEngine(filePath: ResourceLocation, resource: FIXResource, dependencies: Map): FIXNashornScriptEngine? { + return null + } + + override fun compile(script: String, fileName: String, engine: FIXNashornScriptEngine?): CompiledScript { + return CompiledImportedScriptCache.makeCompiled(engine?.baseEngine, script, fileName) + } + + override fun exec(script: CompiledScript): FIXNashornScriptEngine { + val engine = CompiledImportedScriptCache.engine + + val context = SimpleScriptContext() + val bindings = engine.createBindings() + context.setBindings(bindings, ScriptContext.ENGINE_SCOPE) + + engine.eval("""load("nashorn:mozilla_compat.js");""", context) + + bindings[ScriptImporter.importScriptFunctionName] = ImportScriptNashornFunctionImpl + + script.eval(context) + + return FIXNashornScriptEngine(engine, context) + } + + override fun cache(pack: FIXModelPack, filePath: ResourceLocation, dependencies: Map, engine: FIXNashornScriptEngine) { + // not supported so nop + } +}