fix: revert back to old error protocol
This commit is contained in:
parent
22ec95a7b5
commit
bd08902196
@ -22,7 +22,7 @@ public class Environment {
|
||||
|
||||
@Native public FunctionValue compile;
|
||||
@Native public FunctionValue regexConstructor = new NativeFunction("RegExp", (ctx, thisArg, args) -> {
|
||||
throw EngineException.ofError(ctx, "Regular expressions not supported.");
|
||||
throw EngineException.ofError("Regular expressions not supported.");
|
||||
});
|
||||
@Native public ObjectValue proto(String name) {
|
||||
return prototypes.get(name);
|
||||
|
@ -17,7 +17,7 @@ public class MessageContext {
|
||||
|
||||
public MessageContext pushFrame(Context ctx, CodeFrame frame) throws InterruptedException {
|
||||
this.frames.add(frame);
|
||||
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange(ctx, "Stack overflow!");
|
||||
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
||||
return this;
|
||||
}
|
||||
public boolean popFrame(CodeFrame frame) {
|
||||
|
@ -27,7 +27,7 @@ public class Runners {
|
||||
throw new EngineException(frame.pop());
|
||||
}
|
||||
public static Object execThrowSyntax(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
throw EngineException.ofSyntax(ctx, (String)instr.get(0));
|
||||
throw EngineException.ofSyntax((String)instr.get(0));
|
||||
}
|
||||
|
||||
private static Object call(Context ctx, Object func, Object thisArg, Object ...args) throws InterruptedException {
|
||||
@ -77,9 +77,9 @@ public class Runners {
|
||||
var name = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
if (getter != null && !Values.isFunction(getter)) throw EngineException.ofType(ctx, "Getter must be a function or undefined.");
|
||||
if (setter != null && !Values.isFunction(setter)) throw EngineException.ofType(ctx, "Setter must be a function or undefined.");
|
||||
if (!Values.isObject(obj)) throw EngineException.ofType(ctx, "Property apply target must be an object.");
|
||||
if (getter != null && !Values.isFunction(getter)) throw EngineException.ofType("Getter must be a function or undefined.");
|
||||
if (setter != null && !Values.isFunction(setter)) throw EngineException.ofType("Setter must be a function or undefined.");
|
||||
if (!Values.isObject(obj)) throw EngineException.ofType("Property apply target must be an object.");
|
||||
Values.object(obj).defineProperty(ctx, name, Values.function(getter), Values.function(setter), false, false);
|
||||
|
||||
frame.push(ctx, obj);
|
||||
@ -214,7 +214,7 @@ public class Runners {
|
||||
frame.push(ctx, Values.getMember(ctx, obj, key));
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw EngineException.ofType(ctx, e.getMessage());
|
||||
throw EngineException.ofType(e.getMessage());
|
||||
}
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
@ -239,7 +239,7 @@ public class Runners {
|
||||
var key = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
if (!Values.setMember(ctx, obj, key, val)) throw EngineException.ofSyntax(ctx, "Can't set member '" + key + "'.");
|
||||
if (!Values.setMember(ctx, obj, key, val)) throw EngineException.ofSyntax("Can't set member '" + key + "'.");
|
||||
if ((boolean)instr.get(0)) frame.push(ctx, val);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
@ -311,7 +311,7 @@ public class Runners {
|
||||
if (instr.is(0, "dbg_names")) {
|
||||
var names = new String[instr.params.length - 1];
|
||||
for (var i = 0; i < instr.params.length - 1; i++) {
|
||||
if (!(instr.params[i + 1] instanceof String)) throw EngineException.ofSyntax(ctx, "NOP dbg_names instruction must specify only string parameters.");
|
||||
if (!(instr.params[i + 1] instanceof String)) throw EngineException.ofSyntax("NOP dbg_names instruction must specify only string parameters.");
|
||||
names[i] = (String)instr.params[i + 1];
|
||||
}
|
||||
frame.scope.setNames(names);
|
||||
@ -325,7 +325,7 @@ public class Runners {
|
||||
var key = frame.pop();
|
||||
var val = frame.pop();
|
||||
|
||||
if (!Values.deleteMember(ctx, val, key)) throw EngineException.ofSyntax(ctx, "Can't delete member '" + key + "'.");
|
||||
if (!Values.deleteMember(ctx, val, key)) throw EngineException.ofSyntax("Can't delete member '" + key + "'.");
|
||||
frame.push(ctx, true);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
@ -383,7 +383,7 @@ public class Runners {
|
||||
|
||||
case OPERATION: return execOperation(ctx, instr, frame);
|
||||
|
||||
default: throw EngineException.ofSyntax(ctx, "Invalid instruction " + instr.type.name() + ".");
|
||||
default: throw EngineException.ofSyntax("Invalid instruction " + instr.type.name() + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,12 +60,12 @@ public class GlobalScope implements ScopeRecord {
|
||||
}
|
||||
|
||||
public Object get(Context ctx, String name) throws InterruptedException {
|
||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax(ctx, "The variable '" + name + "' doesn't exist.");
|
||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
||||
else return obj.getMember(ctx, name);
|
||||
}
|
||||
public void set(Context ctx, String name, Object val) throws InterruptedException {
|
||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax(ctx, "The variable '" + name + "' doesn't exist.");
|
||||
if (!obj.setMember(ctx, name, val, false)) throw EngineException.ofSyntax(ctx, "The global '" + name + "' is readonly.");
|
||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
||||
if (!obj.setMember(ctx, name, val, false)) throw EngineException.ofSyntax("The global '" + name + "' is readonly.");
|
||||
}
|
||||
|
||||
public Set<String> keys() {
|
||||
|
@ -9,7 +9,8 @@ public class LocalScope {
|
||||
public final ArrayList<ValueVariable> catchVars = new ArrayList<>();
|
||||
|
||||
public ValueVariable get(int i) {
|
||||
if (i >= locals.length) return catchVars.get(i - locals.length);
|
||||
if (i >= locals.length)
|
||||
return catchVars.get(i - locals.length);
|
||||
if (i >= 0) return locals[i];
|
||||
else return captures[~i];
|
||||
}
|
||||
|
@ -14,6 +14,10 @@ public class ObjectValue {
|
||||
OBJECT,
|
||||
ARRAY,
|
||||
FUNCTION,
|
||||
ERROR,
|
||||
SYNTAX_ERROR,
|
||||
TYPE_ERROR,
|
||||
RANGE_ERROR,
|
||||
}
|
||||
public static enum State {
|
||||
NORMAL,
|
||||
@ -35,6 +39,10 @@ public class ObjectValue {
|
||||
private static final Object OBJ_PROTO = new Object();
|
||||
private static final Object ARR_PROTO = new Object();
|
||||
private static final Object FUNC_PROTO = new Object();
|
||||
private static final Object ERR_PROTO = new Object();
|
||||
private static final Object SYNTAX_ERR_PROTO = new Object();
|
||||
private static final Object TYPE_ERR_PROTO = new Object();
|
||||
private static final Object RANGE_ERR_PROTO = new Object();
|
||||
|
||||
protected Object prototype;
|
||||
|
||||
@ -142,6 +150,10 @@ public class ObjectValue {
|
||||
if (prototype == OBJ_PROTO) return ctx.env.proto("object");
|
||||
if (prototype == ARR_PROTO) return ctx.env.proto("array");
|
||||
if (prototype == FUNC_PROTO) return ctx.env.proto("function");
|
||||
if (prototype == ERR_PROTO) return ctx.env.proto("error");
|
||||
if (prototype == RANGE_ERR_PROTO) return ctx.env.proto("rangeErr");
|
||||
if (prototype == SYNTAX_ERR_PROTO) return ctx.env.proto("syntaxErr");
|
||||
if (prototype == TYPE_ERR_PROTO) return ctx.env.proto("typeErr");
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
return null;
|
||||
@ -164,6 +176,10 @@ public class ObjectValue {
|
||||
if (obj == ctx.env.proto("object")) prototype = OBJ_PROTO;
|
||||
else if (obj == ctx.env.proto("array")) prototype = ARR_PROTO;
|
||||
else if (obj == ctx.env.proto("function")) prototype = FUNC_PROTO;
|
||||
else if (obj == ctx.env.proto("error")) prototype = ERR_PROTO;
|
||||
else if (obj == ctx.env.proto("syntaxErr")) prototype = SYNTAX_ERR_PROTO;
|
||||
else if (obj == ctx.env.proto("typeErr")) prototype = TYPE_ERR_PROTO;
|
||||
else if (obj == ctx.env.proto("rangeErr")) prototype = RANGE_ERR_PROTO;
|
||||
else prototype = obj;
|
||||
}
|
||||
else prototype = obj;
|
||||
@ -178,6 +194,10 @@ public class ObjectValue {
|
||||
case OBJECT: prototype = OBJ_PROTO; break;
|
||||
case FUNCTION: prototype = FUNC_PROTO; break;
|
||||
case ARRAY: prototype = ARR_PROTO; break;
|
||||
case ERROR: prototype = ERR_PROTO; break;
|
||||
case SYNTAX_ERROR: prototype = SYNTAX_ERR_PROTO; break;
|
||||
case TYPE_ERROR: prototype = TYPE_ERR_PROTO; break;
|
||||
case RANGE_ERROR: prototype = RANGE_ERR_PROTO; break;
|
||||
case NONE: prototype = null; break;
|
||||
}
|
||||
return true;
|
||||
|
@ -75,7 +75,7 @@ public class Values {
|
||||
if (isPrimitive(res)) return res;
|
||||
}
|
||||
|
||||
throw EngineException.ofType(ctx, "Value couldn't be converted to a primitive.");
|
||||
throw EngineException.ofType("Value couldn't be converted to a primitive.");
|
||||
}
|
||||
|
||||
public static boolean isPrimitive(Object obj) {
|
||||
@ -105,7 +105,7 @@ public class Values {
|
||||
}
|
||||
}
|
||||
|
||||
throw EngineException.ofType(ctx, "Value couldn't be converted to a primitive.");
|
||||
throw EngineException.ofType("Value couldn't be converted to a primitive.");
|
||||
}
|
||||
public static boolean toBoolean(Object obj) {
|
||||
if (obj == NULL || obj == null) return false;
|
||||
@ -284,8 +284,8 @@ public class Values {
|
||||
}
|
||||
public static boolean setMember(Context ctx, Object obj, Object key, Object val) throws InterruptedException {
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key); val = normalize(ctx, val);
|
||||
if (obj == null) throw EngineException.ofType(ctx, "Tried to access member of undefined.");
|
||||
if (obj == NULL) throw EngineException.ofType(ctx, "Tried to access member of null.");
|
||||
if (obj == null) throw EngineException.ofType("Tried to access member of undefined.");
|
||||
if (obj == NULL) throw EngineException.ofType("Tried to access member of null.");
|
||||
if (key.equals("__proto__")) return setPrototype(ctx, obj, val);
|
||||
if (isObject(obj)) return object(obj).setMember(ctx, key, val, false);
|
||||
|
||||
@ -373,7 +373,7 @@ public class Values {
|
||||
}
|
||||
|
||||
public static Object call(Context ctx, Object func, Object thisArg, Object ...args) throws InterruptedException {
|
||||
if (!isFunction(func)) throw EngineException.ofType(ctx, "Tried to call a non-function value.");
|
||||
if (!isFunction(func)) throw EngineException.ofType("Tried to call a non-function value.");
|
||||
return function(func).call(ctx, thisArg, args);
|
||||
}
|
||||
public static Object callNew(Context ctx, Object func, Object ...args) throws InterruptedException {
|
||||
|
@ -5,8 +5,9 @@ import java.util.List;
|
||||
|
||||
import me.topchetoeu.jscript.Location;
|
||||
import me.topchetoeu.jscript.engine.Context;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue.PlaceholderProto;
|
||||
|
||||
public class EngineException extends RuntimeException {
|
||||
public final Object value;
|
||||
@ -48,20 +49,11 @@ public class EngineException extends RuntimeException {
|
||||
return ss.toString();
|
||||
}
|
||||
|
||||
private static Object err(Context ctx, String type, String name, String msg) throws InterruptedException {
|
||||
try {
|
||||
var proto = ctx.env.proto(type);
|
||||
var constr = Values.getMember(ctx, proto, "constructor");
|
||||
|
||||
if (constr instanceof FunctionValue) {
|
||||
var res = Values.callNew(ctx, constr, msg);
|
||||
if (name != null) Values.setMember(ctx, res, "name", name);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) { }
|
||||
|
||||
return name + ": " + msg;
|
||||
private static Object err(String name, String msg, PlaceholderProto proto) {
|
||||
var res = new ObjectValue(proto);
|
||||
if (name != null) res.defineProperty(null, "name", name);
|
||||
res.defineProperty(null, "message", msg);
|
||||
return res;
|
||||
}
|
||||
|
||||
public EngineException(Object error) {
|
||||
@ -71,22 +63,22 @@ public class EngineException extends RuntimeException {
|
||||
this.cause = null;
|
||||
}
|
||||
|
||||
public static EngineException ofError(Context ctx, String name, String msg) throws InterruptedException {
|
||||
return new EngineException(err(ctx, "error", name, msg));
|
||||
public static EngineException ofError(String name, String msg) {
|
||||
return new EngineException(err(name, msg, PlaceholderProto.ERROR));
|
||||
}
|
||||
public static EngineException ofError(Context ctx, String msg) throws InterruptedException {
|
||||
return new EngineException(err(ctx, "error", null, msg));
|
||||
public static EngineException ofError(String msg) {
|
||||
return new EngineException(err(null, msg, PlaceholderProto.ERROR));
|
||||
}
|
||||
public static EngineException ofSyntax(Context ctx, SyntaxException e) throws InterruptedException {
|
||||
return new EngineException(err(ctx, "syntaxErr", null, e.msg)).add(null, e.loc);
|
||||
public static EngineException ofSyntax(SyntaxException e) {
|
||||
return new EngineException(err(null, e.msg, PlaceholderProto.SYNTAX_ERROR)).add(null, e.loc);
|
||||
}
|
||||
public static EngineException ofSyntax(Context ctx, String msg) throws InterruptedException {
|
||||
return new EngineException(err(ctx, "syntaxErr", null, msg));
|
||||
public static EngineException ofSyntax(String msg) {
|
||||
return new EngineException(err(null, msg, PlaceholderProto.SYNTAX_ERROR));
|
||||
}
|
||||
public static EngineException ofType(Context ctx, String msg) throws InterruptedException {
|
||||
return new EngineException(err(ctx, "typeErr", null, msg));
|
||||
public static EngineException ofType(String msg) {
|
||||
return new EngineException(err(null, msg, PlaceholderProto.TYPE_ERROR));
|
||||
}
|
||||
public static EngineException ofRange(Context ctx, String msg) throws InterruptedException {
|
||||
return new EngineException(err(ctx, "rangeErr", null, msg));
|
||||
public static EngineException ofRange(String msg) {
|
||||
return new EngineException(err(null, msg, PlaceholderProto.RANGE_ERROR));
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ public class NativeWrapperProvider implements WrappersProvider {
|
||||
}
|
||||
|
||||
if (((OverloadFunction)func).overloads.size() == 0) {
|
||||
func = new NativeFunction(clazz.getName(), (a, b, c) -> { throw EngineException.ofError(a, "This constructor is not invokable."); });
|
||||
func = new NativeFunction(clazz.getName(), (a, b, c) -> { throw EngineException.ofError("This constructor is not invokable."); });
|
||||
}
|
||||
|
||||
applyMethods(ctx, false, func, clazz);
|
||||
|
@ -34,7 +34,7 @@ public class OverloadFunction extends FunctionValue {
|
||||
}
|
||||
catch (ConvertException e) {
|
||||
if (overloads.size() > 1) continue loop;
|
||||
else throw EngineException.ofType(ctx, String.format("Argument %d can't be converted from %s to %s", i - start, e.source, e.target));
|
||||
else throw EngineException.ofType(String.format("Argument %d can't be converted from %s to %s", i - start, e.source, e.target));
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ public class OverloadFunction extends FunctionValue {
|
||||
}
|
||||
catch (ConvertException e) {
|
||||
if (overloads.size() > 1) continue loop;
|
||||
else throw EngineException.ofType(ctx, String.format("Element in variadic argument can't be converted from %s to %s", 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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ public class OverloadFunction extends FunctionValue {
|
||||
}
|
||||
catch (ConvertException e) {
|
||||
if (overloads.size() > 1) continue loop;
|
||||
else throw EngineException.ofType(ctx, String.format("This argument can't be converted from %s to %s", e.source, e.target));
|
||||
else throw EngineException.ofType(String.format("This argument can't be converted from %s to %s", e.source, e.target));
|
||||
}
|
||||
|
||||
if (consumesEngine) newArgs[0] = ctx;
|
||||
@ -77,7 +77,7 @@ public class OverloadFunction extends FunctionValue {
|
||||
return Values.normalize(ctx, overload.runner.run(ctx, _this, newArgs));
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw EngineException.ofError(ctx, "The class may not be instantiated.");
|
||||
throw EngineException.ofError("The class may not be instantiated.");
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException e) {
|
||||
continue;
|
||||
@ -88,21 +88,21 @@ public class OverloadFunction extends FunctionValue {
|
||||
throw ((EngineException)e.getTargetException()).add(name, loc);
|
||||
}
|
||||
else if (e.getTargetException() instanceof NullPointerException) {
|
||||
throw EngineException.ofType(ctx, "Unexpected value of 'undefined'.").add(name, loc);
|
||||
throw EngineException.ofType("Unexpected value of 'undefined'.").add(name, loc);
|
||||
}
|
||||
else {
|
||||
throw EngineException.ofError(ctx, e.getTargetException().getMessage()).add(name, loc);
|
||||
throw EngineException.ofError(e.getTargetException().getMessage()).add(name, loc);
|
||||
}
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw EngineException.ofError(ctx, e.getMessage()).add(name, new Location(0, 0, "<internal>"));
|
||||
throw EngineException.ofError(e.getMessage()).add(name, new Location(0, 0, "<internal>"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
throw EngineException.ofType(ctx, "No overload found for native method.");
|
||||
throw EngineException.ofType("No overload found for native method.");
|
||||
}
|
||||
|
||||
public OverloadFunction add(Overload overload) {
|
||||
|
@ -65,7 +65,7 @@ public class AsyncFunctionPolyfill extends FunctionValue {
|
||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
||||
var handler = new AsyncHelper();
|
||||
var func = factory.call(ctx, thisArg, new NativeFunction("await", handler::await));
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType(ctx, "Return value of argument must be a js function.");
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||
handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func);
|
||||
handler.next(ctx, Runners.NO_RETURN, Runners.NO_RETURN);
|
||||
return handler.promise;
|
||||
|
@ -122,7 +122,7 @@ public class AsyncGeneratorPolyfill extends FunctionValue {
|
||||
new NativeFunction("await", handler::await),
|
||||
new NativeFunction("yield", handler::yield)
|
||||
);
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType(ctx, "Return value of argument must be a js function.");
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||
handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func);
|
||||
return handler;
|
||||
}
|
||||
|
@ -5,31 +5,31 @@ import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.interop.Native;
|
||||
import me.topchetoeu.jscript.interop.NativeConstructor;
|
||||
|
||||
public class ErrorPolyfill {
|
||||
public static class SyntaxErrorPolyfill extends ErrorPolyfill {
|
||||
@Native public SyntaxErrorPolyfill(Context ctx, Object message) throws InterruptedException {
|
||||
super(ctx, message);
|
||||
this.name = "SyntaxError";
|
||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
||||
var target = ErrorPolyfill.constructor(ctx, thisArg, message);
|
||||
target.defineProperty(ctx, "name", "SyntaxError");
|
||||
return target;
|
||||
}
|
||||
}
|
||||
public static class TypeErrorPolyfill extends ErrorPolyfill {
|
||||
@Native public TypeErrorPolyfill(Context ctx, Object message) throws InterruptedException {
|
||||
super(ctx, message);
|
||||
this.name = "TypeError";
|
||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
||||
var target = ErrorPolyfill.constructor(ctx, thisArg, message);
|
||||
target.defineProperty(ctx, "name", "TypeError");
|
||||
return target;
|
||||
}
|
||||
}
|
||||
public static class RangeErrorPolyfill extends ErrorPolyfill {
|
||||
@Native public RangeErrorPolyfill(Context ctx, Object message) throws InterruptedException {
|
||||
super(ctx, message);
|
||||
this.name = "RangeError";
|
||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
||||
var target = ErrorPolyfill.constructor(ctx, thisArg, message);
|
||||
target.defineProperty(ctx, "name", "RangeError");
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
@Native public final ArrayValue stack;
|
||||
@Native public String message;
|
||||
@Native public String name = "Error";
|
||||
|
||||
private static String toString(Context ctx, Object name, Object message, ArrayValue stack) throws InterruptedException {
|
||||
if (name == null) name = "";
|
||||
else name = Values.toString(ctx, name).trim();
|
||||
@ -52,10 +52,7 @@ public class ErrorPolyfill {
|
||||
}
|
||||
|
||||
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
||||
if (thisArg instanceof ErrorPolyfill) {
|
||||
return toString(ctx, ((ErrorPolyfill)thisArg).name, ((ErrorPolyfill)thisArg).message, ((ErrorPolyfill)thisArg).stack);
|
||||
}
|
||||
else if (thisArg instanceof ObjectValue) {
|
||||
if (thisArg instanceof ObjectValue) {
|
||||
var stack = Values.getMember(ctx, thisArg, "stack");
|
||||
if (!(stack instanceof ArrayValue)) stack = null;
|
||||
return toString(ctx,
|
||||
@ -67,9 +64,15 @@ public class ErrorPolyfill {
|
||||
else return "[Invalid error]";
|
||||
}
|
||||
|
||||
@Native public ErrorPolyfill(Context ctx, Object message) throws InterruptedException {
|
||||
this.stack = new ArrayValue(ctx, ctx.message.stackTrace().toArray());
|
||||
if (message == null) this.message = "";
|
||||
else this.message = Values.toString(ctx, message);
|
||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
||||
var target = new ObjectValue();
|
||||
if (thisArg instanceof ObjectValue) target = (ObjectValue)thisArg;
|
||||
|
||||
target.defineProperty(ctx, "stack", new ArrayValue(ctx, ctx.message.stackTrace().toArray()));
|
||||
target.defineProperty(ctx, "name", "Error");
|
||||
if (message == null) target.defineProperty(ctx, "message", "");
|
||||
else target.defineProperty(ctx, "message", Values.toString(ctx, message));
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ public class FunctionPolyfill {
|
||||
return func.call(ctx, thisArg, args.toArray());
|
||||
}
|
||||
@Native(thisArg = true) public static Object call(Context ctx, FunctionValue func, Object thisArg, Object... args) throws InterruptedException {
|
||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError(ctx, "Expected this to be a function.");
|
||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
||||
|
||||
return func.call(ctx, thisArg, args);
|
||||
}
|
||||
@Native(thisArg = true) public static FunctionValue bind(Context ctx, FunctionValue func, Object thisArg, Object... args) throws InterruptedException {
|
||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError(ctx, "Expected this to be a function.");
|
||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
||||
|
||||
return new NativeFunction(func.name + " (bound)", (callCtx, _0, callArgs) -> {
|
||||
var resArgs = new Object[args.length + callArgs.length];
|
||||
|
@ -89,7 +89,7 @@ public class GeneratorPolyfill extends FunctionValue {
|
||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
||||
var handler = new Generator();
|
||||
var func = factory.call(ctx, thisArg, new NativeFunction("yield", handler::yield));
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType(ctx, "Return value of argument must be a js function.");
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||
handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func);
|
||||
return handler;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class JSON {
|
||||
return toJS(me.topchetoeu.jscript.json.JSON.parse("<value>", val));
|
||||
}
|
||||
catch (SyntaxException e) {
|
||||
throw EngineException.ofSyntax(ctx, e.msg);
|
||||
throw EngineException.ofSyntax(e.msg);
|
||||
}
|
||||
}
|
||||
@Native
|
||||
|
@ -33,27 +33,27 @@ public class ObjectPolyfill {
|
||||
var hasSet = attrib.hasMember(ctx, "set", false);
|
||||
|
||||
if (hasVal) {
|
||||
if (hasGet || hasSet) throw EngineException.ofType(ctx, "Cannot specify a value and accessors for a property.");
|
||||
if (hasGet || hasSet) throw EngineException.ofType("Cannot specify a value and accessors for a property.");
|
||||
if (!obj.defineProperty(
|
||||
ctx, key,
|
||||
attrib.getMember(ctx, "value"),
|
||||
Values.toBoolean(attrib.getMember(ctx, "writable")),
|
||||
Values.toBoolean(attrib.getMember(ctx, "configurable")),
|
||||
Values.toBoolean(attrib.getMember(ctx, "enumerable"))
|
||||
)) throw EngineException.ofType(ctx, "Can't define property '" + key + "'.");
|
||||
)) throw EngineException.ofType("Can't define property '" + key + "'.");
|
||||
}
|
||||
else {
|
||||
var get = attrib.getMember(ctx, "get");
|
||||
var set = attrib.getMember(ctx, "set");
|
||||
if (get != null && !(get instanceof FunctionValue)) throw EngineException.ofType(ctx, "Get accessor must be a function.");
|
||||
if (set != null && !(set instanceof FunctionValue)) throw EngineException.ofType(ctx, "Set accessor must be a function.");
|
||||
if (get != null && !(get instanceof FunctionValue)) throw EngineException.ofType("Get accessor must be a function.");
|
||||
if (set != null && !(set instanceof FunctionValue)) throw EngineException.ofType("Set accessor must be a function.");
|
||||
|
||||
if (!obj.defineProperty(
|
||||
ctx, key,
|
||||
(FunctionValue)get, (FunctionValue)set,
|
||||
Values.toBoolean(attrib.getMember(ctx, "configurable")),
|
||||
Values.toBoolean(attrib.getMember(ctx, "enumerable"))
|
||||
)) throw EngineException.ofType(ctx, "Can't define property '" + key + "'.");
|
||||
)) throw EngineException.ofType("Can't define property '" + key + "'.");
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -44,7 +44,7 @@ public class PromisePolyfill {
|
||||
}
|
||||
|
||||
@Native public static PromisePolyfill any(Context ctx, Object _promises) throws InterruptedException {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType(ctx, "Expected argument for any to be an array.");
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||
var n = new int[] { promises.size() };
|
||||
@ -69,7 +69,7 @@ public class PromisePolyfill {
|
||||
return res;
|
||||
}
|
||||
@Native public static PromisePolyfill race(Context ctx, Object _promises) throws InterruptedException {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType(ctx, "Expected argument for any to be an array.");
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||
var res = new PromisePolyfill();
|
||||
@ -85,7 +85,7 @@ public class PromisePolyfill {
|
||||
return res;
|
||||
}
|
||||
@Native public static PromisePolyfill all(Context ctx, Object _promises) throws InterruptedException {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType(ctx, "Expected argument for any to be an array.");
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||
var n = new int[] { promises.size() };
|
||||
@ -112,7 +112,7 @@ public class PromisePolyfill {
|
||||
return res;
|
||||
}
|
||||
@Native public static PromisePolyfill allSettled(Context ctx, Object _promises) throws InterruptedException {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType(ctx, "Expected argument for any to be an array.");
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||
var n = new int[] { promises.size() };
|
||||
@ -314,7 +314,7 @@ public class PromisePolyfill {
|
||||
* NOT THREAD SAFE - must be called from the engine executor thread
|
||||
*/
|
||||
@Native public PromisePolyfill(Context ctx, FunctionValue func) throws InterruptedException {
|
||||
if (!(func instanceof FunctionValue)) throw EngineException.ofType(ctx, "A function must be passed to the promise constructor.");
|
||||
if (!(func instanceof FunctionValue)) throw EngineException.ofType("A function must be passed to the promise constructor.");
|
||||
try {
|
||||
func.call(
|
||||
ctx, null,
|
||||
|
@ -21,7 +21,7 @@ public class StringPolyfill {
|
||||
private static String passThis(Context ctx, String funcName, Object val) throws InterruptedException {
|
||||
if (val instanceof StringPolyfill) return ((StringPolyfill)val).value;
|
||||
else if (val instanceof String) return (String)val;
|
||||
else throw EngineException.ofType(ctx, String.format("'%s' may only be called upon object and primitve strings.", funcName));
|
||||
else throw EngineException.ofType(String.format("'%s' may only be called upon object and primitve strings.", funcName));
|
||||
}
|
||||
private static int normalizeI(int i, int len, boolean clamp) {
|
||||
if (i < 0) i += len;
|
||||
@ -137,9 +137,9 @@ public class StringPolyfill {
|
||||
var regex = Values.callNew(ctx, ctx.env.regexConstructor, Values.toString(ctx, term), "");
|
||||
_match = Values.getMember(ctx, regex, ctx.env.symbol("Symbol.match"));
|
||||
if (_match instanceof FunctionValue) match = (FunctionValue)_match;
|
||||
else throw EngineException.ofError(ctx, "Regular expressions don't support matching.");
|
||||
else throw EngineException.ofError("Regular expressions don't support matching.");
|
||||
}
|
||||
else throw EngineException.ofError(ctx, "Regular expressions not supported.");
|
||||
else throw EngineException.ofError("Regular expressions not supported.");
|
||||
}
|
||||
catch (IllegalArgumentException e) { return new ArrayValue(ctx, ""); }
|
||||
|
||||
@ -162,9 +162,9 @@ public class StringPolyfill {
|
||||
var regex = Values.callNew(ctx, ctx.env.regexConstructor, Values.toString(ctx, term), "g");
|
||||
var _match = Values.getMember(ctx, regex, ctx.env.symbol("Symbol.matchAll"));
|
||||
if (_match instanceof FunctionValue) match = (FunctionValue)_match;
|
||||
else throw EngineException.ofError(ctx, "Regular expressions don't support matching.");
|
||||
else throw EngineException.ofError("Regular expressions don't support matching.");
|
||||
}
|
||||
else throw EngineException.ofError(ctx, "Regular expressions not supported.");
|
||||
else throw EngineException.ofError("Regular expressions not supported.");
|
||||
|
||||
return match.call(ctx, term, val);
|
||||
}
|
||||
|
@ -30,11 +30,11 @@ public class SymbolPolyfill {
|
||||
private static Symbol passThis(Context ctx, String funcName, Object val) throws InterruptedException {
|
||||
if (val instanceof SymbolPolyfill) return ((SymbolPolyfill)val).value;
|
||||
else if (val instanceof Symbol) return (Symbol)val;
|
||||
else throw EngineException.ofType(ctx, String.format("'%s' may only be called upon object and primitve symbols.", funcName));
|
||||
else throw EngineException.ofType(String.format("'%s' may only be called upon object and primitve symbols.", funcName));
|
||||
}
|
||||
|
||||
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object val) throws InterruptedException {
|
||||
if (thisArg instanceof ObjectValue) throw EngineException.ofType(ctx, "Symbol constructor may not be called with new.");
|
||||
if (thisArg instanceof ObjectValue) throw EngineException.ofType("Symbol constructor may not be called with new.");
|
||||
if (val == null) return new Symbol("");
|
||||
else return new Symbol(Values.toString(ctx, val));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user