fix: remove raw native funcs, use this arg passing instead
This commit is contained in:
parent
356a5a5b78
commit
0b7442a3d8
@ -9,5 +9,5 @@ import java.lang.annotation.Target;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Native {
|
public @interface Native {
|
||||||
public String value() default "";
|
public String value() default "";
|
||||||
public boolean raw() default false;
|
public boolean thisArg() default false;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ import java.lang.annotation.Target;
|
|||||||
@Target({ ElementType.METHOD })
|
@Target({ ElementType.METHOD })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface NativeConstructor {
|
public @interface NativeConstructor {
|
||||||
public boolean raw() default false;
|
public boolean thisArg() default false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,5 +9,5 @@ import java.lang.annotation.Target;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface NativeGetter {
|
public @interface NativeGetter {
|
||||||
public String value();
|
public String value();
|
||||||
public boolean raw() default false;
|
public boolean thisArg() default false;
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,5 @@ import java.lang.annotation.Target;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface NativeSetter {
|
public @interface NativeSetter {
|
||||||
public String value();
|
public String value();
|
||||||
public boolean raw() default false;
|
public boolean thisArg() default false;
|
||||||
}
|
}
|
||||||
|
@ -13,23 +13,15 @@ public class NativeTypeRegister implements WrappersProvider {
|
|||||||
private final HashMap<Class<?>, FunctionValue> constructors = new HashMap<>();
|
private final HashMap<Class<?>, FunctionValue> constructors = new HashMap<>();
|
||||||
private final HashMap<Class<?>, ObjectValue> prototypes = new HashMap<>();
|
private final HashMap<Class<?>, ObjectValue> prototypes = new HashMap<>();
|
||||||
|
|
||||||
private static boolean isMember(Class<?>[] args) {
|
|
||||||
return args.length == 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void applyMethods(boolean member, ObjectValue target, Class<?> clazz) {
|
private static void applyMethods(boolean member, ObjectValue target, Class<?> clazz) {
|
||||||
for (var method : clazz.getDeclaredMethods()) {
|
for (var method : clazz.getDeclaredMethods()) {
|
||||||
var nat = method.getAnnotation(Native.class);
|
var nat = method.getAnnotation(Native.class);
|
||||||
var get = method.getAnnotation(NativeGetter.class);
|
var get = method.getAnnotation(NativeGetter.class);
|
||||||
var set = method.getAnnotation(NativeSetter.class);
|
var set = method.getAnnotation(NativeSetter.class);
|
||||||
var params = method.getParameterTypes();
|
|
||||||
var memberMismatch = !Modifier.isStatic(method.getModifiers()) != member;
|
var memberMismatch = !Modifier.isStatic(method.getModifiers()) != member;
|
||||||
|
|
||||||
if (nat != null) {
|
if (nat != null) {
|
||||||
if (nat.raw()) {
|
if (nat.thisArg() != member && memberMismatch) continue;
|
||||||
if (isMember(params) != member) continue;
|
|
||||||
}
|
|
||||||
else if (memberMismatch) continue;
|
|
||||||
|
|
||||||
var name = nat.value();
|
var name = nat.value();
|
||||||
var val = target.values.get(name);
|
var val = target.values.get(name);
|
||||||
@ -37,11 +29,12 @@ public class NativeTypeRegister implements WrappersProvider {
|
|||||||
if (name.equals("")) name = method.getName();
|
if (name.equals("")) name = method.getName();
|
||||||
if (!(val instanceof OverloadFunction)) target.defineProperty(null, name, val = new OverloadFunction(name));
|
if (!(val instanceof OverloadFunction)) target.defineProperty(null, name, val = new OverloadFunction(name));
|
||||||
|
|
||||||
((OverloadFunction)val).overloads.add(Overload.fromMethod(method, nat.raw()));
|
((OverloadFunction)val).overloads.add(Overload.fromMethod(method, nat.thisArg()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (get != null) {
|
if (get != null) {
|
||||||
if (get.raw() && isMember(params) != member || memberMismatch) continue;
|
if (get.thisArg() != member && memberMismatch) continue;
|
||||||
|
|
||||||
var name = get.value();
|
var name = get.value();
|
||||||
var prop = target.properties.get(name);
|
var prop = target.properties.get(name);
|
||||||
OverloadFunction getter = null;
|
OverloadFunction getter = null;
|
||||||
@ -50,11 +43,12 @@ public class NativeTypeRegister implements WrappersProvider {
|
|||||||
if (prop != null && prop.getter instanceof OverloadFunction) getter = (OverloadFunction)prop.getter;
|
if (prop != null && prop.getter instanceof OverloadFunction) getter = (OverloadFunction)prop.getter;
|
||||||
else getter = new OverloadFunction("get " + name);
|
else getter = new OverloadFunction("get " + name);
|
||||||
|
|
||||||
getter.overloads.add(Overload.fromMethod(method, get.raw()));
|
getter.overloads.add(Overload.fromMethod(method, get.thisArg()));
|
||||||
target.defineProperty(null, name, getter, setter, true, true);
|
target.defineProperty(null, name, getter, setter, true, true);
|
||||||
}
|
}
|
||||||
if (set != null) {
|
if (set != null) {
|
||||||
if (set.raw() && isMember(params) != member || memberMismatch) continue;
|
if (set.thisArg() != member && memberMismatch) continue;
|
||||||
|
|
||||||
var name = set.value();
|
var name = set.value();
|
||||||
var prop = target.properties.get(name);
|
var prop = target.properties.get(name);
|
||||||
var getter = prop == null ? null : prop.getter;
|
var getter = prop == null ? null : prop.getter;
|
||||||
@ -63,7 +57,7 @@ public class NativeTypeRegister implements WrappersProvider {
|
|||||||
if (prop != null && prop.setter instanceof OverloadFunction) setter = (OverloadFunction)prop.setter;
|
if (prop != null && prop.setter instanceof OverloadFunction) setter = (OverloadFunction)prop.setter;
|
||||||
else setter = new OverloadFunction("set " + name);
|
else setter = new OverloadFunction("set " + name);
|
||||||
|
|
||||||
setter.overloads.add(Overload.fromMethod(method, set.raw()));
|
setter.overloads.add(Overload.fromMethod(method, set.thisArg()));
|
||||||
target.defineProperty(null, name, getter, setter, true, true);
|
target.defineProperty(null, name, getter, setter, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,8 +71,8 @@ public class NativeTypeRegister implements WrappersProvider {
|
|||||||
if (nat != null) {
|
if (nat != null) {
|
||||||
var name = nat.value();
|
var name = nat.value();
|
||||||
if (name.equals("")) name = field.getName();
|
if (name.equals("")) name = field.getName();
|
||||||
var getter = new OverloadFunction("get " + name).add(Overload.getterFromField(field, nat.raw()));
|
var getter = new OverloadFunction("get " + name).add(Overload.getterFromField(field));
|
||||||
var setter = new OverloadFunction("set " + name).add(Overload.setterFromField(field, nat.raw()));
|
var setter = new OverloadFunction("set " + name).add(Overload.setterFromField(field));
|
||||||
target.defineProperty(null, name, getter, setter, true, false);
|
target.defineProperty(null, name, getter, setter, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,12 +120,12 @@ public class NativeTypeRegister implements WrappersProvider {
|
|||||||
for (var overload : clazz.getConstructors()) {
|
for (var overload : clazz.getConstructors()) {
|
||||||
var nat = overload.getAnnotation(Native.class);
|
var nat = overload.getAnnotation(Native.class);
|
||||||
if (nat == null) continue;
|
if (nat == null) continue;
|
||||||
((OverloadFunction)func).add(Overload.fromConstructor(overload, nat.raw()));
|
((OverloadFunction)func).add(Overload.fromConstructor(overload, nat.thisArg()));
|
||||||
}
|
}
|
||||||
for (var overload : clazz.getMethods()) {
|
for (var overload : clazz.getMethods()) {
|
||||||
var constr = overload.getAnnotation(NativeConstructor.class);
|
var constr = overload.getAnnotation(NativeConstructor.class);
|
||||||
if (constr == null) continue;
|
if (constr == null) continue;
|
||||||
((OverloadFunction)func).add(Overload.fromMethod(overload, constr.raw()));
|
((OverloadFunction)func).add(Overload.fromMethod(overload, constr.thisArg()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((OverloadFunction)func).overloads.size() == 0) {
|
if (((OverloadFunction)func).overloads.size() == 0) {
|
||||||
|
@ -17,63 +17,55 @@ public class Overload {
|
|||||||
|
|
||||||
public final OverloadRunner runner;
|
public final OverloadRunner runner;
|
||||||
public final boolean variadic;
|
public final boolean variadic;
|
||||||
public final boolean raw;
|
public final boolean passThis;
|
||||||
public final Class<?> thisArg;
|
public final Class<?> thisArg;
|
||||||
public final Class<?>[] params;
|
public final Class<?>[] params;
|
||||||
|
|
||||||
public static Overload fromMethod(Method method, boolean raw) {
|
public static Overload fromMethod(Method method, boolean passThis) {
|
||||||
return new Overload(
|
return new Overload(
|
||||||
(ctx, th, args) -> method.invoke(th, args),
|
(ctx, th, args) -> method.invoke(th, args),
|
||||||
method.isVarArgs(), raw,
|
method.isVarArgs(), passThis,
|
||||||
Modifier.isStatic(method.getModifiers()) ? null : method.getDeclaringClass(),
|
Modifier.isStatic(method.getModifiers()) ? null : method.getDeclaringClass(),
|
||||||
method.getParameterTypes()
|
method.getParameterTypes()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public static Overload fromConstructor(Constructor<?> method, boolean raw) {
|
public static Overload fromConstructor(Constructor<?> method, boolean passThis) {
|
||||||
return new Overload(
|
return new Overload(
|
||||||
(ctx, th, args) -> method.newInstance(args),
|
(ctx, th, args) -> method.newInstance(args),
|
||||||
method.isVarArgs(), raw,
|
method.isVarArgs(), passThis,
|
||||||
Modifier.isStatic(method.getModifiers()) ? null : method.getDeclaringClass(),
|
Modifier.isStatic(method.getModifiers()) ? null : method.getDeclaringClass(),
|
||||||
method.getParameterTypes()
|
method.getParameterTypes()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public static Overload getterFromField(Field field, boolean raw) {
|
public static Overload getterFromField(Field field) {
|
||||||
return new Overload(
|
return new Overload(
|
||||||
(ctx, th, args) -> field.get(th), false, raw,
|
(ctx, th, args) -> field.get(th), false, false,
|
||||||
Modifier.isStatic(field.getModifiers()) ? null : field.getDeclaringClass(),
|
Modifier.isStatic(field.getModifiers()) ? null : field.getDeclaringClass(),
|
||||||
new Class[0]
|
new Class[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public static Overload setterFromField(Field field, boolean raw) {
|
public static Overload setterFromField(Field field) {
|
||||||
if (Modifier.isFinal(field.getModifiers())) return null;
|
if (Modifier.isFinal(field.getModifiers())) return null;
|
||||||
return new Overload(
|
return new Overload(
|
||||||
(ctx, th, args) -> { field.set(th, args[0]); return null; }, false, raw,
|
(ctx, th, args) -> { field.set(th, args[0]); return null; }, false, false,
|
||||||
Modifier.isStatic(field.getModifiers()) ? null : field.getDeclaringClass(),
|
Modifier.isStatic(field.getModifiers()) ? null : field.getDeclaringClass(),
|
||||||
new Class[0]
|
new Class[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Overload getter(Class<?> thisArg, OverloadRunner runner, boolean raw) {
|
public static Overload getter(Class<?> thisArg, OverloadRunner runner, boolean passThis) {
|
||||||
return new Overload(
|
return new Overload(
|
||||||
(ctx, th, args) -> runner.run(ctx, th, args), false, raw,
|
(ctx, th, args) -> runner.run(ctx, th, args), false, passThis,
|
||||||
thisArg,
|
thisArg,
|
||||||
new Class[0]
|
new Class[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Overload(OverloadRunner runner, boolean variadic, boolean raw, Class<?> thisArg, Class<?> args[]) {
|
public Overload(OverloadRunner runner, boolean variadic, boolean passThis, Class<?> thisArg, Class<?> args[]) {
|
||||||
this.runner = runner;
|
this.runner = runner;
|
||||||
this.variadic = variadic;
|
this.variadic = variadic;
|
||||||
this.raw = raw;
|
this.passThis = passThis;
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
this.params = args;
|
this.params = args;
|
||||||
|
|
||||||
if (raw) {
|
|
||||||
if (!(
|
|
||||||
thisArg == null && (
|
|
||||||
args.length == 3 && args[0] == Context.class && args[1] == Object.class && args[2] == Object[].class ||
|
|
||||||
args.length == 2 && args[0] == Context.class && args[1] == Object[].class
|
|
||||||
))) throw new IllegalArgumentException("Invalid signature for raw method.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,53 +18,48 @@ public class OverloadFunction extends FunctionValue {
|
|||||||
loop: for (var overload : overloads) {
|
loop: for (var overload : overloads) {
|
||||||
Object[] newArgs = new Object[overload.params.length];
|
Object[] newArgs = new Object[overload.params.length];
|
||||||
|
|
||||||
if (overload.raw) {
|
boolean consumesEngine = overload.params.length > 0 && overload.params[0] == Context.class;
|
||||||
newArgs[0] = ctx;
|
int start = (consumesEngine ? 1 : 0) + (overload.passThis ? 1 : 0);
|
||||||
newArgs[1] = thisArg;
|
int end = overload.params.length - (overload.variadic ? 1 : 0);
|
||||||
newArgs[2] = args;
|
|
||||||
|
for (var i = start; i < end; i++) {
|
||||||
|
Object val;
|
||||||
|
|
||||||
|
if (i - start >= args.length) val = null;
|
||||||
|
else val = args[i - start];
|
||||||
|
|
||||||
|
try {
|
||||||
|
newArgs[i] = Values.convert(ctx, val, overload.params[i]);
|
||||||
|
}
|
||||||
|
catch (ConvertException e) {
|
||||||
|
if (overloads.size() > 1) continue loop;
|
||||||
|
else throw EngineException.ofType(String.format("Argument %d can't be converted from %s to %s", i - start, e.source, e.target));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
boolean consumesEngine = overload.params.length > 0 && overload.params[0] == Context.class;
|
|
||||||
int start = consumesEngine ? 1 : 0;
|
|
||||||
int end = overload.params.length - (overload.variadic ? 1 : 0);
|
|
||||||
|
|
||||||
for (var i = start; i < end; i++) {
|
if (overload.variadic) {
|
||||||
Object val;
|
var type = overload.params[overload.params.length - 1].getComponentType();
|
||||||
|
var n = Math.max(args.length - end + start, 0);
|
||||||
if (i - start >= args.length) val = null;
|
Object varArg = Array.newInstance(type, n);
|
||||||
else val = args[i - start];
|
|
||||||
|
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
try {
|
try {
|
||||||
newArgs[i] = Values.convert(ctx, val, overload.params[i]);
|
Array.set(varArg, i, Values.convert(ctx, args[i + end - start], type));
|
||||||
}
|
}
|
||||||
catch (ConvertException e) {
|
catch (ConvertException e) {
|
||||||
if (overloads.size() > 1) continue loop;
|
if (overloads.size() > 1) continue loop;
|
||||||
else throw EngineException.ofType(String.format("Argument %d can't be converted from %s to %s", i - start, e.source, e.target));
|
else throw EngineException.ofType(String.format("Element in variadic argument can't be converted from %s to %s", e.source, e.target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overload.variadic) {
|
newArgs[newArgs.length - 1] = varArg;
|
||||||
var type = overload.params[overload.params.length - 1].getComponentType();
|
|
||||||
var n = Math.max(args.length - end + start, 0);
|
|
||||||
Object varArg = Array.newInstance(type, n);
|
|
||||||
|
|
||||||
for (var i = 0; i < n; i++) {
|
|
||||||
try {
|
|
||||||
Array.set(varArg, i, Values.convert(ctx, args[i + end - start], type));
|
|
||||||
}
|
|
||||||
catch (ConvertException e) {
|
|
||||||
if (overloads.size() > 1) continue loop;
|
|
||||||
else throw EngineException.ofType(String.format("Element in variadic argument can't be converted from %s to %s", e.source, e.target));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newArgs[newArgs.length - 1] = varArg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumesEngine) newArgs[0] = ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object _this = overload.thisArg == null ? null : Values.convert(ctx, thisArg, overload.thisArg);
|
var thisArgType = overload.passThis ? overload.params[consumesEngine ? 1 : 0] : overload.thisArg;
|
||||||
|
Object _this = thisArgType == null ? null : Values.convert(ctx, thisArg, thisArgType);
|
||||||
|
|
||||||
|
if (consumesEngine) newArgs[0] = ctx;
|
||||||
|
if (overload.passThis) newArgs[consumesEngine ? 1 : 0] = _this;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Values.normalize(ctx, overload.runner.run(ctx, _this, newArgs));
|
return Values.normalize(ctx, overload.runner.run(ctx, _this, newArgs));
|
||||||
|
@ -8,43 +8,26 @@ import me.topchetoeu.jscript.exceptions.EngineException;
|
|||||||
import me.topchetoeu.jscript.interop.Native;
|
import me.topchetoeu.jscript.interop.Native;
|
||||||
|
|
||||||
public class FunctionPolyfill {
|
public class FunctionPolyfill {
|
||||||
@Native(raw=true) public static Object apply(Context ctx, Object func, Object[] args) throws InterruptedException {
|
@Native(thisArg = true) public static Object apply(Context ctx, FunctionValue func, Object thisArg, ArrayValue args) throws InterruptedException {
|
||||||
var thisArg = args.length > 0 ? args[0] : null;
|
return func.call(ctx, thisArg, args.toArray());
|
||||||
var _args = args.length > 1 ? args[1] : null;
|
|
||||||
|
|
||||||
if (!(_args instanceof ArrayValue)) throw EngineException.ofError("Expected arguments to be an array.");
|
|
||||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
|
||||||
|
|
||||||
return ((FunctionValue)func).call(ctx, thisArg, ((ArrayValue)_args).toArray());
|
|
||||||
}
|
}
|
||||||
@Native(raw=true) public static Object call(Context ctx, Object func, Object[] args) throws InterruptedException {
|
@Native(thisArg = true) public static Object call(Context ctx, FunctionValue func, Object thisArg, Object... args) throws InterruptedException {
|
||||||
var thisArg = args.length > 0 ? args[0] : null;
|
|
||||||
var _args = new Object[args.length > 1 ? args.length - 1 : 0];
|
|
||||||
|
|
||||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
||||||
|
|
||||||
if (_args.length != 0) System.arraycopy(args, 1, _args, 0, _args.length);
|
return func.call(ctx, thisArg, args);
|
||||||
|
|
||||||
return ((FunctionValue)func).call(ctx, thisArg, _args);
|
|
||||||
}
|
}
|
||||||
@Native(raw=true) public static Object bind(Context ctx, Object func, Object[] args) {
|
@Native(thisArg = true) public static Object bind(Context ctx, FunctionValue func, Object thisArg, Object... args) {
|
||||||
var thisArg = args.length > 0 ? args[0] : null;
|
|
||||||
var _args = new Object[args.length > 1 ? args.length - 1 : 0];
|
|
||||||
FunctionValue _func = (FunctionValue)func;
|
|
||||||
|
|
||||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
||||||
|
|
||||||
if (_args.length != 0) System.arraycopy(args, 1, _args, 0, _args.length);
|
return new NativeFunction(func.name + " (bound)", (callCtx, _0, callArgs) -> {
|
||||||
|
var resArgs = new Object[args.length + callArgs.length];
|
||||||
|
System.arraycopy(args, 0, resArgs, 0, args.length);
|
||||||
|
System.arraycopy(callArgs, 0, resArgs, args.length, callArgs.length);
|
||||||
|
|
||||||
return new NativeFunction(_func.name + " (bound)", (callCtx, _0, callArgs) -> {
|
return func.call(ctx, thisArg, resArgs);
|
||||||
var resArgs = new Object[_args.length + callArgs.length];
|
|
||||||
System.arraycopy(_args, 0, resArgs, 0, _args.length);
|
|
||||||
System.arraycopy(callArgs, 0, resArgs, _args.length, resArgs.length - _args.length);
|
|
||||||
|
|
||||||
return _func.call(ctx, thisArg, resArgs);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@Native(raw=true) public static String toString(Context ctx, Object func, Object[] args) {
|
@Native(thisArg = true) public static String toString(Context ctx, Object func) {
|
||||||
return "function (...) { ... }";
|
return "function (...) { ... }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,18 +187,18 @@ public class ObjectPolyfill {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(raw = true) public static Object valueOf(Context ctx, Object thisArg, Object[] args) {
|
@Native(thisArg = true) public static Object valueOf(Context ctx, Object thisArg) {
|
||||||
return thisArg;
|
return thisArg;
|
||||||
}
|
}
|
||||||
@Native(raw = true) public static String toString(Context ctx, Object thisArg, Object[] args) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
||||||
var name = Values.getMember(ctx, thisArg, ctx.env.symbol("Symbol.typeName"));
|
var name = Values.getMember(ctx, thisArg, ctx.env.symbol("Symbol.typeName"));
|
||||||
if (name == null) name = "Unknown";
|
if (name == null) name = "Unknown";
|
||||||
else name = Values.toString(ctx, name);
|
else name = Values.toString(ctx, name);
|
||||||
|
|
||||||
return "[object " + name + "]";
|
return "[object " + name + "]";
|
||||||
}
|
}
|
||||||
@Native(raw = true) public static boolean hasOwnProperty(Context ctx, Object thisArg, Object[] args) throws InterruptedException {
|
@Native(thisArg = true) public static boolean hasOwnProperty(Context ctx, Object thisArg, Object key) throws InterruptedException {
|
||||||
return ObjectPolyfill.hasOwn(ctx, thisArg, Values.convert(ctx, args.length == 0 ? null : args[0], String.class));
|
return ObjectPolyfill.hasOwn(ctx, thisArg, Values.convert(ctx, key, String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeConstructor public static Object constructor(Context ctx, Object arg) throws InterruptedException {
|
@NativeConstructor public static Object constructor(Context ctx, Object arg) throws InterruptedException {
|
||||||
|
@ -152,12 +152,9 @@ public class PromisePolyfill {
|
|||||||
* Thread safe - you can call this from anywhere
|
* Thread safe - you can call this from anywhere
|
||||||
* HOWEVER, it's strongly recommended to use this only in javascript
|
* HOWEVER, it's strongly recommended to use this only in javascript
|
||||||
*/
|
*/
|
||||||
@Native(raw = true) public static Object then(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
@Native(thisArg=true) public static Object then(Context ctx, Object thisArg, Object _onFulfill, Object _onReject) throws InterruptedException {
|
||||||
var onFulfill = args.length > 0 ? args[0] : null;
|
var onFulfill = _onFulfill instanceof FunctionValue ? ((FunctionValue)_onFulfill) : null;
|
||||||
var onReject = args.length > 1 ? args[1]: null;
|
var onReject = _onReject instanceof FunctionValue ? ((FunctionValue)_onReject) : null;
|
||||||
|
|
||||||
if (!(onFulfill instanceof FunctionValue)) onFulfill = null;
|
|
||||||
if (!(onReject instanceof FunctionValue)) onReject = null;
|
|
||||||
|
|
||||||
var res = new PromisePolyfill();
|
var res = new PromisePolyfill();
|
||||||
|
|
||||||
@ -206,24 +203,22 @@ public class PromisePolyfill {
|
|||||||
* Thread safe - you can call this from anywhere
|
* Thread safe - you can call this from anywhere
|
||||||
* HOWEVER, it's strongly recommended to use this only in javascript
|
* HOWEVER, it's strongly recommended to use this only in javascript
|
||||||
*/
|
*/
|
||||||
@Native(value = "catch", raw = true) public static Object _catch(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
@Native(value="catch", thisArg=true) public static Object _catch(Context ctx, Object thisArg, Object _onReject) throws InterruptedException {
|
||||||
return then(ctx, thisArg, null, args.length > 0 ? args[0] : null);
|
return then(ctx, thisArg, null, _onReject);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Thread safe - you can call this from anywhere
|
* Thread safe - you can call this from anywhere
|
||||||
* HOWEVER, it's strongly recommended to use this only in javascript
|
* HOWEVER, it's strongly recommended to use this only in javascript
|
||||||
*/
|
*/
|
||||||
@Native(value = "finally", raw = true) public static Object _finally(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
@Native(value="finally", thisArg=true) public static Object _finally(Context ctx, Object thisArg, Object _handle) throws InterruptedException {
|
||||||
var handleFunc = args.length > 0 ? args[0] : null;
|
|
||||||
|
|
||||||
return then(ctx, thisArg,
|
return then(ctx, thisArg,
|
||||||
new NativeFunction(null, (e, th, _args) -> {
|
new NativeFunction(null, (e, th, _args) -> {
|
||||||
if (handleFunc instanceof FunctionValue) ((FunctionValue)handleFunc).call(ctx);
|
if (_handle instanceof FunctionValue) ((FunctionValue)_handle).call(ctx);
|
||||||
return args[0];
|
return _args.length > 0 ? _args[0] : null;
|
||||||
}),
|
}),
|
||||||
new NativeFunction(null, (e, th, _args) -> {
|
new NativeFunction(null, (e, th, _args) -> {
|
||||||
if (handleFunc instanceof FunctionValue) ((FunctionValue)handleFunc).call(ctx);
|
if (_handle instanceof FunctionValue) ((FunctionValue)_handle).call(ctx);
|
||||||
throw new EngineException(_args[0]);
|
throw new EngineException(_args.length > 0 ? _args[0] : null);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user