From 0e04459fe742aa6b130988fe1e2854e75708bf07 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Sat, 9 Sep 2023 17:32:46 +0300 Subject: [PATCH] feat: implement new system for context tracking --- lib/core.ts | 11 +- lib/map.ts | 11 +- lib/set.ts | 9 +- lib/values/array.ts | 12 +- lib/values/function.ts | 4 +- lib/values/object.ts | 2 +- lib/values/string.ts | 28 ++--- lib/values/symbol.ts | 4 +- src/me/topchetoeu/jscript/Main.java | 26 ++-- .../compilation/CompoundStatement.java | 2 +- .../jscript/compilation/Instruction.java | 2 +- .../compilation/values/CallStatement.java | 4 +- .../compilation/values/NewStatement.java | 2 +- .../values/OperationStatement.java | 2 +- .../jscript/engine/BreakpointData.java | 13 -- .../jscript/engine/CallContext.java | 67 ---------- src/me/topchetoeu/jscript/engine/Context.java | 11 ++ .../jscript/engine/DebugCommand.java | 8 -- src/me/topchetoeu/jscript/engine/Engine.java | 32 ++--- ...{Environment.java => FunctionContext.java} | 10 +- .../jscript/engine/MessageContext.java | 33 +++++ .../jscript/engine/frame/CodeFrame.java | 74 +++-------- .../jscript/engine/frame/Runners.java | 116 +++++++++--------- .../jscript/engine/scope/GlobalScope.java | 12 +- .../engine/scope/LocalScopeRecord.java | 4 +- .../jscript/engine/scope/ValueVariable.java | 6 +- .../jscript/engine/scope/Variable.java | 6 +- .../jscript/engine/values/ArrayValue.java | 16 +-- .../jscript/engine/values/CodeFunction.java | 25 +--- .../jscript/engine/values/FunctionValue.java | 14 +-- .../jscript/engine/values/NativeFunction.java | 6 +- .../jscript/engine/values/NativeWrapper.java | 6 +- .../jscript/engine/values/ObjectValue.java | 68 +++++----- .../jscript/engine/values/Values.java | 88 ++++++------- .../jscript/exceptions/EngineException.java | 11 +- .../filesystem/FilesystemRegister.java | 7 -- .../topchetoeu/jscript/interop/Overload.java | 4 +- .../jscript/interop/OverloadFunction.java | 6 +- .../topchetoeu/jscript/parsing/ParseRes.java | 4 +- .../topchetoeu/jscript/parsing/Parsing.java | 10 +- src/me/topchetoeu/jscript/polyfills/Date.java | 36 +++--- .../jscript/polyfills/GeneratorFunction.java | 18 +-- .../jscript/polyfills/Internals.java | 39 +++--- src/me/topchetoeu/jscript/polyfills/JSON.java | 8 +- src/me/topchetoeu/jscript/polyfills/Math.java | 70 +++++------ .../jscript/polyfills/PolyfillEngine.java- | 105 ---------------- .../topchetoeu/jscript/polyfills/RegExp.java | 14 +-- .../jscript/polyfills/TypescriptEngine.java- | 61 --------- 48 files changed, 435 insertions(+), 692 deletions(-) delete mode 100644 src/me/topchetoeu/jscript/engine/BreakpointData.java delete mode 100644 src/me/topchetoeu/jscript/engine/CallContext.java create mode 100644 src/me/topchetoeu/jscript/engine/Context.java delete mode 100644 src/me/topchetoeu/jscript/engine/DebugCommand.java rename src/me/topchetoeu/jscript/engine/{Environment.java => FunctionContext.java} (91%) create mode 100644 src/me/topchetoeu/jscript/engine/MessageContext.java delete mode 100644 src/me/topchetoeu/jscript/filesystem/FilesystemRegister.java delete mode 100644 src/me/topchetoeu/jscript/polyfills/PolyfillEngine.java- delete mode 100644 src/me/topchetoeu/jscript/polyfills/TypescriptEngine.java- diff --git a/lib/core.ts b/lib/core.ts index f28ad57..4e1b9d9 100644 --- a/lib/core.ts +++ b/lib/core.ts @@ -29,9 +29,14 @@ interface Internals { extensible(obj: object): boolean; sort(arr: any[], comaprator: (a: any, b: any) => number): void; + + constructor: { + log(...args: any[]): void; + } } -var env: Environment = arguments[0], internals: Internals = arguments[1]; +// @ts-ignore +var env: Environment = arguments[0], internals: Internals = arguments[1], log = internals.constructor.log; try { run('values/object'); @@ -47,7 +52,9 @@ try { run('set'); run('regex'); run('timeout'); - + + env.global.log = log; + log('Loaded polyfills!'); } catch (e: any) { diff --git a/lib/map.ts b/lib/map.ts index f318687..b7745af 100644 --- a/lib/map.ts +++ b/lib/map.ts @@ -1,10 +1,11 @@ define("map", () => { const syms = { values: internals.symbol('Map.values') } as { readonly values: unique symbol }; + const Object = env.global.Object; class Map { [syms.values]: any = {}; - public [Symbol.iterator](): IterableIterator<[KeyT, ValueT]> { + public [env.global.Symbol.iterator](): IterableIterator<[KeyT, ValueT]> { return this.entries(); } @@ -28,7 +29,7 @@ define("map", () => { if (i >= keys.length) return { done: true }; else return { done: false, value: [ keys[i], this[syms.values][keys[i++]] ] } }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } } } public keys(): IterableIterator { @@ -40,7 +41,7 @@ define("map", () => { if (i >= keys.length) return { done: true }; else return { done: false, value: keys[i] } }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } } } public values(): IterableIterator { @@ -52,7 +53,7 @@ define("map", () => { if (i >= keys.length) return { done: true }; else return { done: false, value: this[syms.values][keys[i++]] } }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } } } @@ -80,7 +81,7 @@ define("map", () => { } public constructor(iterable: Iterable<[KeyT, ValueT]>) { - const it = iterable[Symbol.iterator](); + const it = iterable[env.global.Symbol.iterator](); for (let el = it.next(); !el.done; el = it.next()) { this[syms.values][el.value[0]] = el.value[1]; diff --git a/lib/set.ts b/lib/set.ts index 7bf9a19..a0ac277 100644 --- a/lib/set.ts +++ b/lib/set.ts @@ -1,10 +1,11 @@ define("set", () => { const syms = { values: internals.symbol('Map.values') } as { readonly values: unique symbol }; + const Object = env.global.Object; class Set { [syms.values]: any = {}; - public [Symbol.iterator](): IterableIterator<[T, T]> { + public [env.global.Symbol.iterator](): IterableIterator<[T, T]> { return this.entries(); } @@ -28,7 +29,7 @@ define("set", () => { if (i >= keys.length) return { done: true }; else return { done: false, value: [ keys[i], keys[i] ] } }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } } } public keys(): IterableIterator { @@ -40,7 +41,7 @@ define("set", () => { if (i >= keys.length) return { done: true }; else return { done: false, value: keys[i] } }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } } } public values(): IterableIterator { @@ -68,7 +69,7 @@ define("set", () => { } public constructor(iterable: Iterable) { - const it = iterable[Symbol.iterator](); + const it = iterable[env.global.Symbol.iterator](); for (let el = it.next(); !el.done; el = it.next()) { this[syms.values][el.value] = undefined; diff --git a/lib/values/array.ts b/lib/values/array.ts index 9eea6d7..12928ba 100644 --- a/lib/values/array.ts +++ b/lib/values/array.ts @@ -16,14 +16,14 @@ define("values/array", () => { } as ArrayConstructor; env.setProto('array', Array.prototype); - (Array.prototype as any)[Symbol.typeName] = "Array"; + (Array.prototype as any)[env.global.Symbol.typeName] = "Array"; setConstr(Array.prototype, Array); setProps(Array.prototype, { - [Symbol.iterator]: function() { + [env.global.Symbol.iterator]: function() { return this.values(); }, - [Symbol.typeName]: "Array", + [env.global.Symbol.typeName]: "Array", values() { var i = 0; @@ -35,7 +35,7 @@ define("values/array", () => { } return { done: true, value: undefined }; }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } }; }, keys() { @@ -48,7 +48,7 @@ define("values/array", () => { } return { done: true, value: undefined }; }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } }; }, entries() { @@ -61,7 +61,7 @@ define("values/array", () => { } return { done: true, value: undefined }; }, - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } }; }, concat() { diff --git a/lib/values/function.ts b/lib/values/function.ts index c49a4f2..4a161d6 100644 --- a/lib/values/function.ts +++ b/lib/values/function.ts @@ -117,7 +117,7 @@ define("values/function", () => { }, return: (value) => new Promise((res, rej) => next(res, rej, 'ret', value)), throw: (value) => new Promise((res, rej) => next(res, rej, 'err', value)), - [Symbol.asyncIterator]() { return this; } + [env.global.Symbol.asyncIterator]() { return this; } } } }, @@ -131,7 +131,7 @@ define("values/function", () => { next: (...args) => internals.apply(it.next, it, args), return: (val) => internals.apply(it.next, it, [val]), throw: (val) => internals.apply(it.next, it, [val]), - [Symbol.iterator]() { return this; } + [env.global.Symbol.iterator]() { return this; } } } } diff --git a/lib/values/object.ts b/lib/values/object.ts index 277decd..475e4da 100644 --- a/lib/values/object.ts +++ b/lib/values/object.ts @@ -216,7 +216,7 @@ define("values/object", () => { return this; }, toString() { - return '[object ' + (this[Symbol.typeName] ?? 'Unknown') + ']'; + return '[object ' + (this[env.global.Symbol.typeName] ?? 'Unknown') + ']'; }, hasOwnProperty(key) { return Object.hasOwn(this, key); diff --git a/lib/values/string.ts b/lib/values/string.ts index b1af549..bfce164 100644 --- a/lib/values/string.ts +++ b/lib/values/string.ts @@ -142,9 +142,9 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof term[Symbol.search] !== 'function') term = RegExp.escape(term); + if (typeof term[env.global.Symbol.search] !== 'function') term = RegExp.escape(term); - return term[Symbol.search](this, false, start); + return term[env.global.Symbol.search](this, false, start); }, lastIndexOf(term: any, start) { if (typeof this !== 'string') { @@ -152,9 +152,9 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof term[Symbol.search] !== 'function') term = RegExp.escape(term); + if (typeof term[env.global.Symbol.search] !== 'function') term = RegExp.escape(term); - return term[Symbol.search](this, true, start); + return term[env.global.Symbol.search](this, true, start); }, includes(term, start) { return this.indexOf(term, start) >= 0; @@ -166,9 +166,9 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof pattern[Symbol.replace] !== 'function') pattern = RegExp.escape(pattern); + if (typeof pattern[env.global.Symbol.replace] !== 'function') pattern = RegExp.escape(pattern); - return pattern[Symbol.replace](this, val); + return pattern[env.global.Symbol.replace](this, val); }, replaceAll(pattern: any, val) { if (typeof this !== 'string') { @@ -176,10 +176,10 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof pattern[Symbol.replace] !== 'function') pattern = RegExp.escape(pattern, "g"); + if (typeof pattern[env.global.Symbol.replace] !== 'function') pattern = RegExp.escape(pattern, "g"); if (pattern instanceof RegExp && !pattern.global) pattern = new pattern.constructor(pattern.source, pattern.flags + "g"); - return pattern[Symbol.replace](this, val); + return pattern[env.global.Symbol.replace](this, val); }, match(pattern: any) { @@ -188,9 +188,9 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof pattern[Symbol.match] !== 'function') pattern = RegExp.escape(pattern); + if (typeof pattern[env.global.Symbol.match] !== 'function') pattern = RegExp.escape(pattern); - return pattern[Symbol.match](this); + return pattern[env.global.Symbol.match](this); }, matchAll(pattern: any) { if (typeof this !== 'string') { @@ -198,10 +198,10 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof pattern[Symbol.match] !== 'function') pattern = RegExp.escape(pattern, "g"); + if (typeof pattern[env.global.Symbol.match] !== 'function') pattern = RegExp.escape(pattern, "g"); if (pattern instanceof RegExp && !pattern.global) pattern = new pattern.constructor(pattern.source, pattern.flags + "g"); - return pattern[Symbol.match](this); + return pattern[env.global.Symbol.match](this); }, split(pattern: any, lim, sensible) { @@ -210,9 +210,9 @@ define("values/string", () => { else throw new Error('This function may be used only with primitive or object strings.'); } - if (typeof pattern[Symbol.split] !== 'function') pattern = RegExp.escape(pattern, "g"); + if (typeof pattern[env.global.Symbol.split] !== 'function') pattern = RegExp.escape(pattern, "g"); - return pattern[Symbol.split](this, lim, sensible); + return pattern[env.global.Symbol.split](this, lim, sensible); }, slice(start, end) { if (typeof this !== 'string') { diff --git a/lib/values/symbol.ts b/lib/values/symbol.ts index 4e47c16..64b4d5e 100644 --- a/lib/values/symbol.ts +++ b/lib/values/symbol.ts @@ -31,6 +31,6 @@ define("values/symbol", () => { asyncIterator: Symbol('Symbol.asyncIterator') as any, }); - env.global.Object.defineProperty(Object.prototype, Symbol.typeName, { value: 'Object' }); - env.global.Object.defineProperty(env.global, Symbol.typeName, { value: 'Window' }); + internals.defineField(env.global.Object.prototype, Symbol.typeName, 'Object', false, false, false); + internals.defineField(env.global, Symbol.typeName, 'Window', false, false, false); }); \ No newline at end of file diff --git a/src/me/topchetoeu/jscript/Main.java b/src/me/topchetoeu/jscript/Main.java index 7fe117b..9de34f3 100644 --- a/src/me/topchetoeu/jscript/Main.java +++ b/src/me/topchetoeu/jscript/Main.java @@ -6,12 +6,11 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Map; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.MessageContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Engine; -import me.topchetoeu.jscript.engine.Environment; -import me.topchetoeu.jscript.engine.values.NativeFunction; +import me.topchetoeu.jscript.engine.FunctionContext; import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.events.Observer; import me.topchetoeu.jscript.exceptions.EngineException; @@ -22,7 +21,7 @@ import me.topchetoeu.jscript.polyfills.Internals; public class Main { static Thread task; static Engine engine; - static Environment env; + static FunctionContext env; public static String streamToString(InputStream in) { try { @@ -59,7 +58,7 @@ public class Main { try { try { if (err instanceof EngineException) { - System.out.println("Uncaught " + ((EngineException)err).toString(new CallContext(engine, env))); + System.out.println("Uncaught " + ((EngineException)err).toString(new Context(null, new MessageContext(engine)))); } else if (err instanceof SyntaxException) { System.out.println("Syntax error:" + ((SyntaxException)err).msg); @@ -86,7 +85,8 @@ public class Main { System.out.println(String.format("Running %s v%s by %s", Metadata.NAME, Metadata.VERSION, Metadata.AUTHOR)); var in = new BufferedReader(new InputStreamReader(System.in)); engine = new Engine(); - env = new Environment(null, null, null); + env = new FunctionContext(null, null, null); + var builderEnv = new FunctionContext(null, new NativeTypeRegister(), null); var exited = new boolean[1]; env.global.define("exit", ctx -> { @@ -103,16 +103,8 @@ public class Main { throw new EngineException("Couldn't open do.js"); } }); - env.global.define(true, new NativeFunction("log", (el, t, _args) -> { - for (var obj : _args) Values.printValue(el, obj); - System.out.println(); - return null; - })); - var builderEnv = env.child(); - builderEnv.wrappersProvider = new NativeTypeRegister(); - - engine.pushMsg(false, Map.of(), builderEnv, "core.js", resourceToString("js/core.js"), null, env, new Internals()); + engine.pushMsg(false, new Context(builderEnv, new MessageContext(engine)), "core.js", resourceToString("js/core.js"), null, env, new Internals()).toObservable().on(valuePrinter); task = engine.start(); var reader = new Thread(() -> { @@ -122,7 +114,7 @@ public class Main { var raw = in.readLine(); if (raw == null) break; - engine.pushMsg(false, Map.of(), env, "", raw, null).toObservable().once(valuePrinter); + engine.pushMsg(false, new Context(env, new MessageContext(engine)), "", raw, null).toObservable().once(valuePrinter); } catch (EngineException e) { try { diff --git a/src/me/topchetoeu/jscript/compilation/CompoundStatement.java b/src/me/topchetoeu/jscript/compilation/CompoundStatement.java index d85bbe6..b5054c3 100644 --- a/src/me/topchetoeu/jscript/compilation/CompoundStatement.java +++ b/src/me/topchetoeu/jscript/compilation/CompoundStatement.java @@ -70,7 +70,7 @@ public class CompoundStatement extends Statement { else return new CompoundStatement(loc(), res.toArray(Statement[]::new)); } - public CompoundStatement(Location loc, Statement... statements) { + public CompoundStatement(Location loc, Statement ...statements) { super(loc); this.statements = statements; } diff --git a/src/me/topchetoeu/jscript/compilation/Instruction.java b/src/me/topchetoeu/jscript/compilation/Instruction.java index 6e3be1c..b0f66a0 100644 --- a/src/me/topchetoeu/jscript/compilation/Instruction.java +++ b/src/me/topchetoeu/jscript/compilation/Instruction.java @@ -129,7 +129,7 @@ public class Instruction { return params[i].equals(arg); } - private Instruction(Location location, Type type, Object... params) { + private Instruction(Location location, Type type, Object ...params) { this.location = location; this.type = type; this.params = params; diff --git a/src/me/topchetoeu/jscript/compilation/values/CallStatement.java b/src/me/topchetoeu/jscript/compilation/values/CallStatement.java index 5a9f33c..de1c495 100644 --- a/src/me/topchetoeu/jscript/compilation/values/CallStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/CallStatement.java @@ -31,12 +31,12 @@ public class CallStatement extends Statement { target.add(Instruction.call(args.length).locate(loc()).setDebug(true)); } - public CallStatement(Location loc, Statement func, Statement... args) { + public CallStatement(Location loc, Statement func, Statement ...args) { super(loc); this.func = func; this.args = args; } - public CallStatement(Location loc, Statement obj, Object key, Statement... args) { + public CallStatement(Location loc, Statement obj, Object key, Statement ...args) { super(loc); this.func = new IndexStatement(loc, obj, new ConstantStatement(loc, key)); this.args = args; diff --git a/src/me/topchetoeu/jscript/compilation/values/NewStatement.java b/src/me/topchetoeu/jscript/compilation/values/NewStatement.java index c325429..3b5d1d8 100644 --- a/src/me/topchetoeu/jscript/compilation/values/NewStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/NewStatement.java @@ -24,7 +24,7 @@ public class NewStatement extends Statement { target.add(Instruction.callNew(args.length).locate(loc()).setDebug(true)); } - public NewStatement(Location loc, Statement func, Statement... args) { + public NewStatement(Location loc, Statement func, Statement ...args) { super(loc); this.func = func; this.args = args; diff --git a/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java b/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java index ab56757..1723429 100644 --- a/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java @@ -63,7 +63,7 @@ public class OperationStatement extends Statement { } - public OperationStatement(Location loc, Operation operation, Statement... args) { + public OperationStatement(Location loc, Operation operation, Statement ...args) { super(loc); this.operation = operation; this.args = args; diff --git a/src/me/topchetoeu/jscript/engine/BreakpointData.java b/src/me/topchetoeu/jscript/engine/BreakpointData.java deleted file mode 100644 index 5e68ec1..0000000 --- a/src/me/topchetoeu/jscript/engine/BreakpointData.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.topchetoeu.jscript.engine; - -import me.topchetoeu.jscript.Location; - -public class BreakpointData { - public final Location loc; - public final CallContext ctx; - - public BreakpointData(Location loc, CallContext ctx) { - this.loc = loc; - this.ctx = ctx; - } -} \ No newline at end of file diff --git a/src/me/topchetoeu/jscript/engine/CallContext.java b/src/me/topchetoeu/jscript/engine/CallContext.java deleted file mode 100644 index e62bd12..0000000 --- a/src/me/topchetoeu/jscript/engine/CallContext.java +++ /dev/null @@ -1,67 +0,0 @@ -package me.topchetoeu.jscript.engine; - -import java.util.Collections; -import java.util.Hashtable; -import java.util.Map; - -@SuppressWarnings("unchecked") -public class CallContext { - public static final class DataKey {} - - public final Engine engine; - public Environment environment; - private final Map, Object> data; - - public Map, Object> data() { return Collections.unmodifiableMap(data); } - - public CallContext copy() { - return new CallContext(engine, environment).mergeData(data); - } - - public CallContext mergeData(Map, Object> objs) { - data.putAll(objs); - return this; - } - public CallContext setData(DataKey key, T val) { - if (val == null) data.remove(key); - else data.put(key, val); - return this; - } - public T addData(DataKey key, T val) { - if (data.containsKey(key)) return (T)data.get(key); - else { - if (val == null) data.remove(key); - else data.put(key, val); - return val; - } - } - public T getData(DataKey key) { - return getData(key, null); - } - public T getData(DataKey key, T defaultVal) { - if (!hasData(key)) return defaultVal; - else return (T)data.get(key); - } - public boolean hasData(DataKey key) { return data.containsKey(key); } - - public CallContext changeData(DataKey key, int n, int start) { - return setData(key, getData(key, start) + n); - } - public CallContext changeData(DataKey key, int n) { - return changeData(key, n, 0); - } - public CallContext changeData(DataKey key) { - return changeData(key, 1, 0); - } - - public CallContext(Engine engine, Environment env) { - this.engine = engine; - this.data = new Hashtable<>(); - this.environment = env; - } - public CallContext(CallContext parent, Environment env) { - this.engine = parent.engine; - this.data = parent.data; - this.environment = env; - } -} diff --git a/src/me/topchetoeu/jscript/engine/Context.java b/src/me/topchetoeu/jscript/engine/Context.java new file mode 100644 index 0000000..adcc37a --- /dev/null +++ b/src/me/topchetoeu/jscript/engine/Context.java @@ -0,0 +1,11 @@ +package me.topchetoeu.jscript.engine; + +public class Context { + public final FunctionContext function; + public final MessageContext message; + + public Context(FunctionContext funcCtx, MessageContext msgCtx) { + this.function = funcCtx; + this.message = msgCtx; + } +} diff --git a/src/me/topchetoeu/jscript/engine/DebugCommand.java b/src/me/topchetoeu/jscript/engine/DebugCommand.java deleted file mode 100644 index 1afb346..0000000 --- a/src/me/topchetoeu/jscript/engine/DebugCommand.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.topchetoeu.jscript.engine; - -public enum DebugCommand { - NORMAL, - STEP_OVER, - STEP_OUT, - STEP_INTO, -} \ No newline at end of file diff --git a/src/me/topchetoeu/jscript/engine/Engine.java b/src/me/topchetoeu/jscript/engine/Engine.java index 917d3db..e98e000 100644 --- a/src/me/topchetoeu/jscript/engine/Engine.java +++ b/src/me/topchetoeu/jscript/engine/Engine.java @@ -3,7 +3,6 @@ package me.topchetoeu.jscript.engine; import java.util.Map; import java.util.concurrent.LinkedBlockingDeque; -import me.topchetoeu.jscript.engine.CallContext.DataKey; import me.topchetoeu.jscript.engine.values.FunctionValue; import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.events.Awaitable; @@ -15,16 +14,19 @@ public class Engine { private class UncompiledFunction extends FunctionValue { public final String filename; public final String raw; + public final FunctionContext ctx; @Override - public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException { + public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { + ctx = new Context(this.ctx, ctx.message); return compile(ctx, filename, raw).call(ctx, thisArg, args); } - public UncompiledFunction(String filename, String raw) { + public UncompiledFunction(FunctionContext ctx, String filename, String raw) { super(filename, 0); this.filename = filename; this.raw = raw; + this.ctx = ctx; } } @@ -32,14 +34,12 @@ public class Engine { public final FunctionValue func; public final Object thisArg; public final Object[] args; - public final Map, Object> data; public final DataNotifier notifier = new DataNotifier<>(); - public final Environment env; + public final MessageContext ctx; - public Task(Environment env, FunctionValue func, Map, Object> data, Object thisArg, Object[] args) { - this.env = env; + public Task(MessageContext ctx, FunctionValue func, Object thisArg, Object[] args) { + this.ctx = ctx; this.func = func; - this.data = data; this.thisArg = thisArg; this.args = args; } @@ -60,7 +60,7 @@ public class Engine { private void runTask(Task task) throws InterruptedException { try { - task.notifier.next(task.func.call(new CallContext(this, task.env).mergeData(task.data), task.thisArg, task.args)); + task.notifier.next(task.func.call(new Context(null, new MessageContext(this)), task.thisArg, task.args)); } catch (InterruptedException e) { task.notifier.error(new RuntimeException(e)); @@ -110,19 +110,19 @@ public class Engine { return this.thread != null; } - public Awaitable pushMsg(boolean micro, Map, Object> data, Environment env, FunctionValue func, Object thisArg, Object... args) { - var msg = new Task(env, func, data, thisArg, args); + public Awaitable pushMsg(boolean micro, MessageContext ctx, FunctionValue func, Object thisArg, Object ...args) { + var msg = new Task(ctx, func, thisArg, args); if (micro) microTasks.addLast(msg); else macroTasks.addLast(msg); return msg.notifier; } - public Awaitable pushMsg(boolean micro, Map, Object> data, Environment env, String filename, String raw, Object thisArg, Object... args) { - return pushMsg(micro, data, env, new UncompiledFunction(filename, raw), thisArg, args); + public Awaitable pushMsg(boolean micro, Context ctx, String filename, String raw, Object thisArg, Object ...args) { + return pushMsg(micro, ctx.message, new UncompiledFunction(ctx.function, filename, raw), thisArg, args); } - public FunctionValue compile(CallContext ctx, String filename, String raw) throws InterruptedException { - var res = Values.toString(ctx, ctx.environment.compile.call(ctx, null, raw, filename)); - return Parsing.compile(ctx.environment, filename, res); + public FunctionValue compile(Context ctx, String filename, String raw) throws InterruptedException { + var res = Values.toString(ctx, ctx.function.compile.call(ctx, null, raw, filename)); + return Parsing.compile(ctx.function, filename, res); } // public Engine() { diff --git a/src/me/topchetoeu/jscript/engine/Environment.java b/src/me/topchetoeu/jscript/engine/FunctionContext.java similarity index 91% rename from src/me/topchetoeu/jscript/engine/Environment.java rename to src/me/topchetoeu/jscript/engine/FunctionContext.java index 8224833..e21b7d9 100644 --- a/src/me/topchetoeu/jscript/engine/Environment.java +++ b/src/me/topchetoeu/jscript/engine/FunctionContext.java @@ -11,7 +11,7 @@ import me.topchetoeu.jscript.interop.Native; import me.topchetoeu.jscript.interop.NativeGetter; import me.topchetoeu.jscript.interop.NativeSetter; -public class Environment { +public class FunctionContext { private HashMap prototypes = new HashMap<>(); public GlobalScope global; public WrappersProvider wrappersProvider; @@ -48,21 +48,21 @@ public class Environment { } @Native - public Environment fork() { - var res = new Environment(compile, wrappersProvider, global); + public FunctionContext fork() { + var res = new FunctionContext(compile, wrappersProvider, global); res.regexConstructor = regexConstructor; res.prototypes = new HashMap<>(prototypes); return res; } @Native - public Environment child() { + public FunctionContext child() { var res = fork(); res.global = res.global.globalChild(); return res; } - public Environment(FunctionValue compile, WrappersProvider nativeConverter, GlobalScope global) { + public FunctionContext(FunctionValue compile, WrappersProvider nativeConverter, GlobalScope global) { if (compile == null) compile = new NativeFunction("compile", (ctx, thisArg, args) -> args.length == 0 ? "" : args[0]); if (nativeConverter == null) nativeConverter = new WrappersProvider() { public ObjectValue getConstr(Class obj) { diff --git a/src/me/topchetoeu/jscript/engine/MessageContext.java b/src/me/topchetoeu/jscript/engine/MessageContext.java new file mode 100644 index 0000000..2ac19b4 --- /dev/null +++ b/src/me/topchetoeu/jscript/engine/MessageContext.java @@ -0,0 +1,33 @@ +package me.topchetoeu.jscript.engine; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import me.topchetoeu.jscript.engine.frame.CodeFrame; +import me.topchetoeu.jscript.exceptions.EngineException; + +public class MessageContext { + public final Engine engine; + + private final ArrayList frames = new ArrayList<>(); + public int maxStackFrames = 1000; + + public List frames() { return Collections.unmodifiableList(frames); } + + public MessageContext pushFrame(CodeFrame frame) { + this.frames.add(frame); + if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!"); + return this; + } + public boolean popFrame(CodeFrame frame) { + if (this.frames.size() == 0) return false; + if (this.frames.get(this.frames.size() - 1) != frame) return false; + this.frames.remove(this.frames.size() - 1); + return true; + } + + public MessageContext(Engine engine) { + this.engine = engine; + } +} diff --git a/src/me/topchetoeu/jscript/engine/frame/CodeFrame.java b/src/me/topchetoeu/jscript/engine/frame/CodeFrame.java index 5a6e188..aeaf264 100644 --- a/src/me/topchetoeu/jscript/engine/frame/CodeFrame.java +++ b/src/me/topchetoeu/jscript/engine/frame/CodeFrame.java @@ -4,9 +4,7 @@ import java.util.ArrayList; import java.util.List; import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.engine.CallContext; -import me.topchetoeu.jscript.engine.DebugCommand; -import me.topchetoeu.jscript.engine.CallContext.DataKey; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.scope.LocalScope; import me.topchetoeu.jscript.engine.scope.ValueVariable; import me.topchetoeu.jscript.engine.values.ArrayValue; @@ -44,11 +42,6 @@ public class CodeFrame { } } - public static final DataKey STACK_N_KEY = new DataKey<>(); - public static final DataKey MAX_STACK_KEY = new DataKey<>(); - public static final DataKey STOP_AT_START_KEY = new DataKey<>(); - public static final DataKey STEPPING_TROUGH_KEY = new DataKey<>(); - public final LocalScope scope; public final Object thisArg; public final Object[] args; @@ -59,7 +52,6 @@ public class CodeFrame { public int stackPtr = 0; public int codePtr = 0; public boolean jumpFlag = false; - private DebugCommand debugCmd = null; private Location prevLoc = null; public void addTry(int n, int catchN, int finallyN) { @@ -92,7 +84,7 @@ public class CodeFrame { return res; } - public void push(CallContext ctx, Object val) { + public void push(Context ctx, Object val) { if (stack.length <= stackPtr) { var newStack = new Object[stack.length * 2]; System.arraycopy(stack, 0, newStack, 0, stack.length); @@ -101,21 +93,7 @@ public class CodeFrame { stack[stackPtr++] = Values.normalize(ctx, val); } - public void start(CallContext ctx) { - if (ctx.getData(STACK_N_KEY, 0) >= ctx.addData(MAX_STACK_KEY, 10000)) throw EngineException.ofRange("Stack overflow!"); - ctx.changeData(STACK_N_KEY); - - // var debugState = ctx.getData(Engine.DEBUG_STATE_KEY); - // if (debugState != null) debugState.pushFrame(this); - } - public void end(CallContext ctx) { - ctx.changeData(STACK_N_KEY, -1); - - // var debugState = ctx.getData(Engine.DEBUG_STATE_KEY); - // if (debugState != null) debugState.popFrame(); - } - - private Object nextNoTry(CallContext ctx) throws InterruptedException { + private Object nextNoTry(Context ctx) throws InterruptedException { if (Thread.currentThread().isInterrupted()) throw new InterruptedException(); if (codePtr < 0 || codePtr >= function.body.length) return null; @@ -124,39 +102,16 @@ public class CodeFrame { var loc = instr.location; if (loc != null) prevLoc = loc; - // var debugState = ctx.getData(Engine.DEBUG_STATE_KEY); - // if (debugCmd == null) { - // if (ctx.getData(STOP_AT_START_KEY, false)) debugCmd = DebugCommand.STEP_OVER; - // else debugCmd = DebugCommand.NORMAL; - - // if (debugState != null) debugState.pushFrame(this); - // } - - // if (debugState != null && loc != null) { - // if ( - // instr.type == Type.NOP && instr.match("debug") || debugState.breakpoints.contains(loc) || ( - // ctx.getData(STEPPING_TROUGH_KEY, false) && - // (debugCmd == DebugCommand.STEP_INTO || debugCmd == DebugCommand.STEP_OVER) - // ) - // ) { - // ctx.setData(STEPPING_TROUGH_KEY, true); - - // debugState.breakpointNotifier.next(new BreakpointData(loc, ctx)); - // debugCmd = debugState.commandNotifier.toAwaitable().await(); - // if (debugCmd == DebugCommand.NORMAL) ctx.setData(STEPPING_TROUGH_KEY, false); - // } - // } - try { this.jumpFlag = false; - return Runners.exec(ctx, debugCmd, instr, this); + return Runners.exec(ctx, instr, this); } catch (EngineException e) { throw e.add(function.name, prevLoc); } } - public Object next(CallContext ctx, Object prevReturn, Object prevError) throws InterruptedException { + public Object next(Context ctx, Object prevReturn, Object prevError) throws InterruptedException { TryCtx tryCtx = null; if (prevError != Runners.NO_RETURN) prevReturn = Runners.NO_RETURN; @@ -256,6 +211,7 @@ public class CodeFrame { catch (EngineException e) { if (tryCtx.hasCatch) { tryCtx.state = TryCtx.STATE_CATCH; + tryCtx.err = e; codePtr = tryCtx.catchStart; scope.catchVars.add(new ValueVariable(false, e.value)); return Runners.NO_RETURN; @@ -280,6 +236,7 @@ public class CodeFrame { else return res; } catch (EngineException e) { + e.cause = tryCtx.err; if (tryCtx.hasFinally) { tryCtx.err = e; tryCtx.state = TryCtx.STATE_FINALLY_THREW; @@ -290,23 +247,32 @@ public class CodeFrame { codePtr = tryCtx.finallyStart; return Runners.NO_RETURN; } + else if (tryCtx.state == TryCtx.STATE_FINALLY_THREW) { + try { + return nextNoTry(ctx); + } + catch (EngineException e) { + e.cause = tryCtx.err; + throw e; + } + } else return nextNoTry(ctx); } - public Object run(CallContext ctx) throws InterruptedException { + public Object run(Context ctx) throws InterruptedException { try { - start(ctx); + ctx.message.pushFrame(this); while (true) { var res = next(ctx, Runners.NO_RETURN, Runners.NO_RETURN); if (res != Runners.NO_RETURN) return res; } } finally { - end(ctx); + ctx.message.popFrame(this); } } - public CodeFrame(CallContext ctx, Object thisArg, Object[] args, CodeFunction func) { + public CodeFrame(Context 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); diff --git a/src/me/topchetoeu/jscript/engine/frame/Runners.java b/src/me/topchetoeu/jscript/engine/frame/Runners.java index 631706e..37ce098 100644 --- a/src/me/topchetoeu/jscript/engine/frame/Runners.java +++ b/src/me/topchetoeu/jscript/engine/frame/Runners.java @@ -3,8 +3,7 @@ package me.topchetoeu.jscript.engine.frame; import java.util.Collections; import me.topchetoeu.jscript.compilation.Instruction; -import me.topchetoeu.jscript.engine.CallContext; -import me.topchetoeu.jscript.engine.DebugCommand; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Operation; import me.topchetoeu.jscript.engine.scope.ValueVariable; import me.topchetoeu.jscript.engine.values.ArrayValue; @@ -18,48 +17,45 @@ import me.topchetoeu.jscript.exceptions.EngineException; public class Runners { public static final Object NO_RETURN = new Object(); - public static Object execReturn(CallContext ctx, Instruction instr, CodeFrame frame) { - frame.codePtr++; + public static Object execReturn(Context ctx, Instruction instr, CodeFrame frame) { return frame.pop(); } - public static Object execSignal(CallContext ctx, Instruction instr, CodeFrame frame) { - frame.codePtr++; + public static Object execSignal(Context ctx, Instruction instr, CodeFrame frame) { return new SignalValue(instr.get(0)); } - public static Object execThrow(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execThrow(Context ctx, Instruction instr, CodeFrame frame) { throw new EngineException(frame.pop()); } - public static Object execThrowSyntax(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execThrowSyntax(Context ctx, Instruction instr, CodeFrame frame) { throw EngineException.ofSyntax((String)instr.get(0)); } - 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); + private static Object call(Context ctx, Object func, Object thisArg, Object ...args) throws InterruptedException { return Values.call(ctx, func, thisArg, args); } - public static Object execCall(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execCall(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var callArgs = frame.take(instr.get(0)); var func = frame.pop(); var thisArg = frame.pop(); - frame.push(ctx, call(ctx, state, func, thisArg, callArgs)); + frame.push(ctx, call(ctx, func, thisArg, callArgs)); frame.codePtr++; return NO_RETURN; } - public static Object execCallNew(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execCallNew(Context ctx, 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(ctx, call(ctx, state, funcObj, null, callArgs)); + frame.push(ctx, call(ctx, funcObj, null, callArgs)); } else { var proto = Values.getMember(ctx, funcObj, "prototype"); var obj = new ObjectValue(); obj.setPrototype(ctx, proto); - call(ctx, state, funcObj, obj, callArgs); + call(ctx, funcObj, obj, callArgs); frame.push(ctx, obj); } @@ -67,13 +63,13 @@ public class Runners { return NO_RETURN; } - public static Object execMakeVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var name = (String)instr.get(0); - frame.function.environment.global.define(name); + ctx.function.global.define(name); frame.codePtr++; return NO_RETURN; } - public static Object execDefProp(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execDefProp(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var setter = frame.pop(); var getter = frame.pop(); var name = frame.pop(); @@ -88,7 +84,7 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execInstanceof(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execInstanceof(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var type = frame.pop(); var obj = frame.pop(); @@ -103,7 +99,7 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execKeys(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execKeys(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var val = frame.pop(); var arr = new ObjectValue(); @@ -123,13 +119,13 @@ public class Runners { return NO_RETURN; } - public static Object execTry(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execTry(Context 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(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execDup(Context ctx, Instruction instr, CodeFrame frame) { int offset = instr.get(0), count = instr.get(1); for (var i = 0; i < count; i++) { @@ -139,7 +135,7 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execMove(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execMove(Context ctx, Instruction instr, CodeFrame frame) { int offset = instr.get(0), count = instr.get(1); var tmp = frame.take(offset); @@ -151,43 +147,43 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execLoadUndefined(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execLoadUndefined(Context ctx, Instruction instr, CodeFrame frame) { frame.push(ctx, null); frame.codePtr++; return NO_RETURN; } - public static Object execLoadValue(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execLoadValue(Context ctx, Instruction instr, CodeFrame frame) { frame.push(ctx, instr.get(0)); frame.codePtr++; return NO_RETURN; } - public static Object execLoadVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var i = instr.get(0); - if (i instanceof String) frame.push(ctx, frame.function.environment.global.get(ctx, (String)i)); + if (i instanceof String) frame.push(ctx, ctx.function.global.get(ctx, (String)i)); else frame.push(ctx, frame.scope.get((int)i).get(ctx)); frame.codePtr++; return NO_RETURN; } - public static Object execLoadObj(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execLoadObj(Context ctx, Instruction instr, CodeFrame frame) { frame.push(ctx, new ObjectValue()); frame.codePtr++; return NO_RETURN; } - public static Object execLoadGlob(CallContext ctx, Instruction instr, CodeFrame frame) { - frame.push(ctx, frame.function.environment.global.obj); + public static Object execLoadGlob(Context ctx, Instruction instr, CodeFrame frame) { + frame.push(ctx, ctx.function.global.obj); frame.codePtr++; return NO_RETURN; } - public static Object execLoadArr(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execLoadArr(Context ctx, Instruction instr, CodeFrame frame) { var res = new ArrayValue(); res.setSize(instr.get(0)); frame.push(ctx, res); frame.codePtr++; return NO_RETURN; } - public static Object execLoadFunc(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execLoadFunc(Context ctx, Instruction instr, CodeFrame frame) { int n = (Integer)instr.get(0); int localsN = (Integer)instr.get(1); int len = (Integer)instr.get(2); @@ -202,18 +198,17 @@ public class Runners { var body = new Instruction[end - start]; System.arraycopy(frame.function.body, start, body, 0, end - start); - var func = new CodeFunction("", localsN, len, frame.function.environment, captures, body); + var func = new CodeFunction(ctx.function, "", localsN, len, captures, body); frame.push(ctx, func); frame.codePtr += n; return NO_RETURN; } - public static Object execLoadMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execLoadMember(Context ctx, 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(ctx, Values.getMember(ctx, obj, key)); } catch (IllegalArgumentException e) { @@ -222,54 +217,53 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execLoadKeyMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execLoadKeyMember(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { frame.push(ctx, instr.get(0)); - return execLoadMember(ctx, state, instr, frame); + return execLoadMember(ctx, instr, frame); } - public static Object execLoadRegEx(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { - frame.push(ctx, ctx.environment.regexConstructor.call(ctx, null, instr.get(0), instr.get(1))); + public static Object execLoadRegEx(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + frame.push(ctx, ctx.function.regexConstructor.call(ctx, null, instr.get(0), instr.get(1))); frame.codePtr++; return NO_RETURN; } - public static Object execDiscard(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execDiscard(Context ctx, Instruction instr, CodeFrame frame) { frame.pop(); frame.codePtr++; return NO_RETURN; } - public static Object execStoreMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execStoreMember(Context ctx, 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(ctx, val); frame.codePtr++; return NO_RETURN; } - public static Object execStoreVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execStoreVar(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var val = (boolean)instr.get(1) ? frame.peek() : frame.pop(); var i = instr.get(0); - if (i instanceof String) frame.function.environment.global.set(ctx, (String)i, val); + if (i instanceof String) ctx.function.global.set(ctx, (String)i, val); else frame.scope.get((int)i).set(ctx, val); frame.codePtr++; return NO_RETURN; } - public static Object execStoreSelfFunc(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execStoreSelfFunc(Context 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(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execJmp(Context ctx, Instruction instr, CodeFrame frame) { frame.codePtr += (int)instr.get(0); frame.jumpFlag = true; return NO_RETURN; } - public static Object execJmpIf(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execJmpIf(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { if (Values.toBoolean(frame.pop())) { frame.codePtr += (int)instr.get(0); frame.jumpFlag = true; @@ -277,7 +271,7 @@ public class Runners { else frame.codePtr ++; return NO_RETURN; } - public static Object execJmpIfNot(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execJmpIfNot(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { if (Values.not(frame.pop())) { frame.codePtr += (int)instr.get(0); frame.jumpFlag = true; @@ -286,7 +280,7 @@ public class Runners { return NO_RETURN; } - public static Object execIn(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execIn(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var obj = frame.pop(); var index = frame.pop(); @@ -294,13 +288,13 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execTypeof(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execTypeof(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { String name = instr.get(0); Object obj; if (name != null) { - if (frame.function.environment.global.has(ctx, name)) { - obj = frame.function.environment.global.get(ctx, name); + if (ctx.function.global.has(ctx, name)) { + obj = ctx.function.global.get(ctx, name); } else obj = null; } @@ -311,7 +305,7 @@ public class Runners { frame.codePtr++; return NO_RETURN; } - public static Object execNop(CallContext ctx, Instruction instr, CodeFrame frame) { + public static Object execNop(Context 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,7 +319,7 @@ public class Runners { return NO_RETURN; } - public static Object execDelete(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execDelete(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { var key = frame.pop(); var val = frame.pop(); @@ -335,7 +329,7 @@ public class Runners { return NO_RETURN; } - public static Object execOperation(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object execOperation(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { Operation op = instr.get(0); var args = new Object[op.operands]; @@ -346,7 +340,7 @@ public class Runners { return NO_RETURN; } - public static Object exec(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException { + public static Object exec(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { // System.out.println(instr + "@" + instr.location); switch (instr.type) { case NOP: return execNop(ctx, instr, frame); @@ -354,8 +348,8 @@ public class Runners { 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 CALL: return execCall(ctx, instr, frame); + case CALL_NEW: return execCallNew(ctx, instr, frame); case TRY: return execTry(ctx, instr, frame); case DUP: return execDup(ctx, instr, frame); @@ -365,13 +359,13 @@ public class Runners { 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_MEMBER: return execLoadMember(ctx, instr, frame); + case LOAD_VAL_MEMBER: return execLoadKeyMember(ctx, instr, frame); case LOAD_REGEX: return execLoadRegEx(ctx, instr, frame); case LOAD_GLOB: return execLoadGlob(ctx, instr, frame); case DISCARD: return execDiscard(ctx, instr, frame); - case STORE_MEMBER: return execStoreMember(ctx, state, instr, frame); + case STORE_MEMBER: return execStoreMember(ctx, 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); diff --git a/src/me/topchetoeu/jscript/engine/scope/GlobalScope.java b/src/me/topchetoeu/jscript/engine/scope/GlobalScope.java index 38fac3a..e447f2a 100644 --- a/src/me/topchetoeu/jscript/engine/scope/GlobalScope.java +++ b/src/me/topchetoeu/jscript/engine/scope/GlobalScope.java @@ -3,7 +3,7 @@ package me.topchetoeu.jscript.engine.scope; import java.util.HashSet; import java.util.Set; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.FunctionValue; import me.topchetoeu.jscript.engine.values.NativeFunction; import me.topchetoeu.jscript.engine.values.ObjectValue; @@ -15,7 +15,7 @@ public class GlobalScope implements ScopeRecord { @Override public GlobalScope parent() { return null; } - public boolean has(CallContext ctx, String name) throws InterruptedException { + public boolean has(Context ctx, String name) throws InterruptedException { return obj.hasMember(ctx, name, false); } public Object getKey(String name) { @@ -49,21 +49,21 @@ public class GlobalScope implements ScopeRecord { true, true ); } - public void define(CallContext ctx, String name, boolean readonly, Object val) { + public void define(Context ctx, String name, boolean readonly, Object val) { obj.defineProperty(ctx, name, val, readonly, true, true); } - public void define(String... names) { + public void define(String ...names) { for (var n : names) define(n); } public void define(boolean readonly, FunctionValue val) { define(null, val.name, readonly, val); } - public Object get(CallContext ctx, String name) throws InterruptedException { + public Object get(Context ctx, String name) throws InterruptedException { if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist."); else return obj.getMember(ctx, name); } - public void set(CallContext ctx, String name, Object val) throws InterruptedException { + public void set(Context ctx, String name, Object val) throws InterruptedException { 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."); } diff --git a/src/me/topchetoeu/jscript/engine/scope/LocalScopeRecord.java b/src/me/topchetoeu/jscript/engine/scope/LocalScopeRecord.java index 5839e19..7d5cf12 100644 --- a/src/me/topchetoeu/jscript/engine/scope/LocalScopeRecord.java +++ b/src/me/topchetoeu/jscript/engine/scope/LocalScopeRecord.java @@ -2,7 +2,7 @@ package me.topchetoeu.jscript.engine.scope; import java.util.ArrayList; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public class LocalScopeRecord implements ScopeRecord { public final LocalScopeRecord parent; @@ -59,7 +59,7 @@ public class LocalScopeRecord implements ScopeRecord { return name; } - public boolean has(CallContext ctx, String name) throws InterruptedException { + public boolean has(Context ctx, String name) throws InterruptedException { return global.has(ctx, name) || locals.contains(name) || diff --git a/src/me/topchetoeu/jscript/engine/scope/ValueVariable.java b/src/me/topchetoeu/jscript/engine/scope/ValueVariable.java index 2d68066..8a6797c 100644 --- a/src/me/topchetoeu/jscript/engine/scope/ValueVariable.java +++ b/src/me/topchetoeu/jscript/engine/scope/ValueVariable.java @@ -1,6 +1,6 @@ package me.topchetoeu.jscript.engine.scope; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.Values; public class ValueVariable implements Variable { @@ -11,12 +11,12 @@ public class ValueVariable implements Variable { public boolean readonly() { return readonly; } @Override - public Object get(CallContext ctx) { + public Object get(Context ctx) { return value; } @Override - public void set(CallContext ctx, Object val) { + public void set(Context ctx, Object val) { if (readonly) return; this.value = Values.normalize(ctx, val); } diff --git a/src/me/topchetoeu/jscript/engine/scope/Variable.java b/src/me/topchetoeu/jscript/engine/scope/Variable.java index 83b724c..6bd3394 100644 --- a/src/me/topchetoeu/jscript/engine/scope/Variable.java +++ b/src/me/topchetoeu/jscript/engine/scope/Variable.java @@ -1,9 +1,9 @@ package me.topchetoeu.jscript.engine.scope; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public interface Variable { - Object get(CallContext ctx) throws InterruptedException; + Object get(Context ctx) throws InterruptedException; default boolean readonly() { return true; } - default void set(CallContext ctx, Object val) throws InterruptedException { } + default void set(Context ctx, Object val) throws InterruptedException { } } diff --git a/src/me/topchetoeu/jscript/engine/values/ArrayValue.java b/src/me/topchetoeu/jscript/engine/values/ArrayValue.java index 9278ed4..0bd59ea 100644 --- a/src/me/topchetoeu/jscript/engine/values/ArrayValue.java +++ b/src/me/topchetoeu/jscript/engine/values/ArrayValue.java @@ -5,7 +5,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.List; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public class ArrayValue extends ObjectValue { private static final Object EMPTY = new Object(); @@ -29,7 +29,7 @@ public class ArrayValue extends ObjectValue { if (res == EMPTY) return null; else return res; } - public void set(CallContext ctx, int i, Object val) { + public void set(Context ctx, int i, Object val) { if (i < 0) return; while (values.size() <= i) { @@ -83,7 +83,7 @@ public class ArrayValue extends ObjectValue { } @Override - protected Object getField(CallContext ctx, Object key) throws InterruptedException { + protected Object getField(Context ctx, Object key) throws InterruptedException { if (key.equals("length")) return values.size(); if (key instanceof Number) { var i = ((Number)key).doubleValue(); @@ -95,7 +95,7 @@ public class ArrayValue extends ObjectValue { return super.getField(ctx, key); } @Override - protected boolean setField(CallContext ctx, Object key, Object val) throws InterruptedException { + protected boolean setField(Context ctx, Object key, Object val) throws InterruptedException { if (key.equals("length")) { return setSize((int)Values.toNumber(ctx, val)); } @@ -110,7 +110,7 @@ public class ArrayValue extends ObjectValue { return super.setField(ctx, key, val); } @Override - protected boolean hasField(CallContext ctx, Object key) throws InterruptedException { + protected boolean hasField(Context ctx, Object key) throws InterruptedException { if (key.equals("length")) return true; if (key instanceof Number) { var i = Values.number(key); @@ -122,7 +122,7 @@ public class ArrayValue extends ObjectValue { return super.hasField(ctx, key); } @Override - protected void deleteField(CallContext ctx, Object key) throws InterruptedException { + protected void deleteField(Context ctx, Object key) throws InterruptedException { if (key instanceof Number) { var i = Values.number(key); if (i >= 0 && i - Math.floor(i) == 0) { @@ -149,12 +149,12 @@ public class ArrayValue extends ObjectValue { nonEnumerableSet.add("length"); nonConfigurableSet.add("length"); } - public ArrayValue(CallContext ctx, Object ...values) { + public ArrayValue(Context ctx, Object ...values) { this(); for (var i = 0; i < values.length; i++) this.values.add(Values.normalize(ctx, values[i])); } - public static ArrayValue of(CallContext ctx, Collection values) { + public static ArrayValue of(Context ctx, Collection values) { return new ArrayValue(ctx, values.toArray(Object[]::new)); } } diff --git a/src/me/topchetoeu/jscript/engine/values/CodeFunction.java b/src/me/topchetoeu/jscript/engine/values/CodeFunction.java index e2ff92e..d70b20d 100644 --- a/src/me/topchetoeu/jscript/engine/values/CodeFunction.java +++ b/src/me/topchetoeu/jscript/engine/values/CodeFunction.java @@ -1,12 +1,9 @@ package me.topchetoeu.jscript.engine.values; -import java.util.LinkedHashMap; - import me.topchetoeu.jscript.Location; import me.topchetoeu.jscript.compilation.Instruction; -import me.topchetoeu.jscript.compilation.Instruction.Type; -import me.topchetoeu.jscript.engine.CallContext; -import me.topchetoeu.jscript.engine.Environment; +import me.topchetoeu.jscript.engine.Context; +import me.topchetoeu.jscript.engine.FunctionContext; import me.topchetoeu.jscript.engine.frame.CodeFrame; import me.topchetoeu.jscript.engine.scope.ValueVariable; @@ -14,10 +11,8 @@ public class CodeFunction extends FunctionValue { public final int localsN; public final int length; public final Instruction[] body; - public final LinkedHashMap breakableLocToIndex = new LinkedHashMap<>(); - public final LinkedHashMap breakableIndexToLoc = new LinkedHashMap<>(); public final ValueVariable[] captures; - public Environment environment; + public FunctionContext environment; public Location loc() { for (var instr : body) { @@ -33,24 +28,16 @@ public class CodeFunction extends FunctionValue { } @Override - public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException { - return new CodeFrame(ctx, thisArg, args, this).run(new CallContext(ctx, environment)); + public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { + return new CodeFrame(ctx, thisArg, args, this).run(new Context(environment, ctx.message)); } - public CodeFunction(String name, int localsN, int length, Environment environment, ValueVariable[] captures, Instruction[] body) { + public CodeFunction(FunctionContext environment, String name, int localsN, int length, ValueVariable[] captures, Instruction[] body) { super(name, length); this.captures = captures; this.environment = environment; this.localsN = localsN; this.length = length; this.body = body; - - for (var i = 0; i < body.length; i++) { - if (body[i].type == Type.LOAD_FUNC) i += (int)body[i].get(0); - if (body[i].debugged && body[i].location != null) { - breakableLocToIndex.put(body[i].location, i); - breakableIndexToLoc.put(i, body[i].location); - } - } } } diff --git a/src/me/topchetoeu/jscript/engine/values/FunctionValue.java b/src/me/topchetoeu/jscript/engine/values/FunctionValue.java index aaf1061..612f9b8 100644 --- a/src/me/topchetoeu/jscript/engine/values/FunctionValue.java +++ b/src/me/topchetoeu/jscript/engine/values/FunctionValue.java @@ -2,7 +2,7 @@ package me.topchetoeu.jscript.engine.values; import java.util.List; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public abstract class FunctionValue extends ObjectValue { public String name = ""; @@ -11,29 +11,29 @@ public abstract class FunctionValue extends ObjectValue { @Override public String toString() { - return "function(...) { ... }"; + return "function(...) { ...}"; } - public abstract Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException; - public Object call(CallContext ctx) throws InterruptedException { + public abstract Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException; + public Object call(Context ctx) throws InterruptedException { return call(ctx, null); } @Override - protected Object getField(CallContext ctx, Object key) throws InterruptedException { + protected Object getField(Context ctx, Object key) throws InterruptedException { if (key.equals("name")) return name; if (key.equals("length")) return length; return super.getField(ctx, key); } @Override - protected boolean setField(CallContext ctx, Object key, Object val) throws InterruptedException { + protected boolean setField(Context ctx, Object key, Object val) throws InterruptedException { if (key.equals("name")) name = Values.toString(ctx, val); else if (key.equals("length")) length = (int)Values.toNumber(ctx, val); else return super.setField(ctx, key, val); return true; } @Override - protected boolean hasField(CallContext ctx, Object key) throws InterruptedException { + protected boolean hasField(Context ctx, Object key) throws InterruptedException { if (key.equals("name")) return true; if (key.equals("length")) return true; return super.hasField(ctx, key); diff --git a/src/me/topchetoeu/jscript/engine/values/NativeFunction.java b/src/me/topchetoeu/jscript/engine/values/NativeFunction.java index c6a8be2..2056717 100644 --- a/src/me/topchetoeu/jscript/engine/values/NativeFunction.java +++ b/src/me/topchetoeu/jscript/engine/values/NativeFunction.java @@ -1,16 +1,16 @@ package me.topchetoeu.jscript.engine.values; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public class NativeFunction extends FunctionValue { public static interface NativeFunctionRunner { - Object run(CallContext ctx, Object thisArg, Object[] args) throws InterruptedException; + Object run(Context ctx, Object thisArg, Object[] args) throws InterruptedException; } public final NativeFunctionRunner action; @Override - public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException { + public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { return action.run(ctx, thisArg, args); } diff --git a/src/me/topchetoeu/jscript/engine/values/NativeWrapper.java b/src/me/topchetoeu/jscript/engine/values/NativeWrapper.java index 50efae2..753521d 100644 --- a/src/me/topchetoeu/jscript/engine/values/NativeWrapper.java +++ b/src/me/topchetoeu/jscript/engine/values/NativeWrapper.java @@ -1,14 +1,14 @@ package me.topchetoeu.jscript.engine.values; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public class NativeWrapper extends ObjectValue { private static final Object NATIVE_PROTO = new Object(); public final Object wrapped; @Override - public ObjectValue getPrototype(CallContext ctx) throws InterruptedException { - if (prototype == NATIVE_PROTO) return ctx.environment.wrappersProvider.getProto(wrapped.getClass()); + public ObjectValue getPrototype(Context ctx) throws InterruptedException { + if (prototype == NATIVE_PROTO) return ctx.function.wrappersProvider.getProto(wrapped.getClass()); else return super.getPrototype(ctx); } diff --git a/src/me/topchetoeu/jscript/engine/values/ObjectValue.java b/src/me/topchetoeu/jscript/engine/values/ObjectValue.java index ca0fb55..9986cc8 100644 --- a/src/me/topchetoeu/jscript/engine/values/ObjectValue.java +++ b/src/me/topchetoeu/jscript/engine/values/ObjectValue.java @@ -6,7 +6,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public class ObjectValue { public static enum PlaceholderProto { @@ -78,7 +78,7 @@ public class ObjectValue { state = State.FROZEN; } - public final boolean defineProperty(CallContext ctx, Object key, Object val, boolean writable, boolean configurable, boolean enumerable) { + public final boolean defineProperty(Context 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) || @@ -118,10 +118,10 @@ public class ObjectValue { values.put(key, val); return true; } - public final boolean defineProperty(CallContext ctx, Object key, Object val) { + public final boolean defineProperty(Context ctx, Object key, Object val) { return defineProperty(ctx, key, val, true, true, true); } - public final boolean defineProperty(CallContext ctx, Object key, FunctionValue getter, FunctionValue setter, boolean configurable, boolean enumerable) { + public final boolean defineProperty(Context ctx, Object key, FunctionValue getter, FunctionValue setter, boolean configurable, boolean enumerable) { key = Values.normalize(ctx, key); if ( properties.containsKey(key) && @@ -145,15 +145,15 @@ public class ObjectValue { return true; } - public ObjectValue getPrototype(CallContext ctx) throws InterruptedException { + public ObjectValue getPrototype(Context ctx) throws InterruptedException { try { - if (prototype == OBJ_PROTO) return ctx.environment.proto("object"); - if (prototype == ARR_PROTO) return ctx.environment.proto("array"); - if (prototype == FUNC_PROTO) return ctx.environment.proto("function"); - if (prototype == ERR_PROTO) return ctx.environment.proto("error"); - if (prototype == RANGE_ERR_PROTO) return ctx.environment.proto("rangeErr"); - if (prototype == SYNTAX_ERR_PROTO) return ctx.environment.proto("syntaxErr"); - if (prototype == TYPE_ERR_PROTO) return ctx.environment.proto("typeErr"); + if (prototype == OBJ_PROTO) return ctx.function.proto("object"); + if (prototype == ARR_PROTO) return ctx.function.proto("array"); + if (prototype == FUNC_PROTO) return ctx.function.proto("function"); + if (prototype == ERR_PROTO) return ctx.function.proto("error"); + if (prototype == RANGE_ERR_PROTO) return ctx.function.proto("rangeErr"); + if (prototype == SYNTAX_ERR_PROTO) return ctx.function.proto("syntaxErr"); + if (prototype == TYPE_ERR_PROTO) return ctx.function.proto("typeErr"); } catch (NullPointerException e) { return null; @@ -161,7 +161,7 @@ public class ObjectValue { return (ObjectValue)prototype; } - public final boolean setPrototype(CallContext ctx, Object val) { + public final boolean setPrototype(Context ctx, Object val) { val = Values.normalize(ctx, val); if (!extensible()) return false; @@ -172,14 +172,14 @@ public class ObjectValue { else if (Values.isObject(val)) { var obj = Values.object(val); - if (ctx != null && ctx.environment != null) { - if (obj == ctx.environment.proto("object")) prototype = OBJ_PROTO; - else if (obj == ctx.environment.proto("array")) prototype = ARR_PROTO; - else if (obj == ctx.environment.proto("function")) prototype = FUNC_PROTO; - else if (obj == ctx.environment.proto("error")) prototype = ERR_PROTO; - else if (obj == ctx.environment.proto("syntaxErr")) prototype = SYNTAX_ERR_PROTO; - else if (obj == ctx.environment.proto("typeErr")) prototype = TYPE_ERR_PROTO; - else if (obj == ctx.environment.proto("rangeErr")) prototype = RANGE_ERR_PROTO; + if (ctx != null && ctx.function != null) { + if (obj == ctx.function.proto("object")) prototype = OBJ_PROTO; + else if (obj == ctx.function.proto("array")) prototype = ARR_PROTO; + else if (obj == ctx.function.proto("function")) prototype = FUNC_PROTO; + else if (obj == ctx.function.proto("error")) prototype = ERR_PROTO; + else if (obj == ctx.function.proto("syntaxErr")) prototype = SYNTAX_ERR_PROTO; + else if (obj == ctx.function.proto("typeErr")) prototype = TYPE_ERR_PROTO; + else if (obj == ctx.function.proto("rangeErr")) prototype = RANGE_ERR_PROTO; else prototype = obj; } else prototype = obj; @@ -203,19 +203,19 @@ public class ObjectValue { return true; } - protected Property getProperty(CallContext ctx, Object key) throws InterruptedException { + protected Property getProperty(Context ctx, Object key) throws InterruptedException { if (properties.containsKey(key)) return properties.get(key); var proto = getPrototype(ctx); if (proto != null) return proto.getProperty(ctx, key); else return null; } - protected Object getField(CallContext ctx, Object key) throws InterruptedException { + protected Object getField(Context ctx, Object key) throws InterruptedException { if (values.containsKey(key)) return values.get(key); var proto = getPrototype(ctx); if (proto != null) return proto.getField(ctx, key); else return null; } - protected boolean setField(CallContext ctx, Object key, Object val) throws InterruptedException { + protected boolean setField(Context ctx, Object key, Object val) throws InterruptedException { if (val instanceof FunctionValue && ((FunctionValue)val).name.equals("")) { ((FunctionValue)val).name = Values.toString(ctx, key); } @@ -223,14 +223,14 @@ public class ObjectValue { values.put(key, val); return true; } - protected void deleteField(CallContext ctx, Object key) throws InterruptedException { + protected void deleteField(Context ctx, Object key) throws InterruptedException { values.remove(key); } - protected boolean hasField(CallContext ctx, Object key) throws InterruptedException { + protected boolean hasField(Context ctx, Object key) throws InterruptedException { return values.containsKey(key); } - public final Object getMember(CallContext ctx, Object key, Object thisArg) throws InterruptedException { + public final Object getMember(Context ctx, Object key, Object thisArg) throws InterruptedException { key = Values.normalize(ctx, key); if (key.equals("__proto__")) { @@ -246,11 +246,11 @@ public class ObjectValue { } else return getField(ctx, key); } - public final Object getMember(CallContext ctx, Object key) throws InterruptedException { + public final Object getMember(Context ctx, Object key) throws InterruptedException { return getMember(ctx, key, this); } - public final boolean setMember(CallContext 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) throws InterruptedException { key = Values.normalize(ctx, key); val = Values.normalize(ctx, val); var prop = getProperty(ctx, key); @@ -269,11 +269,11 @@ public class ObjectValue { else if (nonWritableSet.contains(key)) return false; else return setField(ctx, key, val); } - public final boolean setMember(CallContext ctx, Object key, Object val, boolean onlyProps) throws InterruptedException { + public final boolean setMember(Context ctx, Object key, Object val, boolean onlyProps) throws InterruptedException { 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 { + public final boolean hasMember(Context ctx, Object key, boolean own) throws InterruptedException { key = Values.normalize(ctx, key); if (key != null && key.equals("__proto__")) return true; @@ -283,7 +283,7 @@ public class ObjectValue { var proto = getPrototype(ctx); return proto != null && proto.hasMember(ctx, key, own); } - public final boolean deleteMember(CallContext ctx, Object key) throws InterruptedException { + public final boolean deleteMember(Context ctx, Object key) throws InterruptedException { key = Values.normalize(ctx, key); if (!memberConfigurable(key)) return false; @@ -294,7 +294,7 @@ public class ObjectValue { return true; } - public final ObjectValue getMemberDescriptor(CallContext ctx, Object key) throws InterruptedException { + public final ObjectValue getMemberDescriptor(Context ctx, Object key) throws InterruptedException { key = Values.normalize(ctx, key); var prop = properties.get(key); @@ -330,7 +330,7 @@ public class ObjectValue { return res; } - public ObjectValue(CallContext ctx, Map values) { + public ObjectValue(Context ctx, Map values) { this(PlaceholderProto.OBJECT); for (var el : values.entrySet()) { defineProperty(ctx, el.getKey(), el.getValue()); diff --git a/src/me/topchetoeu/jscript/engine/values/Values.java b/src/me/topchetoeu/jscript/engine/values/Values.java index 5f7f4ca..73f7029 100644 --- a/src/me/topchetoeu/jscript/engine/values/Values.java +++ b/src/me/topchetoeu/jscript/engine/values/Values.java @@ -10,7 +10,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Operation; import me.topchetoeu.jscript.engine.frame.ConvertHint; import me.topchetoeu.jscript.exceptions.EngineException; @@ -65,7 +65,7 @@ public class Values { return "object"; } - private static Object tryCallConvertFunc(CallContext ctx, Object obj, String name) throws InterruptedException { + private static Object tryCallConvertFunc(Context ctx, Object obj, String name) throws InterruptedException { var func = getMember(ctx, obj, name); if (func != null) { @@ -87,7 +87,7 @@ public class Values { obj == NULL; } - public static Object toPrimitive(CallContext ctx, Object obj, ConvertHint hint) throws InterruptedException { + public static Object toPrimitive(Context ctx, Object obj, ConvertHint hint) throws InterruptedException { obj = normalize(ctx, obj); if (isPrimitive(obj)) return obj; @@ -112,7 +112,7 @@ public class Values { if (obj instanceof Boolean) return (Boolean)obj; return true; } - public static double toNumber(CallContext ctx, Object obj) throws InterruptedException { + public static double toNumber(Context ctx, Object obj) throws InterruptedException { var val = toPrimitive(ctx, obj, ConvertHint.VALUEOF); if (val instanceof Number) return number(obj); @@ -125,7 +125,7 @@ public class Values { } return Double.NaN; } - public static String toString(CallContext ctx, Object obj) throws InterruptedException { + public static String toString(Context ctx, Object obj) throws InterruptedException { var val = toPrimitive(ctx, obj, ConvertHint.VALUEOF); if (val == null) return "undefined"; @@ -146,47 +146,47 @@ public class Values { return "Unknown value"; } - public static Object add(CallContext ctx, Object a, Object b) throws InterruptedException { + public static Object add(Context ctx, Object a, Object b) throws InterruptedException { if (a instanceof String || b instanceof String) return toString(ctx, a) + toString(ctx, b); else return toNumber(ctx, a) + toNumber(ctx, b); } - public static double subtract(CallContext ctx, Object a, Object b) throws InterruptedException { + public static double subtract(Context ctx, Object a, Object b) throws InterruptedException { return toNumber(ctx, a) - toNumber(ctx, b); } - public static double multiply(CallContext ctx, Object a, Object b) throws InterruptedException { + public static double multiply(Context ctx, Object a, Object b) throws InterruptedException { return toNumber(ctx, a) * toNumber(ctx, b); } - public static double divide(CallContext ctx, Object a, Object b) throws InterruptedException { + public static double divide(Context ctx, Object a, Object b) throws InterruptedException { return toNumber(ctx, a) / toNumber(ctx, b); } - public static double modulo(CallContext ctx, Object a, Object b) throws InterruptedException { + public static double modulo(Context ctx, Object a, Object b) throws InterruptedException { return toNumber(ctx, a) % toNumber(ctx, b); } - public static double negative(CallContext ctx, Object obj) throws InterruptedException { + public static double negative(Context ctx, Object obj) throws InterruptedException { return -toNumber(ctx, obj); } - public static int and(CallContext ctx, Object a, Object b) throws InterruptedException { + public static int and(Context ctx, Object a, Object b) throws InterruptedException { return (int)toNumber(ctx, a) & (int)toNumber(ctx, b); } - public static int or(CallContext ctx, Object a, Object b) throws InterruptedException { + public static int or(Context ctx, Object a, Object b) throws InterruptedException { return (int)toNumber(ctx, a) | (int)toNumber(ctx, b); } - public static int xor(CallContext ctx, Object a, Object b) throws InterruptedException { + public static int xor(Context ctx, Object a, Object b) throws InterruptedException { return (int)toNumber(ctx, a) ^ (int)toNumber(ctx, b); } - public static int bitwiseNot(CallContext ctx, Object obj) throws InterruptedException { + public static int bitwiseNot(Context ctx, Object obj) throws InterruptedException { return ~(int)toNumber(ctx, obj); } - public static int shiftLeft(CallContext ctx, Object a, Object b) throws InterruptedException { + public static int shiftLeft(Context ctx, Object a, Object b) throws InterruptedException { return (int)toNumber(ctx, a) << (int)toNumber(ctx, b); } - public static int shiftRight(CallContext ctx, Object a, Object b) throws InterruptedException { + public static int shiftRight(Context ctx, Object a, Object b) throws InterruptedException { return (int)toNumber(ctx, a) >> (int)toNumber(ctx, b); } - public static long unsignedShiftRight(CallContext ctx, Object a, Object b) throws InterruptedException { + public static long unsignedShiftRight(Context ctx, Object a, Object b) throws InterruptedException { long _a = (long)toNumber(ctx, a); long _b = (long)toNumber(ctx, b); @@ -195,7 +195,7 @@ public class Values { return _a >>> _b; } - public static int compare(CallContext ctx, Object a, Object b) throws InterruptedException { + public static int compare(Context ctx, Object a, Object b) throws InterruptedException { a = toPrimitive(ctx, a, ConvertHint.VALUEOF); b = toPrimitive(ctx, b, ConvertHint.VALUEOF); @@ -207,7 +207,7 @@ public class Values { return !toBoolean(obj); } - public static boolean isInstanceOf(CallContext ctx, Object obj, Object proto) throws InterruptedException { + public static boolean isInstanceOf(Context ctx, Object obj, Object proto) throws InterruptedException { if (obj == null || obj == NULL || proto == null || proto == NULL) return false; var val = getPrototype(ctx, obj); @@ -219,7 +219,7 @@ public class Values { return false; } - public static Object operation(CallContext ctx, Operation op, Object... args) throws InterruptedException { + public static Object operation(Context ctx, Operation op, Object ...args) throws InterruptedException { switch (op) { case ADD: return add(ctx, args[0], args[1]); case SUBTRACT: return subtract(ctx, args[0], args[1]); @@ -260,7 +260,7 @@ public class Values { } } - public static Object getMember(CallContext ctx, Object obj, Object key) throws InterruptedException { + public static Object getMember(Context ctx, Object obj, Object key) throws InterruptedException { 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."); @@ -280,7 +280,7 @@ public class Values { else if (key != null && key.equals("__proto__")) return proto; else return proto.getMember(ctx, key, obj); } - public static boolean setMember(CallContext ctx, Object obj, Object key, Object val) throws InterruptedException { + public static boolean setMember(Context ctx, Object obj, Object key, Object val) throws InterruptedException { obj = normalize(ctx, obj); key = normalize(ctx, key); val = normalize(ctx, val); if (obj == null) throw EngineException.ofType("Tried to access member of undefined."); if (obj == NULL) throw EngineException.ofType("Tried to access member of null."); @@ -290,7 +290,7 @@ public class Values { var proto = getPrototype(ctx, obj); return proto.setMember(ctx, key, val, obj, true); } - public static boolean hasMember(CallContext ctx, Object obj, Object key, boolean own) throws InterruptedException { + public static boolean hasMember(Context ctx, Object obj, Object key, boolean own) throws InterruptedException { if (obj == null || obj == NULL) return false; obj = normalize(ctx, obj); key = normalize(ctx, key); @@ -308,31 +308,31 @@ public class Values { var proto = getPrototype(ctx, obj); return proto != null && proto.hasMember(ctx, key, own); } - public static boolean deleteMember(CallContext ctx, Object obj, Object key) throws InterruptedException { + public static boolean deleteMember(Context ctx, Object obj, Object key) throws InterruptedException { if (obj == null || obj == NULL) return false; 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 { + public static ObjectValue getPrototype(Context ctx, Object obj) throws InterruptedException { if (obj == null || obj == NULL) return null; obj = normalize(ctx, obj); if (isObject(obj)) return object(obj).getPrototype(ctx); if (ctx == null) return null; - if (obj instanceof String) return ctx.environment.proto("string"); - else if (obj instanceof Number) return ctx.environment.proto("number"); - else if (obj instanceof Boolean) return ctx.environment.proto("bool"); - else if (obj instanceof Symbol) return ctx.environment.proto("symbol"); + if (obj instanceof String) return ctx.function.proto("string"); + else if (obj instanceof Number) return ctx.function.proto("number"); + else if (obj instanceof Boolean) return ctx.function.proto("bool"); + else if (obj instanceof Symbol) return ctx.function.proto("symbol"); return null; } - public static boolean setPrototype(CallContext ctx, Object obj, Object proto) throws InterruptedException { + public static boolean setPrototype(Context ctx, Object obj, Object proto) throws InterruptedException { obj = normalize(ctx, obj); return isObject(obj) && object(obj).setPrototype(ctx, proto); } - public static List getMembers(CallContext ctx, Object obj, boolean own, boolean includeNonEnumerable) throws InterruptedException { + public static List getMembers(Context ctx, Object obj, boolean own, boolean includeNonEnumerable) throws InterruptedException { List res = new ArrayList<>(); if (isObject(obj)) res = object(obj).keys(includeNonEnumerable); @@ -353,13 +353,13 @@ public class Values { return res; } - public static Object call(CallContext ctx, Object func, Object thisArg, Object ...args) throws InterruptedException { + public static Object call(Context ctx, Object func, Object thisArg, Object ...args) throws InterruptedException { if (!isFunction(func)) throw EngineException.ofType("Tried to call a non-function value."); return function(func).call(ctx, thisArg, args); } - public static boolean strictEquals(CallContext ctx, Object a, Object b) { + public static boolean strictEquals(Context ctx, Object a, Object b) { a = normalize(ctx, a); b = normalize(ctx, b); if (a == null || b == null) return a == null && b == null; @@ -369,7 +369,7 @@ public class Values { return a == b || a.equals(b); } - public static boolean looseEqual(CallContext ctx, Object a, Object b) throws InterruptedException { + public static boolean looseEqual(Context ctx, Object a, Object b) throws InterruptedException { a = normalize(ctx, a); b = normalize(ctx, b); // In loose equality, null is equivalent to undefined @@ -393,7 +393,7 @@ public class Values { return toString(ctx, a).equals(toString(ctx, b)); } - public static Object normalize(CallContext ctx, Object val) { + public static Object normalize(Context ctx, Object val) { if (val instanceof Number) return number(val); if (isPrimitive(val) || val instanceof ObjectValue) return val; if (val instanceof Character) return val + ""; @@ -420,14 +420,14 @@ public class Values { if (val instanceof Class) { if (ctx == null) return null; - else return ctx.environment.wrappersProvider.getConstr((Class)val); + else return ctx.function.wrappersProvider.getConstr((Class)val); } return new NativeWrapper(val); } @SuppressWarnings("unchecked") - public static T convert(CallContext ctx, Object obj, Class clazz) throws InterruptedException { + public static T convert(Context ctx, Object obj, Class clazz) throws InterruptedException { if (clazz == Void.class) return null; if (clazz == null || clazz == Object.class) return (T)obj; @@ -495,10 +495,10 @@ public class Values { throw err; } - public static Iterable toJavaIterable(CallContext ctx, Object obj) throws InterruptedException { + public static Iterable toJavaIterable(Context ctx, Object obj) throws InterruptedException { return () -> { try { - var constr = getMember(ctx, ctx.environment.proto("symbol"), "constructor"); + var constr = getMember(ctx, ctx.function.proto("symbol"), "constructor"); var symbol = getMember(ctx, constr, "iterator"); var iteratorFunc = getMember(ctx, obj, symbol); @@ -562,12 +562,12 @@ public class Values { }; } - public static ObjectValue fromJavaIterable(CallContext ctx, Iterable iterable) throws InterruptedException { + public static ObjectValue fromJavaIterable(Context ctx, Iterable iterable) throws InterruptedException { var res = new ObjectValue(); var it = iterable.iterator(); try { - var key = getMember(ctx, getMember(ctx, ctx.environment.proto("symbol"), "constructor"), "iterator"); + var key = getMember(ctx, getMember(ctx, ctx.function.proto("symbol"), "constructor"), "iterator"); res.defineProperty(ctx, key, new NativeFunction("", (_ctx, thisArg, args) -> thisArg)); } catch (IllegalArgumentException | NullPointerException e) { } @@ -580,7 +580,7 @@ public class Values { return res; } - private static void printValue(CallContext ctx, Object val, HashSet passed, int tab) throws InterruptedException { + private static void printValue(Context ctx, Object val, HashSet passed, int tab) throws InterruptedException { if (passed.contains(val)) { System.out.print("[circular]"); return; @@ -652,7 +652,7 @@ public class Values { else if (val instanceof String) System.out.print("'" + val + "'"); else System.out.print(Values.toString(ctx, val)); } - public static void printValue(CallContext ctx, Object val) throws InterruptedException { + public static void printValue(Context ctx, Object val) throws InterruptedException { printValue(ctx, val, new HashSet<>(), 0); } } diff --git a/src/me/topchetoeu/jscript/exceptions/EngineException.java b/src/me/topchetoeu/jscript/exceptions/EngineException.java index ccdece6..75adb6a 100644 --- a/src/me/topchetoeu/jscript/exceptions/EngineException.java +++ b/src/me/topchetoeu/jscript/exceptions/EngineException.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.engine.values.ObjectValue.PlaceholderProto; @@ -28,9 +28,14 @@ public class EngineException extends RuntimeException { return this; } - public String toString(CallContext ctx) throws InterruptedException { + public String toString(Context ctx) throws InterruptedException { var ss = new StringBuilder(); - ss.append(Values.toString(ctx, value)).append('\n'); + try { + ss.append(Values.toString(ctx, value)).append('\n'); + } + catch (EngineException e) { + ss.append("[Error while stringifying]\n"); + } for (var line : stackTrace) { ss.append(" ").append(line).append('\n'); } diff --git a/src/me/topchetoeu/jscript/filesystem/FilesystemRegister.java b/src/me/topchetoeu/jscript/filesystem/FilesystemRegister.java deleted file mode 100644 index 03940f5..0000000 --- a/src/me/topchetoeu/jscript/filesystem/FilesystemRegister.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.topchetoeu.jscript.filesystem; - -import java.util.HashMap; - -public class FilesystemRegister { - private HashMap filesystems = new HashMap<>(); -} diff --git a/src/me/topchetoeu/jscript/interop/Overload.java b/src/me/topchetoeu/jscript/interop/Overload.java index b37a894..191f0e4 100644 --- a/src/me/topchetoeu/jscript/interop/Overload.java +++ b/src/me/topchetoeu/jscript/interop/Overload.java @@ -5,11 +5,11 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; public class Overload { public static interface OverloadRunner { - Object run(CallContext ctx, Object thisArg, Object[] args) throws + Object run(Context ctx, Object thisArg, Object[] args) throws InterruptedException, ReflectiveOperationException, IllegalArgumentException; diff --git a/src/me/topchetoeu/jscript/interop/OverloadFunction.java b/src/me/topchetoeu/jscript/interop/OverloadFunction.java index e8c78d2..321b04d 100644 --- a/src/me/topchetoeu/jscript/interop/OverloadFunction.java +++ b/src/me/topchetoeu/jscript/interop/OverloadFunction.java @@ -5,7 +5,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.FunctionValue; import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.exceptions.EngineException; @@ -13,9 +13,9 @@ import me.topchetoeu.jscript.exceptions.EngineException; public class OverloadFunction extends FunctionValue { public final List overloads = new ArrayList<>(); - public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException { + public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { for (var overload : overloads) { - boolean consumesEngine = overload.params.length > 0 && overload.params[0] == CallContext.class; + boolean consumesEngine = overload.params.length > 0 && overload.params[0] == Context.class; int start = consumesEngine ? 1 : 0; int end = overload.params.length - (overload.variadic ? 1 : 0); diff --git a/src/me/topchetoeu/jscript/parsing/ParseRes.java b/src/me/topchetoeu/jscript/parsing/ParseRes.java index 307b405..1b8e2d0 100644 --- a/src/me/topchetoeu/jscript/parsing/ParseRes.java +++ b/src/me/topchetoeu/jscript/parsing/ParseRes.java @@ -68,7 +68,7 @@ public class ParseRes { } @SafeVarargs - public static ParseRes any(ParseRes... parsers) { + public static ParseRes any(ParseRes ...parsers) { ParseRes best = null; ParseRes error = ParseRes.failed(); @@ -83,7 +83,7 @@ public class ParseRes { else return error; } @SafeVarargs - public static ParseRes first(String filename, List tokens, Map> named, Parser... parsers) { + public static ParseRes first(String filename, List tokens, Map> named, Parser ...parsers) { ParseRes error = ParseRes.failed(); for (var parser : parsers) { diff --git a/src/me/topchetoeu/jscript/parsing/Parsing.java b/src/me/topchetoeu/jscript/parsing/Parsing.java index ea10930..cf95238 100644 --- a/src/me/topchetoeu/jscript/parsing/Parsing.java +++ b/src/me/topchetoeu/jscript/parsing/Parsing.java @@ -13,7 +13,7 @@ import me.topchetoeu.jscript.compilation.VariableDeclareStatement.Pair; import me.topchetoeu.jscript.compilation.control.*; import me.topchetoeu.jscript.compilation.control.SwitchStatement.SwitchCase; import me.topchetoeu.jscript.compilation.values.*; -import me.topchetoeu.jscript.engine.Environment; +import me.topchetoeu.jscript.engine.FunctionContext; import me.topchetoeu.jscript.engine.Operation; import me.topchetoeu.jscript.engine.scope.ValueVariable; import me.topchetoeu.jscript.engine.values.CodeFunction; @@ -1842,7 +1842,7 @@ public class Parsing { return list.toArray(Statement[]::new); } - public static CodeFunction compile(Environment environment, Statement... statements) { + public static CodeFunction compile(FunctionContext environment, Statement ...statements) { var target = environment.global.globalChild(); var subscope = target.child(); var res = new ArrayList(); @@ -1870,14 +1870,14 @@ public class Parsing { } else res.add(Instruction.ret()); - return new CodeFunction("", subscope.localsCount(), 0, environment, new ValueVariable[0], res.toArray(Instruction[]::new)); + return new CodeFunction(environment, "", subscope.localsCount(), 0, new ValueVariable[0], res.toArray(Instruction[]::new)); } - public static CodeFunction compile(Environment environment, String filename, String raw) { + public static CodeFunction compile(FunctionContext environment, String filename, String raw) { try { return compile(environment, parse(filename, raw)); } catch (SyntaxException e) { - return new CodeFunction(null, 2, 0, environment, new ValueVariable[0], new Instruction[] { Instruction.throwSyntax(e) }); + return new CodeFunction(environment, null, 2, 0, new ValueVariable[0], new Instruction[] { Instruction.throwSyntax(e) }); } } } diff --git a/src/me/topchetoeu/jscript/polyfills/Date.java b/src/me/topchetoeu/jscript/polyfills/Date.java index 8582d11..8ce78a4 100644 --- a/src/me/topchetoeu/jscript/polyfills/Date.java +++ b/src/me/topchetoeu/jscript/polyfills/Date.java @@ -3,7 +3,7 @@ package me.topchetoeu.jscript.polyfills; import java.util.Calendar; import java.util.TimeZone; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.interop.Native; @@ -47,7 +47,7 @@ public class Date { return normal.get(Calendar.YEAR) - 1900; } @Native - public double setYear(CallContext ctx, Object val) throws InterruptedException { + public double setYear(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (real >= 0 && real <= 99) real = real + 1900; if (Double.isNaN(real)) invalidate(); @@ -139,7 +139,7 @@ public class Date { } @Native - public double setFullYear(CallContext ctx, Object val) throws InterruptedException { + public double setFullYear(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.YEAR, (int)real); @@ -147,7 +147,7 @@ public class Date { return getTime(); } @Native - public double setMonth(CallContext ctx, Object val) throws InterruptedException { + public double setMonth(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.MONTH, (int)real); @@ -155,7 +155,7 @@ public class Date { return getTime(); } @Native - public double setDate(CallContext ctx, Object val) throws InterruptedException { + public double setDate(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.DAY_OF_MONTH, (int)real); @@ -163,7 +163,7 @@ public class Date { return getTime(); } @Native - public double setDay(CallContext ctx, Object val) throws InterruptedException { + public double setDay(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.DAY_OF_WEEK, (int)real); @@ -171,7 +171,7 @@ public class Date { return getTime(); } @Native - public double setHours(CallContext ctx, Object val) throws InterruptedException { + public double setHours(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.HOUR_OF_DAY, (int)real); @@ -179,7 +179,7 @@ public class Date { return getTime(); } @Native - public double setMinutes(CallContext ctx, Object val) throws InterruptedException { + public double setMinutes(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.MINUTE, (int)real); @@ -187,7 +187,7 @@ public class Date { return getTime(); } @Native - public double setSeconds(CallContext ctx, Object val) throws InterruptedException { + public double setSeconds(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.SECOND, (int)real); @@ -195,7 +195,7 @@ public class Date { return getTime(); } @Native - public double setMilliseconds(CallContext ctx, Object val) throws InterruptedException { + public double setMilliseconds(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else normal.set(Calendar.MILLISECOND, (int)real); @@ -204,7 +204,7 @@ public class Date { } @Native - public double setUTCFullYear(CallContext ctx, Object val) throws InterruptedException { + public double setUTCFullYear(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.YEAR, (int)real); @@ -212,7 +212,7 @@ public class Date { return getTime(); } @Native - public double setUTCMonth(CallContext ctx, Object val) throws InterruptedException { + public double setUTCMonth(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.MONTH, (int)real); @@ -220,7 +220,7 @@ public class Date { return getTime(); } @Native - public double setUTCDate(CallContext ctx, Object val) throws InterruptedException { + public double setUTCDate(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.DAY_OF_MONTH, (int)real); @@ -228,7 +228,7 @@ public class Date { return getTime(); } @Native - public double setUTCDay(CallContext ctx, Object val) throws InterruptedException { + public double setUTCDay(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.DAY_OF_WEEK, (int)real); @@ -236,7 +236,7 @@ public class Date { return getTime(); } @Native - public double setUTCHours(CallContext ctx, Object val) throws InterruptedException { + public double setUTCHours(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.HOUR_OF_DAY, (int)real); @@ -244,7 +244,7 @@ public class Date { return getTime(); } @Native - public double setUTCMinutes(CallContext ctx, Object val) throws InterruptedException { + public double setUTCMinutes(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.MINUTE, (int)real); @@ -252,7 +252,7 @@ public class Date { return getTime(); } @Native - public double setUTCSeconds(CallContext ctx, Object val) throws InterruptedException { + public double setUTCSeconds(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.SECOND, (int)real); @@ -260,7 +260,7 @@ public class Date { return getTime(); } @Native - public double setUTCMilliseconds(CallContext ctx, Object val) throws InterruptedException { + public double setUTCMilliseconds(Context ctx, Object val) throws InterruptedException { var real = Values.toNumber(ctx, val); if (Double.isNaN(real)) invalidate(); else utc.set(Calendar.MILLISECOND, (int)real); diff --git a/src/me/topchetoeu/jscript/polyfills/GeneratorFunction.java b/src/me/topchetoeu/jscript/polyfills/GeneratorFunction.java index 159a01a..17b098f 100644 --- a/src/me/topchetoeu/jscript/polyfills/GeneratorFunction.java +++ b/src/me/topchetoeu/jscript/polyfills/GeneratorFunction.java @@ -1,6 +1,6 @@ package me.topchetoeu.jscript.polyfills; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.frame.CodeFrame; import me.topchetoeu.jscript.engine.frame.Runners; import me.topchetoeu.jscript.engine.values.CodeFunction; @@ -18,7 +18,7 @@ public class GeneratorFunction extends FunctionValue { private boolean done = false; public CodeFrame frame; - private ObjectValue next(CallContext ctx, Object inducedValue, Object inducedReturn, Object inducedError) throws InterruptedException { + private ObjectValue next(Context ctx, Object inducedValue, Object inducedReturn, Object inducedError) throws InterruptedException { if (done) { if (inducedError != Runners.NO_RETURN) throw new EngineException(inducedError); var res = new ObjectValue(); @@ -29,7 +29,7 @@ public class GeneratorFunction extends FunctionValue { Object res = null; if (inducedValue != Runners.NO_RETURN) frame.push(ctx, inducedValue); - frame.start(ctx); + ctx.message.pushFrame(frame); yielding = false; while (!yielding) { try { @@ -46,7 +46,7 @@ public class GeneratorFunction extends FunctionValue { } } - frame.end(ctx); + ctx.message.popFrame(frame); if (done) frame = null; else res = frame.pop(); @@ -57,16 +57,16 @@ public class GeneratorFunction extends FunctionValue { } @Native - public ObjectValue next(CallContext ctx, Object... args) throws InterruptedException { + public ObjectValue next(Context ctx, Object ...args) throws InterruptedException { 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); } @Native("throw") - public ObjectValue _throw(CallContext ctx, Object error) throws InterruptedException { + public ObjectValue _throw(Context ctx, Object error) throws InterruptedException { return next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, error); } @Native("return") - public ObjectValue _return(CallContext ctx, Object value) throws InterruptedException { + public ObjectValue _return(Context ctx, Object value) throws InterruptedException { return next(ctx, Runners.NO_RETURN, value, Runners.NO_RETURN); } @@ -77,14 +77,14 @@ public class GeneratorFunction extends FunctionValue { return "Generator " + (done ? "[closed]" : "[suspended]"); } - public Object yield(CallContext ctx, Object thisArg, Object[] args) { + public Object yield(Context ctx, Object thisArg, Object[] args) { this.yielding = true; return args.length > 0 ? args[0] : null; } } @Override - public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException { + public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { var handler = new Generator(); var func = factory.call(ctx, thisArg, new NativeFunction("yield", handler::yield)); if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function."); diff --git a/src/me/topchetoeu/jscript/polyfills/Internals.java b/src/me/topchetoeu/jscript/polyfills/Internals.java index c6bee13..71fbbab 100644 --- a/src/me/topchetoeu/jscript/polyfills/Internals.java +++ b/src/me/topchetoeu/jscript/polyfills/Internals.java @@ -1,7 +1,7 @@ package me.topchetoeu.jscript.polyfills; -import me.topchetoeu.jscript.engine.CallContext; -import me.topchetoeu.jscript.engine.Environment; +import me.topchetoeu.jscript.engine.Context; +import me.topchetoeu.jscript.engine.FunctionContext; import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.CodeFunction; import me.topchetoeu.jscript.engine.values.FunctionValue; @@ -12,23 +12,23 @@ import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.interop.Native; public class Internals { - @Native public void markSpecial(FunctionValue... funcs) { + @Native public void markSpecial(FunctionValue ...funcs) { for (var func : funcs) { func.special = true; } } - @Native public Environment getEnv(Object func) { + @Native public FunctionContext getEnv(Object func) { if (func instanceof CodeFunction) return ((CodeFunction)func).environment; else return null; } - @Native public Object setEnv(Object func, Environment env) { + @Native public Object setEnv(Object func, FunctionContext env) { if (func instanceof CodeFunction) ((CodeFunction)func).environment = env; return func; } - @Native public Object apply(CallContext ctx, FunctionValue func, Object thisArg, ArrayValue args) throws InterruptedException { + @Native public Object apply(Context ctx, FunctionValue func, Object thisArg, ArrayValue args) throws InterruptedException { return func.call(ctx, thisArg, args.toArray()); } - @Native public FunctionValue delay(CallContext ctx, double delay, FunctionValue callback) throws InterruptedException { + @Native public FunctionValue delay(Context ctx, double delay, FunctionValue callback) throws InterruptedException { var thread = new Thread((Runnable)() -> { var ms = (long)delay; var ns = (int)((delay - ms) * 10000000); @@ -38,7 +38,7 @@ public class Internals { } catch (InterruptedException e) { return; } - ctx.engine.pushMsg(false, ctx.data(), ctx.environment, callback, null); + ctx.message.engine.pushMsg(false, ctx.message, callback, null); }); thread.start(); @@ -47,8 +47,8 @@ public class Internals { return null; }); } - @Native public void pushMessage(CallContext ctx, boolean micro, FunctionValue func, Object thisArg, Object[] args) { - ctx.engine.pushMsg(micro, ctx.data(), ctx.environment, func, thisArg, args); + @Native public void pushMessage(Context ctx, boolean micro, FunctionValue func, Object thisArg, Object[] args) { + ctx.message.engine.pushMsg(micro, ctx.message, func, thisArg, args); } @Native public int strlen(String str) { @@ -74,6 +74,13 @@ public class Internals { return str.value; } + @Native public static void log(Context ctx, Object ...args) throws InterruptedException { + for (var arg : args) { + Values.printValue(ctx, arg); + } + System.out.println(); + } + @Native public boolean isArray(Object obj) { return obj instanceof ArrayValue; } @@ -81,14 +88,14 @@ public class Internals { return new GeneratorFunction(obj); } - @Native public boolean defineField(CallContext ctx, ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) { + @Native public boolean defineField(Context ctx, ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) { return obj.defineProperty(ctx, key, val, writable, configurable, enumerable); } - @Native public boolean defineProp(CallContext ctx, ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) { + @Native public boolean defineProp(Context ctx, ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) { return obj.defineProperty(ctx, key, getter, setter, configurable, enumerable); } - @Native public ArrayValue keys(CallContext ctx, Object obj, boolean onlyString) throws InterruptedException { + @Native public ArrayValue keys(Context ctx, Object obj, boolean onlyString) throws InterruptedException { var res = new ArrayValue(); var i = 0; @@ -98,7 +105,7 @@ public class Internals { return res; } - @Native public ArrayValue ownPropKeys(CallContext ctx, Object obj, boolean symbols) throws InterruptedException { + @Native public ArrayValue ownPropKeys(Context ctx, Object obj, boolean symbols) throws InterruptedException { var res = new ArrayValue(); if (Values.isObject(obj)) { @@ -110,7 +117,7 @@ public class Internals { return res; } - @Native public ObjectValue ownProp(CallContext ctx, ObjectValue val, Object key) throws InterruptedException { + @Native public ObjectValue ownProp(Context ctx, ObjectValue val, Object key) throws InterruptedException { return val.getMemberDescriptor(ctx, key); } @Native public void lock(ObjectValue val, String type) { @@ -124,7 +131,7 @@ public class Internals { return val.extensible(); } - @Native public void sort(CallContext ctx, ArrayValue arr, FunctionValue cmp) { + @Native public void sort(Context ctx, ArrayValue arr, FunctionValue cmp) { arr.sort((a, b) -> { try { var res = Values.toNumber(ctx, cmp.call(ctx, null, a, b)); diff --git a/src/me/topchetoeu/jscript/polyfills/JSON.java b/src/me/topchetoeu/jscript/polyfills/JSON.java index 755c633..53873a5 100644 --- a/src/me/topchetoeu/jscript/polyfills/JSON.java +++ b/src/me/topchetoeu/jscript/polyfills/JSON.java @@ -3,7 +3,7 @@ package me.topchetoeu.jscript.polyfills; import java.util.HashSet; import java.util.stream.Collectors; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.Values; @@ -30,7 +30,7 @@ public class JSON { if (val.isNull()) return Values.NULL; return null; } - private static JSONElement toJSON(CallContext ctx, Object val, HashSet prev) throws InterruptedException { + private static JSONElement toJSON(Context ctx, Object val, HashSet prev) throws InterruptedException { if (val instanceof Boolean) return JSONElement.bool((boolean)val); if (val instanceof Number) return JSONElement.number(((Number)val).doubleValue()); if (val instanceof String) return JSONElement.string((String)val); @@ -70,7 +70,7 @@ public class JSON { } @Native - public static Object parse(CallContext ctx, String val) throws InterruptedException { + public static Object parse(Context ctx, String val) throws InterruptedException { try { return toJS(me.topchetoeu.jscript.json.JSON.parse("", val)); } @@ -79,7 +79,7 @@ public class JSON { } } @Native - public static String stringify(CallContext ctx, Object val) throws InterruptedException { + public static String stringify(Context ctx, Object val) throws InterruptedException { return me.topchetoeu.jscript.json.JSON.stringify(toJSON(ctx, val, new HashSet<>())); } } diff --git a/src/me/topchetoeu/jscript/polyfills/Math.java b/src/me/topchetoeu/jscript/polyfills/Math.java index 8a4380f..fe6f0d3 100644 --- a/src/me/topchetoeu/jscript/polyfills/Math.java +++ b/src/me/topchetoeu/jscript/polyfills/Math.java @@ -1,6 +1,6 @@ package me.topchetoeu.jscript.polyfills; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.MessageContext; import me.topchetoeu.jscript.interop.Native; public class Math { @@ -22,19 +22,19 @@ public class Math { public static final double LOG10E = java.lang.Math.log10(java.lang.Math.E); @Native - public static double asin(CallContext ctx, double x) throws InterruptedException { + public static double asin(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.asin(x); } @Native - public static double acos(CallContext ctx, double x) throws InterruptedException { + public static double acos(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.acos(x); } @Native - public static double atan(CallContext ctx, double x) throws InterruptedException { + public static double atan(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.atan(x); } @Native - public static double atan2(CallContext ctx, double y, double x) throws InterruptedException { + public static double atan2(MessageContext ctx, double y, double x) throws InterruptedException { double _y = y; double _x = x; if (_x == 0) { @@ -51,59 +51,59 @@ public class Math { } @Native - public static double asinh(CallContext ctx, double x) throws InterruptedException { + public static double asinh(MessageContext ctx, double x) throws InterruptedException { double _x = x; return java.lang.Math.log(_x + java.lang.Math.sqrt(_x * _x + 1)); } @Native - public static double acosh(CallContext ctx, double x) throws InterruptedException { + public static double acosh(MessageContext ctx, double x) throws InterruptedException { double _x = x; return java.lang.Math.log(_x + java.lang.Math.sqrt(_x * _x - 1)); } @Native - public static double atanh(CallContext ctx, double x) throws InterruptedException { + public static double atanh(MessageContext ctx, double x) throws InterruptedException { double _x = x; if (_x <= -1 || _x >= 1) return Double.NaN; return .5 * java.lang.Math.log((1 + _x) / (1 - _x)); } @Native - public static double sin(CallContext ctx, double x) throws InterruptedException { + public static double sin(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.sin(x); } @Native - public static double cos(CallContext ctx, double x) throws InterruptedException { + public static double cos(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.cos(x); } @Native - public static double tan(CallContext ctx, double x) throws InterruptedException { + public static double tan(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.tan(x); } @Native - public static double sinh(CallContext ctx, double x) throws InterruptedException { + public static double sinh(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.sinh(x); } @Native - public static double cosh(CallContext ctx, double x) throws InterruptedException { + public static double cosh(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.cosh(x); } @Native - public static double tanh(CallContext ctx, double x) throws InterruptedException { + public static double tanh(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.tanh(x); } @Native - public static double sqrt(CallContext ctx, double x) throws InterruptedException { + public static double sqrt(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.sqrt(x); } @Native - public static double cbrt(CallContext ctx, double x) throws InterruptedException { + public static double cbrt(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.cbrt(x); } @Native - public static double hypot(CallContext ctx, double... vals) throws InterruptedException { + public static double hypot(MessageContext ctx, double ...vals) throws InterruptedException { var res = 0.; for (var el : vals) { var val = el; @@ -112,68 +112,68 @@ public class Math { return java.lang.Math.sqrt(res); } @Native - public static int imul(CallContext ctx, double a, double b) throws InterruptedException { + public static int imul(MessageContext ctx, double a, double b) throws InterruptedException { return (int)a * (int)b; } @Native - public static double exp(CallContext ctx, double x) throws InterruptedException { + public static double exp(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.exp(x); } @Native - public static double expm1(CallContext ctx, double x) throws InterruptedException { + public static double expm1(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.expm1(x); } @Native - public static double pow(CallContext ctx, double x, double y) throws InterruptedException { + public static double pow(MessageContext ctx, double x, double y) throws InterruptedException { return java.lang.Math.pow(x, y); } @Native - public static double log(CallContext ctx, double x) throws InterruptedException { + public static double log(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.log(x); } @Native - public static double log10(CallContext ctx, double x) throws InterruptedException { + public static double log10(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.log10(x); } @Native - public static double log1p(CallContext ctx, double x) throws InterruptedException { + public static double log1p(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.log1p(x); } @Native - public static double log2(CallContext ctx, double x) throws InterruptedException { + public static double log2(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.log(x) / LN2; } @Native - public static double ceil(CallContext ctx, double x) throws InterruptedException { + public static double ceil(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.ceil(x); } @Native - public static double floor(CallContext ctx, double x) throws InterruptedException { + public static double floor(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.floor(x); } @Native - public static double round(CallContext ctx, double x) throws InterruptedException { + public static double round(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.round(x); } @Native - public static float fround(CallContext ctx, double x) throws InterruptedException { + public static float fround(MessageContext ctx, double x) throws InterruptedException { return (float)x; } @Native - public static double trunc(CallContext ctx, double x) throws InterruptedException { + public static double trunc(MessageContext ctx, double x) throws InterruptedException { var _x = x; return java.lang.Math.floor(java.lang.Math.abs(_x)) * java.lang.Math.signum(_x); } @Native - public static double abs(CallContext ctx, double x) throws InterruptedException { + public static double abs(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.abs(x); } @Native - public static double max(CallContext ctx, double... vals) throws InterruptedException { + public static double max(MessageContext ctx, double ...vals) throws InterruptedException { var res = Double.NEGATIVE_INFINITY; for (var el : vals) { @@ -184,7 +184,7 @@ public class Math { return res; } @Native - public static double min(CallContext ctx, double... vals) throws InterruptedException { + public static double min(MessageContext ctx, double ...vals) throws InterruptedException { var res = Double.POSITIVE_INFINITY; for (var el : vals) { @@ -196,7 +196,7 @@ public class Math { } @Native - public static double sign(CallContext ctx, double x) throws InterruptedException { + public static double sign(MessageContext ctx, double x) throws InterruptedException { return java.lang.Math.signum(x); } @@ -205,7 +205,7 @@ public class Math { return java.lang.Math.random(); } @Native - public static int clz32(CallContext ctx, double x) throws InterruptedException { + public static int clz32(MessageContext ctx, double x) throws InterruptedException { return Integer.numberOfLeadingZeros((int)x); } } diff --git a/src/me/topchetoeu/jscript/polyfills/PolyfillEngine.java- b/src/me/topchetoeu/jscript/polyfills/PolyfillEngine.java- deleted file mode 100644 index 0ea635e..0000000 --- a/src/me/topchetoeu/jscript/polyfills/PolyfillEngine.java- +++ /dev/null @@ -1,105 +0,0 @@ -package me.topchetoeu.jscript.polyfills; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import me.topchetoeu.jscript.engine.Engine; -import me.topchetoeu.jscript.engine.modules.ModuleManager; - -public class PolyfillEngine extends Engine { - public static String streamToString(InputStream in) { - try { - StringBuilder out = new StringBuilder(); - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - - for(var line = br.readLine(); line != null; line = br.readLine()) { - out.append(line).append('\n'); - } - - br.close(); - return out.toString(); - } - catch (IOException e) { - return null; - } - } - public static String resourceToString(String name) { - var str = PolyfillEngine.class.getResourceAsStream("/me/topchetoeu/jscript/" + name); - if (str == null) return null; - return streamToString(str); - } - - public final ModuleManager modules; - - @Override - public Object makeRegex(String pattern, String flags) { - return new RegExp(pattern, flags); - } - - @Override - public ModuleManager modules() { - return modules; - } - public PolyfillEngine(File root) { - super(); - - 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); - - // 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; - // })); - - // 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); - - // func.call(ctx); - // return null; - // })); - - // pushMsg(false, scope.globalChild(), java.util.Map.of(), "core.js", resourceToString("js/core.js"), null); - } -} diff --git a/src/me/topchetoeu/jscript/polyfills/RegExp.java b/src/me/topchetoeu/jscript/polyfills/RegExp.java index 5f7dca6..804d0e7 100644 --- a/src/me/topchetoeu/jscript/polyfills/RegExp.java +++ b/src/me/topchetoeu/jscript/polyfills/RegExp.java @@ -3,7 +3,7 @@ package me.topchetoeu.jscript.polyfills; import java.util.ArrayList; import java.util.regex.Pattern; -import me.topchetoeu.jscript.engine.CallContext; +import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.NativeWrapper; import me.topchetoeu.jscript.engine.values.ObjectValue; @@ -17,7 +17,7 @@ public class RegExp { private static final Pattern NAMED_PATTERN = Pattern.compile("\\(\\?<([^=!].*?)>", Pattern.DOTALL); private static final Pattern ESCAPE_PATTERN = Pattern.compile("[/\\-\\\\^$*+?.()|\\[\\]{}]"); - private static String cleanupPattern(CallContext ctx, Object val) throws InterruptedException { + private static String cleanupPattern(Context ctx, Object val) throws InterruptedException { if (val == null) return "(?:)"; if (val instanceof RegExp) return ((RegExp)val).source; if (val instanceof NativeWrapper && ((NativeWrapper)val).wrapped instanceof RegExp) { @@ -27,7 +27,7 @@ public class RegExp { if (res.equals("")) return "(?:)"; return res; } - private static String cleanupFlags(CallContext ctx, Object val) throws InterruptedException { + private static String cleanupFlags(Context ctx, Object val) throws InterruptedException { if (val == null) return ""; return Values.toString(ctx, val); } @@ -46,7 +46,7 @@ public class RegExp { } @Native - public static RegExp escape(CallContext ctx, Object raw, Object flags) throws InterruptedException { + public static RegExp escape(Context ctx, Object raw, Object flags) throws InterruptedException { return escape(Values.toString(ctx, raw), cleanupFlags(ctx, flags)); } public static RegExp escape(String raw, String flags) { @@ -79,7 +79,7 @@ public class RegExp { @NativeGetter("lastIndex") public int lastIndex() { return lastI; } @NativeSetter("lastIndex") - public void setLastIndex(CallContext ctx, Object i) throws InterruptedException { + public void setLastIndex(Context ctx, Object i) throws InterruptedException { lastI = (int)Values.toNumber(ctx, i); } public void setLastIndex(int i) { @@ -100,7 +100,7 @@ public class RegExp { } @Native - public Object exec(CallContext ctx, Object str) throws InterruptedException { + public Object exec(Context ctx, Object str) throws InterruptedException { return exec(Values.toString(ctx, str)); } public Object exec(String str) { @@ -150,7 +150,7 @@ public class RegExp { } @Native - public RegExp(CallContext ctx, Object pattern, Object flags) throws InterruptedException { + public RegExp(Context ctx, Object pattern, Object flags) throws InterruptedException { this(cleanupPattern(ctx, pattern), cleanupFlags(ctx, flags)); } public RegExp(String pattern, String flags) { diff --git a/src/me/topchetoeu/jscript/polyfills/TypescriptEngine.java- b/src/me/topchetoeu/jscript/polyfills/TypescriptEngine.java- deleted file mode 100644 index 54b677e..0000000 --- a/src/me/topchetoeu/jscript/polyfills/TypescriptEngine.java- +++ /dev/null @@ -1,61 +0,0 @@ -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(); - 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); - } -}