feat: add async function
This commit is contained in:
parent
6da7720c67
commit
79a93ef971
@ -14,6 +14,7 @@ interface FunctionConstructor extends Function {
|
||||
(...args: string[]): (...args: any[]) => any;
|
||||
new (...args: string[]): (...args: any[]) => any;
|
||||
prototype: Function;
|
||||
async<ArgsT extends any[], RetT>(func: (await: <T>(val: T) => Awaited<T>, args: ArgsT) => RetT): Promise<RetT>;
|
||||
}
|
||||
|
||||
interface CallableFunction extends Function {
|
||||
@ -76,3 +77,9 @@ setProps(Function.prototype, {
|
||||
return 'function (...) { ... }';
|
||||
},
|
||||
});
|
||||
setProps(Function, {
|
||||
async(func) {
|
||||
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
||||
return internals.makeAsync(func);
|
||||
}
|
||||
})
|
@ -4,6 +4,8 @@ import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import me.topchetoeu.jscript.engine.Engine;
|
||||
@ -12,7 +14,6 @@ import me.topchetoeu.jscript.events.Observer;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
||||
import me.topchetoeu.jscript.polyfills.PolyfillEngine;
|
||||
import me.topchetoeu.jscript.polyfills.TypescriptEngine;
|
||||
|
||||
public class Main {
|
||||
static Thread task;
|
||||
@ -52,7 +53,7 @@ public class Main {
|
||||
|
||||
public static void main(String args[]) {
|
||||
var in = new BufferedReader(new InputStreamReader(System.in));
|
||||
engine = new TypescriptEngine(new File("."));
|
||||
engine = new PolyfillEngine(new File("."));
|
||||
var scope = engine.global().globalChild();
|
||||
var exited = new boolean[1];
|
||||
|
||||
@ -61,6 +62,15 @@ public class Main {
|
||||
task.interrupt();
|
||||
throw new InterruptedException();
|
||||
});
|
||||
scope.define("go", ctx -> {
|
||||
try {
|
||||
var func = engine.compile(scope, "do.js", new String(Files.readAllBytes(Path.of("do.js"))));
|
||||
return func.call(ctx);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new EngineException("Couldn't open do.js");
|
||||
}
|
||||
});
|
||||
|
||||
task = engine.start();
|
||||
var reader = new Thread(() -> {
|
||||
|
@ -26,6 +26,7 @@ public class CodeFrame {
|
||||
public final Object thisArg;
|
||||
public final Object[] args;
|
||||
public final List<Object> stack = new ArrayList<>();
|
||||
public final List<TryContext> tryCtxs = new ArrayList<>();
|
||||
public final CodeFunction function;
|
||||
|
||||
public int codePtr = 0;
|
||||
@ -47,7 +48,7 @@ public class CodeFrame {
|
||||
stack.add(stack.size(), Values.normalize(val));
|
||||
}
|
||||
|
||||
private void cleanup(CallContext ctx) {
|
||||
public void cleanup(CallContext ctx) {
|
||||
stack.clear();
|
||||
codePtr = 0;
|
||||
debugCmd = null;
|
||||
@ -61,7 +62,7 @@ public class CodeFrame {
|
||||
var debugState = ctx.getData(Engine.DEBUG_STATE_KEY);
|
||||
|
||||
if (debugCmd == null) {
|
||||
if (ctx.getData(STACK_N_KEY, 0) >= ctx.addData(MAX_STACK_KEY, 1000))
|
||||
if (ctx.getData(STACK_N_KEY, 0) >= ctx.addData(MAX_STACK_KEY, 100000))
|
||||
throw EngineException.ofRange("Stack overflow!");
|
||||
ctx.changeData(STACK_N_KEY);
|
||||
|
||||
@ -72,7 +73,10 @@ public class CodeFrame {
|
||||
}
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
|
||||
if (codePtr < 0 || codePtr >= function.body.length) return null;
|
||||
|
||||
var instr = function.body[codePtr];
|
||||
|
||||
var loc = instr.location;
|
||||
if (loc != null) prevLoc = loc;
|
||||
|
||||
@ -92,73 +96,80 @@ public class CodeFrame {
|
||||
}
|
||||
|
||||
try {
|
||||
var res = Runners.exec(debugCmd, instr, this, ctx);
|
||||
if (res != Runners.NO_RETURN) cleanup(ctx);
|
||||
return res;
|
||||
return Runners.exec(debugCmd, instr, this, ctx);
|
||||
}
|
||||
catch (EngineException e) {
|
||||
cleanup(ctx);
|
||||
throw e.add(function.name, prevLoc);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
cleanup(ctx);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public Object run(CallContext ctx) throws InterruptedException {
|
||||
var debugState = ctx.getData(Engine.DEBUG_STATE_KEY);
|
||||
DebugCommand command = ctx.getData(STOP_AT_START_KEY, false) ? DebugCommand.STEP_OVER : DebugCommand.NORMAL;
|
||||
|
||||
if (ctx.getData(STACK_N_KEY, 0) >= ctx.addData(MAX_STACK_KEY, 200)) throw EngineException.ofRange("Stack overflow!");
|
||||
ctx.changeData(STACK_N_KEY);
|
||||
|
||||
if (debugState != null) debugState.pushFrame(this);
|
||||
|
||||
Location loc = null;
|
||||
|
||||
try {
|
||||
while (codePtr >= 0 && codePtr < function.body.length) {
|
||||
var _loc = function.body[codePtr].location;
|
||||
if (_loc != null) loc = _loc;
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
|
||||
var instr = function.body[codePtr];
|
||||
|
||||
if (debugState != null && loc != null) {
|
||||
if (
|
||||
instr.type == Type.NOP && instr.match("debug") ||
|
||||
(
|
||||
(command == DebugCommand.STEP_INTO || command == DebugCommand.STEP_OVER) &&
|
||||
ctx.getData(STEPPING_TROUGH_KEY, false)
|
||||
) ||
|
||||
debugState.breakpoints.contains(loc)
|
||||
) {
|
||||
ctx.setData(STEPPING_TROUGH_KEY, true);
|
||||
|
||||
debugState.breakpointNotifier.next(new BreakpointData(loc, ctx));
|
||||
command = debugState.commandNotifier.toAwaitable().await();
|
||||
if (command == DebugCommand.NORMAL) ctx.setData(STEPPING_TROUGH_KEY, false);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var res = Runners.exec(command, instr, this, ctx);
|
||||
if (res != Runners.NO_RETURN) return res;
|
||||
}
|
||||
catch (EngineException e) {
|
||||
throw e.add(function.name, instr.location);
|
||||
}
|
||||
while (true) {
|
||||
var res = next(ctx);
|
||||
if (res != Runners.NO_RETURN) return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// catch (StackOverflowError e) {
|
||||
// e.printStackTrace();
|
||||
// throw EngineException.ofRange("Stack overflow!").add(function.name, loc);
|
||||
// }
|
||||
finally {
|
||||
ctx.changeData(STACK_N_KEY, -1);
|
||||
cleanup(ctx);
|
||||
}
|
||||
|
||||
|
||||
// var debugState = ctx.getData(Engine.DEBUG_STATE_KEY);
|
||||
// DebugCommand command = ctx.getData(STOP_AT_START_KEY, false) ? DebugCommand.STEP_OVER : DebugCommand.NORMAL;
|
||||
|
||||
// if (ctx.getData(STACK_N_KEY, 0) >= ctx.addData(MAX_STACK_KEY, 200)) throw EngineException.ofRange("Stack overflow!");
|
||||
// ctx.changeData(STACK_N_KEY);
|
||||
|
||||
// if (debugState != null) debugState.pushFrame(this);
|
||||
|
||||
// Location loc = null;
|
||||
|
||||
|
||||
// Location loc = null;
|
||||
|
||||
// try {
|
||||
// while (codePtr >= 0 && codePtr < function.body.length) {
|
||||
// var _loc = function.body[codePtr].location;
|
||||
// if (_loc != null) loc = _loc;
|
||||
|
||||
// if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
|
||||
// var instr = function.body[codePtr];
|
||||
|
||||
// if (debugState != null && loc != null) {
|
||||
// if (
|
||||
// instr.type == Type.NOP && instr.match("debug") ||
|
||||
// (
|
||||
// (command == DebugCommand.STEP_INTO || command == DebugCommand.STEP_OVER) &&
|
||||
// ctx.getData(STEPPING_TROUGH_KEY, false)
|
||||
// ) ||
|
||||
// debugState.breakpoints.contains(loc)
|
||||
// ) {
|
||||
// ctx.setData(STEPPING_TROUGH_KEY, true);
|
||||
|
||||
// debugState.breakpointNotifier.next(new BreakpointData(loc, ctx));
|
||||
// command = debugState.commandNotifier.toAwaitable().await();
|
||||
// if (command == DebugCommand.NORMAL) ctx.setData(STEPPING_TROUGH_KEY, false);
|
||||
// }
|
||||
// }
|
||||
|
||||
// try {
|
||||
// var res = Runners.exec(command, instr, this, ctx);
|
||||
// if (res != Runners.NO_RETURN) return res;
|
||||
// }
|
||||
// catch (EngineException e) {
|
||||
// throw e.add(function.name, instr.location);
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
// // catch (StackOverflowError e) {
|
||||
// // e.printStackTrace();
|
||||
// // throw EngineException.ofRange("Stack overflow!").add(function.name, loc);
|
||||
// // }
|
||||
// finally {
|
||||
// ctx.changeData(STACK_N_KEY, -1);
|
||||
// }
|
||||
}
|
||||
|
||||
public CodeFrame(Object thisArg, Object[] args, CodeFunction func) {
|
||||
|
@ -56,7 +56,7 @@ public class ModuleManager {
|
||||
if (realName == null) return null;
|
||||
if (cache.containsKey(realName)) return cache.get(realName);
|
||||
var mod = files.getModule(cwd, name);
|
||||
// cache.put(mod.name(), mod);
|
||||
cache.put(mod.name(), mod);
|
||||
mod.execute(ctx);
|
||||
return mod;
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class ModuleManager {
|
||||
if (realName == null) continue;
|
||||
if (cache.containsKey(realName)) return cache.get(realName);
|
||||
var mod = provider.getModule(cwd, name);
|
||||
// cache.put(mod.name(), mod);
|
||||
cache.put(mod.name(), mod);
|
||||
mod.execute(ctx);
|
||||
return mod;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import me.topchetoeu.jscript.engine.CallContext;
|
||||
|
||||
public class NativeFunction extends FunctionValue {
|
||||
public static interface NativeFunctionRunner {
|
||||
Object run(CallContext ctx, Object thisArg, Object[] values) throws InterruptedException;
|
||||
Object run(CallContext ctx, Object thisArg, Object[] args) throws InterruptedException;
|
||||
}
|
||||
|
||||
public final NativeFunctionRunner action;
|
||||
@ -18,4 +18,8 @@ public class NativeFunction extends FunctionValue {
|
||||
super(name, 0);
|
||||
this.action = action;
|
||||
}
|
||||
public NativeFunction(NativeFunctionRunner action) {
|
||||
super("", 0);
|
||||
this.action = action;
|
||||
}
|
||||
}
|
||||
|
@ -391,19 +391,21 @@ public class Values {
|
||||
}
|
||||
|
||||
if (obj instanceof ArrayValue) {
|
||||
var raw = array(obj).toArray();
|
||||
|
||||
if (clazz.isAssignableFrom(ArrayList.class)) {
|
||||
var raw = array(obj).toArray();
|
||||
var res = new ArrayList<>();
|
||||
for (var i = 0; i < raw.length; i++) res.add(convert(ctx, raw[i], Object.class));
|
||||
return (T)new ArrayList<>(res);
|
||||
}
|
||||
if (clazz.isAssignableFrom(HashSet.class)) {
|
||||
var raw = array(obj).toArray();
|
||||
var res = new HashSet<>();
|
||||
for (var i = 0; i < raw.length; i++) res.add(convert(ctx, raw[i], Object.class));
|
||||
return (T)new HashSet<>(res);
|
||||
}
|
||||
if (clazz.isArray()) {
|
||||
var raw = array(obj).toArray();
|
||||
Object res = Array.newInstance(clazz.arrayType(), raw.length);
|
||||
for (var i = 0; i < raw.length; i++) Array.set(res, i, convert(ctx, raw[i], Object.class));
|
||||
return (T)res;
|
||||
|
76
src/me/topchetoeu/jscript/js/bootstrap.js
vendored
76
src/me/topchetoeu/jscript/js/bootstrap.js
vendored
@ -1,7 +1,8 @@
|
||||
// TODO: load this in java
|
||||
var ts = require('./ts__');
|
||||
log("Loaded typescript!");
|
||||
|
||||
var src = '', lib = libs.join(''), decls = [], version = 0;
|
||||
var src = '', lib = libs.join(''), decls = '', version = 0;
|
||||
var libSnapshot = ts.ScriptSnapshot.fromString(lib);
|
||||
|
||||
var settings = {
|
||||
@ -9,7 +10,7 @@ var settings = {
|
||||
declarationDir: "/out",
|
||||
target: ts.ScriptTarget.ES5,
|
||||
lib: [ ],
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
module: ts.ModuleKind.None,
|
||||
declaration: true,
|
||||
stripInternal: true,
|
||||
downlevelIteration: true,
|
||||
@ -20,41 +21,17 @@ var settings = {
|
||||
|
||||
var reg = ts.createDocumentRegistry();
|
||||
var service = ts.createLanguageService({
|
||||
getCanonicalFileName: function (fileName) { return fileName; },
|
||||
useCaseSensitiveFileNames: function () { return true; },
|
||||
getNewLine: function () { return "\n"; },
|
||||
getEnvironmentVariable: function () { return ""; },
|
||||
|
||||
log: function() {
|
||||
log.apply(undefined, arguments);
|
||||
},
|
||||
fileExists: function (fileName) {
|
||||
return (
|
||||
fileName === "/src.ts" ||
|
||||
fileName === "/lib.d.ts" ||
|
||||
fileName === "/glob.d.ts"
|
||||
);
|
||||
},
|
||||
readFile: function (fileName) {
|
||||
if (fileName === "/src.ts") return src;
|
||||
if (fileName === "/lib.d.ts") return lib;
|
||||
if (fileName === "/glob.d.ts") return decls.join('\n');
|
||||
throw new Error("File '" + fileName + "' doesn't exist.");
|
||||
},
|
||||
writeFile: function (fileName, data) {
|
||||
if (fileName.endsWith(".js")) res = data;
|
||||
else if (fileName.endsWith(".d.ts")) decls.push(data);
|
||||
else throw new Error("File '" + fileName + "' isn't writable.");
|
||||
},
|
||||
getCompilationSettings: function () {
|
||||
return settings;
|
||||
},
|
||||
getCurrentDirectory: function() { return "/"; },
|
||||
getDefaultLibFileName: function() { return "/lib_.d.ts"; },
|
||||
getScriptFileNames: function() { return [ "/src.ts", "/lib.d.ts", "/glob.d.ts" ]; },
|
||||
getCompilationSettings: function () { return settings; },
|
||||
fileExists: function(filename) { return filename === "/lib.d.ts" || filename === "/src.ts" || filename === "/glob.d.ts"; },
|
||||
|
||||
getScriptSnapshot: function(filename) {
|
||||
if (filename === "/lib.d.ts") return libSnapshot;
|
||||
else return ts.ScriptSnapshot.fromString(this.readFile(filename));
|
||||
if (filename === "/src.ts") return ts.ScriptSnapshot.fromString(src);
|
||||
if (filename === "/glob.d.ts") return ts.ScriptSnapshot.fromString(decls);
|
||||
throw new Error("File '" + filename + "' doesn't exist.");
|
||||
},
|
||||
getScriptVersion: function (filename) {
|
||||
if (filename === "/lib.d.ts") return 0;
|
||||
@ -65,16 +42,11 @@ var service = ts.createLanguageService({
|
||||
service.getEmitOutput('/lib.d.ts');
|
||||
log('Loaded libraries!');
|
||||
|
||||
|
||||
function compile(code) {
|
||||
src = code;
|
||||
version++;
|
||||
function compile(filename, code) {
|
||||
src = code, version++;
|
||||
|
||||
var emit = service.getEmitOutput("/src.ts");
|
||||
|
||||
var res = emit.outputFiles[0].text;
|
||||
var decl = emit.outputFiles[1].text;
|
||||
|
||||
var diagnostics = []
|
||||
.concat(service.getCompilerOptionsDiagnostics())
|
||||
.concat(service.getSyntacticDiagnostics("/src.ts"))
|
||||
@ -83,7 +55,9 @@ function compile(code) {
|
||||
var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
||||
if (diagnostic.file) {
|
||||
var pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
return diagnostic.file.fileName.substring(1) + ":" + (pos.line + 1) + ":" + (pos.character + 1) + ": " + message;
|
||||
var file = diagnostic.file.fileName.substring(1);
|
||||
if (file === "src.ts") file = filename;
|
||||
return file + ":" + (pos.line + 1) + ":" + (pos.character + 1) + ": " + message;
|
||||
}
|
||||
else return "Error: " + message;
|
||||
});
|
||||
@ -92,17 +66,21 @@ function compile(code) {
|
||||
throw new SyntaxError(diagnostics.join('\n'));
|
||||
}
|
||||
|
||||
decls.push(decl);
|
||||
|
||||
return {
|
||||
result: res,
|
||||
diagnostics: diagnostics
|
||||
result: emit.outputFiles[0].text,
|
||||
declaration: emit.outputFiles[1].text
|
||||
};
|
||||
}
|
||||
|
||||
log("Loaded typescript!");
|
||||
init(function (code) {
|
||||
var res = compile(code);
|
||||
return res.result;
|
||||
});
|
||||
init(function (filename, code) {
|
||||
var res = compile(filename, code);
|
||||
|
||||
return [
|
||||
res.result,
|
||||
function(func, th, args) {
|
||||
var val = func.apply(th, args);
|
||||
decls += res.declaration;
|
||||
return val;
|
||||
}
|
||||
];
|
||||
});
|
||||
|
@ -68,7 +68,7 @@ public class Parsing {
|
||||
reserved.add("yield");
|
||||
// Although the standards allow it, these are keywords in newer ES, so we won't allow them
|
||||
reserved.add("const");
|
||||
reserved.add("await");
|
||||
// reserved.add("await");
|
||||
reserved.add("async");
|
||||
// These are allowed too, however our parser considers them keywords
|
||||
reserved.add("undefined");
|
||||
|
87
src/me/topchetoeu/jscript/polyfills/AsyncFunction.java
Normal file
87
src/me/topchetoeu/jscript/polyfills/AsyncFunction.java
Normal file
@ -0,0 +1,87 @@
|
||||
package me.topchetoeu.jscript.polyfills;
|
||||
|
||||
import me.topchetoeu.jscript.engine.CallContext;
|
||||
import me.topchetoeu.jscript.engine.frame.CodeFrame;
|
||||
import me.topchetoeu.jscript.engine.frame.Runners;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.CodeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
|
||||
public class AsyncFunction extends FunctionValue {
|
||||
public final CodeFunction body;
|
||||
|
||||
private class CallHandler {
|
||||
private boolean awaiting = false;
|
||||
private Object awaited = null;
|
||||
public final Promise promise = new Promise();
|
||||
public CodeFrame frame;
|
||||
private final NativeFunction fulfillFunc = new NativeFunction("", this::fulfill);
|
||||
private final NativeFunction rejectFunc = new NativeFunction("", this::reject);
|
||||
|
||||
private Object reject(CallContext ctx, Object thisArg, Object[] args) throws InterruptedException {
|
||||
if (args.length > 0) promise.reject(ctx, args[0]);
|
||||
return null;
|
||||
}
|
||||
public Object fulfill(CallContext ctx, Object thisArg, Object[] args) throws InterruptedException {
|
||||
if (args.length == 1) frame.push(args[0]);
|
||||
|
||||
while (true) {
|
||||
awaiting = false;
|
||||
awaited = null;
|
||||
|
||||
try {
|
||||
var res = frame.next(ctx);
|
||||
if (res != Runners.NO_RETURN) {
|
||||
promise.fulfill(ctx, res);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (EngineException e) {
|
||||
promise.reject(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!awaiting) continue;
|
||||
|
||||
frame.pop();
|
||||
|
||||
if (awaited instanceof Promise) ((Promise)awaited).then(ctx, fulfillFunc, rejectFunc);
|
||||
else if (Values.isPrimitive(awaited)) frame.push(awaited);
|
||||
try {
|
||||
var res = Values.getMember(ctx, awaited, "then");
|
||||
if (res instanceof FunctionValue) {
|
||||
Values.function(res).call(ctx, awaited, fulfillFunc, rejectFunc);
|
||||
return null;
|
||||
}
|
||||
else frame.push(awaited);
|
||||
}
|
||||
catch (EngineException e) {
|
||||
promise.reject(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object await(CallContext ctx, Object thisArg, Object[] args) {
|
||||
this.awaiting = true;
|
||||
this.awaited = args[0];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(CallContext _ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
var handler = new CallHandler();
|
||||
handler.frame = new CodeFrame(thisArg, new Object[] { new NativeFunction("await", handler::await), new ArrayValue(args) }, body);
|
||||
handler.fulfill(_ctx, null, new Object[0]);
|
||||
return handler.promise;
|
||||
}
|
||||
|
||||
public AsyncFunction(CodeFunction body) {
|
||||
super(body.name, body.length);
|
||||
this.body = body;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import java.util.HashMap;
|
||||
|
||||
import me.topchetoeu.jscript.engine.CallContext;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.CodeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Symbol;
|
||||
@ -235,6 +236,12 @@ public class Internals {
|
||||
return res.exports();
|
||||
}
|
||||
|
||||
@Native
|
||||
public AsyncFunction makeAsync(FunctionValue func) {
|
||||
if (func instanceof CodeFunction) return new AsyncFunction((CodeFunction)func);
|
||||
else throw EngineException.ofType("Can't create an async function with a non-js function.");
|
||||
}
|
||||
|
||||
@NativeGetter("err")
|
||||
public ObjectValue errProto(CallContext ctx) {
|
||||
return ctx.engine.errorProto();
|
||||
|
@ -203,11 +203,11 @@ public class Promise {
|
||||
public void fulfill(CallContext ctx, Object val) {
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(ctx,
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
this.fulfill(args[0]);
|
||||
this.fulfill(e, args[0]);
|
||||
return null;
|
||||
}),
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
this.reject(args[0]);
|
||||
this.reject(e, args[0]);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
@ -231,11 +231,11 @@ public class Promise {
|
||||
public void reject(CallContext ctx, Object val) {
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(ctx,
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
this.reject(args[0]);
|
||||
this.reject(e, args[0]);
|
||||
return null;
|
||||
}),
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
this.reject(args[0]);
|
||||
this.reject(e, args[0]);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
|
@ -6,16 +6,26 @@ import java.util.Map;
|
||||
|
||||
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.CodeFunction;
|
||||
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 CodeFunction compile(GlobalScope scope, String filename, String raw) throws InterruptedException {
|
||||
if (ts != null) raw = (String)ts.call(context(), null, raw);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -42,7 +52,7 @@ public class TypescriptEngine extends PolyfillEngine {
|
||||
|
||||
scope.define("libs", true, ArrayValue.of(decls));
|
||||
scope.define(true, new NativeFunction("init", (el, t, args) -> {
|
||||
ts = (FunctionValue)args[0];
|
||||
ts = Values.function(args[0]);
|
||||
return null;
|
||||
}));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user