diff --git a/src/main/java/org/ssssssss/script/MagicScript.java b/src/main/java/org/ssssssss/script/MagicScript.java index e64b7aae28d01f9a81cb7bd53706743628d120bd..65dce1b25150b2ed6d2d555a0943ced531fa4313 100644 --- a/src/main/java/org/ssssssss/script/MagicScript.java +++ b/src/main/java/org/ssssssss/script/MagicScript.java @@ -24,9 +24,12 @@ import javax.script.CompiledScript; import javax.script.ScriptContext; import javax.script.ScriptEngine; import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; public class MagicScript extends CompiledScript { @@ -48,7 +51,12 @@ public class MagicScript extends CompiledScript { private final Set varIndices; /** - * 编译后的类 + * 是否已经编译过 + */ + private final AtomicBoolean compile = new AtomicBoolean(false); + + /** + * 如果是简单的取值操作,则跳过编译 */ private MagicScriptVariableAccessRuntime accessRuntime; @@ -135,6 +143,18 @@ public class MagicScript extends CompiledScript { return this.accessRuntime = new MagicScriptVariableAccessRuntime(((VariableAccess) returnNode.getReturnValue()).getVarIndex().getName()); } } + if (!compile.get()) { + synchronized (compile) { + if (!compile.get()) { + compile0(); + compile.set(true); + } + } + } + return buildRuntime(); + } + + private void compile0() { try { MagicScriptCompiler compiler = new MagicScriptCompiler(this.varIndices, this.debug); nodes.forEach(node -> node.visitMethod(compiler)); @@ -159,7 +179,6 @@ public class MagicScript extends CompiledScript { this.varNames = varIndices.stream().map(VarIndex::getName).toArray(String[]::new); // 设置所有Span this.spans = compiler.getSpans(); - return buildRuntime(); } catch (MagicScriptException mse) { throw new MagicScriptCompileException(mse.getSimpleMessage(), mse); } catch (MagicScriptCompileException e) { @@ -171,12 +190,12 @@ public class MagicScript extends CompiledScript { private MagicScriptRuntime buildRuntime() { try { - MagicScriptRuntime target = constructor.newInstance(); - // 设置变量名字 - target.setVarNames(this.varNames); - // 设置所有Span - target.setSpans(this.spans); - return target; + MagicScriptRuntime runtime = constructor.newInstance(); + // 设置变量名字,为Runtime拷贝副本 + runtime.setVarNames(Arrays.copyOf(this.varNames, this.varNames.length)); + // 设置所有Span,为Runtime拷贝副本 + runtime.setSpans(new ArrayList<>(this.spans)); + return runtime; } catch (Exception e) { throw new MagicScriptCompileException(e); }