fix: reprogram standard library for env api
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package me.topchetoeu.jscript;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
@@ -13,8 +12,6 @@ import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.events.Observer;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
||||
import me.topchetoeu.jscript.polyfills.PolyfillEngine;
|
||||
import me.topchetoeu.jscript.polyfills.TypescriptEngine;
|
||||
|
||||
public class Main {
|
||||
static Thread task;
|
||||
@@ -54,7 +51,7 @@ public class Main {
|
||||
|
||||
public static void main(String args[]) {
|
||||
var in = new BufferedReader(new InputStreamReader(System.in));
|
||||
engine = new TypescriptEngine(new File("."));
|
||||
engine = new Engine();
|
||||
var scope = engine.global().globalChild();
|
||||
var exited = new boolean[1];
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import me.topchetoeu.jscript.Location;
|
||||
import me.topchetoeu.jscript.compilation.Instruction;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.control.ThrowStatement;
|
||||
import me.topchetoeu.jscript.engine.CallContext;
|
||||
import me.topchetoeu.jscript.engine.Operation;
|
||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
@@ -52,40 +51,7 @@ public class OperationStatement extends Statement {
|
||||
}
|
||||
|
||||
try {
|
||||
var ctx = new CallContext(null);
|
||||
|
||||
switch (operation) {
|
||||
case ADD: return new ConstantStatement(loc(), Values.add(ctx, vals[0], vals[1]));
|
||||
case SUBTRACT: return new ConstantStatement(loc(), Values.subtract(ctx, vals[0], vals[1]));
|
||||
case DIVIDE: return new ConstantStatement(loc(), Values.divide(ctx, vals[0], vals[1]));
|
||||
case MULTIPLY: return new ConstantStatement(loc(), Values.multiply(ctx, vals[0], vals[1]));
|
||||
case MODULO: return new ConstantStatement(loc(), Values.modulo(ctx, vals[0], vals[1]));
|
||||
|
||||
case AND: return new ConstantStatement(loc(), Values.and(ctx, vals[0], vals[1]));
|
||||
case OR: return new ConstantStatement(loc(), Values.or(ctx, vals[0], vals[1]));
|
||||
case XOR: return new ConstantStatement(loc(), Values.xor(ctx, vals[0], vals[1]));
|
||||
|
||||
case EQUALS: return new ConstantStatement(loc(), Values.strictEquals(vals[0], vals[1]));
|
||||
case NOT_EQUALS: return new ConstantStatement(loc(), !Values.strictEquals(vals[0], vals[1]));
|
||||
case LOOSE_EQUALS: return new ConstantStatement(loc(), Values.looseEqual(ctx, vals[0], vals[1]));
|
||||
case LOOSE_NOT_EQUALS: return new ConstantStatement(loc(), !Values.looseEqual(ctx, vals[0], vals[1]));
|
||||
|
||||
case GREATER: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) < 0);
|
||||
case GREATER_EQUALS: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) <= 0);
|
||||
case LESS: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) > 0);
|
||||
case LESS_EQUALS: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) >= 0);
|
||||
|
||||
case INVERSE: return new ConstantStatement(loc(), Values.bitwiseNot(ctx, vals[0]));
|
||||
case NOT: return new ConstantStatement(loc(), Values.not(vals[0]));
|
||||
case POS: return new ConstantStatement(loc(), Values.toNumber(ctx, vals[0]));
|
||||
case NEG: return new ConstantStatement(loc(), Values.negative(ctx, vals[0]));
|
||||
|
||||
case SHIFT_LEFT: return new ConstantStatement(loc(), Values.shiftLeft(ctx, vals[0], vals[1]));
|
||||
case SHIFT_RIGHT: return new ConstantStatement(loc(), Values.shiftRight(ctx, vals[0], vals[1]));
|
||||
case USHIFT_RIGHT: return new ConstantStatement(loc(), Values.unsignedShiftRight(ctx, vals[0], vals[1]));
|
||||
|
||||
default: break;
|
||||
}
|
||||
return new ConstantStatement(loc(), Values.operation(null, operation, vals));
|
||||
}
|
||||
catch (EngineException e) {
|
||||
return new ThrowStatement(loc(), new ConstantStatement(loc(), e.value));
|
||||
|
||||
@@ -142,13 +142,6 @@ public class Engine {
|
||||
}
|
||||
}
|
||||
|
||||
public void exposeClass(String name, Class<?> clazz) {
|
||||
global.define(name, true, typeRegister.getConstr(clazz));
|
||||
}
|
||||
public void exposeNamespace(String name, Class<?> clazz) {
|
||||
global.define(name, true, NativeTypeRegister.makeNamespace(clazz));
|
||||
}
|
||||
|
||||
public Thread start() {
|
||||
if (this.thread == null) {
|
||||
this.thread = new Thread(this::run, "JavaScript Runner #" + id);
|
||||
@@ -176,6 +169,9 @@ public class Engine {
|
||||
public ObjectValue getPrototype(Class<?> clazz) {
|
||||
return typeRegister.getProto(clazz);
|
||||
}
|
||||
public FunctionValue getConstructor(Class<?> clazz) {
|
||||
return typeRegister.getConstr(clazz);
|
||||
}
|
||||
public CallContext context() { return new CallContext(this).mergeData(callCtxVals); }
|
||||
|
||||
public Awaitable<Object> pushMsg(boolean micro, FunctionValue func, Map<DataKey<?>, Object> data, Object thisArg, Object... args) {
|
||||
|
||||
@@ -93,13 +93,13 @@ public class CodeFrame {
|
||||
|
||||
return res;
|
||||
}
|
||||
public void push(Object val) {
|
||||
public void push(CallContext ctx, Object val) {
|
||||
if (stack.length <= stackPtr) {
|
||||
var newStack = new Object[stack.length * 2];
|
||||
System.arraycopy(stack, 0, newStack, 0, stack.length);
|
||||
stack = newStack;
|
||||
}
|
||||
stack[stackPtr++] = Values.normalize(val);
|
||||
stack[stackPtr++] = Values.normalize(ctx, val);
|
||||
}
|
||||
|
||||
public void start(CallContext ctx) {
|
||||
@@ -150,7 +150,7 @@ public class CodeFrame {
|
||||
|
||||
try {
|
||||
this.jumpFlag = false;
|
||||
return Runners.exec(debugCmd, instr, this, ctx);
|
||||
return Runners.exec(ctx, debugCmd, instr, this);
|
||||
}
|
||||
catch (EngineException e) {
|
||||
throw e.add(function.name, prevLoc);
|
||||
@@ -307,13 +307,13 @@ public class CodeFrame {
|
||||
}
|
||||
}
|
||||
|
||||
public CodeFrame(Object thisArg, Object[] args, CodeFunction func) {
|
||||
public CodeFrame(CallContext ctx, Object thisArg, Object[] args, CodeFunction func) {
|
||||
this.args = args.clone();
|
||||
this.scope = new LocalScope(func.localsN, func.captures);
|
||||
this.scope.get(0).set(null, thisArg);
|
||||
var argsObj = new ArrayValue();
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
argsObj.set(i, args[i]);
|
||||
argsObj.set(ctx, i, args[i]);
|
||||
}
|
||||
this.scope.get(1).value = argsObj;
|
||||
|
||||
|
||||
@@ -18,62 +18,62 @@ import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
public class Runners {
|
||||
public static final Object NO_RETURN = new Object();
|
||||
|
||||
public static Object execReturn(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execReturn(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.codePtr++;
|
||||
return frame.pop();
|
||||
}
|
||||
public static Object execSignal(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execSignal(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.codePtr++;
|
||||
return new SignalValue(instr.get(0));
|
||||
}
|
||||
public static Object execThrow(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execThrow(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
throw new EngineException(frame.pop());
|
||||
}
|
||||
public static Object execThrowSyntax(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execThrowSyntax(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
throw EngineException.ofSyntax((String)instr.get(0));
|
||||
}
|
||||
|
||||
private static Object call(DebugCommand state, CallContext ctx, Object func, Object thisArg, Object... args) throws InterruptedException {
|
||||
private static Object call(CallContext ctx, DebugCommand state, Object func, Object thisArg, Object... args) throws InterruptedException {
|
||||
ctx.setData(CodeFrame.STOP_AT_START_KEY, state == DebugCommand.STEP_INTO);
|
||||
return Values.call(ctx, func, thisArg, args);
|
||||
}
|
||||
|
||||
public static Object execCall(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execCall(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var callArgs = frame.take(instr.get(0));
|
||||
var func = frame.pop();
|
||||
var thisArg = frame.pop();
|
||||
|
||||
frame.push(call(state, ctx, func, thisArg, callArgs));
|
||||
frame.push(ctx, call(ctx, state, func, thisArg, callArgs));
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execCallNew(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execCallNew(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var callArgs = frame.take(instr.get(0));
|
||||
var funcObj = frame.pop();
|
||||
|
||||
if (Values.isFunction(funcObj) && Values.function(funcObj).special) {
|
||||
frame.push(call(state, ctx, funcObj, null, callArgs));
|
||||
frame.push(ctx, call(ctx, state, funcObj, null, callArgs));
|
||||
}
|
||||
else {
|
||||
var proto = Values.getMember(ctx, funcObj, "prototype");
|
||||
var obj = new ObjectValue();
|
||||
obj.setPrototype(ctx, proto);
|
||||
call(state, ctx, funcObj, obj, callArgs);
|
||||
frame.push(obj);
|
||||
call(ctx, state, funcObj, obj, callArgs);
|
||||
frame.push(ctx, obj);
|
||||
}
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execMakeVar(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execMakeVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var name = (String)instr.get(0);
|
||||
frame.function.globals.define(name);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execDefProp(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execDefProp(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var setter = frame.pop();
|
||||
var getter = frame.pop();
|
||||
var name = frame.pop();
|
||||
@@ -82,28 +82,28 @@ public class Runners {
|
||||
if (getter != null && !Values.isFunction(getter)) throw EngineException.ofType("Getter must be a function or undefined.");
|
||||
if (setter != null && !Values.isFunction(setter)) throw EngineException.ofType("Setter must be a function or undefined.");
|
||||
if (!Values.isObject(obj)) throw EngineException.ofType("Property apply target must be an object.");
|
||||
Values.object(obj).defineProperty(name, Values.function(getter), Values.function(setter), false, false);
|
||||
Values.object(obj).defineProperty(ctx, name, Values.function(getter), Values.function(setter), false, false);
|
||||
|
||||
frame.push(obj);
|
||||
frame.push(ctx, obj);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execInstanceof(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execInstanceof(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var type = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
if (!Values.isPrimitive(type)) {
|
||||
var proto = Values.getMember(ctx, type, "prototype");
|
||||
frame.push(Values.isInstanceOf(ctx, obj, proto));
|
||||
frame.push(ctx, Values.isInstanceOf(ctx, obj, proto));
|
||||
}
|
||||
else {
|
||||
frame.push(false);
|
||||
frame.push(ctx, false);
|
||||
}
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execKeys(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execKeys(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var val = frame.pop();
|
||||
|
||||
var arr = new ObjectValue();
|
||||
@@ -113,81 +113,81 @@ public class Runners {
|
||||
Collections.reverse(members);
|
||||
for (var el : members) {
|
||||
if (el instanceof Symbol) continue;
|
||||
arr.defineProperty(i++, el);
|
||||
arr.defineProperty(ctx, i++, el);
|
||||
}
|
||||
|
||||
arr.defineProperty("length", i);
|
||||
arr.defineProperty(ctx, "length", i);
|
||||
|
||||
frame.push(arr);
|
||||
frame.push(ctx, arr);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execTry(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execTry(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
frame.addTry(instr.get(0), instr.get(1), instr.get(2));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execDup(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execDup(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
int offset = instr.get(0), count = instr.get(1);
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
frame.push(frame.peek(offset + count - 1));
|
||||
frame.push(ctx, frame.peek(offset + count - 1));
|
||||
}
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execMove(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execMove(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
int offset = instr.get(0), count = instr.get(1);
|
||||
|
||||
var tmp = frame.take(offset);
|
||||
var res = frame.take(count);
|
||||
|
||||
for (var i = 0; i < offset; i++) frame.push(tmp[i]);
|
||||
for (var i = 0; i < count; i++) frame.push(res[i]);
|
||||
for (var i = 0; i < offset; i++) frame.push(ctx, tmp[i]);
|
||||
for (var i = 0; i < count; i++) frame.push(ctx, res[i]);
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadUndefined(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(null);
|
||||
public static Object execLoadUndefined(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, null);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadValue(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(instr.get(0));
|
||||
public static Object execLoadValue(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, instr.get(0));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadVar(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execLoadVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var i = instr.get(0);
|
||||
|
||||
if (i instanceof String) frame.push(frame.function.globals.get(ctx, (String)i));
|
||||
else frame.push(frame.scope.get((int)i).get(ctx));
|
||||
if (i instanceof String) frame.push(ctx, frame.function.globals.get(ctx, (String)i));
|
||||
else frame.push(ctx, frame.scope.get((int)i).get(ctx));
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadObj(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(new ObjectValue());
|
||||
public static Object execLoadObj(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, new ObjectValue());
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadGlob(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(frame.function.globals.obj);
|
||||
public static Object execLoadGlob(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, frame.function.globals.obj);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadArr(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execLoadArr(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
var res = new ArrayValue();
|
||||
res.setSize(instr.get(0));
|
||||
frame.push(res);
|
||||
frame.push(ctx, res);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadFunc(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execLoadFunc(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
int n = (Integer)instr.get(0);
|
||||
int localsN = (Integer)instr.get(1);
|
||||
int len = (Integer)instr.get(2);
|
||||
@@ -203,18 +203,18 @@ public class Runners {
|
||||
System.arraycopy(frame.function.body, start, body, 0, end - start);
|
||||
|
||||
var func = new CodeFunction("", localsN, len, frame.function.globals, captures, body);
|
||||
frame.push(func);
|
||||
frame.push(ctx, func);
|
||||
|
||||
frame.codePtr += n;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadMember(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execLoadMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var key = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
try {
|
||||
ctx.setData(CodeFrame.STOP_AT_START_KEY, state == DebugCommand.STEP_INTO);
|
||||
frame.push(Values.getMember(ctx, obj, key));
|
||||
frame.push(ctx, Values.getMember(ctx, obj, key));
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw EngineException.ofType(e.getMessage());
|
||||
@@ -222,33 +222,33 @@ public class Runners {
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadKeyMember(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
frame.push(instr.get(0));
|
||||
return execLoadMember(state, instr, frame, ctx);
|
||||
public static Object execLoadKeyMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
frame.push(ctx, instr.get(0));
|
||||
return execLoadMember(ctx, state, instr, frame);
|
||||
}
|
||||
public static Object execLoadRegEx(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
frame.push(ctx.engine().makeRegex(instr.get(0), instr.get(1)));
|
||||
public static Object execLoadRegEx(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
frame.push(ctx, ctx.engine().makeRegex(instr.get(0), instr.get(1)));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execDiscard(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execDiscard(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.pop();
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execStoreMember(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execStoreMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var val = frame.pop();
|
||||
var key = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
ctx.setData(CodeFrame.STOP_AT_START_KEY, state == DebugCommand.STEP_INTO);
|
||||
if (!Values.setMember(ctx, obj, key, val)) throw EngineException.ofSyntax("Can't set member '" + key + "'.");
|
||||
if ((boolean)instr.get(0)) frame.push(val);
|
||||
if ((boolean)instr.get(0)) frame.push(ctx, val);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execStoreVar(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execStoreVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
|
||||
var i = instr.get(0);
|
||||
|
||||
@@ -258,18 +258,18 @@ public class Runners {
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execStoreSelfFunc(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execStoreSelfFunc(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.scope.locals[(int)instr.get(0)].set(ctx, frame.function);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execJmp(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execJmp(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.codePtr += (int)instr.get(0);
|
||||
frame.jumpFlag = true;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execJmpIf(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execJmpIf(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
if (Values.toBoolean(frame.pop())) {
|
||||
frame.codePtr += (int)instr.get(0);
|
||||
frame.jumpFlag = true;
|
||||
@@ -277,7 +277,7 @@ public class Runners {
|
||||
else frame.codePtr ++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execJmpIfNot(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execJmpIfNot(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
if (Values.not(frame.pop())) {
|
||||
frame.codePtr += (int)instr.get(0);
|
||||
frame.jumpFlag = true;
|
||||
@@ -286,15 +286,15 @@ public class Runners {
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execIn(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execIn(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var obj = frame.pop();
|
||||
var index = frame.pop();
|
||||
|
||||
frame.push(Values.hasMember(ctx, obj, index, false));
|
||||
frame.push(ctx, Values.hasMember(ctx, obj, index, false));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execTypeof(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execTypeof(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
String name = instr.get(0);
|
||||
Object obj;
|
||||
|
||||
@@ -306,12 +306,12 @@ public class Runners {
|
||||
}
|
||||
else obj = frame.pop();
|
||||
|
||||
frame.push(Values.type(obj));
|
||||
frame.push(ctx, Values.type(obj));
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execNop(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execNop(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
if (instr.is(0, "dbg_names")) {
|
||||
var names = new String[instr.params.length - 1];
|
||||
for (var i = 0; i < instr.params.length - 1; i++) {
|
||||
@@ -325,67 +325,67 @@ public class Runners {
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execDelete(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execDelete(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var key = frame.pop();
|
||||
var val = frame.pop();
|
||||
|
||||
if (!Values.deleteMember(ctx, val, key)) throw EngineException.ofSyntax("Can't delete member '" + key + "'.");
|
||||
frame.push(true);
|
||||
frame.push(ctx, true);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execOperation(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execOperation(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
Operation op = instr.get(0);
|
||||
var args = new Object[op.operands];
|
||||
|
||||
for (var i = op.operands - 1; i >= 0; i--) args[i] = frame.pop();
|
||||
|
||||
frame.push(Values.operation(ctx, op, args));
|
||||
frame.push(ctx, Values.operation(ctx, op, args));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object exec(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object exec(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
// System.out.println(instr + "@" + instr.location);
|
||||
switch (instr.type) {
|
||||
case NOP: return execNop(instr, frame, ctx);
|
||||
case RETURN: return execReturn(instr, frame, ctx);
|
||||
case SIGNAL: return execSignal(instr, frame, ctx);
|
||||
case THROW: return execThrow(instr, frame, ctx);
|
||||
case THROW_SYNTAX: return execThrowSyntax(instr, frame, ctx);
|
||||
case CALL: return execCall(state, instr, frame, ctx);
|
||||
case CALL_NEW: return execCallNew(state, instr, frame, ctx);
|
||||
case TRY: return execTry(state, instr, frame, ctx);
|
||||
case NOP: return execNop(ctx, instr, frame);
|
||||
case RETURN: return execReturn(ctx, instr, frame);
|
||||
case SIGNAL: return execSignal(ctx, instr, frame);
|
||||
case THROW: return execThrow(ctx, instr, frame);
|
||||
case THROW_SYNTAX: return execThrowSyntax(ctx, instr, frame);
|
||||
case CALL: return execCall(ctx, state, instr, frame);
|
||||
case CALL_NEW: return execCallNew(ctx, state, instr, frame);
|
||||
case TRY: return execTry(ctx, instr, frame);
|
||||
|
||||
case DUP: return execDup(instr, frame, ctx);
|
||||
case MOVE: return execMove(instr, frame, ctx);
|
||||
case LOAD_VALUE: return execLoadValue(instr, frame, ctx);
|
||||
case LOAD_VAR: return execLoadVar(instr, frame, ctx);
|
||||
case LOAD_OBJ: return execLoadObj(instr, frame, ctx);
|
||||
case LOAD_ARR: return execLoadArr(instr, frame, ctx);
|
||||
case LOAD_FUNC: return execLoadFunc(instr, frame, ctx);
|
||||
case LOAD_MEMBER: return execLoadMember(state, instr, frame, ctx);
|
||||
case LOAD_VAL_MEMBER: return execLoadKeyMember(state, instr, frame, ctx);
|
||||
case LOAD_REGEX: return execLoadRegEx(instr, frame, ctx);
|
||||
case LOAD_GLOB: return execLoadGlob(instr, frame, ctx);
|
||||
case DUP: return execDup(ctx, instr, frame);
|
||||
case MOVE: return execMove(ctx, instr, frame);
|
||||
case LOAD_VALUE: return execLoadValue(ctx, instr, frame);
|
||||
case LOAD_VAR: return execLoadVar(ctx, instr, frame);
|
||||
case LOAD_OBJ: return execLoadObj(ctx, instr, frame);
|
||||
case LOAD_ARR: return execLoadArr(ctx, instr, frame);
|
||||
case LOAD_FUNC: return execLoadFunc(ctx, instr, frame);
|
||||
case LOAD_MEMBER: return execLoadMember(ctx, state, instr, frame);
|
||||
case LOAD_VAL_MEMBER: return execLoadKeyMember(ctx, state, instr, frame);
|
||||
case LOAD_REGEX: return execLoadRegEx(ctx, instr, frame);
|
||||
case LOAD_GLOB: return execLoadGlob(ctx, instr, frame);
|
||||
|
||||
case DISCARD: return execDiscard(instr, frame, ctx);
|
||||
case STORE_MEMBER: return execStoreMember(state, instr, frame, ctx);
|
||||
case STORE_VAR: return execStoreVar(instr, frame, ctx);
|
||||
case STORE_SELF_FUNC: return execStoreSelfFunc(instr, frame, ctx);
|
||||
case MAKE_VAR: return execMakeVar(instr, frame, ctx);
|
||||
case DISCARD: return execDiscard(ctx, instr, frame);
|
||||
case STORE_MEMBER: return execStoreMember(ctx, state, instr, frame);
|
||||
case STORE_VAR: return execStoreVar(ctx, instr, frame);
|
||||
case STORE_SELF_FUNC: return execStoreSelfFunc(ctx, instr, frame);
|
||||
case MAKE_VAR: return execMakeVar(ctx, instr, frame);
|
||||
|
||||
case KEYS: return execKeys(instr, frame, ctx);
|
||||
case DEF_PROP: return execDefProp(instr, frame, ctx);
|
||||
case TYPEOF: return execTypeof(instr, frame, ctx);
|
||||
case DELETE: return execDelete(instr, frame, ctx);
|
||||
case KEYS: return execKeys(ctx, instr, frame);
|
||||
case DEF_PROP: return execDefProp(ctx, instr, frame);
|
||||
case TYPEOF: return execTypeof(ctx, instr, frame);
|
||||
case DELETE: return execDelete(ctx, instr, frame);
|
||||
|
||||
case JMP: return execJmp(instr, frame, ctx);
|
||||
case JMP_IF: return execJmpIf(instr, frame, ctx);
|
||||
case JMP_IFN: return execJmpIfNot(instr, frame, ctx);
|
||||
case JMP: return execJmp(ctx, instr, frame);
|
||||
case JMP_IF: return execJmpIf(ctx, instr, frame);
|
||||
case JMP_IFN: return execJmpIfNot(ctx, instr, frame);
|
||||
|
||||
case OPERATION: return execOperation(instr, frame, ctx);
|
||||
case OPERATION: return execOperation(ctx, instr, frame);
|
||||
|
||||
default: throw EngineException.ofSyntax("Invalid instruction " + instr.type.name() + ".");
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class Module {
|
||||
|
||||
executing = true;
|
||||
var scope = ctx.engine().global().globalChild();
|
||||
scope.define("module", true, this);
|
||||
scope.define(null, "module", true, this);
|
||||
scope.define("exports", new ExportsVariable());
|
||||
|
||||
var parent = new File(filename).getParentFile();
|
||||
|
||||
@@ -38,24 +38,24 @@ public class GlobalScope implements ScopeRecord {
|
||||
Thread.currentThread().interrupt();
|
||||
return name;
|
||||
}
|
||||
obj.defineProperty(name, null);
|
||||
obj.defineProperty(null, name, null);
|
||||
return name;
|
||||
}
|
||||
public void define(String name, Variable val) {
|
||||
obj.defineProperty(name,
|
||||
obj.defineProperty(null, name,
|
||||
new NativeFunction("get " + name, (ctx, th, a) -> val.get(ctx)),
|
||||
new NativeFunction("set " + name, (ctx, th, args) -> { val.set(ctx, args.length > 0 ? args[0] : null); return null; }),
|
||||
true, true
|
||||
);
|
||||
}
|
||||
public void define(String name, boolean readonly, Object val) {
|
||||
obj.defineProperty(name, val, readonly, true, true);
|
||||
public void define(CallContext ctx, String name, boolean readonly, Object val) {
|
||||
obj.defineProperty(ctx, name, val, readonly, true, true);
|
||||
}
|
||||
public void define(String... names) {
|
||||
for (var n : names) define(n);
|
||||
}
|
||||
public void define(boolean readonly, FunctionValue val) {
|
||||
define(val.name, readonly, val);
|
||||
define(null, val.name, readonly, val);
|
||||
}
|
||||
|
||||
public Object get(CallContext ctx, String name) throws InterruptedException {
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ValueVariable implements Variable {
|
||||
@Override
|
||||
public void set(CallContext ctx, Object val) {
|
||||
if (readonly) return;
|
||||
this.value = Values.normalize(val);
|
||||
this.value = Values.normalize(ctx, val);
|
||||
}
|
||||
|
||||
public ValueVariable(boolean readonly, Object val) {
|
||||
|
||||
@@ -29,14 +29,14 @@ public class ArrayValue extends ObjectValue {
|
||||
if (res == EMPTY) return null;
|
||||
else return res;
|
||||
}
|
||||
public void set(int i, Object val) {
|
||||
public void set(CallContext ctx, int i, Object val) {
|
||||
if (i < 0) return;
|
||||
|
||||
while (values.size() <= i) {
|
||||
values.add(EMPTY);
|
||||
}
|
||||
|
||||
values.set(i, Values.normalize(val));
|
||||
values.set(i, Values.normalize(ctx, val));
|
||||
}
|
||||
public boolean has(int i) {
|
||||
return i >= 0 && i < values.size() && values.get(i) != EMPTY;
|
||||
@@ -102,7 +102,7 @@ public class ArrayValue extends ObjectValue {
|
||||
if (key instanceof Number) {
|
||||
var i = Values.number(key);
|
||||
if (i >= 0 && i - Math.floor(i) == 0) {
|
||||
set((int)i, val);
|
||||
set(ctx, (int)i, val);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -149,12 +149,12 @@ public class ArrayValue extends ObjectValue {
|
||||
nonEnumerableSet.add("length");
|
||||
nonConfigurableSet.add("length");
|
||||
}
|
||||
public ArrayValue(Object ...values) {
|
||||
public ArrayValue(CallContext ctx, Object ...values) {
|
||||
this();
|
||||
for (var i = 0; i < values.length; i++) this.values.add(values[i]);
|
||||
for (var i = 0; i < values.length; i++) this.values.add(Values.normalize(ctx, values[i]));
|
||||
}
|
||||
|
||||
public static ArrayValue of(Collection<Object> values) {
|
||||
return new ArrayValue(values.toArray(Object[]::new));
|
||||
public static ArrayValue of(CallContext ctx, Collection<Object> values) {
|
||||
return new ArrayValue(ctx, values.toArray(Object[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class CodeFunction extends FunctionValue {
|
||||
|
||||
@Override
|
||||
public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
return new CodeFrame(thisArg, args, this).run(ctx);
|
||||
return new CodeFrame(ctx, thisArg, args, this).run(ctx);
|
||||
}
|
||||
|
||||
public CodeFunction(String name, int localsN, int length, GlobalScope globals, ValueVariable[] captures, Instruction[] body) {
|
||||
|
||||
@@ -63,8 +63,8 @@ public abstract class FunctionValue extends ObjectValue {
|
||||
nonEnumerableSet.add("length");
|
||||
|
||||
var proto = new ObjectValue();
|
||||
proto.defineProperty("constructor", this, true, false, false);
|
||||
this.defineProperty("prototype", proto, true, false, false);
|
||||
proto.defineProperty(null, "constructor", this, true, false, false);
|
||||
this.defineProperty(null, "prototype", proto, true, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ public class ObjectValue {
|
||||
state = State.FROZEN;
|
||||
}
|
||||
|
||||
public final boolean defineProperty(Object key, Object val, boolean writable, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(key); val = Values.normalize(val);
|
||||
public final boolean defineProperty(CallContext ctx, Object key, Object val, boolean writable, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||
boolean reconfigured =
|
||||
writable != memberWritable(key) ||
|
||||
configurable != memberConfigurable(key) ||
|
||||
@@ -118,11 +118,11 @@ public class ObjectValue {
|
||||
values.put(key, val);
|
||||
return true;
|
||||
}
|
||||
public final boolean defineProperty(Object key, Object val) {
|
||||
return defineProperty(Values.normalize(key), Values.normalize(val), true, true, true);
|
||||
public final boolean defineProperty(CallContext ctx, Object key, Object val) {
|
||||
return defineProperty(ctx, key, val, true, true, true);
|
||||
}
|
||||
public final boolean defineProperty(Object key, FunctionValue getter, FunctionValue setter, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(key);
|
||||
public final boolean defineProperty(CallContext ctx, Object key, FunctionValue getter, FunctionValue setter, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(ctx, key);
|
||||
if (
|
||||
properties.containsKey(key) &&
|
||||
properties.get(key).getter == getter &&
|
||||
@@ -162,7 +162,7 @@ public class ObjectValue {
|
||||
return (ObjectValue)prototype;
|
||||
}
|
||||
public final boolean setPrototype(CallContext ctx, Object val) {
|
||||
val = Values.normalize(val);
|
||||
val = Values.normalize(ctx, val);
|
||||
|
||||
if (!extensible()) return false;
|
||||
if (val == null || val == Values.NULL) prototype = null;
|
||||
@@ -228,7 +228,7 @@ public class ObjectValue {
|
||||
}
|
||||
|
||||
public final Object getMember(CallContext ctx, Object key, Object thisArg) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (key.equals("__proto__")) {
|
||||
var res = getPrototype(ctx);
|
||||
@@ -239,7 +239,7 @@ public class ObjectValue {
|
||||
|
||||
if (prop != null) {
|
||||
if (prop.getter == null) return null;
|
||||
else return prop.getter.call(ctx, Values.normalize(thisArg));
|
||||
else return prop.getter.call(ctx, Values.normalize(ctx, thisArg));
|
||||
}
|
||||
else return getField(ctx, key);
|
||||
}
|
||||
@@ -248,12 +248,12 @@ public class ObjectValue {
|
||||
}
|
||||
|
||||
public final boolean setMember(CallContext ctx, Object key, Object val, Object thisArg, boolean onlyProps) throws InterruptedException {
|
||||
key = Values.normalize(key); val = Values.normalize(val);
|
||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||
|
||||
var prop = getProperty(ctx, key);
|
||||
if (prop != null) {
|
||||
if (prop.setter == null) return false;
|
||||
prop.setter.call(ctx, Values.normalize(thisArg), val);
|
||||
prop.setter.call(ctx, Values.normalize(ctx, thisArg), val);
|
||||
return true;
|
||||
}
|
||||
else if (onlyProps) return false;
|
||||
@@ -267,11 +267,11 @@ public class ObjectValue {
|
||||
else return setField(ctx, key, val);
|
||||
}
|
||||
public final boolean setMember(CallContext ctx, Object key, Object val, boolean onlyProps) throws InterruptedException {
|
||||
return setMember(ctx, Values.normalize(key), Values.normalize(val), this, onlyProps);
|
||||
return setMember(ctx, Values.normalize(ctx, key), Values.normalize(ctx, val), this, onlyProps);
|
||||
}
|
||||
|
||||
public final boolean hasMember(CallContext ctx, Object key, boolean own) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (key != null && key.equals("__proto__")) return true;
|
||||
if (hasField(ctx, key)) return true;
|
||||
@@ -280,7 +280,7 @@ public class ObjectValue {
|
||||
return prototype != null && getPrototype(ctx).hasMember(ctx, key, own);
|
||||
}
|
||||
public final boolean deleteMember(CallContext ctx, Object key) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (!memberConfigurable(key)) return false;
|
||||
properties.remove(key);
|
||||
@@ -291,21 +291,21 @@ public class ObjectValue {
|
||||
}
|
||||
|
||||
public final ObjectValue getMemberDescriptor(CallContext ctx, Object key) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
var prop = properties.get(key);
|
||||
var res = new ObjectValue();
|
||||
|
||||
res.defineProperty("configurable", memberConfigurable(key));
|
||||
res.defineProperty("enumerable", memberEnumerable(key));
|
||||
res.defineProperty(ctx, "configurable", memberConfigurable(key));
|
||||
res.defineProperty(ctx, "enumerable", memberEnumerable(key));
|
||||
|
||||
if (prop != null) {
|
||||
res.defineProperty("get", prop.getter);
|
||||
res.defineProperty("set", prop.setter);
|
||||
res.defineProperty(ctx, "get", prop.getter);
|
||||
res.defineProperty(ctx, "set", prop.setter);
|
||||
}
|
||||
else if (hasField(ctx, key)) {
|
||||
res.defineProperty("value", values.get(key));
|
||||
res.defineProperty("writable", memberWritable(key));
|
||||
res.defineProperty(ctx, "value", values.get(key));
|
||||
res.defineProperty(ctx, "writable", memberWritable(key));
|
||||
}
|
||||
else return null;
|
||||
return res;
|
||||
@@ -326,10 +326,10 @@ public class ObjectValue {
|
||||
return res;
|
||||
}
|
||||
|
||||
public ObjectValue(Map<?, ?> values) {
|
||||
public ObjectValue(CallContext ctx, Map<?, ?> values) {
|
||||
this(PlaceholderProto.OBJECT);
|
||||
for (var el : values.entrySet()) {
|
||||
defineProperty(el.getKey(), el.getValue());
|
||||
defineProperty(ctx, el.getKey(), el.getValue());
|
||||
}
|
||||
}
|
||||
public ObjectValue(PlaceholderProto proto) {
|
||||
|
||||
@@ -88,7 +88,7 @@ public class Values {
|
||||
}
|
||||
|
||||
public static Object toPrimitive(CallContext ctx, Object obj, ConvertHint hint) throws InterruptedException {
|
||||
obj = normalize(obj);
|
||||
obj = normalize(ctx, obj);
|
||||
if (isPrimitive(obj)) return obj;
|
||||
|
||||
var first = hint == ConvertHint.VALUEOF ? "valueOf" : "toString";
|
||||
@@ -231,8 +231,8 @@ public class Values {
|
||||
case OR: return or(ctx, args[0], args[1]);
|
||||
case XOR: return xor(ctx, args[0], args[1]);
|
||||
|
||||
case EQUALS: return strictEquals(args[0], args[1]);
|
||||
case NOT_EQUALS: return !strictEquals(args[0], args[1]);
|
||||
case EQUALS: return strictEquals(ctx, args[0], args[1]);
|
||||
case NOT_EQUALS: return !strictEquals(ctx, args[0], args[1]);
|
||||
case LOOSE_EQUALS: return looseEqual(ctx, args[0], args[1]);
|
||||
case LOOSE_NOT_EQUALS: return !looseEqual(ctx, args[0], args[1]);
|
||||
|
||||
@@ -261,7 +261,7 @@ public class Values {
|
||||
}
|
||||
|
||||
public static Object getMember(CallContext ctx, Object obj, Object key) throws InterruptedException {
|
||||
obj = normalize(obj); key = normalize(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 null.");
|
||||
if (isObject(obj)) return object(obj).getMember(ctx, key);
|
||||
@@ -281,7 +281,7 @@ public class Values {
|
||||
else return proto.getMember(ctx, key, obj);
|
||||
}
|
||||
public static boolean setMember(CallContext ctx, Object obj, Object key, Object val) throws InterruptedException {
|
||||
obj = normalize(obj); key = normalize(key); val = normalize(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 null.");
|
||||
if (key.equals("__proto__")) return setPrototype(ctx, obj, val);
|
||||
@@ -292,7 +292,7 @@ public class Values {
|
||||
}
|
||||
public static boolean hasMember(CallContext ctx, Object obj, Object key, boolean own) throws InterruptedException {
|
||||
if (obj == null || obj == NULL) return false;
|
||||
obj = normalize(obj); key = normalize(key);
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||
|
||||
if (key.equals("__proto__")) return true;
|
||||
if (isObject(obj)) return object(obj).hasMember(ctx, key, own);
|
||||
@@ -310,14 +310,14 @@ public class Values {
|
||||
}
|
||||
public static boolean deleteMember(CallContext ctx, Object obj, Object key) throws InterruptedException {
|
||||
if (obj == null || obj == NULL) return false;
|
||||
obj = normalize(obj); key = normalize(key);
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||
|
||||
if (isObject(obj)) return object(obj).deleteMember(ctx, key);
|
||||
else return false;
|
||||
}
|
||||
public static ObjectValue getPrototype(CallContext ctx, Object obj) throws InterruptedException {
|
||||
if (obj == null || obj == NULL) return null;
|
||||
obj = normalize(obj);
|
||||
obj = normalize(ctx, obj);
|
||||
if (isObject(obj)) return object(obj).getPrototype(ctx);
|
||||
if (ctx == null) return null;
|
||||
|
||||
@@ -329,7 +329,7 @@ public class Values {
|
||||
return null;
|
||||
}
|
||||
public static boolean setPrototype(CallContext ctx, Object obj, Object proto) throws InterruptedException {
|
||||
obj = normalize(obj); proto = normalize(proto);
|
||||
obj = normalize(ctx, obj); proto = normalize(ctx, proto);
|
||||
return isObject(obj) && object(obj).setPrototype(ctx, proto);
|
||||
}
|
||||
public static List<Object> getMembers(CallContext ctx, Object obj, boolean own, boolean includeNonEnumerable) throws InterruptedException {
|
||||
@@ -359,8 +359,8 @@ public class Values {
|
||||
return function(func).call(ctx, thisArg, args);
|
||||
}
|
||||
|
||||
public static boolean strictEquals(Object a, Object b) {
|
||||
a = normalize(a); b = normalize(b);
|
||||
public static boolean strictEquals(CallContext ctx, Object a, Object b) {
|
||||
a = normalize(ctx, a); b = normalize(ctx, b);
|
||||
|
||||
if (a == null || b == null) return a == null && b == null;
|
||||
if (isNan(a) || isNan(b)) return false;
|
||||
@@ -370,7 +370,7 @@ public class Values {
|
||||
return a == b || a.equals(b);
|
||||
}
|
||||
public static boolean looseEqual(CallContext ctx, Object a, Object b) throws InterruptedException {
|
||||
a = normalize(a); b = normalize(b);
|
||||
a = normalize(ctx, a); b = normalize(ctx, b);
|
||||
|
||||
// In loose equality, null is equivalent to undefined
|
||||
if (a == NULL) a = null;
|
||||
@@ -387,13 +387,13 @@ public class Values {
|
||||
// Compare symbols by reference
|
||||
if (a instanceof Symbol || b instanceof Symbol) return a == b;
|
||||
if (a instanceof Boolean || b instanceof Boolean) return toBoolean(a) == toBoolean(b);
|
||||
if (a instanceof Number || b instanceof Number) return strictEquals(toNumber(ctx, a), toNumber(ctx, b));
|
||||
if (a instanceof Number || b instanceof Number) return strictEquals(ctx, toNumber(ctx, a), toNumber(ctx, b));
|
||||
|
||||
// Default to strings
|
||||
return toString(ctx, a).equals(toString(ctx, b));
|
||||
}
|
||||
|
||||
public static Object normalize(Object val) {
|
||||
public static Object normalize(CallContext ctx, Object val) {
|
||||
if (val instanceof Number) return number(val);
|
||||
if (isPrimitive(val) || val instanceof ObjectValue) return val;
|
||||
if (val instanceof Character) return val + "";
|
||||
@@ -402,7 +402,7 @@ public class Values {
|
||||
var res = new ObjectValue();
|
||||
|
||||
for (var entry : ((Map<?, ?>)val).entrySet()) {
|
||||
res.defineProperty(entry.getKey(), entry.getValue());
|
||||
res.defineProperty(ctx, entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -412,12 +412,17 @@ public class Values {
|
||||
var res = new ArrayValue();
|
||||
|
||||
for (var entry : ((Iterable<?>)val)) {
|
||||
res.set(res.size(), entry);
|
||||
res.set(ctx, res.size(), entry);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (val instanceof Class) {
|
||||
if (ctx == null) return null;
|
||||
else return ctx.engine.getConstructor((Class<?>)val);
|
||||
}
|
||||
|
||||
return new NativeWrapper(val);
|
||||
}
|
||||
|
||||
@@ -562,14 +567,14 @@ public class Values {
|
||||
var it = iterable.iterator();
|
||||
|
||||
try {
|
||||
var key = getMember(ctx, getMember(ctx, ctx.engine().symbolProto(), "constructor"), "iterable");
|
||||
res.defineProperty(key, new NativeFunction("", (_ctx, thisArg, args) -> fromJavaIterable(ctx, iterable)));
|
||||
var key = getMember(ctx, getMember(ctx, ctx.engine().symbolProto(), "constructor"), "iterator");
|
||||
res.defineProperty(ctx, key, new NativeFunction("", (_ctx, thisArg, args) -> thisArg));
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException e) { }
|
||||
|
||||
res.defineProperty("next", new NativeFunction("", (_ctx, _th, _args) -> {
|
||||
if (!it.hasNext()) return new ObjectValue(Map.of("done", true));
|
||||
else return new ObjectValue(Map.of("value", it.next()));
|
||||
res.defineProperty(ctx, "next", new NativeFunction("", (_ctx, _th, _args) -> {
|
||||
if (!it.hasNext()) return new ObjectValue(ctx, Map.of("done", true));
|
||||
else return new ObjectValue(ctx, Map.of("value", it.next()));
|
||||
}));
|
||||
|
||||
return res;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class EngineException extends RuntimeException {
|
||||
|
||||
private static Object err(String msg, PlaceholderProto proto) {
|
||||
var res = new ObjectValue(proto);
|
||||
res.defineProperty("message", msg);
|
||||
res.defineProperty(null, "message", msg);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public class NativeTypeRegister {
|
||||
var val = target.values.get(name);
|
||||
|
||||
if (name.equals("")) name = method.getName();
|
||||
if (!(val instanceof OverloadFunction)) target.defineProperty(name, val = new OverloadFunction(name));
|
||||
if (!(val instanceof OverloadFunction)) target.defineProperty(null, name, val = new OverloadFunction(name));
|
||||
|
||||
((OverloadFunction)val).overloads.add(Overload.fromMethod(method));
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public class NativeTypeRegister {
|
||||
else getter = new OverloadFunction("get " + name);
|
||||
|
||||
getter.overloads.add(Overload.fromMethod(method));
|
||||
target.defineProperty(name, getter, setter, true, true);
|
||||
target.defineProperty(null, name, getter, setter, true, true);
|
||||
}
|
||||
if (set != null) {
|
||||
var name = set.value();
|
||||
@@ -52,7 +52,7 @@ public class NativeTypeRegister {
|
||||
else setter = new OverloadFunction("set " + name);
|
||||
|
||||
setter.overloads.add(Overload.fromMethod(method));
|
||||
target.defineProperty(name, getter, setter, true, true);
|
||||
target.defineProperty(null, name, getter, setter, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class NativeTypeRegister {
|
||||
if (name.equals("")) name = field.getName();
|
||||
var getter = new OverloadFunction("get " + name).add(Overload.getterFromField(field));
|
||||
var setter = new OverloadFunction("set " + name).add(Overload.setterFromField(field));
|
||||
target.defineProperty(name, getter, setter, true, false);
|
||||
target.defineProperty(null, name, getter, setter, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class NativeTypeRegister {
|
||||
return ctx.engine().typeRegister().getConstr(cl);
|
||||
}));
|
||||
|
||||
target.defineProperty(name, getter, null, true, false);
|
||||
target.defineProperty(null, name, getter, null, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class OverloadFunction extends FunctionValue {
|
||||
Object _this = overload.thisArg == null ? null : Values.convert(ctx, thisArg, overload.thisArg);
|
||||
|
||||
try {
|
||||
return Values.normalize(overload.runner.run(ctx, _this, newArgs));
|
||||
return Values.normalize(ctx, overload.runner.run(ctx, _this, newArgs));
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw EngineException.ofError("The class may not be instantiated.");
|
||||
|
||||
@@ -22,13 +22,13 @@ public class GeneratorFunction extends FunctionValue {
|
||||
if (done) {
|
||||
if (inducedError != Runners.NO_RETURN) throw new EngineException(inducedError);
|
||||
var res = new ObjectValue();
|
||||
res.defineProperty("done", true);
|
||||
res.defineProperty("value", inducedReturn == Runners.NO_RETURN ? null : inducedReturn);
|
||||
res.defineProperty(ctx, "done", true);
|
||||
res.defineProperty(ctx, "value", inducedReturn == Runners.NO_RETURN ? null : inducedReturn);
|
||||
return res;
|
||||
}
|
||||
|
||||
Object res = null;
|
||||
if (inducedValue != Runners.NO_RETURN) frame.push(inducedValue);
|
||||
if (inducedValue != Runners.NO_RETURN) frame.push(ctx, inducedValue);
|
||||
frame.start(ctx);
|
||||
yielding = false;
|
||||
while (!yielding) {
|
||||
@@ -51,8 +51,8 @@ public class GeneratorFunction extends FunctionValue {
|
||||
else res = frame.pop();
|
||||
|
||||
var obj = new ObjectValue();
|
||||
obj.defineProperty("done", done);
|
||||
obj.defineProperty("value", res);
|
||||
obj.defineProperty(ctx, "done", done);
|
||||
obj.defineProperty(ctx, "value", res);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -84,11 +84,11 @@ public class GeneratorFunction extends FunctionValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(CallContext _ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
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.");
|
||||
handler.frame = new CodeFrame(thisArg, args, (CodeFunction)func);
|
||||
handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func);
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ public class Internals {
|
||||
return func.call(ctx, th, args.toArray());
|
||||
}
|
||||
@Native
|
||||
public boolean defineProp(ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(key, getter, setter, configurable, enumerable);
|
||||
public boolean defineProp(CallContext ctx, ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(ctx, key, getter, setter, configurable, enumerable);
|
||||
}
|
||||
@Native
|
||||
public boolean defineField(ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(key, val, writable, configurable, enumerable);
|
||||
public boolean defineField(CallContext ctx, ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(ctx, key, val, writable, configurable, enumerable);
|
||||
}
|
||||
|
||||
@Native
|
||||
@@ -209,7 +209,7 @@ public class Internals {
|
||||
|
||||
for (var el : list) {
|
||||
if (el instanceof Symbol && onlyString) continue;
|
||||
res.set(i++, el);
|
||||
res.set(ctx, i++, el);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -223,7 +223,7 @@ public class Internals {
|
||||
var list = Values.object(obj).keys(true);
|
||||
|
||||
for (var el : list) {
|
||||
if (el instanceof Symbol == symbols) res.set(i++, el);
|
||||
if (el instanceof Symbol == symbols) res.set(ctx, i++, el);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ public class JSON {
|
||||
if (val.isBoolean()) return val.bool();
|
||||
if (val.isString()) return val.string();
|
||||
if (val.isNumber()) return val.number();
|
||||
if (val.isList()) return ArrayValue.of(val.list().stream().map(JSON::toJS).collect(Collectors.toList()));
|
||||
if (val.isList()) return ArrayValue.of(null, val.list().stream().map(JSON::toJS).collect(Collectors.toList()));
|
||||
if (val.isMap()) {
|
||||
var res = new ObjectValue();
|
||||
for (var el : val.map().entrySet()) {
|
||||
res.defineProperty(el.getKey(), toJS(el.getValue()));
|
||||
res.defineProperty(null, el.getKey(), toJS(el.getValue()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class Map {
|
||||
return Values.fromJavaIterable(ctx, objs
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(v -> new ArrayValue(v.getKey(), v.getValue()))
|
||||
.map(v -> new ArrayValue(ctx, v.getKey(), v.getValue()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,10 +8,6 @@ import java.io.InputStreamReader;
|
||||
|
||||
import me.topchetoeu.jscript.engine.Engine;
|
||||
import me.topchetoeu.jscript.engine.modules.ModuleManager;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.parsing.Parsing;
|
||||
|
||||
public class PolyfillEngine extends Engine {
|
||||
public static String streamToString(InputStream in) {
|
||||
@@ -52,59 +48,58 @@ public class PolyfillEngine extends Engine {
|
||||
|
||||
this.modules = new ModuleManager(root);
|
||||
|
||||
exposeNamespace("Math", Math.class);
|
||||
exposeNamespace("JSON", JSON.class);
|
||||
exposeClass("Promise", Promise.class);
|
||||
exposeClass("RegExp", RegExp.class);
|
||||
exposeClass("Date", Date.class);
|
||||
exposeClass("Map", Map.class);
|
||||
exposeClass("Set", Set.class);
|
||||
// exposeNamespace("Math", Math.class);
|
||||
// exposeNamespace("JSON", JSON.class);
|
||||
// exposeClass("Promise", Promise.class);
|
||||
// exposeClass("RegExp", RegExp.class);
|
||||
// exposeClass("Date", Date.class);
|
||||
// exposeClass("Map", Map.class);
|
||||
// exposeClass("Set", Set.class);
|
||||
|
||||
global().define("Object", "Function", "String", "Number", "Boolean", "Symbol");
|
||||
global().define("Array", "require");
|
||||
global().define("Error", "SyntaxError", "TypeError", "RangeError");
|
||||
global().define("setTimeout", "setInterval", "clearTimeout", "clearInterval");
|
||||
// global().define("process", true, "trololo");
|
||||
global().define("debugger");
|
||||
// global().define("Object", "Function", "String", "Number", "Boolean", "Symbol");
|
||||
// global().define("Array", "require");
|
||||
// global().define("Error", "SyntaxError", "TypeError", "RangeError");
|
||||
// global().define("setTimeout", "setInterval", "clearTimeout", "clearInterval");
|
||||
// global().define("debugger");
|
||||
|
||||
global().define(true, new NativeFunction("measure", (ctx, thisArg, values) -> {
|
||||
var start = System.nanoTime();
|
||||
try {
|
||||
return Values.call(ctx, values[0], ctx);
|
||||
}
|
||||
finally {
|
||||
System.out.println(String.format("Function took %s ms", (System.nanoTime() - start) / 1000000.));
|
||||
}
|
||||
}));
|
||||
global().define(true, new NativeFunction("isNaN", (ctx, thisArg, args) -> {
|
||||
if (args.length == 0) return true;
|
||||
else return Double.isNaN(Values.toNumber(ctx, args[0]));
|
||||
}));
|
||||
global().define(true, new NativeFunction("log", (el, t, args) -> {
|
||||
for (var obj : args) Values.printValue(el, obj);
|
||||
System.out.println();
|
||||
return null;
|
||||
}));
|
||||
// global().define(true, new NativeFunction("measure", (ctx, thisArg, values) -> {
|
||||
// var start = System.nanoTime();
|
||||
// try {
|
||||
// return Values.call(ctx, values[0], ctx);
|
||||
// }
|
||||
// finally {
|
||||
// System.out.println(String.format("Function took %s ms", (System.nanoTime() - start) / 1000000.));
|
||||
// }
|
||||
// }));
|
||||
// global().define(true, new NativeFunction("isNaN", (ctx, thisArg, args) -> {
|
||||
// if (args.length == 0) return true;
|
||||
// else return Double.isNaN(Values.toNumber(ctx, args[0]));
|
||||
// }));
|
||||
// global().define(true, new NativeFunction("log", (el, t, args) -> {
|
||||
// for (var obj : args) Values.printValue(el, obj);
|
||||
// System.out.println();
|
||||
// return null;
|
||||
// }));
|
||||
|
||||
var scope = global().globalChild();
|
||||
scope.define("gt", true, global().obj);
|
||||
scope.define("lgt", true, scope.obj);
|
||||
scope.define("setProps", "setConstr");
|
||||
scope.define("internals", true, new Internals());
|
||||
scope.define(true, new NativeFunction("run", (ctx, thisArg, args) -> {
|
||||
var filename = (String)args[0];
|
||||
boolean pollute = args.length > 1 && args[1].equals(true);
|
||||
FunctionValue func;
|
||||
var src = resourceToString("js/" + filename);
|
||||
if (src == null) throw new RuntimeException("The source '" + filename + "' doesn't exist.");
|
||||
// var scope = global().globalChild();
|
||||
// scope.define("gt", true, global().obj);
|
||||
// scope.define("lgt", true, scope.obj);
|
||||
// scope.define("setProps", "setConstr");
|
||||
// scope.define("internals", true, new Internals());
|
||||
// scope.define(true, new NativeFunction("run", (ctx, thisArg, args) -> {
|
||||
// var filename = (String)args[0];
|
||||
// boolean pollute = args.length > 1 && args[1].equals(true);
|
||||
// FunctionValue func;
|
||||
// var src = resourceToString("js/" + filename);
|
||||
// if (src == null) throw new RuntimeException("The source '" + filename + "' doesn't exist.");
|
||||
|
||||
if (pollute) func = Parsing.compile(global(), filename, src);
|
||||
else func = Parsing.compile(scope.globalChild(), filename, src);
|
||||
// if (pollute) func = Parsing.compile(global(), filename, src);
|
||||
// else func = Parsing.compile(scope.globalChild(), filename, src);
|
||||
|
||||
func.call(ctx);
|
||||
return null;
|
||||
}));
|
||||
// func.call(ctx);
|
||||
// return null;
|
||||
// }));
|
||||
|
||||
pushMsg(false, scope.globalChild(), java.util.Map.of(), "core.js", resourceToString("js/core.js"), null);
|
||||
// pushMsg(false, scope.globalChild(), java.util.Map.of(), "core.js", resourceToString("js/core.js"), null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ public class Promise {
|
||||
}
|
||||
|
||||
@Native("resolve")
|
||||
public static Promise ofResolved(CallContext engine, Object val) {
|
||||
public static Promise ofResolved(CallContext ctx, Object val) {
|
||||
if (Values.isWrapper(val, Promise.class)) return Values.wrapper(val, Promise.class);
|
||||
var res = new Promise();
|
||||
res.fulfill(engine, val);
|
||||
res.fulfill(ctx, val);
|
||||
return res;
|
||||
}
|
||||
public static Promise ofResolved(Object val) {
|
||||
@@ -41,9 +41,9 @@ public class Promise {
|
||||
}
|
||||
|
||||
@Native("reject")
|
||||
public static Promise ofRejected(CallContext engine, Object val) {
|
||||
public static Promise ofRejected(CallContext ctx, Object val) {
|
||||
var res = new Promise();
|
||||
res.reject(engine, val);
|
||||
res.reject(ctx, val);
|
||||
return res;
|
||||
}
|
||||
public static Promise ofRejected(Object val) {
|
||||
@@ -53,7 +53,7 @@ public class Promise {
|
||||
}
|
||||
|
||||
@Native
|
||||
public static Promise any(CallContext engine, Object _promises) {
|
||||
public static Promise any(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@@ -66,17 +66,17 @@ public class Promise {
|
||||
var index = i;
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> { res.fulfill(e, args[0]); return null; }),
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
errors.set(index, args[0]);
|
||||
errors.set(ctx, index, args[0]);
|
||||
n[0]--;
|
||||
if (n[0] <= 0) res.reject(e, errors);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
else {
|
||||
res.fulfill(engine, val);
|
||||
res.fulfill(ctx, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class Promise {
|
||||
return res;
|
||||
}
|
||||
@Native
|
||||
public static Promise race(CallContext engine, Object _promises) {
|
||||
public static Promise race(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@@ -93,7 +93,7 @@ public class Promise {
|
||||
for (var i = 0; i < promises.size(); i++) {
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> { res.fulfill(e, args[0]); return null; }),
|
||||
new NativeFunction(null, (e, th, args) -> { res.reject(e, args[0]); return null; })
|
||||
);
|
||||
@@ -106,7 +106,7 @@ public class Promise {
|
||||
return res;
|
||||
}
|
||||
@Native
|
||||
public static Promise all(CallContext engine, Object _promises) {
|
||||
public static Promise all(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@@ -119,9 +119,9 @@ public class Promise {
|
||||
var index = i;
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
result.set(index, args[0]);
|
||||
result.set(ctx, index, args[0]);
|
||||
n[0]--;
|
||||
if (n[0] <= 0) res.fulfill(e, result);
|
||||
return null;
|
||||
@@ -129,17 +129,17 @@ public class Promise {
|
||||
new NativeFunction(null, (e, th, args) -> { res.reject(e, args[0]); return null; })
|
||||
);
|
||||
else {
|
||||
result.set(i, val);
|
||||
result.set(ctx, i, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n[0] <= 0) res.fulfill(engine, result);
|
||||
if (n[0] <= 0) res.fulfill(ctx, result);
|
||||
|
||||
return res;
|
||||
}
|
||||
@Native
|
||||
public static Promise allSettled(CallContext engine, Object _promises) {
|
||||
public static Promise allSettled(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@@ -152,9 +152,9 @@ public class Promise {
|
||||
var index = i;
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
result.set(index, new ObjectValue(Map.of(
|
||||
result.set(ctx, index, new ObjectValue(ctx, Map.of(
|
||||
"status", "fulfilled",
|
||||
"value", args[0]
|
||||
)));
|
||||
@@ -163,7 +163,7 @@ public class Promise {
|
||||
return null;
|
||||
}),
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
result.set(index, new ObjectValue(Map.of(
|
||||
result.set(ctx, index, new ObjectValue(ctx, Map.of(
|
||||
"status", "rejected",
|
||||
"reason", args[0]
|
||||
)));
|
||||
@@ -173,7 +173,7 @@ public class Promise {
|
||||
})
|
||||
);
|
||||
else {
|
||||
result.set(i, new ObjectValue(Map.of(
|
||||
result.set(ctx, i, new ObjectValue(ctx, Map.of(
|
||||
"status", "fulfilled",
|
||||
"value", val
|
||||
)));
|
||||
@@ -181,7 +181,7 @@ public class Promise {
|
||||
}
|
||||
}
|
||||
|
||||
if (n[0] <= 0) res.fulfill(engine, result);
|
||||
if (n[0] <= 0) res.fulfill(ctx, result);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public class RegExp {
|
||||
|
||||
for (var el : namedGroups) {
|
||||
try {
|
||||
groups.defineProperty(el, matcher.group(el));
|
||||
groups.defineProperty(null, el, matcher.group(el));
|
||||
}
|
||||
catch (IllegalArgumentException e) { }
|
||||
}
|
||||
@@ -127,23 +127,23 @@ public class RegExp {
|
||||
|
||||
|
||||
for (int i = 0; i < matcher.groupCount() + 1; i++) {
|
||||
obj.set(i, matcher.group(i));
|
||||
obj.set(null, i, matcher.group(i));
|
||||
}
|
||||
obj.defineProperty("groups", groups);
|
||||
obj.defineProperty("index", matcher.start());
|
||||
obj.defineProperty("input", str);
|
||||
obj.defineProperty(null, "groups", groups);
|
||||
obj.defineProperty(null, "index", matcher.start());
|
||||
obj.defineProperty(null, "input", str);
|
||||
|
||||
if (hasIndices) {
|
||||
var indices = new ArrayValue();
|
||||
for (int i = 0; i < matcher.groupCount() + 1; i++) {
|
||||
indices.set(i, new ArrayValue(matcher.start(i), matcher.end(i)));
|
||||
indices.set(null, i, new ArrayValue(null, matcher.start(i), matcher.end(i)));
|
||||
}
|
||||
var groupIndices = new ObjectValue();
|
||||
for (var el : namedGroups) {
|
||||
groupIndices.defineProperty(el, new ArrayValue(matcher.start(el), matcher.end(el)));
|
||||
groupIndices.defineProperty(null, el, new ArrayValue(null, matcher.start(el), matcher.end(el)));
|
||||
}
|
||||
indices.defineProperty("groups", groupIndices);
|
||||
obj.defineProperty("indices", indices);
|
||||
indices.defineProperty(null, "groups", groupIndices);
|
||||
obj.defineProperty(null, "indices", indices);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.stream.Collectors;
|
||||
import me.topchetoeu.jscript.engine.CallContext;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
@@ -44,55 +43,20 @@ public class Set {
|
||||
}
|
||||
|
||||
@Native
|
||||
public ObjectValue entries() {
|
||||
var it = objs.stream().collect(Collectors.toList()).iterator();
|
||||
|
||||
var next = new NativeFunction("next", (ctx, thisArg, args) -> {
|
||||
if (it.hasNext()) {
|
||||
var val = it.next();
|
||||
return new ObjectValue(java.util.Map.of(
|
||||
"value", new ArrayValue(val, val),
|
||||
"done", false
|
||||
));
|
||||
}
|
||||
else return new ObjectValue(java.util.Map.of("done", true));
|
||||
});
|
||||
|
||||
return new ObjectValue(java.util.Map.of("next", next));
|
||||
public ObjectValue entries(CallContext ctx) throws InterruptedException {
|
||||
return Values.fromJavaIterable(ctx, objs
|
||||
.stream()
|
||||
.map(v -> new ArrayValue(ctx, v, v))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
@Native
|
||||
public ObjectValue keys() {
|
||||
var it = objs.stream().collect(Collectors.toList()).iterator();
|
||||
|
||||
var next = new NativeFunction("next", (ctx, thisArg, args) -> {
|
||||
if (it.hasNext()) {
|
||||
var val = it.next();
|
||||
return new ObjectValue(java.util.Map.of(
|
||||
"value", val,
|
||||
"done", false
|
||||
));
|
||||
}
|
||||
else return new ObjectValue(java.util.Map.of("done", true));
|
||||
});
|
||||
|
||||
return new ObjectValue(java.util.Map.of("next", next));
|
||||
public ObjectValue keys(CallContext ctx) throws InterruptedException {
|
||||
return Values.fromJavaIterable(ctx, objs);
|
||||
}
|
||||
@Native
|
||||
public ObjectValue values() {
|
||||
var it = objs.stream().collect(Collectors.toList()).iterator();
|
||||
|
||||
var next = new NativeFunction("next", (ctx, thisArg, args) -> {
|
||||
if (it.hasNext()) {
|
||||
var val = it.next();
|
||||
return new ObjectValue(java.util.Map.of(
|
||||
"value", val,
|
||||
"done", false
|
||||
));
|
||||
}
|
||||
else return new ObjectValue(java.util.Map.of("done", true));
|
||||
});
|
||||
|
||||
return new ObjectValue(java.util.Map.of("next", next));
|
||||
public ObjectValue values(CallContext ctx) throws InterruptedException {
|
||||
return Values.fromJavaIterable(ctx, objs);
|
||||
}
|
||||
|
||||
@NativeGetter("size")
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
package me.topchetoeu.jscript.polyfills;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
|
||||
public class TypescriptEngine extends PolyfillEngine {
|
||||
private FunctionValue ts;
|
||||
|
||||
@Override
|
||||
public FunctionValue compile(GlobalScope scope, String filename, String raw) throws InterruptedException {
|
||||
if (ts != null) {
|
||||
var res = Values.array(ts.call(context(), null, filename, raw));
|
||||
var src = Values.toString(context(), res.get(0));
|
||||
var func = Values.function(res.get(1));
|
||||
|
||||
var compiled = super.compile(scope, filename, src);
|
||||
|
||||
return new NativeFunction(null, (ctx, thisArg, args) -> {
|
||||
return func.call(context(), null, compiled, thisArg, new ArrayValue(args));
|
||||
});
|
||||
}
|
||||
return super.compile(scope, filename, raw);
|
||||
}
|
||||
|
||||
public TypescriptEngine(File root) {
|
||||
super(root);
|
||||
var scope = global().globalChild();
|
||||
|
||||
var decls = new ArrayList<Object>();
|
||||
decls.add(resourceToString("dts/core.d.ts"));
|
||||
decls.add(resourceToString("dts/iterators.d.ts"));
|
||||
decls.add(resourceToString("dts/map.d.ts"));
|
||||
decls.add(resourceToString("dts/promise.d.ts"));
|
||||
decls.add(resourceToString("dts/regex.d.ts"));
|
||||
decls.add(resourceToString("dts/require.d.ts"));
|
||||
decls.add(resourceToString("dts/set.d.ts"));
|
||||
decls.add(resourceToString("dts/values/array.d.ts"));
|
||||
decls.add(resourceToString("dts/values/boolean.d.ts"));
|
||||
decls.add(resourceToString("dts/values/number.d.ts"));
|
||||
decls.add(resourceToString("dts/values/errors.d.ts"));
|
||||
decls.add(resourceToString("dts/values/function.d.ts"));
|
||||
decls.add(resourceToString("dts/values/object.d.ts"));
|
||||
decls.add(resourceToString("dts/values/string.d.ts"));
|
||||
decls.add(resourceToString("dts/values/symbol.d.ts"));
|
||||
|
||||
scope.define("libs", true, ArrayValue.of(decls));
|
||||
scope.define(true, new NativeFunction("init", (el, t, args) -> {
|
||||
ts = Values.function(args[0]);
|
||||
return null;
|
||||
}));
|
||||
|
||||
pushMsg(false, scope, Map.of(), "bootstrap.js", resourceToString("js/bootstrap.js"), null);
|
||||
}
|
||||
}
|
||||
package me.topchetoeu.jscript.polyfills;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
|
||||
public class TypescriptEngine extends PolyfillEngine {
|
||||
private FunctionValue ts;
|
||||
|
||||
@Override
|
||||
public FunctionValue compile(GlobalScope scope, String filename, String raw) throws InterruptedException {
|
||||
if (ts != null) {
|
||||
var res = Values.array(ts.call(context(), null, filename, raw));
|
||||
var src = Values.toString(context(), res.get(0));
|
||||
var func = Values.function(res.get(1));
|
||||
|
||||
var compiled = super.compile(scope, filename, src);
|
||||
|
||||
return new NativeFunction(null, (ctx, thisArg, args) -> {
|
||||
return func.call(context(), null, compiled, thisArg, new ArrayValue(args));
|
||||
});
|
||||
}
|
||||
return super.compile(scope, filename, raw);
|
||||
}
|
||||
|
||||
public TypescriptEngine(File root) {
|
||||
super(root);
|
||||
var scope = global().globalChild();
|
||||
|
||||
var decls = new ArrayList<Object>();
|
||||
decls.add(resourceToString("dts/core.d.ts"));
|
||||
decls.add(resourceToString("dts/iterators.d.ts"));
|
||||
decls.add(resourceToString("dts/map.d.ts"));
|
||||
decls.add(resourceToString("dts/promise.d.ts"));
|
||||
decls.add(resourceToString("dts/regex.d.ts"));
|
||||
decls.add(resourceToString("dts/require.d.ts"));
|
||||
decls.add(resourceToString("dts/set.d.ts"));
|
||||
decls.add(resourceToString("dts/values/array.d.ts"));
|
||||
decls.add(resourceToString("dts/values/boolean.d.ts"));
|
||||
decls.add(resourceToString("dts/values/number.d.ts"));
|
||||
decls.add(resourceToString("dts/values/errors.d.ts"));
|
||||
decls.add(resourceToString("dts/values/function.d.ts"));
|
||||
decls.add(resourceToString("dts/values/object.d.ts"));
|
||||
decls.add(resourceToString("dts/values/string.d.ts"));
|
||||
decls.add(resourceToString("dts/values/symbol.d.ts"));
|
||||
|
||||
scope.define("libs", true, ArrayValue.of(decls));
|
||||
scope.define(true, new NativeFunction("init", (el, t, args) -> {
|
||||
ts = Values.function(args[0]);
|
||||
return null;
|
||||
}));
|
||||
|
||||
pushMsg(false, scope, Map.of(), "bootstrap.js", resourceToString("js/bootstrap.js"), null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user