refactor: improve Engine API

This commit is contained in:
TopchetoEU 2023-12-24 14:26:42 +02:00
parent 93973c12b1
commit 078d7ed95f
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
7 changed files with 402 additions and 403 deletions

View File

@ -1,170 +1,168 @@
package me.topchetoeu.jscript; package me.topchetoeu.jscript;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.Engine; import me.topchetoeu.jscript.engine.Engine;
import me.topchetoeu.jscript.engine.Environment; import me.topchetoeu.jscript.engine.Environment;
import me.topchetoeu.jscript.engine.debug.DebugServer; import me.topchetoeu.jscript.engine.debug.DebugServer;
import me.topchetoeu.jscript.engine.debug.SimpleDebugger; import me.topchetoeu.jscript.engine.debug.SimpleDebugger;
import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.NativeFunction; import me.topchetoeu.jscript.engine.values.NativeFunction;
import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.events.Observer; import me.topchetoeu.jscript.events.Observer;
import me.topchetoeu.jscript.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.exceptions.InterruptException; import me.topchetoeu.jscript.exceptions.InterruptException;
import me.topchetoeu.jscript.exceptions.SyntaxException; import me.topchetoeu.jscript.exceptions.SyntaxException;
import me.topchetoeu.jscript.filesystem.MemoryFilesystem; import me.topchetoeu.jscript.filesystem.MemoryFilesystem;
import me.topchetoeu.jscript.filesystem.Mode; import me.topchetoeu.jscript.filesystem.Mode;
import me.topchetoeu.jscript.filesystem.PhysicalFilesystem; import me.topchetoeu.jscript.filesystem.PhysicalFilesystem;
import me.topchetoeu.jscript.lib.Internals; import me.topchetoeu.jscript.lib.Internals;
public class Main { public class Main {
public static class Printer implements Observer<Object> { public static class Printer implements Observer<Object> {
public void next(Object data) { public void next(Object data) {
Values.printValue(null, data); Values.printValue(null, data);
System.out.println(); System.out.println();
} }
public void error(RuntimeException err) { public void error(RuntimeException err) {
Values.printError(err, null); Values.printError(err, null);
} }
public void finish() { public void finish() {
engineTask.interrupt(); engineTask.interrupt();
} }
} }
static Thread engineTask, debugTask; static Thread engineTask, debugTask;
static Engine engine = new Engine(true); static Engine engine = new Engine(true);
static DebugServer debugServer = new DebugServer(); static DebugServer debugServer = new DebugServer();
static Environment environment = new Environment(null, null, null); static Environment environment = new Environment(null, null, null);
static int j = 0; static int j = 0;
static boolean exited = false; static boolean exited = false;
static String[] args; static String[] args;
private static void reader() { private static void reader() {
try { try {
for (var arg : args) { for (var arg : args) {
try { try {
if (arg.equals("--ts")) initTypescript(); if (arg.equals("--ts")) initTypescript();
else { else {
var file = Path.of(arg); var file = Path.of(arg);
var raw = Files.readString(file); var raw = Files.readString(file);
var res = engine.pushMsg( var res = engine.pushMsg(
false, new Context(engine, environment), false, environment,
Filename.fromFile(file.toFile()), Filename.fromFile(file.toFile()),
raw, null raw, null
).await(); ).await();
Values.printValue(null, res); Values.printValue(null, res);
System.out.println(); System.out.println();
} }
} }
catch (EngineException e) { Values.printError(e, null); } catch (EngineException e) { Values.printError(e, null); }
} }
for (var i = 0; ; i++) { for (var i = 0; ; i++) {
try { try {
var raw = Reading.read(); var raw = Reading.read();
if (raw == null) break; if (raw == null) break;
var res = engine.pushMsg( var res = engine.pushMsg(
false, new Context(engine, environment), false, environment,
new Filename("jscript", "repl/" + i + ".js"), new Filename("jscript", "repl/" + i + ".js"),
raw, null raw, null
).await(); ).await();
Values.printValue(null, res); Values.printValue(null, res);
System.out.println(); System.out.println();
} }
catch (EngineException e) { Values.printError(e, null); } catch (EngineException e) { Values.printError(e, null); }
catch (SyntaxException e) { Values.printError(e, null); } catch (SyntaxException e) { Values.printError(e, null); }
} }
} }
catch (IOException e) { catch (IOException e) {
System.out.println(e.toString()); System.out.println(e.toString());
exited = true; exited = true;
} }
catch (RuntimeException ex) { catch (RuntimeException ex) {
if (!exited) { if (!exited) {
System.out.println("Internal error ocurred:"); System.out.println("Internal error ocurred:");
ex.printStackTrace(); ex.printStackTrace();
} }
} }
if (exited) { if (exited) {
debugTask.interrupt(); debugTask.interrupt();
engineTask.interrupt(); engineTask.interrupt();
} }
} }
private static void initEnv() { private static void initEnv() {
environment = Internals.apply(environment); environment = Internals.apply(environment);
environment.global.define(false, new NativeFunction("exit", (_ctx, th, args) -> { environment.global.define(false, new NativeFunction("exit", (_ctx, th, args) -> {
exited = true; exited = true;
throw new InterruptException(); throw new InterruptException();
})); }));
environment.global.define(false, new NativeFunction("go", (_ctx, th, args) -> { environment.global.define(false, new NativeFunction("go", (_ctx, th, args) -> {
try { try {
var f = Path.of("do.js"); var f = Path.of("do.js");
var func = _ctx.compile(new Filename("do", "do/" + j++ + ".js"), new String(Files.readAllBytes(f))); var func = _ctx.compile(new Filename("do", "do/" + j++ + ".js"), new String(Files.readAllBytes(f)));
return func.call(_ctx); return func.call(_ctx);
} }
catch (IOException e) { catch (IOException e) {
throw new EngineException("Couldn't open do.js"); throw new EngineException("Couldn't open do.js");
} }
})); }));
environment.filesystem.protocols.put("temp", new MemoryFilesystem(Mode.READ_WRITE)); environment.filesystem.protocols.put("temp", new MemoryFilesystem(Mode.READ_WRITE));
environment.filesystem.protocols.put("file", new PhysicalFilesystem(Path.of(".").toAbsolutePath())); environment.filesystem.protocols.put("file", new PhysicalFilesystem(Path.of(".").toAbsolutePath()));
} }
private static void initEngine() { private static void initEngine() {
debugServer.targets.put("target", (ws, req) -> new SimpleDebugger(ws, engine)); debugServer.targets.put("target", (ws, req) -> new SimpleDebugger(ws, engine));
engineTask = engine.start(); engineTask = engine.start();
debugTask = debugServer.start(new InetSocketAddress("127.0.0.1", 9229), true); debugTask = debugServer.start(new InetSocketAddress("127.0.0.1", 9229), true);
} }
private static void initTypescript() { private static void initTypescript() {
try { try {
var tsEnv = Internals.apply(new Environment(null, null, null)); var tsEnv = Internals.apply(new Environment(null, null, null));
tsEnv.stackVisible = false; tsEnv.stackVisible = false;
tsEnv.global.define(null, "module", false, new ObjectValue()); tsEnv.global.define(null, "module", false, new ObjectValue());
var bsEnv = Internals.apply(new Environment(null, null, null)); var bsEnv = Internals.apply(new Environment(null, null, null));
bsEnv.stackVisible = false; bsEnv.stackVisible = false;
engine.pushMsg( engine.pushMsg(
false, new Context(engine, tsEnv), false, tsEnv,
new Filename("jscript", "ts.js"), new Filename("jscript", "ts.js"),
Reading.resourceToString("js/ts.js"), null Reading.resourceToString("js/ts.js"), null
).await(); ).await();
System.out.println("Loaded typescript!"); System.out.println("Loaded typescript!");
var ctx = new Context(engine, bsEnv); engine.pushMsg(
false, bsEnv,
engine.pushMsg( new Filename("jscript", "bootstrap.js"), Reading.resourceToString("js/bootstrap.js"), null,
false, ctx, tsEnv.global.get(new Context(engine, bsEnv), "ts"), environment, new ArrayValue(null, Reading.resourceToString("js/lib.d.ts"))
new Filename("jscript", "bootstrap.js"), Reading.resourceToString("js/bootstrap.js"), null, ).await();
tsEnv.global.get(ctx, "ts"), environment, new ArrayValue(null, Reading.resourceToString("js/lib.d.ts")) }
).await(); catch (EngineException e) {
} Values.printError(e, "(while initializing TS)");
catch (EngineException e) { }
Values.printError(e, "(while initializing TS)"); }
}
} public static void main(String args[]) {
System.out.println(String.format("Running %s v%s by %s", Metadata.name(), Metadata.version(), Metadata.author()));
public static void main(String args[]) {
System.out.println(String.format("Running %s v%s by %s", Metadata.name(), Metadata.version(), Metadata.author())); Main.args = args;
var reader = new Thread(Main::reader);
Main.args = args;
var reader = new Thread(Main::reader); initEnv();
initEngine();
initEnv();
initEngine(); reader.setDaemon(true);
reader.setName("STD Reader");
reader.setDaemon(true); reader.start();
reader.setName("STD Reader"); }
reader.start(); }
}
}

View File

@ -119,7 +119,6 @@ public class Context {
} }
public Context(Engine engine, Environment env) { public Context(Engine engine, Environment env) {
this(engine); this(engine);
this.pushEnv(env); if (env != null) this.pushEnv(env);
} }
} }

View File

@ -141,13 +141,13 @@ public class Engine implements DebugController {
return this.thread != null; return this.thread != null;
} }
public Awaitable<Object> pushMsg(boolean micro, Context ctx, FunctionValue func, Object thisArg, Object ...args) { public Awaitable<Object> pushMsg(boolean micro, Environment env, FunctionValue func, Object thisArg, Object ...args) {
var msg = new Task(ctx == null ? new Context(this) : ctx, func, thisArg, args, micro); var msg = new Task(new Context(this, env), func, thisArg, args, micro);
tasks.add(msg); tasks.add(msg);
return msg.notifier; return msg.notifier;
} }
public Awaitable<Object> pushMsg(boolean micro, Context ctx, Filename filename, String raw, Object thisArg, Object ...args) { public Awaitable<Object> pushMsg(boolean micro, Environment env, Filename filename, String raw, Object thisArg, Object ...args) {
return pushMsg(micro, ctx, new UncompiledFunction(filename, raw), thisArg, args); return pushMsg(micro, env, new UncompiledFunction(filename, raw), thisArg, args);
} }
@Override @Override

View File

@ -53,7 +53,6 @@ public class Environment implements PermissionsProvider {
res.defineProperty(ctx, "function", target.func(env)); res.defineProperty(ctx, "function", target.func(env));
res.defineProperty(ctx, "mapChain", new ArrayValue()); res.defineProperty(ctx, "mapChain", new ArrayValue());
if (isDebug) { if (isDebug) {
res.defineProperty(ctx, "breakpoints", ArrayValue.of(ctx, target.breakpoints.stream().map(Location::toString).collect(Collectors.toList()))); res.defineProperty(ctx, "breakpoints", ArrayValue.of(ctx, target.breakpoints.stream().map(Location::toString).collect(Collectors.toList())));
} }
@ -128,4 +127,7 @@ public class Environment implements PermissionsProvider {
this.wrappers = nativeConverter; this.wrappers = nativeConverter;
this.global = global; this.global = global;
} }
public Environment() {
this(null, null, null);
}
} }

View File

@ -483,7 +483,7 @@ public class SimpleDebugger implements Debugger {
env.global = new GlobalScope(codeFrame.local); env.global = new GlobalScope(codeFrame.local);
var ctx = new Context(engine).pushEnv(env); var ctx = new Context(engine).pushEnv(env);
var awaiter = engine.pushMsg(false, ctx, new Filename("jscript", "eval"), code, codeFrame.frame.thisArg, codeFrame.frame.args); var awaiter = engine.pushMsg(false, ctx.environment(), new Filename("jscript", "eval"), code, codeFrame.frame.thisArg, codeFrame.frame.args);
engine.run(true); engine.run(true);

View File

@ -1,221 +1,221 @@
package me.topchetoeu.jscript.lib; package me.topchetoeu.jscript.lib;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import me.topchetoeu.jscript.Buffer; import me.topchetoeu.jscript.Buffer;
import me.topchetoeu.jscript.Reading; import me.topchetoeu.jscript.Reading;
import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.DataKey; import me.topchetoeu.jscript.engine.DataKey;
import me.topchetoeu.jscript.engine.Environment; import me.topchetoeu.jscript.engine.Environment;
import me.topchetoeu.jscript.engine.scope.GlobalScope; import me.topchetoeu.jscript.engine.scope.GlobalScope;
import me.topchetoeu.jscript.engine.values.FunctionValue; import me.topchetoeu.jscript.engine.values.FunctionValue;
import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Native; import me.topchetoeu.jscript.interop.Native;
import me.topchetoeu.jscript.interop.NativeGetter; import me.topchetoeu.jscript.interop.NativeGetter;
import me.topchetoeu.jscript.parsing.Parsing; import me.topchetoeu.jscript.parsing.Parsing;
public class Internals { public class Internals {
private static final DataKey<HashMap<Integer, Thread>> THREADS = new DataKey<>(); private static final DataKey<HashMap<Integer, Thread>> THREADS = new DataKey<>();
private static final DataKey<Integer> I = new DataKey<>(); private static final DataKey<Integer> I = new DataKey<>();
@Native public static Object log(Context ctx, Object ...args) { @Native public static Object log(Context ctx, Object ...args) {
for (var arg : args) { for (var arg : args) {
Values.printValue(ctx, arg); Values.printValue(ctx, arg);
System.out.print(" "); System.out.print(" ");
} }
System.out.println(); System.out.println();
if (args.length == 0) return null; if (args.length == 0) return null;
else return args[0]; else return args[0];
} }
@Native public static String readline(Context ctx) { @Native public static String readline(Context ctx) {
try { try {
return Reading.read(); return Reading.read();
} }
catch (IOException e) { catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
@Native public static int setTimeout(Context ctx, FunctionValue func, int delay, Object ...args) { @Native public static int setTimeout(Context ctx, FunctionValue func, int delay, Object ...args) {
var thread = new Thread(() -> { var thread = new Thread(() -> {
var ms = (long)delay; var ms = (long)delay;
var ns = (int)((delay - ms) * 10000000); var ns = (int)((delay - ms) * 10000000);
try { try {
Thread.sleep(ms, ns); Thread.sleep(ms, ns);
} }
catch (InterruptedException e) { return; } catch (InterruptedException e) { return; }
ctx.engine.pushMsg(false, ctx, func, null, args); ctx.engine.pushMsg(false, ctx.environment(), func, null, args);
}); });
thread.start(); thread.start();
int i = ctx.environment().data.increase(I, 1, 0); int i = ctx.environment().data.increase(I, 1, 0);
var threads = ctx.environment().data.get(THREADS, new HashMap<>()); var threads = ctx.environment().data.get(THREADS, new HashMap<>());
threads.put(++i, thread); threads.put(++i, thread);
return i; return i;
} }
@Native public static int setInterval(Context ctx, FunctionValue func, int delay, Object ...args) { @Native public static int setInterval(Context ctx, FunctionValue func, int delay, Object ...args) {
var thread = new Thread(() -> { var thread = new Thread(() -> {
var ms = (long)delay; var ms = (long)delay;
var ns = (int)((delay - ms) * 10000000); var ns = (int)((delay - ms) * 10000000);
while (true) { while (true) {
try { try {
Thread.sleep(ms, ns); Thread.sleep(ms, ns);
} }
catch (InterruptedException e) { return; } catch (InterruptedException e) { return; }
ctx.engine.pushMsg(false, ctx, func, null, args); ctx.engine.pushMsg(false, ctx.environment(), func, null, args);
} }
}); });
thread.start(); thread.start();
int i = ctx.environment().data.increase(I, 1, 0); int i = ctx.environment().data.increase(I, 1, 0);
var threads = ctx.environment().data.get(THREADS, new HashMap<>()); var threads = ctx.environment().data.get(THREADS, new HashMap<>());
threads.put(++i, thread); threads.put(++i, thread);
return i; return i;
} }
@Native public static void clearTimeout(Context ctx, int i) { @Native public static void clearTimeout(Context ctx, int i) {
var threads = ctx.environment().data.get(THREADS, new HashMap<>()); var threads = ctx.environment().data.get(THREADS, new HashMap<>());
var thread = threads.remove(i); var thread = threads.remove(i);
if (thread != null) thread.interrupt(); if (thread != null) thread.interrupt();
} }
@Native public static void clearInterval(Context ctx, int i) { @Native public static void clearInterval(Context ctx, int i) {
clearTimeout(ctx, i); clearTimeout(ctx, i);
} }
@Native public static double parseInt(Context ctx, String val) { @Native public static double parseInt(Context ctx, String val) {
return NumberLib.parseInt(ctx, val); return NumberLib.parseInt(ctx, val);
} }
@Native public static double parseFloat(Context ctx, String val) { @Native public static double parseFloat(Context ctx, String val) {
return NumberLib.parseFloat(ctx, val); return NumberLib.parseFloat(ctx, val);
} }
@Native public static boolean isNaN(Context ctx, double val) { @Native public static boolean isNaN(Context ctx, double val) {
return NumberLib.isNaN(ctx, val); return NumberLib.isNaN(ctx, val);
} }
@Native public static boolean isFinite(Context ctx, double val) { @Native public static boolean isFinite(Context ctx, double val) {
return NumberLib.isFinite(ctx, val); return NumberLib.isFinite(ctx, val);
} }
@Native public static boolean isInfinite(Context ctx, double val) { @Native public static boolean isInfinite(Context ctx, double val) {
return NumberLib.isInfinite(ctx, val); return NumberLib.isInfinite(ctx, val);
} }
@NativeGetter public static double NaN(Context ctx) { @NativeGetter public static double NaN(Context ctx) {
return Double.NaN; return Double.NaN;
} }
@NativeGetter public static double Infinity(Context ctx) { @NativeGetter public static double Infinity(Context ctx) {
return Double.POSITIVE_INFINITY; return Double.POSITIVE_INFINITY;
} }
private static final String HEX = "0123456789ABCDEF"; private static final String HEX = "0123456789ABCDEF";
private static String encodeUriAny(String str, String keepAlphabet) { private static String encodeUriAny(String str, String keepAlphabet) {
if (str == null) str = "undefined"; if (str == null) str = "undefined";
var bytes = str.getBytes(); var bytes = str.getBytes();
var sb = new StringBuilder(bytes.length); var sb = new StringBuilder(bytes.length);
for (byte c : bytes) { for (byte c : bytes) {
if (Parsing.isAlphanumeric((char)c) || Parsing.isAny((char)c, keepAlphabet)) sb.append((char)c); if (Parsing.isAlphanumeric((char)c) || Parsing.isAny((char)c, keepAlphabet)) sb.append((char)c);
else { else {
sb.append('%'); sb.append('%');
sb.append(HEX.charAt(c / 16)); sb.append(HEX.charAt(c / 16));
sb.append(HEX.charAt(c % 16)); sb.append(HEX.charAt(c % 16));
} }
} }
return sb.toString(); return sb.toString();
} }
private static String decodeUriAny(String str, String keepAlphabet) { private static String decodeUriAny(String str, String keepAlphabet) {
if (str == null) str = "undefined"; if (str == null) str = "undefined";
var res = new Buffer(); var res = new Buffer();
var bytes = str.getBytes(); var bytes = str.getBytes();
for (var i = 0; i < bytes.length; i++) { for (var i = 0; i < bytes.length; i++) {
var c = bytes[i]; var c = bytes[i];
if (c == '%') { if (c == '%') {
if (i >= bytes.length - 2) throw EngineException.ofError("URIError", "URI malformed."); if (i >= bytes.length - 2) throw EngineException.ofError("URIError", "URI malformed.");
var b = Parsing.fromHex((char)bytes[i + 1]) * 16 | Parsing.fromHex((char)bytes[i + 2]); var b = Parsing.fromHex((char)bytes[i + 1]) * 16 | Parsing.fromHex((char)bytes[i + 2]);
if (!Parsing.isAny((char)b, keepAlphabet)) { if (!Parsing.isAny((char)b, keepAlphabet)) {
i += 2; i += 2;
res.append((byte)b); res.append((byte)b);
continue; continue;
} }
} }
res.append(c); res.append(c);
} }
return new String(res.data()); return new String(res.data());
} }
@Native public static String encodeURIComponent(String str) { @Native public static String encodeURIComponent(String str) {
return encodeUriAny(str, ".-_!~*'()"); return encodeUriAny(str, ".-_!~*'()");
} }
@Native public static String decodeURIComponent(String str) { @Native public static String decodeURIComponent(String str) {
return decodeUriAny(str, ""); return decodeUriAny(str, "");
} }
@Native public static String encodeURI(String str) { @Native public static String encodeURI(String str) {
return encodeUriAny(str, ";,/?:@&=+$#.-_!~*'()"); return encodeUriAny(str, ";,/?:@&=+$#.-_!~*'()");
} }
@Native public static String decodeURI(String str) { @Native public static String decodeURI(String str) {
return decodeUriAny(str, ",/?:@&=+$#."); return decodeUriAny(str, ",/?:@&=+$#.");
} }
public static Environment apply(Environment env) { public static Environment apply(Environment env) {
var wp = env.wrappers; var wp = env.wrappers;
var glob = env.global = new GlobalScope(wp.getNamespace(Internals.class)); var glob = env.global = new GlobalScope(wp.getNamespace(Internals.class));
glob.define(null, "Math", false, wp.getNamespace(MathLib.class)); glob.define(null, "Math", false, wp.getNamespace(MathLib.class));
glob.define(null, "JSON", false, wp.getNamespace(JSONLib.class)); glob.define(null, "JSON", false, wp.getNamespace(JSONLib.class));
glob.define(null, "Encoding", false, wp.getNamespace(EncodingLib.class)); glob.define(null, "Encoding", false, wp.getNamespace(EncodingLib.class));
glob.define(null, "Filesystem", false, wp.getNamespace(FilesystemLib.class)); glob.define(null, "Filesystem", false, wp.getNamespace(FilesystemLib.class));
glob.define(false, wp.getConstr(DateLib.class)); glob.define(false, wp.getConstr(DateLib.class));
glob.define(false, wp.getConstr(ObjectLib.class)); glob.define(false, wp.getConstr(ObjectLib.class));
glob.define(false, wp.getConstr(FunctionLib.class)); glob.define(false, wp.getConstr(FunctionLib.class));
glob.define(false, wp.getConstr(ArrayLib.class)); glob.define(false, wp.getConstr(ArrayLib.class));
glob.define(false, wp.getConstr(BooleanLib.class)); glob.define(false, wp.getConstr(BooleanLib.class));
glob.define(false, wp.getConstr(NumberLib.class)); glob.define(false, wp.getConstr(NumberLib.class));
glob.define(false, wp.getConstr(StringLib.class)); glob.define(false, wp.getConstr(StringLib.class));
glob.define(false, wp.getConstr(SymbolLib.class)); glob.define(false, wp.getConstr(SymbolLib.class));
glob.define(false, wp.getConstr(PromiseLib.class)); glob.define(false, wp.getConstr(PromiseLib.class));
glob.define(false, wp.getConstr(RegExpLib.class)); glob.define(false, wp.getConstr(RegExpLib.class));
glob.define(false, wp.getConstr(MapLib.class)); glob.define(false, wp.getConstr(MapLib.class));
glob.define(false, wp.getConstr(SetLib.class)); glob.define(false, wp.getConstr(SetLib.class));
glob.define(false, wp.getConstr(ErrorLib.class)); glob.define(false, wp.getConstr(ErrorLib.class));
glob.define(false, wp.getConstr(SyntaxErrorLib.class)); glob.define(false, wp.getConstr(SyntaxErrorLib.class));
glob.define(false, wp.getConstr(TypeErrorLib.class)); glob.define(false, wp.getConstr(TypeErrorLib.class));
glob.define(false, wp.getConstr(RangeErrorLib.class)); glob.define(false, wp.getConstr(RangeErrorLib.class));
env.setProto("object", wp.getProto(ObjectLib.class)); env.setProto("object", wp.getProto(ObjectLib.class));
env.setProto("function", wp.getProto(FunctionLib.class)); env.setProto("function", wp.getProto(FunctionLib.class));
env.setProto("array", wp.getProto(ArrayLib.class)); env.setProto("array", wp.getProto(ArrayLib.class));
env.setProto("bool", wp.getProto(BooleanLib.class)); env.setProto("bool", wp.getProto(BooleanLib.class));
env.setProto("number", wp.getProto(NumberLib.class)); env.setProto("number", wp.getProto(NumberLib.class));
env.setProto("string", wp.getProto(StringLib.class)); env.setProto("string", wp.getProto(StringLib.class));
env.setProto("symbol", wp.getProto(SymbolLib.class)); env.setProto("symbol", wp.getProto(SymbolLib.class));
env.setProto("error", wp.getProto(ErrorLib.class)); env.setProto("error", wp.getProto(ErrorLib.class));
env.setProto("syntaxErr", wp.getProto(SyntaxErrorLib.class)); env.setProto("syntaxErr", wp.getProto(SyntaxErrorLib.class));
env.setProto("typeErr", wp.getProto(TypeErrorLib.class)); env.setProto("typeErr", wp.getProto(TypeErrorLib.class));
env.setProto("rangeErr", wp.getProto(RangeErrorLib.class)); env.setProto("rangeErr", wp.getProto(RangeErrorLib.class));
wp.getProto(ObjectLib.class).setPrototype(null, null); wp.getProto(ObjectLib.class).setPrototype(null, null);
env.regexConstructor = wp.getConstr(RegExpLib.class); env.regexConstructor = wp.getConstr(RegExpLib.class);
return env; return env;
} }
} }

View File

@ -253,7 +253,7 @@ import me.topchetoeu.jscript.interop.Native;
this.val = val; this.val = val;
this.state = STATE_FULFILLED; this.state = STATE_FULFILLED;
ctx.engine.pushMsg(true, ctx, new NativeFunction((_ctx, _thisArg, _args) -> { ctx.engine.pushMsg(true, ctx.environment(), new NativeFunction((_ctx, _thisArg, _args) -> {
for (var handle : handles) { for (var handle : handles) {
handle.fulfilled.call(handle.ctx, null, val); handle.fulfilled.call(handle.ctx, null, val);
} }
@ -288,7 +288,7 @@ import me.topchetoeu.jscript.interop.Native;
this.val = val; this.val = val;
this.state = STATE_REJECTED; this.state = STATE_REJECTED;
ctx.engine.pushMsg(true, ctx, new NativeFunction((_ctx, _thisArg, _args) -> { ctx.engine.pushMsg(true, ctx.environment(), new NativeFunction((_ctx, _thisArg, _args) -> {
for (var handle : handles) handle.rejected.call(handle.ctx, null, val); for (var handle : handles) handle.rejected.call(handle.ctx, null, val);
if (!handled) { if (!handled) {
Values.printError(new EngineException(val).setCtx(ctx.environment(), ctx.engine), "(in promise)"); Values.printError(new EngineException(val).setCtx(ctx.environment(), ctx.engine), "(in promise)");
@ -305,9 +305,9 @@ import me.topchetoeu.jscript.interop.Native;
} }
private void handle(Context ctx, FunctionValue fulfill, FunctionValue reject) { private void handle(Context ctx, FunctionValue fulfill, FunctionValue reject) {
if (state == STATE_FULFILLED) ctx.engine.pushMsg(true, ctx, fulfill, null, val); if (state == STATE_FULFILLED) ctx.engine.pushMsg(true, ctx.environment(), fulfill, null, val);
else if (state == STATE_REJECTED) { else if (state == STATE_REJECTED) {
ctx.engine.pushMsg(true, ctx, reject, null, val); ctx.engine.pushMsg(true, ctx.environment(), reject, null, val);
handled = true; handled = true;
} }
else handles.add(new Handle(ctx, fulfill, reject)); else handles.add(new Handle(ctx, fulfill, reject));