Debugging support #7
@ -14,6 +14,7 @@ import me.topchetoeu.jscript.engine.values.NativeFunction;
|
|||||||
import me.topchetoeu.jscript.engine.values.Values;
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
import me.topchetoeu.jscript.events.Observer;
|
import me.topchetoeu.jscript.events.Observer;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
|
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||||
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
||||||
import me.topchetoeu.jscript.lib.Internals;
|
import me.topchetoeu.jscript.lib.Internals;
|
||||||
|
|
||||||
@ -46,14 +47,12 @@ public class Main {
|
|||||||
|
|
||||||
private static Observer<Object> valuePrinter = new Observer<Object>() {
|
private static Observer<Object> valuePrinter = new Observer<Object>() {
|
||||||
public void next(Object data) {
|
public void next(Object data) {
|
||||||
try { Values.printValue(null, data); }
|
Values.printValue(null, data);
|
||||||
catch (InterruptedException e) { }
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void error(RuntimeException err) {
|
public void error(RuntimeException err) {
|
||||||
try { Values.printError(err, null); }
|
Values.printError(err, null);
|
||||||
catch (InterruptedException ex) { return; }
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,8 +69,7 @@ public class Main {
|
|||||||
|
|
||||||
env.global.define("exit", _ctx -> {
|
env.global.define("exit", _ctx -> {
|
||||||
exited[0] = true;
|
exited[0] = true;
|
||||||
task.interrupt();
|
throw new InterruptException();
|
||||||
throw new InterruptedException();
|
|
||||||
});
|
});
|
||||||
env.global.define("go", _ctx -> {
|
env.global.define("go", _ctx -> {
|
||||||
try {
|
try {
|
||||||
@ -96,14 +94,7 @@ public class Main {
|
|||||||
if (raw == null) break;
|
if (raw == null) break;
|
||||||
engine.pushMsg(false, new Context(engine).pushEnv(env), "<stdio>", raw, null).toObservable().once(valuePrinter);
|
engine.pushMsg(false, new Context(engine).pushEnv(env), "<stdio>", raw, null).toObservable().once(valuePrinter);
|
||||||
}
|
}
|
||||||
catch (EngineException e) {
|
catch (EngineException e) { Values.printError(e, ""); }
|
||||||
try {
|
|
||||||
System.out.println("Uncaught " + e.toString(null));
|
|
||||||
}
|
|
||||||
catch (EngineException ex) {
|
|
||||||
System.out.println("Uncaught [error while converting to string]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
@ -114,12 +105,12 @@ public class Main {
|
|||||||
if (exited[0]) return;
|
if (exited[0]) return;
|
||||||
System.out.println("Syntax error:" + ex.msg);
|
System.out.println("Syntax error:" + ex.msg);
|
||||||
}
|
}
|
||||||
|
catch (InterruptException e) { return; }
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
if (exited[0]) return;
|
if (exited[0]) return;
|
||||||
System.out.println("Internal error ocurred:");
|
System.out.println("Internal error ocurred:");
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) { return; }
|
|
||||||
if (exited[0]) return;
|
if (exited[0]) return;
|
||||||
});
|
});
|
||||||
reader.setDaemon(true);
|
reader.setDaemon(true);
|
||||||
|
@ -23,7 +23,7 @@ public class Context {
|
|||||||
if (!env.empty()) this.env.pop();
|
if (!env.empty()) this.env.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionValue compile(String filename, String raw) throws InterruptedException {
|
public FunctionValue compile(String filename, String raw) {
|
||||||
var res = Values.toString(this, environment().compile.call(this, null, raw, filename));
|
var res = Values.toString(this, environment().compile.call(this, null, raw, filename));
|
||||||
return Parsing.compile(engine.functions, environment(), filename, res);
|
return Parsing.compile(engine.functions, environment(), filename, res);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public class Engine {
|
|||||||
private FunctionValue compiled = null;
|
private FunctionValue compiled = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
if (compiled == null) compiled = ctx.compile(filename, raw);
|
if (compiled == null) compiled = ctx.compile(filename, raw);
|
||||||
return compiled.call(ctx, thisArg, args);
|
return compiled.call(ctx, thisArg, args);
|
||||||
}
|
}
|
||||||
@ -53,14 +53,10 @@ public class Engine {
|
|||||||
public final HashMap<Long, Instruction[]> functions = new HashMap<>();
|
public final HashMap<Long, Instruction[]> functions = new HashMap<>();
|
||||||
public final Data data = new Data().set(StackData.MAX_FRAMES, 10000);
|
public final Data data = new Data().set(StackData.MAX_FRAMES, 10000);
|
||||||
|
|
||||||
private void runTask(Task task) throws InterruptedException {
|
private void runTask(Task task) {
|
||||||
try {
|
try {
|
||||||
task.notifier.next(task.func.call(task.ctx, task.thisArg, task.args));
|
task.notifier.next(task.func.call(task.ctx, task.thisArg, task.args));
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
|
||||||
task.notifier.error(new RuntimeException(e));
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
catch (EngineException e) {
|
catch (EngineException e) {
|
||||||
task.notifier.error(e);
|
task.notifier.error(e);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ public class StackData {
|
|||||||
public static final DataKey<Integer> MAX_FRAMES = new DataKey<>();
|
public static final DataKey<Integer> MAX_FRAMES = new DataKey<>();
|
||||||
public static final DataKey<DebugServer> DEBUGGER = new DataKey<>();
|
public static final DataKey<DebugServer> DEBUGGER = new DataKey<>();
|
||||||
|
|
||||||
public static void pushFrame(Context ctx, CodeFrame frame) throws InterruptedException {
|
public static void pushFrame(Context ctx, CodeFrame frame) {
|
||||||
var frames = ctx.data.get(FRAMES, new ArrayList<>());
|
var frames = ctx.data.get(FRAMES, new ArrayList<>());
|
||||||
frames.add(frame);
|
frames.add(frame);
|
||||||
if (frames.size() > ctx.data.get(MAX_FRAMES, 10000)) throw EngineException.ofRange("Stack overflow!");
|
if (frames.size() > ctx.data.get(MAX_FRAMES, 10000)) throw EngineException.ofRange("Stack overflow!");
|
||||||
|
@ -11,6 +11,7 @@ import me.topchetoeu.jscript.engine.values.CodeFunction;
|
|||||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.engine.values.Values;
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
|
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||||
|
|
||||||
public class CodeFrame {
|
public class CodeFrame {
|
||||||
private class TryCtx {
|
private class TryCtx {
|
||||||
@ -93,14 +94,14 @@ public class CodeFrame {
|
|||||||
stack[stackPtr++] = Values.normalize(ctx, val);
|
stack[stackPtr++] = Values.normalize(ctx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCause(Context ctx, EngineException err, EngineException cause) throws InterruptedException {
|
private void setCause(Context ctx, EngineException err, EngineException cause) {
|
||||||
if (err.value instanceof ObjectValue) {
|
if (err.value instanceof ObjectValue) {
|
||||||
Values.setMember(ctx, err, ctx.environment().symbol("Symbol.cause"), cause);
|
Values.setMember(ctx, err, ctx.environment().symbol("Symbol.cause"), cause);
|
||||||
}
|
}
|
||||||
err.cause = cause;
|
err.cause = cause;
|
||||||
}
|
}
|
||||||
private Object nextNoTry(Context ctx) throws InterruptedException {
|
private Object nextNoTry(Context ctx) {
|
||||||
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
|
if (Thread.currentThread().isInterrupted()) throw new InterruptException();
|
||||||
if (codePtr < 0 || codePtr >= function.body.length) return null;
|
if (codePtr < 0 || codePtr >= function.body.length) return null;
|
||||||
|
|
||||||
var instr = function.body[codePtr];
|
var instr = function.body[codePtr];
|
||||||
@ -117,7 +118,7 @@ public class CodeFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next(Context ctx, Object value, Object returnValue, EngineException error) throws InterruptedException {
|
public Object next(Context ctx, Object value, Object returnValue, EngineException error) {
|
||||||
if (value != Runners.NO_RETURN) push(ctx, value);
|
if (value != Runners.NO_RETURN) push(ctx, value);
|
||||||
|
|
||||||
if (returnValue == Runners.NO_RETURN && error == null) {
|
if (returnValue == Runners.NO_RETURN && error == null) {
|
||||||
|
@ -22,15 +22,15 @@ public class Runners {
|
|||||||
public static Object execThrow(Context ctx, Instruction instr, CodeFrame frame) {
|
public static Object execThrow(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
throw new EngineException(frame.pop());
|
throw new EngineException(frame.pop());
|
||||||
}
|
}
|
||||||
public static Object execThrowSyntax(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execThrowSyntax(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
throw EngineException.ofSyntax((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 {
|
private static Object call(Context ctx, Object func, Object thisArg, Object ...args) {
|
||||||
return Values.call(ctx, func, thisArg, args);
|
return Values.call(ctx, func, thisArg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object execCall(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execCall(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var callArgs = frame.take(instr.get(0));
|
var callArgs = frame.take(instr.get(0));
|
||||||
var func = frame.pop();
|
var func = frame.pop();
|
||||||
var thisArg = frame.pop();
|
var thisArg = frame.pop();
|
||||||
@ -40,7 +40,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execCallNew(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execCallNew(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var callArgs = frame.take(instr.get(0));
|
var callArgs = frame.take(instr.get(0));
|
||||||
var funcObj = frame.pop();
|
var funcObj = frame.pop();
|
||||||
|
|
||||||
@ -61,13 +61,13 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var name = (String)instr.get(0);
|
var name = (String)instr.get(0);
|
||||||
ctx.environment().global.define(name);
|
ctx.environment().global.define(name);
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execDefProp(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execDefProp(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var setter = frame.pop();
|
var setter = frame.pop();
|
||||||
var getter = frame.pop();
|
var getter = frame.pop();
|
||||||
var name = frame.pop();
|
var name = frame.pop();
|
||||||
@ -82,7 +82,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execInstanceof(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execInstanceof(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var type = frame.pop();
|
var type = frame.pop();
|
||||||
var obj = frame.pop();
|
var obj = frame.pop();
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execKeys(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execKeys(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var val = frame.pop();
|
var val = frame.pop();
|
||||||
|
|
||||||
var arr = new ObjectValue();
|
var arr = new ObjectValue();
|
||||||
@ -117,7 +117,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object execTry(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execTry(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
frame.addTry(instr.get(0), instr.get(1), instr.get(2));
|
frame.addTry(instr.get(0), instr.get(1), instr.get(2));
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
@ -155,7 +155,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var i = instr.get(0);
|
var i = instr.get(0);
|
||||||
|
|
||||||
if (i instanceof String) frame.push(ctx, ctx.environment().global.get(ctx, (String)i));
|
if (i instanceof String) frame.push(ctx, ctx.environment().global.get(ctx, (String)i));
|
||||||
@ -199,7 +199,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execLoadMember(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execLoadMember(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var key = frame.pop();
|
var key = frame.pop();
|
||||||
var obj = frame.pop();
|
var obj = frame.pop();
|
||||||
|
|
||||||
@ -212,11 +212,11 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execLoadKeyMember(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execLoadKeyMember(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
frame.push(ctx, instr.get(0));
|
frame.push(ctx, instr.get(0));
|
||||||
return execLoadMember(ctx, instr, frame);
|
return execLoadMember(ctx, instr, frame);
|
||||||
}
|
}
|
||||||
public static Object execLoadRegEx(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execLoadRegEx(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
frame.push(ctx, ctx.environment().regexConstructor.call(ctx, null, instr.get(0), instr.get(1)));
|
frame.push(ctx, ctx.environment().regexConstructor.call(ctx, null, instr.get(0), instr.get(1)));
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
@ -227,7 +227,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execStoreMember(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execStoreMember(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var val = frame.pop();
|
var val = frame.pop();
|
||||||
var key = frame.pop();
|
var key = frame.pop();
|
||||||
var obj = frame.pop();
|
var obj = frame.pop();
|
||||||
@ -237,7 +237,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execStoreVar(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execStoreVar(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
|
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
|
||||||
var i = instr.get(0);
|
var i = instr.get(0);
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ public class Runners {
|
|||||||
frame.jumpFlag = true;
|
frame.jumpFlag = true;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execJmpIf(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execJmpIf(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
if (Values.toBoolean(frame.pop())) {
|
if (Values.toBoolean(frame.pop())) {
|
||||||
frame.codePtr += (int)instr.get(0);
|
frame.codePtr += (int)instr.get(0);
|
||||||
frame.jumpFlag = true;
|
frame.jumpFlag = true;
|
||||||
@ -266,7 +266,7 @@ public class Runners {
|
|||||||
else frame.codePtr ++;
|
else frame.codePtr ++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execJmpIfNot(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execJmpIfNot(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
if (Values.not(frame.pop())) {
|
if (Values.not(frame.pop())) {
|
||||||
frame.codePtr += (int)instr.get(0);
|
frame.codePtr += (int)instr.get(0);
|
||||||
frame.jumpFlag = true;
|
frame.jumpFlag = true;
|
||||||
@ -275,7 +275,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object execIn(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execIn(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var obj = frame.pop();
|
var obj = frame.pop();
|
||||||
var index = frame.pop();
|
var index = frame.pop();
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execTypeof(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execTypeof(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
String name = instr.get(0);
|
String name = instr.get(0);
|
||||||
Object obj;
|
Object obj;
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ public class Runners {
|
|||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execNop(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execNop(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
if (instr.is(0, "dbg_names")) {
|
if (instr.is(0, "dbg_names")) {
|
||||||
var names = new String[instr.params.length - 1];
|
var names = new String[instr.params.length - 1];
|
||||||
for (var i = 0; i < instr.params.length - 1; i++) {
|
for (var i = 0; i < instr.params.length - 1; i++) {
|
||||||
@ -314,7 +314,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object execDelete(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execDelete(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
var key = frame.pop();
|
var key = frame.pop();
|
||||||
var val = frame.pop();
|
var val = frame.pop();
|
||||||
|
|
||||||
@ -324,7 +324,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object execOperation(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execOperation(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
Operation op = instr.get(0);
|
Operation op = instr.get(0);
|
||||||
var args = new Object[op.operands];
|
var args = new Object[op.operands];
|
||||||
|
|
||||||
@ -335,7 +335,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object exec(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object exec(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
switch (instr.type) {
|
switch (instr.type) {
|
||||||
case NOP: return execNop(ctx, instr, frame);
|
case NOP: return execNop(ctx, instr, frame);
|
||||||
case RETURN: return execReturn(ctx, instr, frame);
|
case RETURN: return execReturn(ctx, instr, frame);
|
||||||
|
@ -15,7 +15,7 @@ public class GlobalScope implements ScopeRecord {
|
|||||||
@Override
|
@Override
|
||||||
public GlobalScope parent() { return null; }
|
public GlobalScope parent() { return null; }
|
||||||
|
|
||||||
public boolean has(Context ctx, String name) throws InterruptedException {
|
public boolean has(Context ctx, String name) {
|
||||||
return obj.hasMember(ctx, name, false);
|
return obj.hasMember(ctx, name, false);
|
||||||
}
|
}
|
||||||
public Object getKey(String name) {
|
public Object getKey(String name) {
|
||||||
@ -32,13 +32,7 @@ public class GlobalScope implements ScopeRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object define(String name) {
|
public Object define(String name) {
|
||||||
try {
|
if (obj.hasMember(null, name, true)) return name;
|
||||||
if (obj.hasMember(null, name, true)) return name;
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
obj.defineProperty(null, name, null);
|
obj.defineProperty(null, name, null);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -59,11 +53,11 @@ public class GlobalScope implements ScopeRecord {
|
|||||||
define(null, val.name, readonly, val);
|
define(null, val.name, readonly, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(Context ctx, String name) throws InterruptedException {
|
public Object get(Context ctx, String name) {
|
||||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("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);
|
else return obj.getMember(ctx, name);
|
||||||
}
|
}
|
||||||
public void set(Context ctx, String name, Object val) throws InterruptedException {
|
public void set(Context ctx, String name, Object val) {
|
||||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
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.");
|
if (!obj.setMember(ctx, name, val, false)) throw EngineException.ofSyntax("The global '" + name + "' is readonly.");
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class LocalScopeRecord implements ScopeRecord {
|
|||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
public boolean has(Context ctx, String name) throws InterruptedException {
|
public boolean has(Context ctx, String name) {
|
||||||
return
|
return
|
||||||
global.has(ctx, name) ||
|
global.has(ctx, name) ||
|
||||||
locals.contains(name) ||
|
locals.contains(name) ||
|
||||||
|
@ -3,7 +3,7 @@ package me.topchetoeu.jscript.engine.scope;
|
|||||||
import me.topchetoeu.jscript.engine.Context;
|
import me.topchetoeu.jscript.engine.Context;
|
||||||
|
|
||||||
public interface Variable {
|
public interface Variable {
|
||||||
Object get(Context ctx) throws InterruptedException;
|
Object get(Context ctx);
|
||||||
default boolean readonly() { return true; }
|
default boolean readonly() { return true; }
|
||||||
default void set(Context ctx, Object val) throws InterruptedException { }
|
default void set(Context ctx, Object val) { }
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ public class ArrayValue extends ObjectValue implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getField(Context ctx, Object key) throws InterruptedException {
|
protected Object getField(Context ctx, Object key) {
|
||||||
if (key instanceof Number) {
|
if (key instanceof Number) {
|
||||||
var i = ((Number)key).doubleValue();
|
var i = ((Number)key).doubleValue();
|
||||||
if (i >= 0 && i - Math.floor(i) == 0) {
|
if (i >= 0 && i - Math.floor(i) == 0) {
|
||||||
@ -133,7 +133,7 @@ public class ArrayValue extends ObjectValue implements Iterable<Object> {
|
|||||||
return super.getField(ctx, key);
|
return super.getField(ctx, key);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected boolean setField(Context ctx, Object key, Object val) throws InterruptedException {
|
protected boolean setField(Context ctx, Object key, Object val) {
|
||||||
if (key instanceof Number) {
|
if (key instanceof Number) {
|
||||||
var i = Values.number(key);
|
var i = Values.number(key);
|
||||||
if (i >= 0 && i - Math.floor(i) == 0) {
|
if (i >= 0 && i - Math.floor(i) == 0) {
|
||||||
@ -145,7 +145,7 @@ public class ArrayValue extends ObjectValue implements Iterable<Object> {
|
|||||||
return super.setField(ctx, key, val);
|
return super.setField(ctx, key, val);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasField(Context ctx, Object key) throws InterruptedException {
|
protected boolean hasField(Context ctx, Object key) {
|
||||||
if (key instanceof Number) {
|
if (key instanceof Number) {
|
||||||
var i = Values.number(key);
|
var i = Values.number(key);
|
||||||
if (i >= 0 && i - Math.floor(i) == 0) {
|
if (i >= 0 && i - Math.floor(i) == 0) {
|
||||||
@ -156,7 +156,7 @@ public class ArrayValue extends ObjectValue implements Iterable<Object> {
|
|||||||
return super.hasField(ctx, key);
|
return super.hasField(ctx, key);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void deleteField(Context ctx, Object key) throws InterruptedException {
|
protected void deleteField(Context ctx, Object key) {
|
||||||
if (key instanceof Number) {
|
if (key instanceof Number) {
|
||||||
var i = Values.number(key);
|
var i = Values.number(key);
|
||||||
if (i >= 0 && i - Math.floor(i) == 0) {
|
if (i >= 0 && i - Math.floor(i) == 0) {
|
||||||
|
@ -30,7 +30,7 @@ public class CodeFunction extends FunctionValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var frame = new CodeFrame(ctx, thisArg, args, this);
|
var frame = new CodeFrame(ctx, thisArg, args, this);
|
||||||
try {
|
try {
|
||||||
StackData.pushFrame(ctx, frame);
|
StackData.pushFrame(ctx, frame);
|
||||||
|
@ -14,26 +14,26 @@ public abstract class FunctionValue extends ObjectValue {
|
|||||||
return "function(...) { ...}";
|
return "function(...) { ...}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException;
|
public abstract Object call(Context ctx, Object thisArg, Object ...args);
|
||||||
public Object call(Context ctx) throws InterruptedException {
|
public Object call(Context ctx) {
|
||||||
return call(ctx, null);
|
return call(ctx, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getField(Context ctx, Object key) throws InterruptedException {
|
protected Object getField(Context ctx, Object key) {
|
||||||
if (key.equals("name")) return name;
|
if (key.equals("name")) return name;
|
||||||
if (key.equals("length")) return length;
|
if (key.equals("length")) return length;
|
||||||
return super.getField(ctx, key);
|
return super.getField(ctx, key);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected boolean setField(Context ctx, Object key, Object val) throws InterruptedException {
|
protected boolean setField(Context ctx, Object key, Object val) {
|
||||||
if (key.equals("name")) name = Values.toString(ctx, val);
|
if (key.equals("name")) name = Values.toString(ctx, val);
|
||||||
else if (key.equals("length")) length = (int)Values.toNumber(ctx, val);
|
else if (key.equals("length")) length = (int)Values.toNumber(ctx, val);
|
||||||
else return super.setField(ctx, key, val);
|
else return super.setField(ctx, key, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasField(Context ctx, Object key) throws InterruptedException {
|
protected boolean hasField(Context ctx, Object key) {
|
||||||
if (key.equals("name")) return true;
|
if (key.equals("name")) return true;
|
||||||
if (key.equals("length")) return true;
|
if (key.equals("length")) return true;
|
||||||
return super.hasField(ctx, key);
|
return super.hasField(ctx, key);
|
||||||
|
@ -4,13 +4,13 @@ import me.topchetoeu.jscript.engine.Context;
|
|||||||
|
|
||||||
public class NativeFunction extends FunctionValue {
|
public class NativeFunction extends FunctionValue {
|
||||||
public static interface NativeFunctionRunner {
|
public static interface NativeFunctionRunner {
|
||||||
Object run(Context ctx, Object thisArg, Object[] args) throws InterruptedException;
|
Object run(Context ctx, Object thisArg, Object[] args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final NativeFunctionRunner action;
|
public final NativeFunctionRunner action;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
return action.run(ctx, thisArg, args);
|
return action.run(ctx, thisArg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ public class NativeWrapper extends ObjectValue {
|
|||||||
public final Object wrapped;
|
public final Object wrapped;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectValue getPrototype(Context ctx) throws InterruptedException {
|
public ObjectValue getPrototype(Context ctx) {
|
||||||
if (prototype == NATIVE_PROTO) return ctx.environment().wrappers.getProto(wrapped.getClass());
|
if (prototype == NATIVE_PROTO) return ctx.environment().wrappers.getProto(wrapped.getClass());
|
||||||
else return super.getPrototype(ctx);
|
else return super.getPrototype(ctx);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ public class ObjectValue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectValue getPrototype(Context ctx) throws InterruptedException {
|
public ObjectValue getPrototype(Context ctx) {
|
||||||
try {
|
try {
|
||||||
if (prototype == OBJ_PROTO) return ctx.environment().proto("object");
|
if (prototype == OBJ_PROTO) return ctx.environment().proto("object");
|
||||||
if (prototype == ARR_PROTO) return ctx.environment().proto("array");
|
if (prototype == ARR_PROTO) return ctx.environment().proto("array");
|
||||||
@ -203,19 +203,19 @@ public class ObjectValue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Property getProperty(Context ctx, Object key) throws InterruptedException {
|
protected Property getProperty(Context ctx, Object key) {
|
||||||
if (properties.containsKey(key)) return properties.get(key);
|
if (properties.containsKey(key)) return properties.get(key);
|
||||||
var proto = getPrototype(ctx);
|
var proto = getPrototype(ctx);
|
||||||
if (proto != null) return proto.getProperty(ctx, key);
|
if (proto != null) return proto.getProperty(ctx, key);
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
protected Object getField(Context ctx, Object key) throws InterruptedException {
|
protected Object getField(Context ctx, Object key) {
|
||||||
if (values.containsKey(key)) return values.get(key);
|
if (values.containsKey(key)) return values.get(key);
|
||||||
var proto = getPrototype(ctx);
|
var proto = getPrototype(ctx);
|
||||||
if (proto != null) return proto.getField(ctx, key);
|
if (proto != null) return proto.getField(ctx, key);
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
protected boolean setField(Context ctx, Object key, Object val) throws InterruptedException {
|
protected boolean setField(Context ctx, Object key, Object val) {
|
||||||
if (val instanceof FunctionValue && ((FunctionValue)val).name.equals("")) {
|
if (val instanceof FunctionValue && ((FunctionValue)val).name.equals("")) {
|
||||||
((FunctionValue)val).name = Values.toString(ctx, key);
|
((FunctionValue)val).name = Values.toString(ctx, key);
|
||||||
}
|
}
|
||||||
@ -223,14 +223,14 @@ public class ObjectValue {
|
|||||||
values.put(key, val);
|
values.put(key, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
protected void deleteField(Context ctx, Object key) throws InterruptedException {
|
protected void deleteField(Context ctx, Object key) {
|
||||||
values.remove(key);
|
values.remove(key);
|
||||||
}
|
}
|
||||||
protected boolean hasField(Context ctx, Object key) throws InterruptedException {
|
protected boolean hasField(Context ctx, Object key) {
|
||||||
return values.containsKey(key);
|
return values.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Object getMember(Context ctx, Object key, Object thisArg) throws InterruptedException {
|
public final Object getMember(Context ctx, Object key, Object thisArg) {
|
||||||
key = Values.normalize(ctx, key);
|
key = Values.normalize(ctx, key);
|
||||||
|
|
||||||
if ("__proto__".equals(key)) {
|
if ("__proto__".equals(key)) {
|
||||||
@ -246,11 +246,11 @@ public class ObjectValue {
|
|||||||
}
|
}
|
||||||
else return getField(ctx, key);
|
else return getField(ctx, key);
|
||||||
}
|
}
|
||||||
public final Object getMember(Context ctx, Object key) throws InterruptedException {
|
public final Object getMember(Context ctx, Object key) {
|
||||||
return getMember(ctx, key, this);
|
return getMember(ctx, key, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean setMember(Context ctx, Object key, Object val, Object thisArg, boolean onlyProps) throws InterruptedException {
|
public final boolean setMember(Context ctx, Object key, Object val, Object thisArg, boolean onlyProps) {
|
||||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||||
|
|
||||||
var prop = getProperty(ctx, key);
|
var prop = getProperty(ctx, key);
|
||||||
@ -269,11 +269,11 @@ public class ObjectValue {
|
|||||||
else if (nonWritableSet.contains(key)) return false;
|
else if (nonWritableSet.contains(key)) return false;
|
||||||
else return setField(ctx, key, val);
|
else return setField(ctx, key, val);
|
||||||
}
|
}
|
||||||
public final boolean setMember(Context ctx, Object key, Object val, boolean onlyProps) throws InterruptedException {
|
public final boolean setMember(Context ctx, Object key, Object val, boolean onlyProps) {
|
||||||
return setMember(ctx, Values.normalize(ctx, key), Values.normalize(ctx, val), this, onlyProps);
|
return setMember(ctx, Values.normalize(ctx, key), Values.normalize(ctx, val), this, onlyProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasMember(Context ctx, Object key, boolean own) throws InterruptedException {
|
public final boolean hasMember(Context ctx, Object key, boolean own) {
|
||||||
key = Values.normalize(ctx, key);
|
key = Values.normalize(ctx, key);
|
||||||
|
|
||||||
if (key != null && key.equals("__proto__")) return true;
|
if (key != null && key.equals("__proto__")) return true;
|
||||||
@ -283,7 +283,7 @@ public class ObjectValue {
|
|||||||
var proto = getPrototype(ctx);
|
var proto = getPrototype(ctx);
|
||||||
return proto != null && proto.hasMember(ctx, key, own);
|
return proto != null && proto.hasMember(ctx, key, own);
|
||||||
}
|
}
|
||||||
public final boolean deleteMember(Context ctx, Object key) throws InterruptedException {
|
public final boolean deleteMember(Context ctx, Object key) {
|
||||||
key = Values.normalize(ctx, key);
|
key = Values.normalize(ctx, key);
|
||||||
|
|
||||||
if (!memberConfigurable(key)) return false;
|
if (!memberConfigurable(key)) return false;
|
||||||
@ -294,7 +294,7 @@ public class ObjectValue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ObjectValue getMemberDescriptor(Context ctx, Object key) throws InterruptedException {
|
public final ObjectValue getMemberDescriptor(Context ctx, Object key) {
|
||||||
key = Values.normalize(ctx, key);
|
key = Values.normalize(ctx, key);
|
||||||
|
|
||||||
var prop = properties.get(key);
|
var prop = properties.get(key);
|
||||||
|
@ -15,6 +15,7 @@ import me.topchetoeu.jscript.engine.Operation;
|
|||||||
import me.topchetoeu.jscript.engine.frame.ConvertHint;
|
import me.topchetoeu.jscript.engine.frame.ConvertHint;
|
||||||
import me.topchetoeu.jscript.exceptions.ConvertException;
|
import me.topchetoeu.jscript.exceptions.ConvertException;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
|
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||||
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
||||||
|
|
||||||
public class Values {
|
public class Values {
|
||||||
@ -67,7 +68,7 @@ public class Values {
|
|||||||
return "object";
|
return "object";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object tryCallConvertFunc(Context ctx, Object obj, String name) throws InterruptedException {
|
private static Object tryCallConvertFunc(Context ctx, Object obj, String name) {
|
||||||
var func = getMember(ctx, obj, name);
|
var func = getMember(ctx, obj, name);
|
||||||
|
|
||||||
if (func != null) {
|
if (func != null) {
|
||||||
@ -88,7 +89,7 @@ public class Values {
|
|||||||
obj == NULL;
|
obj == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object toPrimitive(Context ctx, Object obj, ConvertHint hint) throws InterruptedException {
|
public static Object toPrimitive(Context ctx, Object obj, ConvertHint hint) {
|
||||||
obj = normalize(ctx, obj);
|
obj = normalize(ctx, obj);
|
||||||
if (isPrimitive(obj)) return obj;
|
if (isPrimitive(obj)) return obj;
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ public class Values {
|
|||||||
if (obj instanceof Boolean) return (Boolean)obj;
|
if (obj instanceof Boolean) return (Boolean)obj;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public static double toNumber(Context ctx, Object obj) throws InterruptedException {
|
public static double toNumber(Context ctx, Object obj) {
|
||||||
var val = toPrimitive(ctx, obj, ConvertHint.VALUEOF);
|
var val = toPrimitive(ctx, obj, ConvertHint.VALUEOF);
|
||||||
|
|
||||||
if (val instanceof Number) return number(val);
|
if (val instanceof Number) return number(val);
|
||||||
@ -126,7 +127,7 @@ public class Values {
|
|||||||
}
|
}
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
}
|
}
|
||||||
public static String toString(Context ctx, Object obj) throws InterruptedException {
|
public static String toString(Context ctx, Object obj) {
|
||||||
var val = toPrimitive(ctx, obj, ConvertHint.VALUEOF);
|
var val = toPrimitive(ctx, obj, ConvertHint.VALUEOF);
|
||||||
|
|
||||||
if (val == null) return "undefined";
|
if (val == null) return "undefined";
|
||||||
@ -146,47 +147,47 @@ public class Values {
|
|||||||
return "Unknown value";
|
return "Unknown value";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object add(Context ctx, Object a, Object b) throws InterruptedException {
|
public static Object add(Context ctx, Object a, Object b) {
|
||||||
if (a instanceof String || b instanceof String) return toString(ctx, a) + toString(ctx, b);
|
if (a instanceof String || b instanceof String) return toString(ctx, a) + toString(ctx, b);
|
||||||
else return toNumber(ctx, a) + toNumber(ctx, b);
|
else return toNumber(ctx, a) + toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static double subtract(Context ctx, Object a, Object b) throws InterruptedException {
|
public static double subtract(Context ctx, Object a, Object b) {
|
||||||
return toNumber(ctx, a) - toNumber(ctx, b);
|
return toNumber(ctx, a) - toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static double multiply(Context ctx, Object a, Object b) throws InterruptedException {
|
public static double multiply(Context ctx, Object a, Object b) {
|
||||||
return toNumber(ctx, a) * toNumber(ctx, b);
|
return toNumber(ctx, a) * toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static double divide(Context ctx, Object a, Object b) throws InterruptedException {
|
public static double divide(Context ctx, Object a, Object b) {
|
||||||
return toNumber(ctx, a) / toNumber(ctx, b);
|
return toNumber(ctx, a) / toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static double modulo(Context ctx, Object a, Object b) throws InterruptedException {
|
public static double modulo(Context ctx, Object a, Object b) {
|
||||||
return toNumber(ctx, a) % toNumber(ctx, b);
|
return toNumber(ctx, a) % toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double negative(Context ctx, Object obj) throws InterruptedException {
|
public static double negative(Context ctx, Object obj) {
|
||||||
return -toNumber(ctx, obj);
|
return -toNumber(ctx, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int and(Context ctx, Object a, Object b) throws InterruptedException {
|
public static int and(Context ctx, Object a, Object b) {
|
||||||
return (int)toNumber(ctx, a) & (int)toNumber(ctx, b);
|
return (int)toNumber(ctx, a) & (int)toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static int or(Context ctx, Object a, Object b) throws InterruptedException {
|
public static int or(Context ctx, Object a, Object b) {
|
||||||
return (int)toNumber(ctx, a) | (int)toNumber(ctx, b);
|
return (int)toNumber(ctx, a) | (int)toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static int xor(Context ctx, Object a, Object b) throws InterruptedException {
|
public static int xor(Context ctx, Object a, Object b) {
|
||||||
return (int)toNumber(ctx, a) ^ (int)toNumber(ctx, b);
|
return (int)toNumber(ctx, a) ^ (int)toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static int bitwiseNot(Context ctx, Object obj) throws InterruptedException {
|
public static int bitwiseNot(Context ctx, Object obj) {
|
||||||
return ~(int)toNumber(ctx, obj);
|
return ~(int)toNumber(ctx, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int shiftLeft(Context ctx, Object a, Object b) throws InterruptedException {
|
public static int shiftLeft(Context ctx, Object a, Object b) {
|
||||||
return (int)toNumber(ctx, a) << (int)toNumber(ctx, b);
|
return (int)toNumber(ctx, a) << (int)toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static int shiftRight(Context ctx, Object a, Object b) throws InterruptedException {
|
public static int shiftRight(Context ctx, Object a, Object b) {
|
||||||
return (int)toNumber(ctx, a) >> (int)toNumber(ctx, b);
|
return (int)toNumber(ctx, a) >> (int)toNumber(ctx, b);
|
||||||
}
|
}
|
||||||
public static long unsignedShiftRight(Context ctx, Object a, Object b) throws InterruptedException {
|
public static long unsignedShiftRight(Context ctx, Object a, Object b) {
|
||||||
long _a = (long)toNumber(ctx, a);
|
long _a = (long)toNumber(ctx, a);
|
||||||
long _b = (long)toNumber(ctx, b);
|
long _b = (long)toNumber(ctx, b);
|
||||||
|
|
||||||
@ -195,7 +196,7 @@ public class Values {
|
|||||||
return _a >>> _b;
|
return _a >>> _b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int compare(Context ctx, Object a, Object b) throws InterruptedException {
|
public static int compare(Context ctx, Object a, Object b) {
|
||||||
a = toPrimitive(ctx, a, ConvertHint.VALUEOF);
|
a = toPrimitive(ctx, a, ConvertHint.VALUEOF);
|
||||||
b = toPrimitive(ctx, b, ConvertHint.VALUEOF);
|
b = toPrimitive(ctx, b, ConvertHint.VALUEOF);
|
||||||
|
|
||||||
@ -207,7 +208,7 @@ public class Values {
|
|||||||
return !toBoolean(obj);
|
return !toBoolean(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isInstanceOf(Context ctx, Object obj, Object proto) throws InterruptedException {
|
public static boolean isInstanceOf(Context ctx, Object obj, Object proto) {
|
||||||
if (obj == null || obj == NULL || proto == null || proto == NULL) return false;
|
if (obj == null || obj == NULL || proto == null || proto == NULL) return false;
|
||||||
var val = getPrototype(ctx, obj);
|
var val = getPrototype(ctx, obj);
|
||||||
|
|
||||||
@ -219,7 +220,7 @@ public class Values {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object operation(Context ctx, Operation op, Object ...args) throws InterruptedException {
|
public static Object operation(Context ctx, Operation op, Object ...args) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case ADD: return add(ctx, args[0], args[1]);
|
case ADD: return add(ctx, args[0], args[1]);
|
||||||
case SUBTRACT: return subtract(ctx, args[0], args[1]);
|
case SUBTRACT: return subtract(ctx, args[0], args[1]);
|
||||||
@ -260,7 +261,7 @@ public class Values {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object getMember(Context ctx, Object obj, Object key) throws InterruptedException {
|
public static Object getMember(Context ctx, Object obj, Object key) {
|
||||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||||
if (obj == null) throw new IllegalArgumentException("Tried to access member of undefined.");
|
if (obj == null) throw new IllegalArgumentException("Tried to access member of undefined.");
|
||||||
if (obj == NULL) throw new IllegalArgumentException("Tried to access member of null.");
|
if (obj == NULL) throw new IllegalArgumentException("Tried to access member of null.");
|
||||||
@ -280,7 +281,7 @@ public class Values {
|
|||||||
else if (key != null && key.equals("__proto__")) return proto;
|
else if (key != null && key.equals("__proto__")) return proto;
|
||||||
else return proto.getMember(ctx, key, obj);
|
else return proto.getMember(ctx, key, obj);
|
||||||
}
|
}
|
||||||
public static boolean setMember(Context ctx, Object obj, Object key, Object val) throws InterruptedException {
|
public static boolean setMember(Context ctx, Object obj, Object key, Object val) {
|
||||||
obj = normalize(ctx, obj); key = normalize(ctx, key); val = normalize(ctx, val);
|
obj = normalize(ctx, obj); key = normalize(ctx, key); val = normalize(ctx, val);
|
||||||
if (obj == null) throw EngineException.ofType("Tried to access member of undefined.");
|
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 (obj == NULL) throw EngineException.ofType("Tried to access member of null.");
|
||||||
@ -290,7 +291,7 @@ public class Values {
|
|||||||
var proto = getPrototype(ctx, obj);
|
var proto = getPrototype(ctx, obj);
|
||||||
return proto.setMember(ctx, key, val, obj, true);
|
return proto.setMember(ctx, key, val, obj, true);
|
||||||
}
|
}
|
||||||
public static boolean hasMember(Context ctx, Object obj, Object key, boolean own) throws InterruptedException {
|
public static boolean hasMember(Context ctx, Object obj, Object key, boolean own) {
|
||||||
if (obj == null || obj == NULL) return false;
|
if (obj == null || obj == NULL) return false;
|
||||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||||
|
|
||||||
@ -308,14 +309,14 @@ public class Values {
|
|||||||
var proto = getPrototype(ctx, obj);
|
var proto = getPrototype(ctx, obj);
|
||||||
return proto != null && proto.hasMember(ctx, key, own);
|
return proto != null && proto.hasMember(ctx, key, own);
|
||||||
}
|
}
|
||||||
public static boolean deleteMember(Context ctx, Object obj, Object key) throws InterruptedException {
|
public static boolean deleteMember(Context ctx, Object obj, Object key) {
|
||||||
if (obj == null || obj == NULL) return false;
|
if (obj == null || obj == NULL) return false;
|
||||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||||
|
|
||||||
if (isObject(obj)) return object(obj).deleteMember(ctx, key);
|
if (isObject(obj)) return object(obj).deleteMember(ctx, key);
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
public static ObjectValue getPrototype(Context ctx, Object obj) throws InterruptedException {
|
public static ObjectValue getPrototype(Context ctx, Object obj) {
|
||||||
if (obj == null || obj == NULL) return null;
|
if (obj == null || obj == NULL) return null;
|
||||||
obj = normalize(ctx, obj);
|
obj = normalize(ctx, obj);
|
||||||
if (isObject(obj)) return object(obj).getPrototype(ctx);
|
if (isObject(obj)) return object(obj).getPrototype(ctx);
|
||||||
@ -328,11 +329,11 @@ public class Values {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public static boolean setPrototype(Context ctx, Object obj, Object proto) throws InterruptedException {
|
public static boolean setPrototype(Context ctx, Object obj, Object proto) {
|
||||||
obj = normalize(ctx, obj);
|
obj = normalize(ctx, obj);
|
||||||
return isObject(obj) && object(obj).setPrototype(ctx, proto);
|
return isObject(obj) && object(obj).setPrototype(ctx, proto);
|
||||||
}
|
}
|
||||||
public static List<Object> getMembers(Context ctx, Object obj, boolean own, boolean includeNonEnumerable) throws InterruptedException {
|
public static List<Object> getMembers(Context ctx, Object obj, boolean own, boolean includeNonEnumerable) {
|
||||||
List<Object> res = new ArrayList<>();
|
List<Object> res = new ArrayList<>();
|
||||||
|
|
||||||
if (isObject(obj)) res = object(obj).keys(includeNonEnumerable);
|
if (isObject(obj)) res = object(obj).keys(includeNonEnumerable);
|
||||||
@ -352,7 +353,7 @@ public class Values {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public static ObjectValue getMemberDescriptor(Context ctx, Object obj, Object key) throws InterruptedException {
|
public static ObjectValue getMemberDescriptor(Context ctx, Object obj, Object key) {
|
||||||
if (obj instanceof ObjectValue) return ((ObjectValue)obj).getMemberDescriptor(ctx, key);
|
if (obj instanceof ObjectValue) return ((ObjectValue)obj).getMemberDescriptor(ctx, key);
|
||||||
else if (obj instanceof String && key instanceof Number) {
|
else if (obj instanceof String && key instanceof Number) {
|
||||||
var i = ((Number)key).intValue();
|
var i = ((Number)key).intValue();
|
||||||
@ -370,11 +371,11 @@ public class Values {
|
|||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object call(Context ctx, Object func, Object thisArg, Object ...args) throws InterruptedException {
|
public static Object call(Context ctx, Object func, Object thisArg, Object ...args) {
|
||||||
if (!isFunction(func)) throw EngineException.ofType("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);
|
return function(func).call(ctx, thisArg, args);
|
||||||
}
|
}
|
||||||
public static Object callNew(Context ctx, Object func, Object ...args) throws InterruptedException {
|
public static Object callNew(Context ctx, Object func, Object ...args) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
var proto = Values.getMember(ctx, func, "prototype");
|
var proto = Values.getMember(ctx, func, "prototype");
|
||||||
res.setPrototype(ctx, proto);
|
res.setPrototype(ctx, proto);
|
||||||
@ -395,7 +396,7 @@ public class Values {
|
|||||||
|
|
||||||
return a == b || a.equals(b);
|
return a == b || a.equals(b);
|
||||||
}
|
}
|
||||||
public static boolean looseEqual(Context ctx, Object a, Object b) throws InterruptedException {
|
public static boolean looseEqual(Context ctx, Object a, Object b) {
|
||||||
a = normalize(ctx, a); b = normalize(ctx, b);
|
a = normalize(ctx, a); b = normalize(ctx, b);
|
||||||
|
|
||||||
// In loose equality, null is equivalent to undefined
|
// In loose equality, null is equivalent to undefined
|
||||||
@ -453,7 +454,7 @@ public class Values {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T convert(Context ctx, Object obj, Class<T> clazz) throws InterruptedException {
|
public static <T> T convert(Context ctx, Object obj, Class<T> clazz) {
|
||||||
if (clazz == Void.class) return null;
|
if (clazz == Void.class) return null;
|
||||||
|
|
||||||
if (obj instanceof NativeWrapper) {
|
if (obj instanceof NativeWrapper) {
|
||||||
@ -536,7 +537,7 @@ public class Values {
|
|||||||
public boolean consumed = true;
|
public boolean consumed = true;
|
||||||
private FunctionValue next = (FunctionValue)nextFunc;
|
private FunctionValue next = (FunctionValue)nextFunc;
|
||||||
|
|
||||||
private void loadNext() throws InterruptedException {
|
private void loadNext() {
|
||||||
if (next == null) value = null;
|
if (next == null) value = null;
|
||||||
else if (consumed) {
|
else if (consumed) {
|
||||||
var curr = object(next.call(ctx, iterator));
|
var curr = object(next.call(ctx, iterator));
|
||||||
@ -551,32 +552,20 @@ public class Values {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
try {
|
loadNext();
|
||||||
loadNext();
|
return next != null;
|
||||||
return next != null;
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Object next() {
|
public Object next() {
|
||||||
try {
|
loadNext();
|
||||||
loadNext();
|
var res = value;
|
||||||
var res = value;
|
value = null;
|
||||||
value = null;
|
consumed = true;
|
||||||
consumed = true;
|
return res;
|
||||||
return res;
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -586,7 +575,7 @@ public class Values {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectValue fromJavaIterator(Context ctx, Iterator<?> it) throws InterruptedException {
|
public static ObjectValue fromJavaIterator(Context ctx, Iterator<?> it) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -603,11 +592,11 @@ public class Values {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectValue fromJavaIterable(Context ctx, Iterable<?> it) throws InterruptedException {
|
public static ObjectValue fromJavaIterable(Context ctx, Iterable<?> it) {
|
||||||
return fromJavaIterator(ctx, it.iterator());
|
return fromJavaIterator(ctx, it.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printValue(Context ctx, Object val, HashSet<Object> passed, int tab) throws InterruptedException {
|
private static void printValue(Context ctx, Object val, HashSet<Object> passed, int tab) {
|
||||||
if (passed.contains(val)) {
|
if (passed.contains(val)) {
|
||||||
System.out.print("[circular]");
|
System.out.print("[circular]");
|
||||||
return;
|
return;
|
||||||
@ -679,10 +668,10 @@ public class Values {
|
|||||||
else if (val instanceof String) System.out.print("'" + val + "'");
|
else if (val instanceof String) System.out.print("'" + val + "'");
|
||||||
else System.out.print(Values.toString(ctx, val));
|
else System.out.print(Values.toString(ctx, val));
|
||||||
}
|
}
|
||||||
public static void printValue(Context ctx, Object val) throws InterruptedException {
|
public static void printValue(Context ctx, Object val) {
|
||||||
printValue(ctx, val, new HashSet<>(), 0);
|
printValue(ctx, val, new HashSet<>(), 0);
|
||||||
}
|
}
|
||||||
public static void printError(RuntimeException err, String prefix) throws InterruptedException {
|
public static void printError(RuntimeException err, String prefix) {
|
||||||
prefix = prefix == null ? "Uncaught" : "Uncaught " + prefix;
|
prefix = prefix == null ? "Uncaught" : "Uncaught " + prefix;
|
||||||
try {
|
try {
|
||||||
if (err instanceof EngineException) {
|
if (err instanceof EngineException) {
|
||||||
|
@ -19,7 +19,7 @@ public class DataNotifier<T> implements Awaitable<T> {
|
|||||||
isErr = false;
|
isErr = false;
|
||||||
notifier.next();
|
notifier.next();
|
||||||
}
|
}
|
||||||
public T await() throws InterruptedException {
|
public T await() {
|
||||||
notifier.await();
|
notifier.await();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.events;
|
package me.topchetoeu.jscript.events;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||||
|
|
||||||
public class Notifier {
|
public class Notifier {
|
||||||
private boolean ok = false;
|
private boolean ok = false;
|
||||||
|
|
||||||
@ -7,8 +9,11 @@ public class Notifier {
|
|||||||
ok = true;
|
ok = true;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
public synchronized void await() throws InterruptedException {
|
public synchronized void await() {
|
||||||
while (!ok) wait();
|
try {
|
||||||
ok = false;
|
while (!ok) wait();
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) { throw new InterruptException(e); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class EngineException extends RuntimeException {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(Context ctx) throws InterruptedException {
|
public String toString(Context ctx) {
|
||||||
var ss = new StringBuilder();
|
var ss = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
ss.append(Values.toString(ctx, value)).append('\n');
|
ss.append(Values.toString(ctx, value)).append('\n');
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package me.topchetoeu.jscript.exceptions;
|
||||||
|
|
||||||
|
public class InterruptException extends RuntimeException {
|
||||||
|
public InterruptException() { }
|
||||||
|
public InterruptException(InterruptedException e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
}
|
@ -9,10 +9,7 @@ import me.topchetoeu.jscript.engine.Context;
|
|||||||
|
|
||||||
public class Overload {
|
public class Overload {
|
||||||
public static interface OverloadRunner {
|
public static interface OverloadRunner {
|
||||||
Object run(Context ctx, Object thisArg, Object[] args) throws
|
Object run(Context ctx, Object thisArg, Object[] args) throws ReflectiveOperationException, IllegalArgumentException;
|
||||||
InterruptedException,
|
|
||||||
ReflectiveOperationException,
|
|
||||||
IllegalArgumentException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final OverloadRunner runner;
|
public final OverloadRunner runner;
|
||||||
|
@ -15,7 +15,7 @@ import me.topchetoeu.jscript.exceptions.EngineException;
|
|||||||
public class OverloadFunction extends FunctionValue {
|
public class OverloadFunction extends FunctionValue {
|
||||||
public final List<Overload> overloads = new ArrayList<>();
|
public final List<Overload> overloads = new ArrayList<>();
|
||||||
|
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
loop: for (var overload : overloads) {
|
loop: for (var overload : overloads) {
|
||||||
Object[] newArgs = new Object[overload.params.length];
|
Object[] newArgs = new Object[overload.params.length];
|
||||||
|
|
||||||
@ -97,9 +97,6 @@ public class OverloadFunction extends FunctionValue {
|
|||||||
catch (ReflectiveOperationException e) {
|
catch (ReflectiveOperationException e) {
|
||||||
throw EngineException.ofError(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("No overload found for native method.");
|
throw EngineException.ofType("No overload found for native method.");
|
||||||
|
@ -17,17 +17,17 @@ import me.topchetoeu.jscript.interop.NativeInit;
|
|||||||
import me.topchetoeu.jscript.interop.NativeSetter;
|
import me.topchetoeu.jscript.interop.NativeSetter;
|
||||||
|
|
||||||
public class ArrayLib {
|
public class ArrayLib {
|
||||||
@NativeGetter(thisArg = true) public static int length(Context ctx, ArrayValue thisArg) throws InterruptedException {
|
@NativeGetter(thisArg = true) public static int length(Context ctx, ArrayValue thisArg) {
|
||||||
return thisArg.size();
|
return thisArg.size();
|
||||||
}
|
}
|
||||||
@NativeSetter(thisArg = true) public static void length(Context ctx, ArrayValue thisArg, int len) throws InterruptedException {
|
@NativeSetter(thisArg = true) public static void length(Context ctx, ArrayValue thisArg, int len) {
|
||||||
thisArg.setSize(len);
|
thisArg.setSize(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ObjectValue values(Context ctx, ArrayValue thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static ObjectValue values(Context ctx, ArrayValue thisArg) {
|
||||||
return Values.fromJavaIterable(ctx, thisArg);
|
return Values.fromJavaIterable(ctx, thisArg);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ObjectValue keys(Context ctx, ArrayValue thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static ObjectValue keys(Context ctx, ArrayValue thisArg) {
|
||||||
return Values.fromJavaIterable(ctx, () -> new Iterator<Object>() {
|
return Values.fromJavaIterable(ctx, () -> new Iterator<Object>() {
|
||||||
private int i = 0;
|
private int i = 0;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ public class ArrayLib {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ObjectValue entries(Context ctx, ArrayValue thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static ObjectValue entries(Context ctx, ArrayValue thisArg) {
|
||||||
return Values.fromJavaIterable(ctx, () -> new Iterator<Object>() {
|
return Values.fromJavaIterable(ctx, () -> new Iterator<Object>() {
|
||||||
private int i = 0;
|
private int i = 0;
|
||||||
|
|
||||||
@ -59,15 +59,15 @@ public class ArrayLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native(value = "@@Symbol.iterator", thisArg = true)
|
@Native(value = "@@Symbol.iterator", thisArg = true)
|
||||||
public static ObjectValue iterator(Context ctx, ArrayValue thisArg) throws InterruptedException {
|
public static ObjectValue iterator(Context ctx, ArrayValue thisArg) {
|
||||||
return values(ctx, thisArg);
|
return values(ctx, thisArg);
|
||||||
}
|
}
|
||||||
@Native(value = "@@Symbol.asyncIterator", thisArg = true)
|
@Native(value = "@@Symbol.asyncIterator", thisArg = true)
|
||||||
public static ObjectValue asyncIterator(Context ctx, ArrayValue thisArg) throws InterruptedException {
|
public static ObjectValue asyncIterator(Context ctx, ArrayValue thisArg) {
|
||||||
return values(ctx, thisArg);
|
return values(ctx, thisArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue concat(Context ctx, ArrayValue thisArg, Object ...others) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue concat(Context ctx, ArrayValue thisArg, Object ...others) {
|
||||||
// TODO: Fully implement with non-array spreadable objects
|
// TODO: Fully implement with non-array spreadable objects
|
||||||
var size = 0;
|
var size = 0;
|
||||||
|
|
||||||
@ -92,24 +92,13 @@ public class ArrayLib {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static void sort(Context ctx, ArrayValue arr, FunctionValue cmp) throws InterruptedException {
|
@Native(thisArg = true) public static void sort(Context ctx, ArrayValue arr, FunctionValue cmp) {
|
||||||
try {
|
arr.sort((a, b) -> {
|
||||||
arr.sort((a, b) -> {
|
var res = Values.toNumber(ctx, cmp.call(ctx, null, a, b));
|
||||||
try {
|
if (res < 0) return -1;
|
||||||
var res = Values.toNumber(ctx, cmp.call(ctx, null, a, b));
|
if (res > 0) return 1;
|
||||||
if (res < 0) return -1;
|
return 0;
|
||||||
if (res > 0) return 1;
|
});
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (RuntimeException e) {
|
|
||||||
if (e.getCause() instanceof InterruptedException) throw (InterruptedException)e.getCause();
|
|
||||||
else throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int normalizeI(int len, int i, boolean clamp) {
|
private static int normalizeI(int len, int i, boolean clamp) {
|
||||||
@ -121,7 +110,7 @@ public class ArrayLib {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue fill(Context ctx, ArrayValue arr, Object val, int start, int end) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue fill(Context ctx, ArrayValue arr, Object val, int start, int end) {
|
||||||
start = normalizeI(arr.size(), start, true);
|
start = normalizeI(arr.size(), start, true);
|
||||||
end = normalizeI(arr.size(), end, true);
|
end = normalizeI(arr.size(), end, true);
|
||||||
|
|
||||||
@ -131,21 +120,21 @@ public class ArrayLib {
|
|||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ArrayValue fill(Context ctx, ArrayValue arr, Object val, int start) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue fill(Context ctx, ArrayValue arr, Object val, int start) {
|
||||||
return fill(ctx, arr, val, start, arr.size());
|
return fill(ctx, arr, val, start, arr.size());
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ArrayValue fill(Context ctx, ArrayValue arr, Object val) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue fill(Context ctx, ArrayValue arr, Object val) {
|
||||||
return fill(ctx, arr, val, 0, arr.size());
|
return fill(ctx, arr, val, 0, arr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static boolean every(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static boolean every(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) {
|
||||||
for (var i = 0; i < arr.size(); i++) {
|
for (var i = 0; i < arr.size(); i++) {
|
||||||
if (!Values.toBoolean(func.call(ctx, thisArg, arr.get(i), i, arr))) return false;
|
if (!Values.toBoolean(func.call(ctx, thisArg, arr.get(i), i, arr))) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static boolean some(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static boolean some(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) {
|
||||||
for (var i = 0; i < arr.size(); i++) {
|
for (var i = 0; i < arr.size(); i++) {
|
||||||
if (Values.toBoolean(func.call(ctx, thisArg, arr.get(i), i, arr))) return true;
|
if (Values.toBoolean(func.call(ctx, thisArg, arr.get(i), i, arr))) return true;
|
||||||
}
|
}
|
||||||
@ -153,7 +142,7 @@ public class ArrayLib {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue filter(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue filter(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) {
|
||||||
var res = new ArrayValue(arr.size());
|
var res = new ArrayValue(arr.size());
|
||||||
|
|
||||||
for (int i = 0, j = 0; i < arr.size(); i++) {
|
for (int i = 0, j = 0; i < arr.size(); i++) {
|
||||||
@ -161,20 +150,20 @@ public class ArrayLib {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ArrayValue map(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue map(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) {
|
||||||
var res = new ArrayValue(arr.size());
|
var res = new ArrayValue(arr.size());
|
||||||
for (int i = 0, j = 0; i < arr.size(); i++) {
|
for (int i = 0, j = 0; i < arr.size(); i++) {
|
||||||
if (arr.has(i)) res.set(ctx, j++, func.call(ctx, thisArg, arr.get(i), i, arr));
|
if (arr.has(i)) res.set(ctx, j++, func.call(ctx, thisArg, arr.get(i), i, arr));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static void forEach(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static void forEach(Context ctx, ArrayValue arr, FunctionValue func, Object thisArg) {
|
||||||
for (int i = 0; i < arr.size(); i++) {
|
for (int i = 0; i < arr.size(); i++) {
|
||||||
if (arr.has(i)) func.call(ctx, thisArg, arr.get(i), i, arr);
|
if (arr.has(i)) func.call(ctx, thisArg, arr.get(i), i, arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue flat(Context ctx, ArrayValue arr, int depth) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue flat(Context ctx, ArrayValue arr, int depth) {
|
||||||
var res = new ArrayValue(arr.size());
|
var res = new ArrayValue(arr.size());
|
||||||
var stack = new Stack<Object>();
|
var stack = new Stack<Object>();
|
||||||
var depths = new Stack<Integer>();
|
var depths = new Stack<Integer>();
|
||||||
@ -197,18 +186,18 @@ public class ArrayLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ArrayValue flatMap(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue flatMap(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) {
|
||||||
return flat(ctx, map(ctx, arr, cmp, thisArg), 1);
|
return flat(ctx, map(ctx, arr, cmp, thisArg), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static Object find(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static Object find(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) {
|
||||||
for (int i = 0; i < arr.size(); i++) {
|
for (int i = 0; i < arr.size(); i++) {
|
||||||
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return arr.get(i);
|
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return arr.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static Object findLast(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static Object findLast(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) {
|
||||||
for (var i = arr.size() - 1; i >= 0; i--) {
|
for (var i = arr.size() - 1; i >= 0; i--) {
|
||||||
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return arr.get(i);
|
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return arr.get(i);
|
||||||
}
|
}
|
||||||
@ -216,14 +205,14 @@ public class ArrayLib {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static int findIndex(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static int findIndex(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) {
|
||||||
for (int i = 0; i < arr.size(); i++) {
|
for (int i = 0; i < arr.size(); i++) {
|
||||||
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return i;
|
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static int findLastIndex(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static int findLastIndex(Context ctx, ArrayValue arr, FunctionValue cmp, Object thisArg) {
|
||||||
for (var i = arr.size() - 1; i >= 0; i--) {
|
for (var i = arr.size() - 1; i >= 0; i--) {
|
||||||
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return i;
|
if (arr.has(i) && Values.toBoolean(cmp.call(ctx, thisArg, arr.get(i), i, arr))) return i;
|
||||||
}
|
}
|
||||||
@ -231,7 +220,7 @@ public class ArrayLib {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static int indexOf(Context ctx, ArrayValue arr, Object val, int start) throws InterruptedException {
|
@Native(thisArg = true) public static int indexOf(Context ctx, ArrayValue arr, Object val, int start) {
|
||||||
start = normalizeI(arr.size(), start, true);
|
start = normalizeI(arr.size(), start, true);
|
||||||
|
|
||||||
for (int i = 0; i < arr.size() && i < start; i++) {
|
for (int i = 0; i < arr.size() && i < start; i++) {
|
||||||
@ -240,7 +229,7 @@ public class ArrayLib {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static int lastIndexOf(Context ctx, ArrayValue arr, Object val, int start) throws InterruptedException {
|
@Native(thisArg = true) public static int lastIndexOf(Context ctx, ArrayValue arr, Object val, int start) {
|
||||||
start = normalizeI(arr.size(), start, true);
|
start = normalizeI(arr.size(), start, true);
|
||||||
|
|
||||||
for (int i = arr.size(); i >= start; i--) {
|
for (int i = arr.size(); i >= start; i--) {
|
||||||
@ -250,29 +239,29 @@ public class ArrayLib {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static boolean includes(Context ctx, ArrayValue arr, Object el, int start) throws InterruptedException {
|
@Native(thisArg = true) public static boolean includes(Context ctx, ArrayValue arr, Object el, int start) {
|
||||||
return indexOf(ctx, arr, el, start) >= 0;
|
return indexOf(ctx, arr, el, start) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static Object pop(Context ctx, ArrayValue arr) throws InterruptedException {
|
@Native(thisArg = true) public static Object pop(Context ctx, ArrayValue arr) {
|
||||||
if (arr.size() == 0) return null;
|
if (arr.size() == 0) return null;
|
||||||
var val = arr.get(arr.size() - 1);
|
var val = arr.get(arr.size() - 1);
|
||||||
arr.shrink(1);
|
arr.shrink(1);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static int push(Context ctx, ArrayValue arr, Object ...values) throws InterruptedException {
|
@Native(thisArg = true) public static int push(Context ctx, ArrayValue arr, Object ...values) {
|
||||||
arr.copyFrom(ctx, values, 0, arr.size(), values.length);
|
arr.copyFrom(ctx, values, 0, arr.size(), values.length);
|
||||||
return arr.size();
|
return arr.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static Object shift(Context ctx, ArrayValue arr) throws InterruptedException {
|
@Native(thisArg = true) public static Object shift(Context ctx, ArrayValue arr) {
|
||||||
if (arr.size() == 0) return null;
|
if (arr.size() == 0) return null;
|
||||||
var val = arr.get(0);
|
var val = arr.get(0);
|
||||||
arr.move(1, 0, arr.size());
|
arr.move(1, 0, arr.size());
|
||||||
arr.shrink(1);
|
arr.shrink(1);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static int unshift(Context ctx, ArrayValue arr, Object ...values) throws InterruptedException {
|
@Native(thisArg = true) public static int unshift(Context ctx, ArrayValue arr, Object ...values) {
|
||||||
arr.move(0, values.length, arr.size());
|
arr.move(0, values.length, arr.size());
|
||||||
arr.copyFrom(ctx, values, 0, 0, values.length);
|
arr.copyFrom(ctx, values, 0, 0, values.length);
|
||||||
return arr.size();
|
return arr.size();
|
||||||
@ -290,7 +279,7 @@ public class ArrayLib {
|
|||||||
return slice(ctx, arr, start, arr.size());
|
return slice(ctx, arr, start, arr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue splice(Context ctx, ArrayValue arr, int start, int deleteCount, Object ...items) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue splice(Context ctx, ArrayValue arr, int start, int deleteCount, Object ...items) {
|
||||||
start = normalizeI(arr.size(), start, true);
|
start = normalizeI(arr.size(), start, true);
|
||||||
deleteCount = normalizeI(arr.size(), deleteCount, true);
|
deleteCount = normalizeI(arr.size(), deleteCount, true);
|
||||||
if (start + deleteCount >= arr.size()) deleteCount = arr.size() - start;
|
if (start + deleteCount >= arr.size()) deleteCount = arr.size() - start;
|
||||||
@ -304,14 +293,14 @@ public class ArrayLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static ArrayValue splice(Context ctx, ArrayValue arr, int start) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue splice(Context ctx, ArrayValue arr, int start) {
|
||||||
return splice(ctx, arr, start, arr.size() - start);
|
return splice(ctx, arr, start, arr.size() - start);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, ArrayValue arr) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, ArrayValue arr) {
|
||||||
return join(ctx, arr, ",");
|
return join(ctx, arr, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String join(Context ctx, ArrayValue arr, String sep) throws InterruptedException {
|
@Native(thisArg = true) public static String join(Context ctx, ArrayValue arr, String sep) {
|
||||||
var res = new StringBuilder();
|
var res = new StringBuilder();
|
||||||
var comma = true;
|
var comma = true;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public class AsyncFunctionLib extends FunctionValue {
|
|||||||
|
|
||||||
private boolean awaiting = false;
|
private boolean awaiting = false;
|
||||||
|
|
||||||
private void next(Context ctx, Object inducedValue, Object inducedError) throws InterruptedException {
|
private void next(Context ctx, Object inducedValue, Object inducedError) {
|
||||||
Object res = null;
|
Object res = null;
|
||||||
StackData.pushFrame(ctx, frame);
|
StackData.pushFrame(ctx, frame);
|
||||||
ctx.pushEnv(frame.function.environment);
|
ctx.pushEnv(frame.function.environment);
|
||||||
@ -46,11 +46,11 @@ public class AsyncFunctionLib extends FunctionValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object fulfill(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object fulfill(Context ctx, Object thisArg, Object ...args) {
|
||||||
next(ctx, args.length > 0 ? args[0] : null, Runners.NO_RETURN);
|
next(ctx, args.length > 0 ? args[0] : null, Runners.NO_RETURN);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public Object reject(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object reject(Context ctx, Object thisArg, Object ...args) {
|
||||||
next(ctx, Runners.NO_RETURN, args.length > 0 ? args[0] : null);
|
next(ctx, Runners.NO_RETURN, args.length > 0 ? args[0] : null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ public class AsyncFunctionLib extends FunctionValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var handler = new AsyncHelper();
|
var handler = new AsyncHelper();
|
||||||
var func = factory.call(ctx, thisArg, new NativeFunction("await", handler::await));
|
var func = factory.call(ctx, thisArg, new NativeFunction("await", handler::await));
|
||||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("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.");
|
||||||
|
@ -23,7 +23,7 @@ public class AsyncGeneratorLib extends FunctionValue {
|
|||||||
private PromiseLib currPromise;
|
private PromiseLib currPromise;
|
||||||
public CodeFrame frame;
|
public CodeFrame frame;
|
||||||
|
|
||||||
private void next(Context ctx, Object inducedValue, Object inducedReturn, Object inducedError) throws InterruptedException {
|
private void next(Context ctx, Object inducedValue, Object inducedReturn, Object inducedError) {
|
||||||
if (done) {
|
if (done) {
|
||||||
if (inducedError != Runners.NO_RETURN)
|
if (inducedError != Runners.NO_RETURN)
|
||||||
throw new EngineException(inducedError);
|
throw new EngineException(inducedError);
|
||||||
@ -76,30 +76,30 @@ public class AsyncGeneratorLib extends FunctionValue {
|
|||||||
return "Generator [running]";
|
return "Generator [running]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object fulfill(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object fulfill(Context ctx, Object thisArg, Object ...args) {
|
||||||
next(ctx, args.length > 0 ? args[0] : null, Runners.NO_RETURN, Runners.NO_RETURN);
|
next(ctx, args.length > 0 ? args[0] : null, Runners.NO_RETURN, Runners.NO_RETURN);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public Object reject(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object reject(Context ctx, Object thisArg, Object ...args) {
|
||||||
next(ctx, Runners.NO_RETURN, args.length > 0 ? args[0] : null, Runners.NO_RETURN);
|
next(ctx, Runners.NO_RETURN, args.length > 0 ? args[0] : null, Runners.NO_RETURN);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public PromiseLib next(Context ctx, Object ...args) throws InterruptedException {
|
public PromiseLib next(Context ctx, Object ...args) {
|
||||||
this.currPromise = new PromiseLib();
|
this.currPromise = new PromiseLib();
|
||||||
if (args.length == 0) next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, Runners.NO_RETURN);
|
if (args.length == 0) next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, Runners.NO_RETURN);
|
||||||
else next(ctx, args[0], Runners.NO_RETURN, Runners.NO_RETURN);
|
else next(ctx, args[0], Runners.NO_RETURN, Runners.NO_RETURN);
|
||||||
return this.currPromise;
|
return this.currPromise;
|
||||||
}
|
}
|
||||||
@Native("throw")
|
@Native("throw")
|
||||||
public PromiseLib _throw(Context ctx, Object error) throws InterruptedException {
|
public PromiseLib _throw(Context ctx, Object error) {
|
||||||
this.currPromise = new PromiseLib();
|
this.currPromise = new PromiseLib();
|
||||||
next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, error);
|
next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, error);
|
||||||
return this.currPromise;
|
return this.currPromise;
|
||||||
}
|
}
|
||||||
@Native("return")
|
@Native("return")
|
||||||
public PromiseLib _return(Context ctx, Object value) throws InterruptedException {
|
public PromiseLib _return(Context ctx, Object value) {
|
||||||
this.currPromise = new PromiseLib();
|
this.currPromise = new PromiseLib();
|
||||||
next(ctx, Runners.NO_RETURN, value, Runners.NO_RETURN);
|
next(ctx, Runners.NO_RETURN, value, Runners.NO_RETURN);
|
||||||
return this.currPromise;
|
return this.currPromise;
|
||||||
@ -117,7 +117,7 @@ public class AsyncGeneratorLib extends FunctionValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var handler = new AsyncGenerator();
|
var handler = new AsyncGenerator();
|
||||||
var func = factory.call(ctx, thisArg,
|
var func = factory.call(ctx, thisArg,
|
||||||
new NativeFunction("await", handler::await),
|
new NativeFunction("await", handler::await),
|
||||||
|
@ -33,7 +33,7 @@ public class DateLib {
|
|||||||
return normal.get(Calendar.YEAR) - 1900;
|
return normal.get(Calendar.YEAR) - 1900;
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setYear(Context ctx, double real) throws InterruptedException {
|
public double setYear(Context ctx, double real) {
|
||||||
if (real >= 0 && real <= 99) real = real + 1900;
|
if (real >= 0 && real <= 99) real = real + 1900;
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.YEAR, (int)real);
|
else normal.set(Calendar.YEAR, (int)real);
|
||||||
@ -124,56 +124,56 @@ public class DateLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public double setFullYear(Context ctx, double real) throws InterruptedException {
|
public double setFullYear(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.YEAR, (int)real);
|
else normal.set(Calendar.YEAR, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setMonth(Context ctx, double real) throws InterruptedException {
|
public double setMonth(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.MONTH, (int)real);
|
else normal.set(Calendar.MONTH, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setDate(Context ctx, double real) throws InterruptedException {
|
public double setDate(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.DAY_OF_MONTH, (int)real);
|
else normal.set(Calendar.DAY_OF_MONTH, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setDay(Context ctx, double real) throws InterruptedException {
|
public double setDay(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.DAY_OF_WEEK, (int)real);
|
else normal.set(Calendar.DAY_OF_WEEK, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setHours(Context ctx, double real) throws InterruptedException {
|
public double setHours(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.HOUR_OF_DAY, (int)real);
|
else normal.set(Calendar.HOUR_OF_DAY, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setMinutes(Context ctx, double real) throws InterruptedException {
|
public double setMinutes(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.MINUTE, (int)real);
|
else normal.set(Calendar.MINUTE, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setSeconds(Context ctx, double real) throws InterruptedException {
|
public double setSeconds(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.SECOND, (int)real);
|
else normal.set(Calendar.SECOND, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setMilliseconds(Context ctx, double real) throws InterruptedException {
|
public double setMilliseconds(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else normal.set(Calendar.MILLISECOND, (int)real);
|
else normal.set(Calendar.MILLISECOND, (int)real);
|
||||||
updateUTC();
|
updateUTC();
|
||||||
@ -181,56 +181,56 @@ public class DateLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public double setUTCFullYear(Context ctx, double real) throws InterruptedException {
|
public double setUTCFullYear(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.YEAR, (int)real);
|
else utc.set(Calendar.YEAR, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCMonth(Context ctx, double real) throws InterruptedException {
|
public double setUTCMonth(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.MONTH, (int)real);
|
else utc.set(Calendar.MONTH, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCDate(Context ctx, double real) throws InterruptedException {
|
public double setUTCDate(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.DAY_OF_MONTH, (int)real);
|
else utc.set(Calendar.DAY_OF_MONTH, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCDay(Context ctx, double real) throws InterruptedException {
|
public double setUTCDay(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.DAY_OF_WEEK, (int)real);
|
else utc.set(Calendar.DAY_OF_WEEK, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCHours(Context ctx, double real) throws InterruptedException {
|
public double setUTCHours(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.HOUR_OF_DAY, (int)real);
|
else utc.set(Calendar.HOUR_OF_DAY, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCMinutes(Context ctx, double real) throws InterruptedException {
|
public double setUTCMinutes(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.MINUTE, (int)real);
|
else utc.set(Calendar.MINUTE, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCSeconds(Context ctx, double real) throws InterruptedException {
|
public double setUTCSeconds(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.SECOND, (int)real);
|
else utc.set(Calendar.SECOND, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
return getTime();
|
return getTime();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public double setUTCMilliseconds(Context ctx, double real) throws InterruptedException {
|
public double setUTCMilliseconds(Context ctx, double real) {
|
||||||
if (Double.isNaN(real)) invalidate();
|
if (Double.isNaN(real)) invalidate();
|
||||||
else utc.set(Calendar.MILLISECOND, (int)real);
|
else utc.set(Calendar.MILLISECOND, (int)real);
|
||||||
updateNormal();
|
updateNormal();
|
||||||
|
@ -12,7 +12,7 @@ import me.topchetoeu.jscript.interop.NativeConstructor;
|
|||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
|
|
||||||
public class ErrorLib {
|
public class ErrorLib {
|
||||||
private static String toString(Context ctx, Object cause, Object name, Object message, ArrayValue stack) throws InterruptedException {
|
private static String toString(Context ctx, Object cause, Object name, Object message, ArrayValue stack) {
|
||||||
if (name == null) name = "";
|
if (name == null) name = "";
|
||||||
else name = Values.toString(ctx, name).trim();
|
else name = Values.toString(ctx, name).trim();
|
||||||
if (message == null) message = "";
|
if (message == null) message = "";
|
||||||
@ -35,7 +35,7 @@ public class ErrorLib {
|
|||||||
return res.toString();
|
return res.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) {
|
||||||
if (thisArg instanceof ObjectValue) {
|
if (thisArg instanceof ObjectValue) {
|
||||||
var stack = Values.getMember(ctx, thisArg, "stack");
|
var stack = Values.getMember(ctx, thisArg, "stack");
|
||||||
if (!(stack instanceof ArrayValue)) stack = null;
|
if (!(stack instanceof ArrayValue)) stack = null;
|
||||||
@ -49,7 +49,7 @@ public class ErrorLib {
|
|||||||
else return "[Invalid error]";
|
else return "[Invalid error]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) {
|
||||||
var target = new ObjectValue();
|
var target = new ObjectValue();
|
||||||
if (thisArg instanceof ObjectValue) target = (ObjectValue)thisArg;
|
if (thisArg instanceof ObjectValue) target = (ObjectValue)thisArg;
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
|
|
||||||
public class FunctionLib {
|
public class FunctionLib {
|
||||||
@Native(thisArg = true) public static Object apply(Context ctx, FunctionValue func, Object thisArg, ArrayValue args) throws InterruptedException {
|
@Native(thisArg = true) public static Object apply(Context ctx, FunctionValue func, Object thisArg, ArrayValue args) {
|
||||||
return func.call(ctx, thisArg, args.toArray());
|
return func.call(ctx, thisArg, args.toArray());
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static Object call(Context ctx, FunctionValue func, Object thisArg, Object... args) throws InterruptedException {
|
@Native(thisArg = true) public static Object call(Context ctx, FunctionValue func, Object thisArg, Object... args) {
|
||||||
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.");
|
||||||
|
|
||||||
return func.call(ctx, thisArg, args);
|
return func.call(ctx, thisArg, args);
|
||||||
|
@ -21,7 +21,7 @@ public class GeneratorLib extends FunctionValue {
|
|||||||
|
|
||||||
@Native("@@Symbol.typeName") public final String name = "Generator";
|
@Native("@@Symbol.typeName") public final String name = "Generator";
|
||||||
|
|
||||||
private ObjectValue next(Context ctx, Object inducedValue, Object inducedReturn, Object inducedError) throws InterruptedException {
|
private ObjectValue next(Context ctx, Object inducedValue, Object inducedReturn, Object inducedError) {
|
||||||
if (done) {
|
if (done) {
|
||||||
if (inducedError != Runners.NO_RETURN) throw new EngineException(inducedError);
|
if (inducedError != Runners.NO_RETURN) throw new EngineException(inducedError);
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
@ -60,16 +60,16 @@ public class GeneratorLib extends FunctionValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public ObjectValue next(Context ctx, Object ...args) throws InterruptedException {
|
public ObjectValue next(Context ctx, Object ...args) {
|
||||||
if (args.length == 0) return next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, Runners.NO_RETURN);
|
if (args.length == 0) return next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, Runners.NO_RETURN);
|
||||||
else return next(ctx, args[0], Runners.NO_RETURN, Runners.NO_RETURN);
|
else return next(ctx, args[0], Runners.NO_RETURN, Runners.NO_RETURN);
|
||||||
}
|
}
|
||||||
@Native("throw")
|
@Native("throw")
|
||||||
public ObjectValue _throw(Context ctx, Object error) throws InterruptedException {
|
public ObjectValue _throw(Context ctx, Object error) {
|
||||||
return next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, error);
|
return next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, error);
|
||||||
}
|
}
|
||||||
@Native("return")
|
@Native("return")
|
||||||
public ObjectValue _return(Context ctx, Object value) throws InterruptedException {
|
public ObjectValue _return(Context ctx, Object value) {
|
||||||
return next(ctx, Runners.NO_RETURN, value, Runners.NO_RETURN);
|
return next(ctx, Runners.NO_RETURN, value, Runners.NO_RETURN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ public class GeneratorLib extends FunctionValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var handler = new Generator();
|
var handler = new Generator();
|
||||||
var func = factory.call(ctx, thisArg, new NativeFunction("yield", handler::yield));
|
var func = factory.call(ctx, thisArg, new NativeFunction("yield", handler::yield));
|
||||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("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.");
|
||||||
|
@ -14,7 +14,7 @@ public class Internals {
|
|||||||
private static final DataKey<HashMap<Integer, Thread>> THREADS = new DataKey<>();
|
private static final DataKey<HashMap<Integer, Thread>> THREADS = new DataKey<>();
|
||||||
private static final DataKey<Integer> I = new DataKey<>();
|
private static final DataKey<Integer> I = new DataKey<>();
|
||||||
|
|
||||||
@Native public static void log(Context ctx, Object ...args) throws InterruptedException {
|
@Native public static void log(Context ctx, Object ...args) {
|
||||||
for (var arg : args) {
|
for (var arg : args) {
|
||||||
Values.printValue(ctx, arg);
|
Values.printValue(ctx, arg);
|
||||||
}
|
}
|
||||||
@ -72,10 +72,10 @@ public class Internals {
|
|||||||
clearTimeout(ctx, i);
|
clearTimeout(ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static double parseInt(Context ctx, String val) throws InterruptedException {
|
@Native public static double parseInt(Context ctx, String val) {
|
||||||
return NumberLib.parseInt(ctx, val);
|
return NumberLib.parseInt(ctx, val);
|
||||||
}
|
}
|
||||||
@Native public static double parseFloat(Context ctx, String val) throws InterruptedException {
|
@Native public static double parseFloat(Context ctx, String val) {
|
||||||
return NumberLib.parseFloat(ctx, val);
|
return NumberLib.parseFloat(ctx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public class JSONLib {
|
|||||||
if (val.isNull()) return Values.NULL;
|
if (val.isNull()) return Values.NULL;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
private static JSONElement toJSON(Context ctx, Object val, HashSet<Object> prev) throws InterruptedException {
|
private static JSONElement toJSON(Context ctx, Object val, HashSet<Object> prev) {
|
||||||
if (val instanceof Boolean) return JSONElement.bool((boolean)val);
|
if (val instanceof Boolean) return JSONElement.bool((boolean)val);
|
||||||
if (val instanceof Number) return JSONElement.number(((Number)val).doubleValue());
|
if (val instanceof Number) return JSONElement.number(((Number)val).doubleValue());
|
||||||
if (val instanceof String) return JSONElement.string((String)val);
|
if (val instanceof String) return JSONElement.string((String)val);
|
||||||
@ -70,7 +70,7 @@ public class JSONLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static Object parse(Context ctx, String val) throws InterruptedException {
|
public static Object parse(Context ctx, String val) {
|
||||||
try {
|
try {
|
||||||
return toJS(me.topchetoeu.jscript.json.JSON.parse("<value>", val));
|
return toJS(me.topchetoeu.jscript.json.JSON.parse("<value>", val));
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ public class JSONLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static String stringify(Context ctx, Object val) throws InterruptedException {
|
public static String stringify(Context ctx, Object val) {
|
||||||
return me.topchetoeu.jscript.json.JSON.stringify(toJSON(ctx, val, new HashSet<>()));
|
return me.topchetoeu.jscript.json.JSON.stringify(toJSON(ctx, val, new HashSet<>()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public class MapLib {
|
|||||||
private LinkedHashMap<Object, Object> map = new LinkedHashMap<>();
|
private LinkedHashMap<Object, Object> map = new LinkedHashMap<>();
|
||||||
|
|
||||||
@Native("@@Symbol.typeName") public final String name = "Map";
|
@Native("@@Symbol.typeName") public final String name = "Map";
|
||||||
@Native("@@Symbol.iterator") public ObjectValue iterator(Context ctx) throws InterruptedException {
|
@Native("@@Symbol.iterator") public ObjectValue iterator(Context ctx) {
|
||||||
return this.entries(ctx);
|
return this.entries(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,17 +31,17 @@ public class MapLib {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public ObjectValue entries(Context ctx) throws InterruptedException {
|
@Native public ObjectValue entries(Context ctx) {
|
||||||
var res = map.entrySet().stream().map(v -> {
|
var res = map.entrySet().stream().map(v -> {
|
||||||
return new ArrayValue(ctx, v.getKey(), v.getValue());
|
return new ArrayValue(ctx, v.getKey(), v.getValue());
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
return Values.fromJavaIterator(ctx, res.iterator());
|
return Values.fromJavaIterator(ctx, res.iterator());
|
||||||
}
|
}
|
||||||
@Native public ObjectValue keys(Context ctx) throws InterruptedException {
|
@Native public ObjectValue keys(Context ctx) {
|
||||||
var res = new ArrayList<>(map.keySet());
|
var res = new ArrayList<>(map.keySet());
|
||||||
return Values.fromJavaIterator(ctx, res.iterator());
|
return Values.fromJavaIterator(ctx, res.iterator());
|
||||||
}
|
}
|
||||||
@Native public ObjectValue values(Context ctx) throws InterruptedException {
|
@Native public ObjectValue values(Context ctx) {
|
||||||
var res = new ArrayList<>(map.values());
|
var res = new ArrayList<>(map.values());
|
||||||
return Values.fromJavaIterator(ctx, res.iterator());
|
return Values.fromJavaIterator(ctx, res.iterator());
|
||||||
}
|
}
|
||||||
@ -61,13 +61,13 @@ public class MapLib {
|
|||||||
return map.size();
|
return map.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeGetter public void forEach(Context ctx, FunctionValue func, Object thisArg) throws InterruptedException {
|
@NativeGetter public void forEach(Context ctx, FunctionValue func, Object thisArg) {
|
||||||
var keys = new ArrayList<>(map.keySet());
|
var keys = new ArrayList<>(map.keySet());
|
||||||
|
|
||||||
for (var el : keys) func.call(ctx, thisArg, el, map.get(el), this);
|
for (var el : keys) func.call(ctx, thisArg, el, map.get(el), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public MapLib(Context ctx, Object iterable) throws InterruptedException {
|
@Native public MapLib(Context ctx, Object iterable) {
|
||||||
for (var el : Values.toJavaIterable(ctx, iterable)) {
|
for (var el : Values.toJavaIterable(ctx, iterable)) {
|
||||||
try {
|
try {
|
||||||
set(Values.getMember(ctx, el, 0), Values.getMember(ctx, el, 1));
|
set(Values.getMember(ctx, el, 0), Values.getMember(ctx, el, 1));
|
||||||
|
@ -29,22 +29,22 @@ public class NumberLib {
|
|||||||
return val > MIN_SAFE_INTEGER && val < MAX_SAFE_INTEGER;
|
return val > MIN_SAFE_INTEGER && val < MAX_SAFE_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static double parseFloat(Context ctx, String val) throws InterruptedException {
|
@Native public static double parseFloat(Context ctx, String val) {
|
||||||
return Values.toNumber(ctx, val);
|
return Values.toNumber(ctx, val);
|
||||||
}
|
}
|
||||||
@Native public static double parseInt(Context ctx, String val) throws InterruptedException {
|
@Native public static double parseInt(Context ctx, String val) {
|
||||||
return (long)Values.toNumber(ctx, val);
|
return (long)Values.toNumber(ctx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object val) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object val) {
|
||||||
val = Values.toNumber(ctx, val);
|
val = Values.toNumber(ctx, val);
|
||||||
if (thisArg instanceof ObjectValue) return new NumberLib((double)val);
|
if (thisArg instanceof ObjectValue) return new NumberLib((double)val);
|
||||||
else return val;
|
else return val;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) {
|
||||||
return Values.toString(ctx, Values.toNumber(ctx, thisArg));
|
return Values.toString(ctx, Values.toNumber(ctx, thisArg));
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static double valueOf(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static double valueOf(Context ctx, Object thisArg) {
|
||||||
if (thisArg instanceof NumberLib) return ((NumberLib)thisArg).value;
|
if (thisArg instanceof NumberLib) return ((NumberLib)thisArg).value;
|
||||||
else return Values.toNumber(ctx, thisArg);
|
else return Values.toNumber(ctx, thisArg);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import me.topchetoeu.jscript.interop.NativeConstructor;
|
|||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
|
|
||||||
public class ObjectLib {
|
public class ObjectLib {
|
||||||
@Native public static ObjectValue assign(Context ctx, ObjectValue dst, Object... src) throws InterruptedException {
|
@Native public static ObjectValue assign(Context ctx, ObjectValue dst, Object... src) {
|
||||||
for (var obj : src) {
|
for (var obj : src) {
|
||||||
for (var key : Values.getMembers(ctx, obj, true, true)) {
|
for (var key : Values.getMembers(ctx, obj, true, true)) {
|
||||||
Values.setMember(ctx, dst, key, Values.getMember(ctx, obj, key));
|
Values.setMember(ctx, dst, key, Values.getMember(ctx, obj, key));
|
||||||
@ -22,13 +22,13 @@ public class ObjectLib {
|
|||||||
}
|
}
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@Native public static ObjectValue create(Context ctx, ObjectValue proto, ObjectValue props) throws InterruptedException {
|
@Native public static ObjectValue create(Context ctx, ObjectValue proto, ObjectValue props) {
|
||||||
var obj = new ObjectValue();
|
var obj = new ObjectValue();
|
||||||
obj.setPrototype(ctx, proto);
|
obj.setPrototype(ctx, proto);
|
||||||
return defineProperties(ctx, obj, props);
|
return defineProperties(ctx, obj, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static ObjectValue defineProperty(Context ctx, ObjectValue obj, Object key, ObjectValue attrib) throws InterruptedException {
|
@Native public static ObjectValue defineProperty(Context ctx, ObjectValue obj, Object key, ObjectValue attrib) {
|
||||||
var hasVal = attrib.hasMember(ctx, "value", false);
|
var hasVal = attrib.hasMember(ctx, "value", false);
|
||||||
var hasGet = attrib.hasMember(ctx, "get", false);
|
var hasGet = attrib.hasMember(ctx, "get", false);
|
||||||
var hasSet = attrib.hasMember(ctx, "set", false);
|
var hasSet = attrib.hasMember(ctx, "set", false);
|
||||||
@ -59,7 +59,7 @@ public class ObjectLib {
|
|||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@Native public static ObjectValue defineProperties(Context ctx, ObjectValue obj, ObjectValue attrib) throws InterruptedException {
|
@Native public static ObjectValue defineProperties(Context ctx, ObjectValue obj, ObjectValue attrib) {
|
||||||
for (var key : Values.getMembers(null, obj, false, false)) {
|
for (var key : Values.getMembers(null, obj, false, false)) {
|
||||||
obj.defineProperty(ctx, key, attrib.getMember(ctx, key));
|
obj.defineProperty(ctx, key, attrib.getMember(ctx, key));
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ public class ObjectLib {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static ArrayValue keys(Context ctx, Object obj, Object all) throws InterruptedException {
|
@Native public static ArrayValue keys(Context ctx, Object obj, Object all) {
|
||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
var _all = Values.toBoolean(all);
|
var _all = Values.toBoolean(all);
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ public class ObjectLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static ArrayValue entries(Context ctx, Object obj, Object all) throws InterruptedException {
|
@Native public static ArrayValue entries(Context ctx, Object obj, Object all) {
|
||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
var _all = Values.toBoolean(all);
|
var _all = Values.toBoolean(all);
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ public class ObjectLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static ArrayValue values(Context ctx, Object obj, Object all) throws InterruptedException {
|
@Native public static ArrayValue values(Context ctx, Object obj, Object all) {
|
||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
var _all = Values.toBoolean(all);
|
var _all = Values.toBoolean(all);
|
||||||
|
|
||||||
@ -98,10 +98,10 @@ public class ObjectLib {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static ObjectValue getOwnPropertyDescriptor(Context ctx, Object obj, Object key) throws InterruptedException {
|
@Native public static ObjectValue getOwnPropertyDescriptor(Context ctx, Object obj, Object key) {
|
||||||
return Values.getMemberDescriptor(ctx, obj, key);
|
return Values.getMemberDescriptor(ctx, obj, key);
|
||||||
}
|
}
|
||||||
@Native public static ObjectValue getOwnPropertyDescriptors(Context ctx, Object obj) throws InterruptedException {
|
@Native public static ObjectValue getOwnPropertyDescriptors(Context ctx, Object obj) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
for (var key : Values.getMembers(ctx, obj, true, true)) {
|
for (var key : Values.getMembers(ctx, obj, true, true)) {
|
||||||
res.defineProperty(ctx, key, getOwnPropertyDescriptor(ctx, obj, key));
|
res.defineProperty(ctx, key, getOwnPropertyDescriptor(ctx, obj, key));
|
||||||
@ -109,7 +109,7 @@ public class ObjectLib {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static ArrayValue getOwnPropertyNames(Context ctx, Object obj, Object all) throws InterruptedException {
|
@Native public static ArrayValue getOwnPropertyNames(Context ctx, Object obj, Object all) {
|
||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
var _all = Values.toBoolean(all);
|
var _all = Values.toBoolean(all);
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ public class ObjectLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static ArrayValue getOwnPropertySymbols(Context ctx, Object obj) throws InterruptedException {
|
@Native public static ArrayValue getOwnPropertySymbols(Context ctx, Object obj) {
|
||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
|
|
||||||
for (var key : Values.getMembers(ctx, obj, true, true)) {
|
for (var key : Values.getMembers(ctx, obj, true, true)) {
|
||||||
@ -128,19 +128,19 @@ public class ObjectLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static boolean hasOwn(Context ctx, Object obj, Object key) throws InterruptedException {
|
@Native public static boolean hasOwn(Context ctx, Object obj, Object key) {
|
||||||
return Values.hasMember(ctx, obj, key, true);
|
return Values.hasMember(ctx, obj, key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static ObjectValue getPrototypeOf(Context ctx, Object obj) throws InterruptedException {
|
@Native public static ObjectValue getPrototypeOf(Context ctx, Object obj) {
|
||||||
return Values.getPrototype(ctx, obj);
|
return Values.getPrototype(ctx, obj);
|
||||||
}
|
}
|
||||||
@Native public static Object setPrototypeOf(Context ctx, Object obj, Object proto) throws InterruptedException {
|
@Native public static Object setPrototypeOf(Context ctx, Object obj, Object proto) {
|
||||||
Values.setPrototype(ctx, obj, proto);
|
Values.setPrototype(ctx, obj, proto);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static ObjectValue fromEntries(Context ctx, Object iterable) throws InterruptedException {
|
@Native public static ObjectValue fromEntries(Context ctx, Object iterable) {
|
||||||
var res = new ObjectValue();
|
var res = new ObjectValue();
|
||||||
|
|
||||||
for (var el : Values.toJavaIterable(ctx, iterable)) {
|
for (var el : Values.toJavaIterable(ctx, iterable)) {
|
||||||
@ -152,23 +152,23 @@ public class ObjectLib {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static Object preventExtensions(Context ctx, Object obj) throws InterruptedException {
|
@Native public static Object preventExtensions(Context ctx, Object obj) {
|
||||||
if (obj instanceof ObjectValue) ((ObjectValue)obj).preventExtensions();
|
if (obj instanceof ObjectValue) ((ObjectValue)obj).preventExtensions();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@Native public static Object seal(Context ctx, Object obj) throws InterruptedException {
|
@Native public static Object seal(Context ctx, Object obj) {
|
||||||
if (obj instanceof ObjectValue) ((ObjectValue)obj).seal();
|
if (obj instanceof ObjectValue) ((ObjectValue)obj).seal();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@Native public static Object freeze(Context ctx, Object obj) throws InterruptedException {
|
@Native public static Object freeze(Context ctx, Object obj) {
|
||||||
if (obj instanceof ObjectValue) ((ObjectValue)obj).freeze();
|
if (obj instanceof ObjectValue) ((ObjectValue)obj).freeze();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static boolean isExtensible(Context ctx, Object obj) throws InterruptedException {
|
@Native public static boolean isExtensible(Context ctx, Object obj) {
|
||||||
return obj instanceof ObjectValue && ((ObjectValue)obj).extensible();
|
return obj instanceof ObjectValue && ((ObjectValue)obj).extensible();
|
||||||
}
|
}
|
||||||
@Native public static boolean isSealed(Context ctx, Object obj) throws InterruptedException {
|
@Native public static boolean isSealed(Context ctx, Object obj) {
|
||||||
if (obj instanceof ObjectValue && ((ObjectValue)obj).extensible()) {
|
if (obj instanceof ObjectValue && ((ObjectValue)obj).extensible()) {
|
||||||
var _obj = (ObjectValue)obj;
|
var _obj = (ObjectValue)obj;
|
||||||
for (var key : _obj.keys(true)) {
|
for (var key : _obj.keys(true)) {
|
||||||
@ -178,7 +178,7 @@ public class ObjectLib {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@Native public static boolean isFrozen(Context ctx, Object obj) throws InterruptedException {
|
@Native public static boolean isFrozen(Context ctx, Object obj) {
|
||||||
if (obj instanceof ObjectValue && ((ObjectValue)obj).extensible()) {
|
if (obj instanceof ObjectValue && ((ObjectValue)obj).extensible()) {
|
||||||
var _obj = (ObjectValue)obj;
|
var _obj = (ObjectValue)obj;
|
||||||
for (var key : _obj.keys(true)) {
|
for (var key : _obj.keys(true)) {
|
||||||
@ -193,18 +193,18 @@ public class ObjectLib {
|
|||||||
@Native(thisArg = true) public static Object valueOf(Context ctx, Object thisArg) {
|
@Native(thisArg = true) public static Object valueOf(Context ctx, Object thisArg) {
|
||||||
return thisArg;
|
return thisArg;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) {
|
||||||
var name = Values.getMember(ctx, thisArg, ctx.environment().symbol("Symbol.typeName"));
|
var name = Values.getMember(ctx, thisArg, ctx.environment().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(thisArg = true) public static boolean hasOwnProperty(Context ctx, Object thisArg, Object key) throws InterruptedException {
|
@Native(thisArg = true) public static boolean hasOwnProperty(Context ctx, Object thisArg, Object key) {
|
||||||
return ObjectLib.hasOwn(ctx, thisArg, Values.convert(ctx, key, String.class));
|
return ObjectLib.hasOwn(ctx, thisArg, Values.convert(ctx, key, String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object arg) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object arg) {
|
||||||
if (arg == null || arg == Values.NULL) return new ObjectValue();
|
if (arg == null || arg == Values.NULL) return new ObjectValue();
|
||||||
else if (arg instanceof Boolean) return BooleanLib.constructor(ctx, thisArg, arg);
|
else if (arg instanceof Boolean) return BooleanLib.constructor(ctx, thisArg, arg);
|
||||||
else if (arg instanceof Number) return NumberLib.constructor(ctx, thisArg, arg);
|
else if (arg instanceof Number) return NumberLib.constructor(ctx, thisArg, arg);
|
||||||
|
@ -13,6 +13,7 @@ import me.topchetoeu.jscript.engine.values.NativeWrapper;
|
|||||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.engine.values.Values;
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
|
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||||
import me.topchetoeu.jscript.interop.InitType;
|
import me.topchetoeu.jscript.interop.InitType;
|
||||||
import me.topchetoeu.jscript.interop.Native;
|
import me.topchetoeu.jscript.interop.Native;
|
||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
@ -31,19 +32,19 @@ public class PromiseLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native("resolve")
|
@Native("resolve")
|
||||||
public static PromiseLib ofResolved(Context ctx, Object val) throws InterruptedException {
|
public static PromiseLib ofResolved(Context ctx, Object val) {
|
||||||
var res = new PromiseLib();
|
var res = new PromiseLib();
|
||||||
res.fulfill(ctx, val);
|
res.fulfill(ctx, val);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native("reject")
|
@Native("reject")
|
||||||
public static PromiseLib ofRejected(Context ctx, Object val) throws InterruptedException {
|
public static PromiseLib ofRejected(Context ctx, Object val) {
|
||||||
var res = new PromiseLib();
|
var res = new PromiseLib();
|
||||||
res.reject(ctx, val);
|
res.reject(ctx, val);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static PromiseLib any(Context ctx, Object _promises) throws InterruptedException {
|
@Native public static PromiseLib any(Context ctx, Object _promises) {
|
||||||
if (!Values.isArray(_promises)) throw EngineException.ofType("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);
|
var promises = Values.array(_promises);
|
||||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||||
@ -68,7 +69,7 @@ public class PromiseLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static PromiseLib race(Context ctx, Object _promises) throws InterruptedException {
|
@Native public static PromiseLib race(Context ctx, Object _promises) {
|
||||||
if (!Values.isArray(_promises)) throw EngineException.ofType("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);
|
var promises = Values.array(_promises);
|
||||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||||
@ -84,7 +85,7 @@ public class PromiseLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static PromiseLib all(Context ctx, Object _promises) throws InterruptedException {
|
@Native public static PromiseLib all(Context ctx, Object _promises) {
|
||||||
if (!Values.isArray(_promises)) throw EngineException.ofType("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);
|
var promises = Values.array(_promises);
|
||||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||||
@ -111,7 +112,7 @@ public class PromiseLib {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native public static PromiseLib allSettled(Context ctx, Object _promises) throws InterruptedException {
|
@Native public static PromiseLib allSettled(Context ctx, Object _promises) {
|
||||||
if (!Values.isArray(_promises)) throw EngineException.ofType("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);
|
var promises = Values.array(_promises);
|
||||||
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
if (promises.size() == 0) return ofResolved(ctx, new ArrayValue());
|
||||||
@ -154,7 +155,7 @@ public class PromiseLib {
|
|||||||
* 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(thisArg=true) public static Object then(Context ctx, Object thisArg, Object _onFulfill, Object _onReject) throws InterruptedException {
|
@Native(thisArg=true) public static Object then(Context ctx, Object thisArg, Object _onFulfill, Object _onReject) {
|
||||||
var onFulfill = _onFulfill instanceof FunctionValue ? ((FunctionValue)_onFulfill) : null;
|
var onFulfill = _onFulfill instanceof FunctionValue ? ((FunctionValue)_onFulfill) : null;
|
||||||
var onReject = _onReject instanceof FunctionValue ? ((FunctionValue)_onReject) : null;
|
var onReject = _onReject instanceof FunctionValue ? ((FunctionValue)_onReject) : null;
|
||||||
|
|
||||||
@ -205,14 +206,14 @@ public class PromiseLib {
|
|||||||
* 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", thisArg=true) public static Object _catch(Context ctx, Object thisArg, Object _onReject) throws InterruptedException {
|
@Native(value="catch", thisArg=true) public static Object _catch(Context ctx, Object thisArg, Object _onReject) {
|
||||||
return then(ctx, thisArg, null, _onReject);
|
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", thisArg=true) public static Object _finally(Context ctx, Object thisArg, Object _handle) throws InterruptedException {
|
@Native(value="finally", thisArg=true) public static Object _finally(Context ctx, Object thisArg, Object _handle) {
|
||||||
return then(ctx, thisArg,
|
return then(ctx, thisArg,
|
||||||
new NativeFunction(null, (e, th, _args) -> {
|
new NativeFunction(null, (e, th, _args) -> {
|
||||||
if (_handle instanceof FunctionValue) ((FunctionValue)_handle).call(ctx);
|
if (_handle instanceof FunctionValue) ((FunctionValue)_handle).call(ctx);
|
||||||
@ -235,7 +236,7 @@ public class PromiseLib {
|
|||||||
private boolean handled = false;
|
private boolean handled = false;
|
||||||
private Object val;
|
private Object val;
|
||||||
|
|
||||||
private void resolve(Context ctx, Object val, int state) throws InterruptedException {
|
private void resolve(Context ctx, Object val, int state) {
|
||||||
if (this.state != STATE_PENDING) return;
|
if (this.state != STATE_PENDING) return;
|
||||||
|
|
||||||
if (val instanceof PromiseLib) ((PromiseLib)val).handle(ctx,
|
if (val instanceof PromiseLib) ((PromiseLib)val).handle(ctx,
|
||||||
@ -264,8 +265,8 @@ public class PromiseLib {
|
|||||||
if (handles.size() == 0) {
|
if (handles.size() == 0) {
|
||||||
ctx.engine.pushMsg(true, ctx, new NativeFunction((_ctx, _thisArg, _args) -> {
|
ctx.engine.pushMsg(true, ctx, new NativeFunction((_ctx, _thisArg, _args) -> {
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
try { Values.printError(new EngineException(val).setContext(ctx), "(in promise)"); }
|
Values.printError(new EngineException(val).setContext(ctx), "(in promise)");
|
||||||
catch (InterruptedException ex) { }
|
throw new InterruptException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -285,13 +286,13 @@ public class PromiseLib {
|
|||||||
/**
|
/**
|
||||||
* Thread safe - call from any thread
|
* Thread safe - call from any thread
|
||||||
*/
|
*/
|
||||||
public void fulfill(Context ctx, Object val) throws InterruptedException {
|
public void fulfill(Context ctx, Object val) {
|
||||||
resolve(ctx, val, STATE_FULFILLED);
|
resolve(ctx, val, STATE_FULFILLED);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Thread safe - call from any thread
|
* Thread safe - call from any thread
|
||||||
*/
|
*/
|
||||||
public void reject(Context ctx, Object val) throws InterruptedException {
|
public void reject(Context ctx, Object val) {
|
||||||
resolve(ctx, val, STATE_REJECTED);
|
resolve(ctx, val, STATE_REJECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +314,7 @@ public class PromiseLib {
|
|||||||
/**
|
/**
|
||||||
* NOT THREAD SAFE - must be called from the engine executor thread
|
* NOT THREAD SAFE - must be called from the engine executor thread
|
||||||
*/
|
*/
|
||||||
@Native public PromiseLib(Context ctx, FunctionValue func) throws InterruptedException {
|
@Native public PromiseLib(Context ctx, FunctionValue func) {
|
||||||
if (!(func instanceof FunctionValue)) throw EngineException.ofType("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 {
|
try {
|
||||||
func.call(
|
func.call(
|
||||||
|
@ -8,7 +8,7 @@ import me.topchetoeu.jscript.interop.NativeConstructor;
|
|||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
|
|
||||||
public class RangeErrorLib extends ErrorLib {
|
public class RangeErrorLib extends ErrorLib {
|
||||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) {
|
||||||
var target = ErrorLib.constructor(ctx, thisArg, message);
|
var target = ErrorLib.constructor(ctx, thisArg, message);
|
||||||
target.defineProperty(ctx, "name", "RangeError");
|
target.defineProperty(ctx, "name", "RangeError");
|
||||||
return target;
|
return target;
|
||||||
|
@ -17,7 +17,7 @@ public class RegExpLib {
|
|||||||
private static final Pattern NAMED_PATTERN = Pattern.compile("\\(\\?<([^=!].*?)>", Pattern.DOTALL);
|
private static final Pattern NAMED_PATTERN = Pattern.compile("\\(\\?<([^=!].*?)>", Pattern.DOTALL);
|
||||||
private static final Pattern ESCAPE_PATTERN = Pattern.compile("[/\\-\\\\^$*+?.()|\\[\\]{}]");
|
private static final Pattern ESCAPE_PATTERN = Pattern.compile("[/\\-\\\\^$*+?.()|\\[\\]{}]");
|
||||||
|
|
||||||
private static String cleanupPattern(Context ctx, Object val) throws InterruptedException {
|
private static String cleanupPattern(Context ctx, Object val) {
|
||||||
if (val == null) return "(?:)";
|
if (val == null) return "(?:)";
|
||||||
if (val instanceof RegExpLib) return ((RegExpLib)val).source;
|
if (val instanceof RegExpLib) return ((RegExpLib)val).source;
|
||||||
if (val instanceof NativeWrapper && ((NativeWrapper)val).wrapped instanceof RegExpLib) {
|
if (val instanceof NativeWrapper && ((NativeWrapper)val).wrapped instanceof RegExpLib) {
|
||||||
@ -27,7 +27,7 @@ public class RegExpLib {
|
|||||||
if (res.equals("")) return "(?:)";
|
if (res.equals("")) return "(?:)";
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
private static String cleanupFlags(Context ctx, Object val) throws InterruptedException {
|
private static String cleanupFlags(Context ctx, Object val) {
|
||||||
if (val == null) return "";
|
if (val == null) return "";
|
||||||
return Values.toString(ctx, val);
|
return Values.toString(ctx, val);
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ public class RegExpLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static RegExpLib escape(Context ctx, Object raw, Object flags) throws InterruptedException {
|
public static RegExpLib escape(Context ctx, Object raw, Object flags) {
|
||||||
return escape(Values.toString(ctx, raw), cleanupFlags(ctx, flags));
|
return escape(Values.toString(ctx, raw), cleanupFlags(ctx, flags));
|
||||||
}
|
}
|
||||||
public static RegExpLib escape(String raw, String flags) {
|
public static RegExpLib escape(String raw, String flags) {
|
||||||
@ -135,7 +135,7 @@ public class RegExpLib {
|
|||||||
return "/" + source + "/" + flags();
|
return "/" + source + "/" + flags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native("@@Symvol.match") public Object match(Context ctx, String target) throws InterruptedException {
|
@Native("@@Symvol.match") public Object match(Context ctx, String target) {
|
||||||
if (this.global) {
|
if (this.global) {
|
||||||
var res = new ArrayValue();
|
var res = new ArrayValue();
|
||||||
Object val;
|
Object val;
|
||||||
@ -152,7 +152,7 @@ public class RegExpLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native("@@Symvol.matchAll") public Object matchAll(Context ctx, String target) throws InterruptedException {
|
@Native("@@Symvol.matchAll") public Object matchAll(Context ctx, String target) {
|
||||||
var pattern = new RegExpLib(this.source, this.flags() + "g");
|
var pattern = new RegExpLib(this.source, this.flags() + "g");
|
||||||
|
|
||||||
return Values.fromJavaIterator(ctx, new Iterator<Object>() {
|
return Values.fromJavaIterator(ctx, new Iterator<Object>() {
|
||||||
@ -174,7 +174,7 @@ public class RegExpLib {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native("@@Symvol.split") public ArrayValue split(Context ctx, String target, Object limit, boolean sensible) throws InterruptedException {
|
@Native("@@Symvol.split") public ArrayValue split(Context ctx, String target, Object limit, boolean sensible) {
|
||||||
var pattern = new RegExpLib(this.source, this.flags() + "g");
|
var pattern = new RegExpLib(this.source, this.flags() + "g");
|
||||||
Object match;
|
Object match;
|
||||||
int lastEnd = 0;
|
int lastEnd = 0;
|
||||||
@ -260,7 +260,7 @@ public class RegExpLib {
|
|||||||
// else return -1;
|
// else return -1;
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
@Native public RegExpLib(Context ctx, Object pattern, Object flags) throws InterruptedException {
|
@Native public RegExpLib(Context ctx, Object pattern, Object flags) {
|
||||||
this(cleanupPattern(ctx, pattern), cleanupFlags(ctx, flags));
|
this(cleanupPattern(ctx, pattern), cleanupFlags(ctx, flags));
|
||||||
}
|
}
|
||||||
public RegExpLib(String pattern, String flags) {
|
public RegExpLib(String pattern, String flags) {
|
||||||
|
@ -16,19 +16,19 @@ public class SetLib {
|
|||||||
private LinkedHashSet<Object> set = new LinkedHashSet<>();
|
private LinkedHashSet<Object> set = new LinkedHashSet<>();
|
||||||
|
|
||||||
@Native("@@Symbol.typeName") public final String name = "Set";
|
@Native("@@Symbol.typeName") public final String name = "Set";
|
||||||
@Native("@@Symbol.iterator") public ObjectValue iterator(Context ctx) throws InterruptedException {
|
@Native("@@Symbol.iterator") public ObjectValue iterator(Context ctx) {
|
||||||
return this.values(ctx);
|
return this.values(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public ObjectValue entries(Context ctx) throws InterruptedException {
|
@Native public ObjectValue entries(Context ctx) {
|
||||||
var res = set.stream().map(v -> new ArrayValue(ctx, v, v)).collect(Collectors.toList());
|
var res = set.stream().map(v -> new ArrayValue(ctx, v, v)).collect(Collectors.toList());
|
||||||
return Values.fromJavaIterator(ctx, res.iterator());
|
return Values.fromJavaIterator(ctx, res.iterator());
|
||||||
}
|
}
|
||||||
@Native public ObjectValue keys(Context ctx) throws InterruptedException {
|
@Native public ObjectValue keys(Context ctx) {
|
||||||
var res = new ArrayList<>(set);
|
var res = new ArrayList<>(set);
|
||||||
return Values.fromJavaIterator(ctx, res.iterator());
|
return Values.fromJavaIterator(ctx, res.iterator());
|
||||||
}
|
}
|
||||||
@Native public ObjectValue values(Context ctx) throws InterruptedException {
|
@Native public ObjectValue values(Context ctx) {
|
||||||
var res = new ArrayList<>(set);
|
var res = new ArrayList<>(set);
|
||||||
return Values.fromJavaIterator(ctx, res.iterator());
|
return Values.fromJavaIterator(ctx, res.iterator());
|
||||||
}
|
}
|
||||||
@ -51,13 +51,13 @@ public class SetLib {
|
|||||||
return set.size();
|
return set.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeGetter public void forEach(Context ctx, FunctionValue func, Object thisArg) throws InterruptedException {
|
@NativeGetter public void forEach(Context ctx, FunctionValue func, Object thisArg) {
|
||||||
var keys = new ArrayList<>(set);
|
var keys = new ArrayList<>(set);
|
||||||
|
|
||||||
for (var el : keys) func.call(ctx, thisArg, el, el, this);
|
for (var el : keys) func.call(ctx, thisArg, el, el, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public SetLib(Context ctx, Object iterable) throws InterruptedException {
|
@Native public SetLib(Context ctx, Object iterable) {
|
||||||
for (var el : Values.toJavaIterable(ctx, iterable)) add(el);
|
for (var el : Values.toJavaIterable(ctx, iterable)) add(el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import me.topchetoeu.jscript.interop.NativeInit;
|
|||||||
public class StringLib {
|
public class StringLib {
|
||||||
public final String value;
|
public final String value;
|
||||||
|
|
||||||
private static String passThis(Context ctx, String funcName, Object val) throws InterruptedException {
|
private static String passThis(Context ctx, String funcName, Object val) {
|
||||||
if (val instanceof StringLib) return ((StringLib)val).value;
|
if (val instanceof StringLib) return ((StringLib)val).value;
|
||||||
else if (val instanceof String) return (String)val;
|
else if (val instanceof String) return (String)val;
|
||||||
else throw EngineException.ofType(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));
|
||||||
@ -33,46 +33,46 @@ public class StringLib {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeGetter(thisArg = true) public static int length(Context ctx, Object thisArg) throws InterruptedException {
|
@NativeGetter(thisArg = true) public static int length(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "substring", thisArg).length();
|
return passThis(ctx, "substring", thisArg).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String substring(Context ctx, Object thisArg, int start, Object _end) throws InterruptedException {
|
@Native(thisArg = true) public static String substring(Context ctx, Object thisArg, int start, Object _end) {
|
||||||
var val = passThis(ctx, "substring", thisArg);
|
var val = passThis(ctx, "substring", thisArg);
|
||||||
start = normalizeI(start, val.length(), true);
|
start = normalizeI(start, val.length(), true);
|
||||||
int end = normalizeI(_end == null ? val.length() : (int)Values.toNumber(ctx, _end), val.length(), true);
|
int end = normalizeI(_end == null ? val.length() : (int)Values.toNumber(ctx, _end), val.length(), true);
|
||||||
|
|
||||||
return val.substring(start, end);
|
return val.substring(start, end);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String substr(Context ctx, Object thisArg, int start, Object _len) throws InterruptedException {
|
@Native(thisArg = true) public static String substr(Context ctx, Object thisArg, int start, Object _len) {
|
||||||
var val = passThis(ctx, "substr", thisArg);
|
var val = passThis(ctx, "substr", thisArg);
|
||||||
int len = _len == null ? val.length() - start : (int)Values.toNumber(ctx, _len);
|
int len = _len == null ? val.length() - start : (int)Values.toNumber(ctx, _len);
|
||||||
return substring(ctx, val, start, start + len);
|
return substring(ctx, val, start, start + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String toLowerCase(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toLowerCase(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "toLowerCase", thisArg).toLowerCase();
|
return passThis(ctx, "toLowerCase", thisArg).toLowerCase();
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toUpperCase(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toUpperCase(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "toUpperCase", thisArg).toUpperCase();
|
return passThis(ctx, "toUpperCase", thisArg).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String charAt(Context ctx, Object thisArg, int i) throws InterruptedException {
|
@Native(thisArg = true) public static String charAt(Context ctx, Object thisArg, int i) {
|
||||||
return passThis(ctx, "charAt", thisArg).charAt(i) + "";
|
return passThis(ctx, "charAt", thisArg).charAt(i) + "";
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static int charCodeAt(Context ctx, Object thisArg, int i) throws InterruptedException {
|
@Native(thisArg = true) public static int charCodeAt(Context ctx, Object thisArg, int i) {
|
||||||
return passThis(ctx, "charCodeAt", thisArg).charAt(i);
|
return passThis(ctx, "charCodeAt", thisArg).charAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static boolean startsWith(Context ctx, Object thisArg, String term, int pos) throws InterruptedException {
|
@Native(thisArg = true) public static boolean startsWith(Context ctx, Object thisArg, String term, int pos) {
|
||||||
return passThis(ctx, "startsWith", thisArg).startsWith(term, pos);
|
return passThis(ctx, "startsWith", thisArg).startsWith(term, pos);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static boolean endsWith(Context ctx, Object thisArg, String term, int pos) throws InterruptedException {
|
@Native(thisArg = true) public static boolean endsWith(Context ctx, Object thisArg, String term, int pos) {
|
||||||
var val = passThis(ctx, "endsWith", thisArg);
|
var val = passThis(ctx, "endsWith", thisArg);
|
||||||
return val.lastIndexOf(term, pos) >= 0;
|
return val.lastIndexOf(term, pos) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static int indexOf(Context ctx, Object thisArg, Object term, int start) throws InterruptedException {
|
@Native(thisArg = true) public static int indexOf(Context ctx, Object thisArg, Object term, int start) {
|
||||||
var val = passThis(ctx, "indexOf", thisArg);
|
var val = passThis(ctx, "indexOf", thisArg);
|
||||||
|
|
||||||
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
||||||
@ -84,7 +84,7 @@ public class StringLib {
|
|||||||
|
|
||||||
return val.indexOf(Values.toString(ctx, term), start);
|
return val.indexOf(Values.toString(ctx, term), start);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static int lastIndexOf(Context ctx, Object thisArg, Object term, int pos) throws InterruptedException {
|
@Native(thisArg = true) public static int lastIndexOf(Context ctx, Object thisArg, Object term, int pos) {
|
||||||
var val = passThis(ctx, "lastIndexOf", thisArg);
|
var val = passThis(ctx, "lastIndexOf", thisArg);
|
||||||
|
|
||||||
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
||||||
@ -97,11 +97,11 @@ public class StringLib {
|
|||||||
return val.lastIndexOf(Values.toString(ctx, term), pos);
|
return val.lastIndexOf(Values.toString(ctx, term), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static boolean includes(Context ctx, Object thisArg, Object term, int pos) throws InterruptedException {
|
@Native(thisArg = true) public static boolean includes(Context ctx, Object thisArg, Object term, int pos) {
|
||||||
return lastIndexOf(ctx, passThis(ctx, "includes", thisArg), term, pos) >= 0;
|
return lastIndexOf(ctx, passThis(ctx, "includes", thisArg), term, pos) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String replace(Context ctx, Object thisArg, Object term, String replacement) throws InterruptedException {
|
@Native(thisArg = true) public static String replace(Context ctx, Object thisArg, Object term, String replacement) {
|
||||||
var val = passThis(ctx, "replace", thisArg);
|
var val = passThis(ctx, "replace", thisArg);
|
||||||
|
|
||||||
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
||||||
@ -113,7 +113,7 @@ public class StringLib {
|
|||||||
|
|
||||||
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), replacement);
|
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), replacement);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String replaceAll(Context ctx, Object thisArg, Object term, String replacement) throws InterruptedException {
|
@Native(thisArg = true) public static String replaceAll(Context ctx, Object thisArg, Object term, String replacement) {
|
||||||
var val = passThis(ctx, "replaceAll", thisArg);
|
var val = passThis(ctx, "replaceAll", thisArg);
|
||||||
|
|
||||||
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
||||||
@ -126,7 +126,7 @@ public class StringLib {
|
|||||||
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), replacement);
|
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue match(Context ctx, Object thisArg, Object term, String replacement) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue match(Context ctx, Object thisArg, Object term, String replacement) {
|
||||||
var val = passThis(ctx, "match", thisArg);
|
var val = passThis(ctx, "match", thisArg);
|
||||||
|
|
||||||
FunctionValue match;
|
FunctionValue match;
|
||||||
@ -148,7 +148,7 @@ public class StringLib {
|
|||||||
if (res instanceof ArrayValue) return (ArrayValue)res;
|
if (res instanceof ArrayValue) return (ArrayValue)res;
|
||||||
else return new ArrayValue(ctx, "");
|
else return new ArrayValue(ctx, "");
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static Object matchAll(Context ctx, Object thisArg, Object term, String replacement) throws InterruptedException {
|
@Native(thisArg = true) public static Object matchAll(Context ctx, Object thisArg, Object term, String replacement) {
|
||||||
var val = passThis(ctx, "matchAll", thisArg);
|
var val = passThis(ctx, "matchAll", thisArg);
|
||||||
|
|
||||||
FunctionValue match = null;
|
FunctionValue match = null;
|
||||||
@ -170,7 +170,7 @@ public class StringLib {
|
|||||||
return match.call(ctx, term, val);
|
return match.call(ctx, term, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static ArrayValue split(Context ctx, Object thisArg, Object term, Object lim, boolean sensible) throws InterruptedException {
|
@Native(thisArg = true) public static ArrayValue split(Context ctx, Object thisArg, Object term, Object lim, boolean sensible) {
|
||||||
var val = passThis(ctx, "split", thisArg);
|
var val = passThis(ctx, "split", thisArg);
|
||||||
|
|
||||||
if (lim != null) lim = Values.toNumber(ctx, lim);
|
if (lim != null) lim = Values.toNumber(ctx, lim);
|
||||||
@ -217,30 +217,30 @@ public class StringLib {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String slice(Context ctx, Object thisArg, int start, Object _end) throws InterruptedException {
|
@Native(thisArg = true) public static String slice(Context ctx, Object thisArg, int start, Object _end) {
|
||||||
return substring(ctx, passThis(ctx, "slice", thisArg), start, _end);
|
return substring(ctx, passThis(ctx, "slice", thisArg), start, _end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native(thisArg = true) public static String concat(Context ctx, Object thisArg, Object... args) throws InterruptedException {
|
@Native(thisArg = true) public static String concat(Context ctx, Object thisArg, Object... args) {
|
||||||
var res = new StringBuilder(passThis(ctx, "concat", thisArg));
|
var res = new StringBuilder(passThis(ctx, "concat", thisArg));
|
||||||
|
|
||||||
for (var el : args) res.append(Values.toString(ctx, el));
|
for (var el : args) res.append(Values.toString(ctx, el));
|
||||||
|
|
||||||
return res.toString();
|
return res.toString();
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String trim(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String trim(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "trim", thisArg).trim();
|
return passThis(ctx, "trim", thisArg).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object val) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object val) {
|
||||||
val = Values.toString(ctx, val);
|
val = Values.toString(ctx, val);
|
||||||
if (thisArg instanceof ObjectValue) return new StringLib((String)val);
|
if (thisArg instanceof ObjectValue) return new StringLib((String)val);
|
||||||
else return val;
|
else return val;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "toString", thisArg);
|
return passThis(ctx, "toString", thisArg);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String valueOf(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String valueOf(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "valueOf", thisArg);
|
return passThis(ctx, "valueOf", thisArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,21 +29,21 @@ public class SymbolLib {
|
|||||||
|
|
||||||
public final Symbol value;
|
public final Symbol value;
|
||||||
|
|
||||||
private static Symbol passThis(Context ctx, String funcName, Object val) throws InterruptedException {
|
private static Symbol passThis(Context ctx, String funcName, Object val) {
|
||||||
if (val instanceof SymbolLib) return ((SymbolLib)val).value;
|
if (val instanceof SymbolLib) return ((SymbolLib)val).value;
|
||||||
else if (val instanceof Symbol) return (Symbol)val;
|
else if (val instanceof Symbol) return (Symbol)val;
|
||||||
else throw EngineException.ofType(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 {
|
@NativeConstructor(thisArg = true) public static Object constructor(Context ctx, Object thisArg, Object val) {
|
||||||
if (thisArg instanceof ObjectValue) throw EngineException.ofType("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("");
|
if (val == null) return new Symbol("");
|
||||||
else return new Symbol(Values.toString(ctx, val));
|
else return new Symbol(Values.toString(ctx, val));
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static String toString(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "toString", thisArg).value;
|
return passThis(ctx, "toString", thisArg).value;
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static Symbol valueOf(Context ctx, Object thisArg) throws InterruptedException {
|
@Native(thisArg = true) public static Symbol valueOf(Context ctx, Object thisArg) {
|
||||||
return passThis(ctx, "valueOf", thisArg);
|
return passThis(ctx, "valueOf", thisArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import me.topchetoeu.jscript.interop.NativeConstructor;
|
|||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
|
|
||||||
public class SyntaxErrorLib extends ErrorLib {
|
public class SyntaxErrorLib extends ErrorLib {
|
||||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) {
|
||||||
var target = ErrorLib.constructor(ctx, thisArg, message);
|
var target = ErrorLib.constructor(ctx, thisArg, message);
|
||||||
target.defineProperty(ctx, "name", "SyntaxError");
|
target.defineProperty(ctx, "name", "SyntaxError");
|
||||||
return target;
|
return target;
|
||||||
|
@ -8,7 +8,7 @@ import me.topchetoeu.jscript.interop.NativeConstructor;
|
|||||||
import me.topchetoeu.jscript.interop.NativeInit;
|
import me.topchetoeu.jscript.interop.NativeInit;
|
||||||
|
|
||||||
public class TypeErrorLib extends ErrorLib {
|
public class TypeErrorLib extends ErrorLib {
|
||||||
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) throws InterruptedException {
|
@NativeConstructor(thisArg = true) public static ObjectValue constructor(Context ctx, Object thisArg, Object message) {
|
||||||
var target = ErrorLib.constructor(ctx, thisArg, message);
|
var target = ErrorLib.constructor(ctx, thisArg, message);
|
||||||
target.defineProperty(ctx, "name", "TypeError");
|
target.defineProperty(ctx, "name", "TypeError");
|
||||||
return target;
|
return target;
|
||||||
|
Loading…
Reference in New Issue
Block a user