Module support #11

Merged
TopchetoEU merged 20 commits from TopchetoEU/modules into master 2023-12-26 12:20:55 +00:00
7 changed files with 402 additions and 403 deletions
Showing only changes of commit 078d7ed95f - Show all commits

View File

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

View File

@ -119,7 +119,6 @@ public class Context {
}
public Context(Engine engine, Environment env) {
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;
}
public Awaitable<Object> pushMsg(boolean micro, Context ctx, FunctionValue func, Object thisArg, Object ...args) {
var msg = new Task(ctx == null ? new Context(this) : ctx, func, thisArg, args, micro);
public Awaitable<Object> pushMsg(boolean micro, Environment env, FunctionValue func, Object thisArg, Object ...args) {
var msg = new Task(new Context(this, env), func, thisArg, args, micro);
tasks.add(msg);
return msg.notifier;
}
public Awaitable<Object> pushMsg(boolean micro, Context ctx, Filename filename, String raw, Object thisArg, Object ...args) {
return pushMsg(micro, ctx, new UncompiledFunction(filename, raw), thisArg, args);
public Awaitable<Object> pushMsg(boolean micro, Environment env, Filename filename, String raw, Object thisArg, Object ...args) {
return pushMsg(micro, env, new UncompiledFunction(filename, raw), thisArg, args);
}
@Override

View File

@ -53,7 +53,6 @@ public class Environment implements PermissionsProvider {
res.defineProperty(ctx, "function", target.func(env));
res.defineProperty(ctx, "mapChain", new ArrayValue());
if (isDebug) {
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.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);
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);

View File

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

View File

@ -253,7 +253,7 @@ import me.topchetoeu.jscript.interop.Native;
this.val = val;
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) {
handle.fulfilled.call(handle.ctx, null, val);
}
@ -288,7 +288,7 @@ import me.topchetoeu.jscript.interop.Native;
this.val = val;
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);
if (!handled) {
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) {
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) {
ctx.engine.pushMsg(true, ctx, reject, null, val);
ctx.engine.pushMsg(true, ctx.environment(), reject, null, val);
handled = true;
}
else handles.add(new Handle(ctx, fulfill, reject));