Skip to content
This repository was archived by the owner on Dec 31, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const conf = {
version: argv[3]
};

console.log(conf)

if (conf.version.startsWith('refs/tags/')) conf.version = conf.version.substring(10);
if (conf.version.startsWith('v')) conf.version = conf.version.substring(1);

Expand Down
Binary file added src/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JScript Debugger</title>
</head>
<body>
<p>
This is the debugger of JScript. It implement the <a href="https://chromedevtools.github.io/devtools-protocol/1-2/">V8 Debugging protocol</a>,
so you can use the devtools in chrome. <br>
The debugger is still in early development, so please report any issues to
<a href="https://github.com/TopchetoEU/java-jscript/issues">the github repo</a>.
</p>

<p>
Here are the available entrypoints:
<ul>
<li><a href="json/version">/json/version</a> - version and other stuff about the JScript engine</li>
<li><a href="json/list">/json/list</a> - a list of all entrypoints</li>
<li><a href="json/protocol">/json/protocol</a> - documentation of the implemented V8 protocol</li>
<li>/(any target) - websocket entrypoints for debugging</li>
</ul>
</p>

<p>
Running ${NAME} v${VERSION} by ${AUTHOR}
</p>
</body>
</html>
2,007 changes: 2,007 additions & 0 deletions src/assets/protocol.json

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions src/me/topchetoeu/jscript/Filename.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.topchetoeu.jscript;

import java.io.File;

public class Filename {
public final String protocol;
public final String path;

public String toString() {
return protocol + "://" + path;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + protocol.hashCode();
result = prime * result + path.hashCode();
return result;
}


@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;

var other = (Filename) obj;

if (protocol == null) {
if (other.protocol != null) return false;
}
else if (!protocol.equals(other.protocol)) return false;

if (path == null) {
if (other.path != null) return false;
}
else if (!path.equals(other.path)) return false;
return true;
}

public static Filename fromFile(File file) {
return new Filename("file", file.getAbsolutePath());
}


public Filename(String protocol, String path) {
this.protocol = protocol;
this.path = path;
}
}
23 changes: 17 additions & 6 deletions src/me/topchetoeu/jscript/Location.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package me.topchetoeu.jscript;

public class Location {
public static final Location INTERNAL = new Location(0, 0, "<internal>");
public class Location implements Comparable<Location> {
public static final Location INTERNAL = new Location(0, 0, new Filename("jscript", "internal"));
private int line;
private int start;
private String filename;
private Filename filename;

public int line() { return line; }
public int start() { return start; }
public String filename() { return filename; }
public Filename filename() { return filename; }

@Override
public String toString() {
return filename + ":" + line + ":" + start;
return filename.toString() + ":" + line + ":" + start;
}

public Location add(int n, boolean clone) {
Expand Down Expand Up @@ -55,7 +55,18 @@ public boolean equals(Object obj) {
return true;
}

public Location(int line, int start, String filename) {
@Override
public int compareTo(Location other) {
int a = filename.toString().compareTo(other.filename.toString());
int b = Integer.compare(line, other.line);
int c = Integer.compare(start, other.start);

if (a != 0) return a;
if (b != 0) return b;
return c;
}

public Location(int line, int start, Filename filename) {
this.line = line;
this.start = start;
this.filename = filename;
Expand Down
92 changes: 35 additions & 57 deletions src/me/topchetoeu/jscript/Main.java
Original file line number Diff line number Diff line change
@@ -1,81 +1,66 @@
package me.topchetoeu.jscript;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;

import me.topchetoeu.jscript.engine.Message;
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.NativeFunction;
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.exceptions.UncheckedException;
import me.topchetoeu.jscript.lib.Internals;

public class Main {
static Thread task;
static Thread engineTask, debugTask;
static Engine engine;
static Environment env;

public static String streamToString(InputStream in) {
try {
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));

for(var line = br.readLine(); line != null; line = br.readLine()) {
out.append(line).append('\n');
}

br.close();
return out.toString();
}
catch (IOException e) {
return null;
}
}
public static String resourceToString(String name) {
var str = Main.class.getResourceAsStream("/me/topchetoeu/jscript/" + name);
if (str == null) return null;
return streamToString(str);
}
static int j = 0;

private static Observer<Object> valuePrinter = new Observer<Object>() {
public void next(Object data) {
try { Values.printValue(null, data); }
catch (InterruptedException e) { }
Values.printValue(null, data);
System.out.println();
}

public void error(RuntimeException err) {
try { Values.printError(err, null); }
catch (InterruptedException ex) { return; }
Values.printError(err, null);
}

@Override
public void finish() {
engineTask.interrupt();
}
};

public static void main(String args[]) {
System.out.println(String.format("Running %s v%s by %s", Metadata.NAME, Metadata.VERSION, Metadata.AUTHOR));
var in = new BufferedReader(new InputStreamReader(System.in));
engine = new Engine();

env = new Environment(null, null, null);
var exited = new boolean[1];
var server = new DebugServer();
server.targets.put("target", (ws, req) -> SimpleDebugger.get(ws, engine));

engine.pushMsg(false, new Message(engine), new NativeFunction((ctx, thisArg, _a) -> {
engine.pushMsg(false, null, new NativeFunction((ctx, thisArg, _a) -> {
new Internals().apply(env);

env.global.define("exit", _ctx -> {
exited[0] = true;
task.interrupt();
throw new InterruptedException();
throw new InterruptException();
});
env.global.define("go", _ctx -> {
try {
var func = _ctx.compile("do.js", new String(Files.readAllBytes(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)));
return func.call(_ctx);
}
catch (IOException e) {
Expand All @@ -86,41 +71,34 @@ public static void main(String args[]) {
return null;
}), null);

task = engine.start();
engineTask = engine.start();
debugTask = server.start(new InetSocketAddress("127.0.0.1", 9229), true);

var reader = new Thread(() -> {
try {
while (true) {
for (var i = 0; ; i++) {
try {
var raw = in.readLine();
var raw = Reading.read();

if (raw == null) break;
engine.pushMsg(false, env.context(new Message(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter);
}
catch (EngineException e) {
try {
System.out.println("Uncaught " + e.toString(null));
}
catch (EngineException ex) {
System.out.println("Uncaught [error while converting to string]");
}
valuePrinter.next(engine.pushMsg(false, new Context(engine).pushEnv(env), new Filename("jscript", "repl/" + i + ".js"), raw, null).await());
}
catch (EngineException e) { Values.printError(e, ""); }
}
}
catch (IOException e) {
e.printStackTrace();
return;
}
catch (IOException e) { return; }
catch (SyntaxException ex) {
if (exited[0]) return;
System.out.println("Syntax error:" + ex.msg);
}
catch (RuntimeException ex) {
if (exited[0]) return;
System.out.println("Internal error ocurred:");
ex.printStackTrace();
if (!exited[0]) {
System.out.println("Internal error ocurred:");
ex.printStackTrace();
}
}
catch (InterruptedException e) { return; }
if (exited[0]) return;
catch (Throwable e) { throw new UncheckedException(e); }
if (exited[0]) debugTask.interrupt();
});
reader.setDaemon(true);
reader.setName("STD Reader");
Expand Down
36 changes: 36 additions & 0 deletions src/me/topchetoeu/jscript/Reading.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package me.topchetoeu.jscript;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import me.topchetoeu.jscript.exceptions.UncheckedException;

public class Reading {
private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

public static synchronized String read() throws IOException {
return reader.readLine();
}

public static String streamToString(InputStream in) {
try {
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));

for(var line = br.readLine(); line != null; line = br.readLine()) {
out.append(line).append('\n');
}

br.close();
return out.toString();
}
catch (Throwable e) { throw new UncheckedException(e); }
}
public static String resourceToString(String name) {
var str = Main.class.getResourceAsStream("/me/topchetoeu/jscript/" + name);
if (str == null) return null;
return streamToString(str);
}
}
15 changes: 13 additions & 2 deletions src/me/topchetoeu/jscript/compilation/CompileTarget.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package me.topchetoeu.jscript.compilation;

import java.util.Map;
import java.util.TreeSet;
import java.util.Vector;

import me.topchetoeu.jscript.Location;

public class CompileTarget {
public final Vector<Instruction> target = new Vector<>();
public final Map<Long, Instruction[]> functions;
public final Map<Long, FunctionBody> functions;
public final TreeSet<Location> breakpoints;

public Instruction add(Instruction instr) {
target.add(instr);
Expand All @@ -14,14 +18,21 @@ public Instruction add(Instruction instr) {
public Instruction set(int i, Instruction instr) {
return target.set(i, instr);
}
public void setDebug(int i) {
breakpoints.add(target.get(i).location);
}
public void setDebug() {
setDebug(target.size() - 1);
}
public Instruction get(int i) {
return target.get(i);
}
public int size() { return target.size(); }

public Instruction[] array() { return target.toArray(Instruction[]::new); }

public CompileTarget(Map<Long, Instruction[]> functions) {
public CompileTarget(Map<Long, FunctionBody> functions, TreeSet<Location> breakpoints) {
this.functions = functions;
this.breakpoints = breakpoints;
}
}
Loading