Compare commits

..

2 Commits

2 changed files with 55 additions and 3 deletions

View File

@@ -1,16 +1,24 @@
package me.topchetoeu.jscript.lib;
import me.topchetoeu.jscript.common.Filename;
import me.topchetoeu.jscript.runtime.Compiler;
import me.topchetoeu.jscript.runtime.Context;
import me.topchetoeu.jscript.runtime.scope.ValueVariable;
import me.topchetoeu.jscript.runtime.values.ArrayValue;
import me.topchetoeu.jscript.runtime.values.CodeFunction;
import me.topchetoeu.jscript.runtime.values.FunctionValue;
import me.topchetoeu.jscript.runtime.values.NativeFunction;
import me.topchetoeu.jscript.runtime.values.Values;
import me.topchetoeu.jscript.utils.interop.Arguments;
import me.topchetoeu.jscript.utils.interop.Expose;
import me.topchetoeu.jscript.utils.interop.ExposeConstructor;
import me.topchetoeu.jscript.utils.interop.ExposeTarget;
import me.topchetoeu.jscript.utils.interop.WrapperName;
@WrapperName("Function")
public class FunctionLib {
private static int i;
@Expose public static Object __apply(Arguments args) {
return args.self(FunctionValue.class).call(args.ctx, args.get(0), args.convert(1, ArrayValue.class).toArray());
}
@@ -51,4 +59,25 @@ public class FunctionLib {
public static FunctionValue __generator(Arguments args) {
return new GeneratorFunctionLib(args.convert(0, CodeFunction.class));
}
@ExposeConstructor
public static Object __constructor(Arguments args) {
var compiler = Compiler.get(args);
var parts = args.convert(String.class);
if (parts.length == 0) parts = new String[] { "" };
var src = "return function(";
for (var i = 0; i < parts.length - 1; i++) {
if (i != 0) src += ",";
src += parts[i];
}
src += "){" + parts[parts.length - 1] + "}";
var body = compiler.compile(new Filename("jscript", "func/" + i++), src);
var func = new CodeFunction(Context.clean(args.ctx), "", body, new ValueVariable[0]);
return Values.call(args, func, null);
}
}

View File

@@ -7,7 +7,28 @@ import me.topchetoeu.jscript.runtime.Key;
import me.topchetoeu.jscript.utils.interop.NativeWrapperProvider;
public class NativeWrapper extends ObjectValue {
private static final Key<WeakHashMap<Object, NativeWrapper>> WRAPPERS = new Key<>();
private static class MapKey {
public final Object key;
@Override
public int hashCode() {
return System.identityHashCode(key);
}
@Override
public boolean equals(Object obj) {
if (this == null || obj == null) return this == null && obj == null;
if (!(obj instanceof MapKey)) return false;
var other = (MapKey)obj;
return other.key == key;
}
public MapKey(Object key) {
this.key = key;
}
}
private static final Key<WeakHashMap<MapKey, NativeWrapper>> WRAPPERS = new Key<>();
private static final Object NATIVE_PROTO = new Object();
public final Object wrapped;
@@ -48,10 +69,12 @@ public class NativeWrapper extends ObjectValue {
exts.add(WRAPPERS, wrappers);
}
if (wrappers.containsKey(wrapped)) return wrappers.get(wrapped);
var key = new MapKey(wrapped);
if (wrappers.containsKey(key)) return wrappers.get(key);
var res = new NativeWrapper(wrapped);
wrappers.put(wrapped, res);
wrappers.put(key, res);
return res;
}