fix: several bug fixes to help with typescript support
This commit is contained in:
parent
7df4e3b03f
commit
d57044acb7
@ -51,6 +51,7 @@ public class Engine implements DebugController {
|
||||
}
|
||||
|
||||
private static int nextId = 0;
|
||||
public static final HashMap<Long, FunctionBody> functions = new HashMap<>();
|
||||
|
||||
private Thread thread;
|
||||
private LinkedBlockingDeque<Task> macroTasks = new LinkedBlockingDeque<>();
|
||||
@ -58,7 +59,6 @@ public class Engine implements DebugController {
|
||||
|
||||
public final int id = ++nextId;
|
||||
public final Data data = new Data().set(StackData.MAX_FRAMES, 200);
|
||||
public final HashMap<Long, FunctionBody> functions = new HashMap<>();
|
||||
public final boolean debugging;
|
||||
private final HashMap<Filename, String> sources = new HashMap<>();
|
||||
private final HashMap<Filename, TreeSet<Location>> bpts = new HashMap<>();
|
||||
|
@ -473,13 +473,16 @@ public class SimpleDebugger implements Debugger {
|
||||
@Override public void setBreakpointByUrl(V8Message msg) {
|
||||
var line = (int)msg.params.number("lineNumber") + 1;
|
||||
var col = (int)msg.params.number("columnNumber", 0) + 1;
|
||||
var cond = msg.params.string("condition", null);
|
||||
|
||||
if (cond != null) cond = "(" + cond + ")";
|
||||
|
||||
Pattern regex;
|
||||
|
||||
if (msg.params.isString("url")) regex = Pattern.compile(Pattern.quote(msg.params.string("url")));
|
||||
else regex = Pattern.compile(msg.params.string("urlRegex"));
|
||||
|
||||
var bpcd = new BreakpointCandidate(nextId(), regex, line, col, null);
|
||||
var bpcd = new BreakpointCandidate(nextId(), regex, line, col, cond);
|
||||
idToBptCand.put(bpcd.id, bpcd);
|
||||
|
||||
var locs = new JSONList();
|
||||
@ -592,6 +595,7 @@ public class SimpleDebugger implements Debugger {
|
||||
var res = new JSONList();
|
||||
var ctx = objectToCtx.get(obj);
|
||||
|
||||
if (obj != emptyObject) {
|
||||
for (var key : obj.keys(true)) {
|
||||
var propDesc = new JSONMap();
|
||||
|
||||
@ -627,6 +631,7 @@ public class SimpleDebugger implements Debugger {
|
||||
protoDesc.set("configurable", false);
|
||||
protoDesc.set("isOwn", true);
|
||||
res.add(protoDesc);
|
||||
}
|
||||
|
||||
ws.send(msg.respond(new JSONMap().set("result", res)));
|
||||
}
|
||||
@ -662,25 +667,25 @@ public class SimpleDebugger implements Debugger {
|
||||
case VSCODE_STRINGIFY_VAL:
|
||||
case VSCODE_STRINGIFY_PROPS:
|
||||
case VSCODE_SHALLOW_COPY:
|
||||
case VSCODE_SYMBOL_REQUEST:
|
||||
ws.send(msg.respond(new JSONMap().set("result", serializeObj(ctx, emptyObject))));
|
||||
break;
|
||||
case VSCODE_FLATTEN_ARRAY: {
|
||||
case VSCODE_FLATTEN_ARRAY:
|
||||
ws.send(msg.respond(new JSONMap().set("result", serializeObj(ctx, thisArg))));
|
||||
break;
|
||||
}
|
||||
case VSCODE_SYMBOL_REQUEST:
|
||||
ws.send(msg.respond(new JSONMap().set("result", serializeObj(ctx, new ArrayValue(ctx)))));
|
||||
break;
|
||||
case VSCODE_CALL: {
|
||||
var func = (FunctionValue)(args.size() < 1 ? null : args.get(0));
|
||||
ws.send(msg.respond(new JSONMap().set("result", serializeObj(ctx, func.call(ctx, thisArg)))));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
var res = ctx.compile(new Filename("jscript", "eval"), src).call(ctx);
|
||||
if (res instanceof FunctionValue) ((FunctionValue)res).call(ctx, thisArg, args);
|
||||
ws.send(msg.respond(new JSONMap().set("result", serializeObj(ctx, res))));
|
||||
}
|
||||
default:
|
||||
ws.send(new V8Error("Please use well-known functions with callFunctionOn"));
|
||||
break;
|
||||
// default: {
|
||||
// var res = ctx.compile(new Filename("jscript", "eval"), src).call(ctx);
|
||||
// if (res instanceof FunctionValue) ((FunctionValue)res).call(ctx, thisArg, args);
|
||||
// ws.send(msg.respond(new JSONMap().set("result", serializeObj(ctx, res))));
|
||||
// }
|
||||
}
|
||||
}
|
||||
catch (EngineException e) { ws.send(msg.respond(new JSONMap().set("exceptionDetails", serializeException(ctx, e)))); }
|
||||
@ -725,14 +730,15 @@ public class SimpleDebugger implements Debugger {
|
||||
returnVal != Runners.NO_RETURN
|
||||
);
|
||||
|
||||
if (error != null && !caught && StackData.frames(ctx).size() > 1) error = null;
|
||||
// TODO: FIXXXX
|
||||
// if (error != null && !caught && StackData.frames(ctx).size() > 1) error = null;
|
||||
|
||||
if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) {
|
||||
pauseException(ctx);
|
||||
}
|
||||
else if (isBreakpointable && locToBreakpoint.containsKey(loc)) {
|
||||
var bp = locToBreakpoint.get(loc);
|
||||
var ok = bp.condition == null ? true : Values.toBoolean(run(currFrame, bp.condition));
|
||||
var ok = bp.condition == null ? true : Values.toBoolean(run(currFrame, bp.condition).result);
|
||||
if (ok) pauseDebug(ctx, locToBreakpoint.get(loc));
|
||||
}
|
||||
else if (isBreakpointable && tmpBreakpts.remove(loc)) pauseDebug(ctx, null);
|
||||
|
@ -15,7 +15,7 @@ import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||
|
||||
public class CodeFrame {
|
||||
private class TryCtx {
|
||||
public static class TryCtx {
|
||||
public static final int STATE_TRY = 0;
|
||||
public static final int STATE_CATCH = 1;
|
||||
public static final int STATE_FINALLY_THREW = 2;
|
||||
|
2
src/me/topchetoeu/jscript/js/bootstrap.js
vendored
2
src/me/topchetoeu/jscript/js/bootstrap.js
vendored
@ -42,7 +42,7 @@
|
||||
service.getEmitOutput('/lib.d.ts');
|
||||
log('Loaded libraries!');
|
||||
|
||||
function compile(filename, code) {
|
||||
function compile(code, filename) {
|
||||
src = code, version++;
|
||||
|
||||
var emit = service.getEmitOutput("/src.ts");
|
||||
|
@ -188,13 +188,28 @@ public class JSON {
|
||||
if (el.isNumber()) return Double.toString(el.number());
|
||||
if (el.isBoolean()) return el.bool() ? "true" : "false";
|
||||
if (el.isNull()) return "null";
|
||||
if (el.isString()) return "\"" + el.string()
|
||||
.replace("\\", "\\\\")
|
||||
.replace("\n", "\\n")
|
||||
.replace("\r", "\\r")
|
||||
.replace("\t", "\\t")
|
||||
.replace("\"", "\\\"")
|
||||
+ "\"";
|
||||
if (el.isString()) {
|
||||
var res = new StringBuilder("\"");
|
||||
var alphabet = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
for (var c : el.string().toCharArray()) {
|
||||
if (c < 32 || c >= 127) {
|
||||
res
|
||||
.append("\\u")
|
||||
.append(alphabet[(c >> 12) & 0xF])
|
||||
.append(alphabet[(c >> 8) & 0xF])
|
||||
.append(alphabet[(c >> 4) & 0xF])
|
||||
.append(alphabet[(c >> 0) & 0xF]);
|
||||
}
|
||||
else if (c == '\\')
|
||||
res.append("\\\\");
|
||||
else if (c == '"')
|
||||
res.append("\\\"");
|
||||
else res.append(c);
|
||||
}
|
||||
|
||||
return res.append('"').toString();
|
||||
}
|
||||
if (el.isList()) {
|
||||
var res = new StringBuilder().append("[");
|
||||
for (int i = 0; i < el.list().size(); i++) {
|
||||
|
@ -93,13 +93,14 @@ import me.topchetoeu.jscript.interop.NativeSetter;
|
||||
return res;
|
||||
}
|
||||
|
||||
@Native(thisArg = true) public static void sort(Context ctx, ArrayValue arr, FunctionValue cmp) {
|
||||
@Native(thisArg = true) public static ArrayValue sort(Context ctx, ArrayValue arr, FunctionValue cmp) {
|
||||
arr.sort((a, b) -> {
|
||||
var res = Values.toNumber(ctx, cmp.call(ctx, null, a, b));
|
||||
if (res < 0) return -1;
|
||||
if (res > 0) return 1;
|
||||
return 0;
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
private static int normalizeI(int len, int i, boolean clamp) {
|
||||
@ -299,17 +300,14 @@ import me.topchetoeu.jscript.interop.NativeSetter;
|
||||
return arr.size();
|
||||
}
|
||||
|
||||
@Native(thisArg = true) public static ArrayValue slice(Context ctx, ArrayValue arr, int start, int end) {
|
||||
@Native(thisArg = true) public static ArrayValue slice(Context ctx, ArrayValue arr, int start, Object _end) {
|
||||
start = normalizeI(arr.size(), start, true);
|
||||
end = normalizeI(arr.size(), end, true);
|
||||
int end = normalizeI(arr.size(), (int)(_end == null ? arr.size() : Values.toNumber(ctx, _end)), true);
|
||||
|
||||
var res = new ArrayValue(end - start);
|
||||
arr.copyTo(ctx, res, start, 0, end - start);
|
||||
return res;
|
||||
}
|
||||
@Native(thisArg = true) public static ArrayValue slice(Context ctx, ArrayValue arr, int start) {
|
||||
return slice(ctx, arr, start, arr.size());
|
||||
}
|
||||
|
||||
@Native(thisArg = true) public static ArrayValue splice(Context ctx, ArrayValue arr, int start, int deleteCount, Object ...items) {
|
||||
start = normalizeI(arr.size(), start, true);
|
||||
|
@ -2,10 +2,12 @@ package me.topchetoeu.jscript.lib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import me.topchetoeu.jscript.engine.Context;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeWrapper;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
@ -81,7 +83,6 @@ import me.topchetoeu.jscript.interop.NativeGetter;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@Native public Object exec(String str) {
|
||||
var matcher = pattern.matcher(str);
|
||||
if (lastI > str.length() || !matcher.find(lastI) || sticky && matcher.start() != lastI) {
|
||||
@ -133,7 +134,7 @@ import me.topchetoeu.jscript.interop.NativeGetter;
|
||||
return "/" + source + "/" + flags();
|
||||
}
|
||||
|
||||
@Native("@@Symvol.match") public Object match(Context ctx, String target) {
|
||||
@Native("@@Symbol.match") public Object match(Context ctx, String target) {
|
||||
if (this.global) {
|
||||
var res = new ArrayValue();
|
||||
Object val;
|
||||
@ -150,7 +151,7 @@ import me.topchetoeu.jscript.interop.NativeGetter;
|
||||
}
|
||||
}
|
||||
|
||||
@Native("@@Symvol.matchAll") public Object matchAll(Context ctx, String target) {
|
||||
@Native("@@Symbol.matchAll") public Object matchAll(Context ctx, String target) {
|
||||
var pattern = new RegExpLib(this.source, this.flags() + "g");
|
||||
|
||||
return Values.fromJavaIterator(ctx, new Iterator<Object>() {
|
||||
@ -172,7 +173,7 @@ import me.topchetoeu.jscript.interop.NativeGetter;
|
||||
});
|
||||
}
|
||||
|
||||
@Native("@@Symvol.split") public ArrayValue split(Context ctx, String target, Object limit, boolean sensible) {
|
||||
@Native("@@Symbol.split") public ArrayValue split(Context ctx, String target, Object limit, boolean sensible) {
|
||||
var pattern = new RegExpLib(this.source, this.flags() + "g");
|
||||
Object match;
|
||||
int lastEnd = 0;
|
||||
@ -214,29 +215,41 @@ import me.topchetoeu.jscript.interop.NativeGetter;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// [Symbol.replace](target, replacement) {
|
||||
// const pattern = new this.constructor(this, this.flags + "d") as RegExp;
|
||||
// let match: RegExpResult | null;
|
||||
// let lastEnd = 0;
|
||||
// const res: string[] = [];
|
||||
// // log(pattern.toString());
|
||||
// while ((match = pattern.exec(target)) !== null) {
|
||||
// const indices = match.indices![0];
|
||||
// res.push(target.substring(lastEnd, indices[0]));
|
||||
// if (replacement instanceof Function) {
|
||||
// res.push(replacement(target.substring(indices[0], indices[1]), ...match.slice(1), indices[0], target));
|
||||
// }
|
||||
// else {
|
||||
// res.push(replacement);
|
||||
// }
|
||||
// lastEnd = indices[1];
|
||||
// if (!pattern.global) break;
|
||||
// }
|
||||
// if (lastEnd < target.length) {
|
||||
// res.push(target.substring(lastEnd));
|
||||
// }
|
||||
// return res.join('');
|
||||
// },
|
||||
|
||||
@Native("@@Symbol.replace") public String replace(Context ctx, String target, Object replacement) {
|
||||
var pattern = new RegExpLib(this.source, this.flags() + "d");
|
||||
Object match;
|
||||
var lastEnd = 0;
|
||||
var res = new StringBuilder();
|
||||
|
||||
while ((match = pattern.exec(target)) != Values.NULL) {
|
||||
var indices = (ArrayValue)((ArrayValue)Values.getMember(ctx, match, "indices")).get(0);
|
||||
var arrMatch = (ArrayValue)match;
|
||||
|
||||
var start = ((Number)indices.get(0)).intValue();
|
||||
var end = ((Number)indices.get(1)).intValue();
|
||||
|
||||
res.append(target.substring(lastEnd, start));
|
||||
if (replacement instanceof FunctionValue) {
|
||||
var args = new Object[arrMatch.size() + 2];
|
||||
args[0] = target.substring(start, end);
|
||||
arrMatch.copyTo(args, 1, 1, arrMatch.size() - 1);
|
||||
args[args.length - 2] = start;
|
||||
args[args.length - 1] = target;
|
||||
res.append(Values.toString(ctx, ((FunctionValue)replacement).call(ctx, null, args)));
|
||||
}
|
||||
else {
|
||||
res.append(Values.toString(ctx, replacement));
|
||||
}
|
||||
lastEnd = end;
|
||||
if (!pattern.global) break;
|
||||
}
|
||||
if (lastEnd < target.length()) {
|
||||
res.append(target.substring(lastEnd));
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
// [Symbol.search](target, reverse, start) {
|
||||
// const pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
|
||||
// if (!reverse) {
|
||||
@ -258,6 +271,7 @@ import me.topchetoeu.jscript.interop.NativeGetter;
|
||||
// else return -1;
|
||||
// }
|
||||
// },
|
||||
|
||||
@Native public RegExpLib(Context ctx, Object pattern, Object flags) {
|
||||
this(cleanupPattern(ctx, pattern), cleanupFlags(ctx, flags));
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ import me.topchetoeu.jscript.interop.NativeInit;
|
||||
return lastIndexOf(ctx, passThis(ctx, "includes", thisArg), term, pos) >= 0;
|
||||
}
|
||||
|
||||
@Native(thisArg = true) public static String replace(Context ctx, Object thisArg, Object term, String replacement) {
|
||||
@Native(thisArg = true) public static String replace(Context ctx, Object thisArg, Object term, Object replacement) {
|
||||
var val = passThis(ctx, "replace", thisArg);
|
||||
|
||||
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
||||
@ -121,9 +121,9 @@ import me.topchetoeu.jscript.interop.NativeInit;
|
||||
}
|
||||
}
|
||||
|
||||
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), replacement);
|
||||
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), Values.toString(ctx, replacement));
|
||||
}
|
||||
@Native(thisArg = true) public static String replaceAll(Context ctx, Object thisArg, Object term, String replacement) {
|
||||
@Native(thisArg = true) public static String replaceAll(Context ctx, Object thisArg, Object term, Object replacement) {
|
||||
var val = passThis(ctx, "replaceAll", thisArg);
|
||||
|
||||
if (term != null && term != Values.NULL && !(term instanceof String)) {
|
||||
@ -133,7 +133,7 @@ import me.topchetoeu.jscript.interop.NativeInit;
|
||||
}
|
||||
}
|
||||
|
||||
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), replacement);
|
||||
return val.replaceFirst(Pattern.quote(Values.toString(ctx, term)), Values.toString(ctx, replacement));
|
||||
}
|
||||
|
||||
@Native(thisArg = true) public static ArrayValue match(Context ctx, Object thisArg, Object term, String replacement) {
|
||||
|
Loading…
Reference in New Issue
Block a user