From b5b63c4342179a3768393013ec3f81073fa2f154 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:08:07 +0200 Subject: [PATCH] fix: make global cache of native wrappers --- .../jscript/runtime/values/NativeWrapper.java | 19 ++++++++++++++++++- .../jscript/runtime/values/Values.java | 9 ++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/java/me/topchetoeu/jscript/runtime/values/NativeWrapper.java b/src/java/me/topchetoeu/jscript/runtime/values/NativeWrapper.java index 2302745..3bb7e9f 100644 --- a/src/java/me/topchetoeu/jscript/runtime/values/NativeWrapper.java +++ b/src/java/me/topchetoeu/jscript/runtime/values/NativeWrapper.java @@ -1,8 +1,13 @@ package me.topchetoeu.jscript.runtime.values; +import java.util.WeakHashMap; + import me.topchetoeu.jscript.runtime.Context; +import me.topchetoeu.jscript.runtime.Extensions; +import me.topchetoeu.jscript.runtime.Key; public class NativeWrapper extends ObjectValue { + private static final Key> WRAPPERS = new Key<>(); private static final Object NATIVE_PROTO = new Object(); public final Object wrapped; @@ -29,8 +34,20 @@ public class NativeWrapper extends ObjectValue { return wrapped.hashCode(); } - public NativeWrapper(Object wrapped) { + private NativeWrapper(Object wrapped) { this.wrapped = wrapped; prototype = NATIVE_PROTO; } + + public static NativeWrapper of(Extensions exts, Object wrapped) { + var wrappers = exts == null ? null : exts.get(WRAPPERS); + + if (wrappers == null) return new NativeWrapper(wrapped); + if (wrappers.containsKey(wrapped)) return wrappers.get(wrapped); + + var res = new NativeWrapper(wrapped); + wrappers.put(wrapped, res); + + return res; + } } diff --git a/src/java/me/topchetoeu/jscript/runtime/values/Values.java b/src/java/me/topchetoeu/jscript/runtime/values/Values.java index b08a45f..ed4b288 100644 --- a/src/java/me/topchetoeu/jscript/runtime/values/Values.java +++ b/src/java/me/topchetoeu/jscript/runtime/values/Values.java @@ -58,9 +58,8 @@ public class Values { @SuppressWarnings("unchecked") public static T wrapper(Object val, Class clazz) { - if (!isWrapper(val)) val = new NativeWrapper(val); - var res = (NativeWrapper)val; - if (res != null && clazz.isInstance(res.wrapped)) return (T)res.wrapped; + if (isWrapper(val)) val = ((NativeWrapper)val).wrapped; + if (val != null && clazz.isInstance(val)) return (T)val; else return null; } @@ -471,7 +470,7 @@ public class Values { else return ctx.environment.wrappers.getConstr((Class)val); } - return new NativeWrapper(val); + return NativeWrapper.of(ctx, val); } @SuppressWarnings("unchecked") @@ -536,7 +535,7 @@ public class Values { if (obj == null) return null; if (clazz.isInstance(obj)) return (T)obj; if (clazz.isAssignableFrom(NativeWrapper.class)) { - return (T)new NativeWrapper(obj); + return (T)NativeWrapper.of(ctx, obj); } throw new ConvertException(type(obj), clazz.getSimpleName());