refactor: remove old useless exceptions

This commit is contained in:
TopchetoEU 2024-01-06 19:51:48 +02:00
parent 18d22a1282
commit 89eea7d62b
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
10 changed files with 263 additions and 267 deletions

View File

@ -125,7 +125,7 @@ public class Main {
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() throws IOException {
var tsEnv = Internals.apply(new Environment()); var tsEnv = Internals.apply(new Environment());
var bsEnv = Internals.apply(new Environment()); var bsEnv = Internals.apply(new Environment());

View File

@ -4,8 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import me.topchetoeu.jscript.exceptions.UncheckedException;
public class Reading { public class Reading {
private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
@ -14,9 +13,16 @@ public class Reading {
return reader.readLine(); return reader.readLine();
} }
/**
* Reads the given stream to a string
* @param in
* @return
*/
public static String streamToString(InputStream in) { public static String streamToString(InputStream in) {
try { return new String(in.readAllBytes()); } try {
catch (Throwable e) { throw new UncheckedException(e); } return new String(in.readAllBytes());
}
catch (IOException e) { throw new UncheckedIOException(e); }
} }
public static InputStream resourceToStream(String name) { public static InputStream resourceToStream(String name) {
return Reading.class.getResourceAsStream("/" + name); return Reading.class.getResourceAsStream("/" + name);

View File

@ -1,31 +1,33 @@
package me.topchetoeu.jscript.engine.debug; package me.topchetoeu.jscript.engine.debug;
import java.io.IOException;
public interface DebugHandler { public interface DebugHandler {
void enable(V8Message msg); void enable(V8Message msg) throws IOException;
void disable(V8Message msg); void disable(V8Message msg) throws IOException;
void setBreakpointByUrl(V8Message msg); void setBreakpointByUrl(V8Message msg) throws IOException;
void removeBreakpoint(V8Message msg); void removeBreakpoint(V8Message msg) throws IOException;
void continueToLocation(V8Message msg); void continueToLocation(V8Message msg) throws IOException;
void getScriptSource(V8Message msg); void getScriptSource(V8Message msg) throws IOException;
void getPossibleBreakpoints(V8Message msg); void getPossibleBreakpoints(V8Message msg) throws IOException;
void resume(V8Message msg); void resume(V8Message msg) throws IOException;
void pause(V8Message msg); void pause(V8Message msg) throws IOException;
void stepInto(V8Message msg); void stepInto(V8Message msg) throws IOException;
void stepOut(V8Message msg); void stepOut(V8Message msg) throws IOException;
void stepOver(V8Message msg); void stepOver(V8Message msg) throws IOException;
void setPauseOnExceptions(V8Message msg); void setPauseOnExceptions(V8Message msg) throws IOException;
void evaluateOnCallFrame(V8Message msg); void evaluateOnCallFrame(V8Message msg) throws IOException;
void getProperties(V8Message msg); void getProperties(V8Message msg) throws IOException;
void releaseObjectGroup(V8Message msg); void releaseObjectGroup(V8Message msg) throws IOException;
void releaseObject(V8Message msg); void releaseObject(V8Message msg) throws IOException;
void callFunctionOn(V8Message msg); void callFunctionOn(V8Message msg) throws IOException;
void runtimeEnable(V8Message msg); void runtimeEnable(V8Message msg) throws IOException;
} }

View File

@ -1,6 +1,7 @@
package me.topchetoeu.jscript.engine.debug; package me.topchetoeu.jscript.engine.debug;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
@ -13,8 +14,6 @@ import me.topchetoeu.jscript.Reading;
import me.topchetoeu.jscript.engine.debug.WebSocketMessage.Type; import me.topchetoeu.jscript.engine.debug.WebSocketMessage.Type;
import me.topchetoeu.jscript.events.Notifier; import me.topchetoeu.jscript.events.Notifier;
import me.topchetoeu.jscript.exceptions.SyntaxException; import me.topchetoeu.jscript.exceptions.SyntaxException;
import me.topchetoeu.jscript.exceptions.UncheckedException;
import me.topchetoeu.jscript.exceptions.UncheckedIOException;
import me.topchetoeu.jscript.json.JSON; import me.topchetoeu.jscript.json.JSON;
import me.topchetoeu.jscript.json.JSONList; import me.topchetoeu.jscript.json.JSONList;
import me.topchetoeu.jscript.json.JSONMap; import me.topchetoeu.jscript.json.JSONMap;
@ -36,8 +35,7 @@ public class DebugServer {
try { try {
return MessageDigest.getInstance("sha1"); return MessageDigest.getInstance("sha1");
} }
catch (Throwable e) { throw new UncheckedException(e); } catch (Throwable e) { throw new RuntimeException(e); }
} }
private static Thread runAsync(Runnable func, String name) { private static Thread runAsync(Runnable func, String name) {
@ -47,7 +45,7 @@ public class DebugServer {
return res; return res;
} }
private void handle(WebSocket ws, Debugger debugger) { private void handle(WebSocket ws, Debugger debugger) throws IOException {
WebSocketMessage raw; WebSocketMessage raw;
while ((raw = ws.receive()) != null) { while ((raw = ws.receive()) != null) {
@ -66,53 +64,47 @@ public class DebugServer {
return; return;
} }
try { switch (msg.name) {
switch (msg.name) { case "Debugger.enable":
case "Debugger.enable": connNotifier.next();
connNotifier.next(); debugger.enable(msg);
debugger.enable(msg); continue;
continue; case "Debugger.disable": debugger.close(); continue;
case "Debugger.disable": debugger.close(); continue;
case "Debugger.setBreakpointByUrl": debugger.setBreakpointByUrl(msg); continue; case "Debugger.setBreakpointByUrl": debugger.setBreakpointByUrl(msg); continue;
case "Debugger.removeBreakpoint": debugger.removeBreakpoint(msg); continue; case "Debugger.removeBreakpoint": debugger.removeBreakpoint(msg); continue;
case "Debugger.continueToLocation": debugger.continueToLocation(msg); continue; case "Debugger.continueToLocation": debugger.continueToLocation(msg); continue;
case "Debugger.getScriptSource": debugger.getScriptSource(msg); continue; case "Debugger.getScriptSource": debugger.getScriptSource(msg); continue;
case "Debugger.getPossibleBreakpoints": debugger.getPossibleBreakpoints(msg); continue; case "Debugger.getPossibleBreakpoints": debugger.getPossibleBreakpoints(msg); continue;
case "Debugger.resume": debugger.resume(msg); continue; case "Debugger.resume": debugger.resume(msg); continue;
case "Debugger.pause": debugger.pause(msg); continue; case "Debugger.pause": debugger.pause(msg); continue;
case "Debugger.stepInto": debugger.stepInto(msg); continue; case "Debugger.stepInto": debugger.stepInto(msg); continue;
case "Debugger.stepOut": debugger.stepOut(msg); continue; case "Debugger.stepOut": debugger.stepOut(msg); continue;
case "Debugger.stepOver": debugger.stepOver(msg); continue; case "Debugger.stepOver": debugger.stepOver(msg); continue;
case "Debugger.setPauseOnExceptions": debugger.setPauseOnExceptions(msg); continue; case "Debugger.setPauseOnExceptions": debugger.setPauseOnExceptions(msg); continue;
case "Debugger.evaluateOnCallFrame": debugger.evaluateOnCallFrame(msg); continue; case "Debugger.evaluateOnCallFrame": debugger.evaluateOnCallFrame(msg); continue;
case "Runtime.releaseObjectGroup": debugger.releaseObjectGroup(msg); continue; case "Runtime.releaseObjectGroup": debugger.releaseObjectGroup(msg); continue;
case "Runtime.releaseObject": debugger.releaseObject(msg); continue; case "Runtime.releaseObject": debugger.releaseObject(msg); continue;
case "Runtime.getProperties": debugger.getProperties(msg); continue; case "Runtime.getProperties": debugger.getProperties(msg); continue;
case "Runtime.callFunctionOn": debugger.callFunctionOn(msg); continue; case "Runtime.callFunctionOn": debugger.callFunctionOn(msg); continue;
// case "NodeWorker.enable": debugger.nodeWorkerEnable(msg); continue; // case "NodeWorker.enable": debugger.nodeWorkerEnable(msg); continue;
case "Runtime.enable": debugger.runtimeEnable(msg); continue; case "Runtime.enable": debugger.runtimeEnable(msg); continue;
}
if (
msg.name.startsWith("DOM.") ||
msg.name.startsWith("DOMDebugger.") ||
msg.name.startsWith("Emulation.") ||
msg.name.startsWith("Input.") ||
msg.name.startsWith("Network.") ||
msg.name.startsWith("Page.")
) ws.send(new V8Error("This isn't a browser..."));
else ws.send(new V8Error("This API is not supported yet."));
}
catch (Throwable e) {
e.printStackTrace();
throw new UncheckedException(e);
} }
if (
msg.name.startsWith("DOM.") ||
msg.name.startsWith("DOMDebugger.") ||
msg.name.startsWith("Emulation.") ||
msg.name.startsWith("Input.") ||
msg.name.startsWith("Network.") ||
msg.name.startsWith("Page.")
) ws.send(new V8Error("This isn't a browser..."));
else ws.send(new V8Error("This API is not supported yet."));
} }
debugger.close(); debugger.close();
@ -147,8 +139,11 @@ public class DebugServer {
runAsync(() -> { runAsync(() -> {
try { handle(ws, debugger); } try { handle(ws, debugger); }
catch (RuntimeException e) { catch (RuntimeException | IOException e) {
ws.send(new V8Error(e.getMessage())); try {
ws.send(new V8Error(e.getMessage()));
}
catch (IOException e2) { /* Shit outta luck */ }
} }
finally { ws.close(); debugger.close(); } finally { ws.close(); debugger.close(); }
}, "Debug Handler"); }, "Debug Handler");
@ -239,6 +234,8 @@ public class DebugServer {
.replace("${AUTHOR}", Metadata.author()) .replace("${AUTHOR}", Metadata.author())
.getBytes(); .getBytes();
} }
catch (IOException e) { throw new UncheckedIOException(e); } catch (IOException e) {
throw new UncheckedIOException(e);
}
} }
} }

View File

@ -1,5 +1,6 @@
package me.topchetoeu.jscript.engine.debug; package me.topchetoeu.jscript.engine.debug;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -453,44 +454,74 @@ public class SimpleDebugger implements Debugger {
} }
private void resume(State state) { private void resume(State state) {
this.state = state; try {
ws.send(new V8Event("Debugger.resumed", new JSONMap())); this.state = state;
updateNotifier.next(); ws.send(new V8Event("Debugger.resumed", new JSONMap()));
updateNotifier.next();
}
catch (IOException e) {
ws.close();
close();
}
} }
private void pauseDebug(Context ctx, Breakpoint bp) { private void pauseDebug(Context ctx, Breakpoint bp) {
state = State.PAUSED_NORMAL; try {
var map = new JSONMap() state = State.PAUSED_NORMAL;
.set("callFrames", serializeFrames(ctx)) var map = new JSONMap()
.set("reason", "debugCommand"); .set("callFrames", serializeFrames(ctx))
.set("reason", "debugCommand");
if (bp != null) map.set("hitBreakpoints", new JSONList().add(bp.id + "")); if (bp != null) map.set("hitBreakpoints", new JSONList().add(bp.id + ""));
ws.send(new V8Event("Debugger.paused", map)); ws.send(new V8Event("Debugger.paused", map));
}
catch (IOException e) {
ws.close();
close();
}
} }
private void pauseException(Context ctx) { private void pauseException(Context ctx) {
state = State.PAUSED_EXCEPTION; try {
var map = new JSONMap() state = State.PAUSED_EXCEPTION;
.set("callFrames", serializeFrames(ctx)) var map = new JSONMap()
.set("reason", "exception"); .set("callFrames", serializeFrames(ctx))
.set("reason", "exception");
ws.send(new V8Event("Debugger.paused", map)); ws.send(new V8Event("Debugger.paused", map));
}
catch (IOException e) {
ws.close();
close();
}
} }
private void sendSource(Source src) { private void sendSource(Source src){
ws.send(new V8Event("Debugger.scriptParsed", new JSONMap() try {
.set("scriptId", src.id + "") ws.send(new V8Event("Debugger.scriptParsed", new JSONMap()
.set("hash", src.source.hashCode()) .set("scriptId", src.id + "")
.set("url", src.filename + "") .set("hash", src.source.hashCode())
)); .set("url", src.filename + "")
));
}
catch (IOException e) {
ws.close();
close();
}
} }
private void addBreakpoint(Breakpoint bpt) { private void addBreakpoint(Breakpoint bpt) {
idToBreakpoint.put(bpt.id, bpt); try {
locToBreakpoint.put(bpt.location, bpt); idToBreakpoint.put(bpt.id, bpt);
locToBreakpoint.put(bpt.location, bpt);
ws.send(new V8Event("Debugger.breakpointResolved", new JSONMap() ws.send(new V8Event("Debugger.breakpointResolved", new JSONMap()
.set("breakpointId", bpt.id) .set("breakpointId", bpt.id)
.set("location", serializeLocation(bpt.location)) .set("location", serializeLocation(bpt.location))
)); ));
}
catch (IOException e) {
ws.close();
close();
}
} }
private RunResult run(Frame codeFrame, String code) { private RunResult run(Frame codeFrame, String code) {
@ -582,7 +613,7 @@ public class SimpleDebugger implements Debugger {
return resObj; return resObj;
} }
@Override public synchronized void enable(V8Message msg) { @Override public synchronized void enable(V8Message msg) throws IOException {
enabled = true; enabled = true;
ws.send(msg.respond()); ws.send(msg.respond());
@ -591,7 +622,7 @@ public class SimpleDebugger implements Debugger {
updateNotifier.next(); updateNotifier.next();
} }
@Override public synchronized void disable(V8Message msg) { @Override public synchronized void disable(V8Message msg) throws IOException {
close(); close();
ws.send(msg.respond()); ws.send(msg.respond());
} }
@ -625,11 +656,11 @@ public class SimpleDebugger implements Debugger {
updateNotifier.next(); updateNotifier.next();
} }
@Override public synchronized void getScriptSource(V8Message msg) { @Override public synchronized void getScriptSource(V8Message msg) throws IOException {
int id = Integer.parseInt(msg.params.string("scriptId")); int id = Integer.parseInt(msg.params.string("scriptId"));
ws.send(msg.respond(new JSONMap().set("scriptSource", idToSource.get(id).source))); ws.send(msg.respond(new JSONMap().set("scriptSource", idToSource.get(id).source)));
} }
@Override public synchronized void getPossibleBreakpoints(V8Message msg) { @Override public synchronized void getPossibleBreakpoints(V8Message msg) throws IOException {
var src = idToSource.get(Integer.parseInt(msg.params.map("start").string("scriptId"))); var src = idToSource.get(Integer.parseInt(msg.params.map("start").string("scriptId")));
var start = deserializeLocation(msg.params.get("start"), false); var start = deserializeLocation(msg.params.get("start"), false);
var end = msg.params.isMap("end") ? deserializeLocation(msg.params.get("end"), false) : null; var end = msg.params.isMap("end") ? deserializeLocation(msg.params.get("end"), false) : null;
@ -644,16 +675,16 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond(new JSONMap().set("locations", res))); ws.send(msg.respond(new JSONMap().set("locations", res)));
} }
@Override public synchronized void pause(V8Message msg) { @Override public synchronized void pause(V8Message msg) throws IOException {
pendingPause = true; pendingPause = true;
ws.send(msg.respond()); ws.send(msg.respond());
} }
@Override public synchronized void resume(V8Message msg) { @Override public synchronized void resume(V8Message msg) throws IOException {
resume(State.RESUMED); resume(State.RESUMED);
ws.send(msg.respond(new JSONMap())); ws.send(msg.respond(new JSONMap()));
} }
@Override public synchronized void setBreakpointByUrl(V8Message msg) { @Override public synchronized void setBreakpointByUrl(V8Message msg) throws IOException {
var line = (int)msg.params.number("lineNumber") + 1; var line = (int)msg.params.number("lineNumber") + 1;
var col = (int)msg.params.number("columnNumber", 0) + 1; var col = (int)msg.params.number("columnNumber", 0) + 1;
var cond = msg.params.string("condition", "").trim(); var cond = msg.params.string("condition", "").trim();
@ -688,7 +719,7 @@ public class SimpleDebugger implements Debugger {
.set("locations", locs) .set("locations", locs)
)); ));
} }
@Override public synchronized void removeBreakpoint(V8Message msg) { @Override public synchronized void removeBreakpoint(V8Message msg) throws IOException {
var id = Integer.parseInt(msg.params.string("breakpointId")); var id = Integer.parseInt(msg.params.string("breakpointId"));
if (idToBptCand.containsKey(id)) { if (idToBptCand.containsKey(id)) {
@ -705,7 +736,7 @@ public class SimpleDebugger implements Debugger {
} }
ws.send(msg.respond()); ws.send(msg.respond());
} }
@Override public synchronized void continueToLocation(V8Message msg) { @Override public synchronized void continueToLocation(V8Message msg) throws IOException {
var loc = deserializeLocation(msg.params.get("location"), true); var loc = deserializeLocation(msg.params.get("location"), true);
tmpBreakpts.add(loc); tmpBreakpts.add(loc);
@ -714,7 +745,7 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond()); ws.send(msg.respond());
} }
@Override public synchronized void setPauseOnExceptions(V8Message msg) { @Override public synchronized void setPauseOnExceptions(V8Message msg) throws IOException {
switch (msg.params.string("state")) { switch (msg.params.string("state")) {
case "none": execptionType = CatchType.NONE; break; case "none": execptionType = CatchType.NONE; break;
case "all": execptionType = CatchType.ALL; break; case "all": execptionType = CatchType.ALL; break;
@ -727,7 +758,7 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond()); ws.send(msg.respond());
} }
@Override public synchronized void stepInto(V8Message msg) { @Override public synchronized void stepInto(V8Message msg) throws IOException {
if (state == State.RESUMED) ws.send(new V8Error("Debugger is resumed.")); if (state == State.RESUMED) ws.send(new V8Error("Debugger is resumed."));
else { else {
stepOutFrame = currFrame; stepOutFrame = currFrame;
@ -736,7 +767,7 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond()); ws.send(msg.respond());
} }
} }
@Override public synchronized void stepOut(V8Message msg) { @Override public synchronized void stepOut(V8Message msg) throws IOException {
if (state == State.RESUMED) ws.send(new V8Error("Debugger is resumed.")); if (state == State.RESUMED) ws.send(new V8Error("Debugger is resumed."));
else { else {
stepOutFrame = currFrame; stepOutFrame = currFrame;
@ -745,7 +776,7 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond()); ws.send(msg.respond());
} }
} }
@Override public synchronized void stepOver(V8Message msg) { @Override public synchronized void stepOver(V8Message msg) throws IOException {
if (state == State.RESUMED) ws.send(new V8Error("Debugger is resumed.")); if (state == State.RESUMED) ws.send(new V8Error("Debugger is resumed."));
else { else {
stepOutFrame = currFrame; stepOutFrame = currFrame;
@ -755,7 +786,7 @@ public class SimpleDebugger implements Debugger {
} }
} }
@Override public synchronized void evaluateOnCallFrame(V8Message msg) { @Override public synchronized void evaluateOnCallFrame(V8Message msg) throws IOException {
var cfId = Integer.parseInt(msg.params.string("callFrameId")); var cfId = Integer.parseInt(msg.params.string("callFrameId"));
var expr = msg.params.string("expression"); var expr = msg.params.string("expression");
var group = msg.params.string("objectGroup", null); var group = msg.params.string("objectGroup", null);
@ -769,12 +800,12 @@ public class SimpleDebugger implements Debugger {
else ws.send(msg.respond(new JSONMap().set("result", serializeObj(res.ctx, res.result)))); else ws.send(msg.respond(new JSONMap().set("result", serializeObj(res.ctx, res.result))));
} }
@Override public synchronized void releaseObjectGroup(V8Message msg) { @Override public synchronized void releaseObjectGroup(V8Message msg) throws IOException {
var group = msg.params.string("objectGroup"); var group = msg.params.string("objectGroup");
releaseGroup(group); releaseGroup(group);
ws.send(msg.respond()); ws.send(msg.respond());
} }
@Override public synchronized void releaseObject(V8Message msg) { @Override public synchronized void releaseObject(V8Message msg) throws IOException {
var id = Integer.parseInt(msg.params.string("objectId")); var id = Integer.parseInt(msg.params.string("objectId"));
var ref = idToObject.get(id); var ref = idToObject.get(id);
ref.held = false; ref.held = false;
@ -786,7 +817,7 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond()); ws.send(msg.respond());
} }
@Override public synchronized void getProperties(V8Message msg) { @Override public synchronized void getProperties(V8Message msg) throws IOException {
var ref = idToObject.get(Integer.parseInt(msg.params.string("objectId"))); var ref = idToObject.get(Integer.parseInt(msg.params.string("objectId")));
var obj = ref.obj; var obj = ref.obj;
@ -833,7 +864,7 @@ public class SimpleDebugger implements Debugger {
ws.send(msg.respond(new JSONMap().set("result", res))); ws.send(msg.respond(new JSONMap().set("result", res)));
} }
@Override public synchronized void callFunctionOn(V8Message msg) { @Override public synchronized void callFunctionOn(V8Message msg) throws IOException {
var src = msg.params.string("functionDeclaration"); var src = msg.params.string("functionDeclaration");
var args = msg.params var args = msg.params
.list("arguments", new JSONList()) .list("arguments", new JSONList())
@ -881,7 +912,7 @@ public class SimpleDebugger implements Debugger {
catch (EngineException e) { ws.send(msg.respond(new JSONMap().set("exceptionDetails", serializeException(ctx, e)))); } catch (EngineException e) { ws.send(msg.respond(new JSONMap().set("exceptionDetails", serializeException(ctx, e)))); }
} }
@Override public synchronized void runtimeEnable(V8Message msg) { @Override public synchronized void runtimeEnable(V8Message msg) throws IOException {
ws.send(msg.respond()); ws.send(msg.respond());
} }
@ -921,7 +952,11 @@ public class SimpleDebugger implements Debugger {
if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) { if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) {
pauseException(ctx); pauseException(ctx);
} }
else if (loc != null && (state == State.STEPPING_IN || state == State.STEPPING_OVER) && returnVal != Values.NO_RETURN && stepOutFrame == frame) { else if (
loc != null &&
(state == State.STEPPING_IN || state == State.STEPPING_OVER) &&
returnVal != Values.NO_RETURN && stepOutFrame == frame
) {
pauseDebug(ctx, null); pauseDebug(ctx, null);
} }
else if (isBreakpointable && locToBreakpoint.containsKey(loc)) { else if (isBreakpointable && locToBreakpoint.containsKey(loc)) {

View File

@ -7,7 +7,6 @@ import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import me.topchetoeu.jscript.engine.debug.WebSocketMessage.Type; import me.topchetoeu.jscript.engine.debug.WebSocketMessage.Type;
import me.topchetoeu.jscript.exceptions.UncheckedIOException;
public class WebSocket implements AutoCloseable { public class WebSocket implements AutoCloseable {
public long maxLength = 1 << 20; public long maxLength = 1 << 20;
@ -15,109 +14,95 @@ public class WebSocket implements AutoCloseable {
private Socket socket; private Socket socket;
private boolean closed = false; private boolean closed = false;
private OutputStream out() { private OutputStream out() throws IOException {
try { return socket.getOutputStream(); } return socket.getOutputStream();
catch (IOException e) { throw new UncheckedIOException(e); }
} }
private InputStream in() { private InputStream in() throws IOException {
try { return socket.getInputStream(); } return socket.getInputStream();
catch (IOException e) { throw new UncheckedIOException(e); }
} }
private long readLen(int byteLen) { private long readLen(int byteLen) throws IOException {
long res = 0; long res = 0;
try { if (byteLen == 126) {
if (byteLen == 126) { res |= in().read() << 8;
res |= in().read() << 8; res |= in().read();
res |= in().read(); return res;
return res;
}
else if (byteLen == 127) {
res |= in().read() << 56;
res |= in().read() << 48;
res |= in().read() << 40;
res |= in().read() << 32;
res |= in().read() << 24;
res |= in().read() << 16;
res |= in().read() << 8;
res |= in().read();
return res;
}
else return byteLen;
} }
catch (IOException e) { throw new UncheckedIOException(e); } else if (byteLen == 127) {
res |= in().read() << 56;
res |= in().read() << 48;
res |= in().read() << 40;
res |= in().read() << 32;
res |= in().read() << 24;
res |= in().read() << 16;
res |= in().read() << 8;
res |= in().read();
return res;
}
else return byteLen;
} }
private byte[] readMask(boolean has) { private byte[] readMask(boolean has) throws IOException {
if (has) { if (has) {
try { return new byte[] { return new byte[] {
(byte)in().read(), (byte)in().read(),
(byte)in().read(), (byte)in().read(),
(byte)in().read(), (byte)in().read(),
(byte)in().read() (byte)in().read()
}; } };
catch (IOException e) { throw new UncheckedIOException(e); }
} }
else return new byte[4]; else return new byte[4];
} }
private void writeLength(int len) { private void writeLength(int len) throws IOException {
try { if (len < 126) {
if (len < 126) { out().write((int)len);
out().write((int)len);
}
else if (len <= 0xFFFF) {
out().write(126);
out().write((int)(len >> 8) & 0xFF);
out().write((int)len & 0xFF);
}
else {
out().write(127);
out().write((len >> 56) & 0xFF);
out().write((len >> 48) & 0xFF);
out().write((len >> 40) & 0xFF);
out().write((len >> 32) & 0xFF);
out().write((len >> 24) & 0xFF);
out().write((len >> 16) & 0xFF);
out().write((len >> 8) & 0xFF);
out().write(len & 0xFF);
}
} }
catch (IOException e) { throw new UncheckedIOException(e); } else if (len <= 0xFFFF) {
} out().write(126);
private synchronized void write(int type, byte[] data) { out().write((int)(len >> 8) & 0xFF);
try { out().write((int)len & 0xFF);
int i;
for (i = 0; i < data.length / 0xFFFF; i++) {
out().write(type);
writeLength(0xFFFF);
out().write(data, i * 0xFFFF, 0xFFFF);
type = 0;
}
out().write(type | 0x80);
writeLength(data.length % 0xFFFF);
out().write(data, i * 0xFFFF, data.length % 0xFFFF);
} }
catch (IOException e) { else {
throw new UncheckedIOException(e); out().write(127);
out().write((len >> 56) & 0xFF);
out().write((len >> 48) & 0xFF);
out().write((len >> 40) & 0xFF);
out().write((len >> 32) & 0xFF);
out().write((len >> 24) & 0xFF);
out().write((len >> 16) & 0xFF);
out().write((len >> 8) & 0xFF);
out().write(len & 0xFF);
} }
} }
private synchronized void write(int type, byte[] data) throws IOException {
int i;
public void send(String data) { for (i = 0; i < data.length / 0xFFFF; i++) {
out().write(type);
writeLength(0xFFFF);
out().write(data, i * 0xFFFF, 0xFFFF);
type = 0;
}
out().write(type | 0x80);
writeLength(data.length % 0xFFFF);
out().write(data, i * 0xFFFF, data.length % 0xFFFF);
}
public void send(String data) throws IOException {
if (closed) throw new IllegalStateException("Object is closed."); if (closed) throw new IllegalStateException("Object is closed.");
write(1, data.getBytes()); write(1, data.getBytes());
} }
public void send(byte[] data) { public void send(byte[] data) throws IOException {
if (closed) throw new IllegalStateException("Object is closed."); if (closed) throw new IllegalStateException("Object is closed.");
write(2, data); write(2, data);
} }
public void send(WebSocketMessage msg) { public void send(WebSocketMessage msg) throws IOException {
if (msg.type == Type.Binary) send(msg.binaryData()); if (msg.type == Type.Binary) send(msg.binaryData());
else send(msg.textData()); else send(msg.textData());
} }
public void send(Object data) { public void send(Object data) throws IOException {
if (closed) throw new IllegalStateException("Object is closed."); if (closed) throw new IllegalStateException("Object is closed.");
write(1, data.toString().getBytes()); write(1, data.toString().getBytes());
} }
@ -144,67 +129,59 @@ public class WebSocket implements AutoCloseable {
return null; return null;
} }
private byte[] readData() { private byte[] readData() throws IOException {
try { var maskLen = in().read();
var maskLen = in().read(); var hasMask = (maskLen & 0x80) != 0;
var hasMask = (maskLen & 0x80) != 0; var len = (int)readLen(maskLen & 0x7F);
var len = (int)readLen(maskLen & 0x7F); var mask = readMask(hasMask);
var mask = readMask(hasMask);
if (len > maxLength) fail("WebSocket Error: client exceeded configured max message size");
else {
var buff = new byte[len];
if (in().read(buff) < len) fail("WebSocket Error: payload too short");
else {
for (int i = 0; i < len; i++) {
buff[i] ^= mask[(int)(i % 4)];
}
return buff;
}
}
return null; if (len > maxLength) fail("WebSocket Error: client exceeded configured max message size");
else {
var buff = new byte[len];
if (in().read(buff) < len) fail("WebSocket Error: payload too short");
else {
for (int i = 0; i < len; i++) {
buff[i] ^= mask[(int)(i % 4)];
}
return buff;
}
} }
catch (IOException e) { throw new UncheckedIOException(e); }
return null;
} }
public WebSocketMessage receive() { public WebSocketMessage receive() throws IOException {
try { var data = new ByteArrayOutputStream();
var data = new ByteArrayOutputStream(); var type = 0;
var type = 0;
while (socket != null && !closed) { while (socket != null && !closed) {
var finId = in().read(); var finId = in().read();
if (finId < 0) break; if (finId < 0) break;
var fin = (finId & 0x80) != 0; var fin = (finId & 0x80) != 0;
int id = finId & 0x0F; int id = finId & 0x0F;
if (id == 0x8) { close(); return null; } if (id == 0x8) { close(); return null; }
if (id >= 0x8) { if (id >= 0x8) {
if (!fin) return fail("WebSocket Error: client-sent control frame was fragmented"); if (!fin) return fail("WebSocket Error: client-sent control frame was fragmented");
if (id == 0x9) write(0xA, data.toByteArray()); if (id == 0x9) write(0xA, data.toByteArray());
continue; continue;
}
if (type == 0) type = id;
if (type == 0) return fail("WebSocket Error: client used opcode 0x00 for first fragment");
var buff = readData();
if (buff == null) break;
if (data.size() + buff.length > maxLength) return fail("WebSocket Error: client exceeded configured max message size");
data.write(buff);
if (!fin) continue;
var raw = data.toByteArray();
if (type == 1) return new WebSocketMessage(new String(raw));
else return new WebSocketMessage(raw);
} }
}
catch (IOException e) { if (type == 0) type = id;
close(); if (type == 0) return fail("WebSocket Error: client used opcode 0x00 for first fragment");
var buff = readData();
if (buff == null) break;
if (data.size() + buff.length > maxLength) return fail("WebSocket Error: client exceeded configured max message size");
data.write(buff);
if (!fin) continue;
var raw = data.toByteArray();
if (type == 1) return new WebSocketMessage(new String(raw));
else return new WebSocketMessage(raw);
} }
return null; return null;

View File

@ -17,7 +17,6 @@ import me.topchetoeu.jscript.engine.frame.ConvertHint;
import me.topchetoeu.jscript.exceptions.ConvertException; import me.topchetoeu.jscript.exceptions.ConvertException;
import me.topchetoeu.jscript.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.exceptions.SyntaxException; import me.topchetoeu.jscript.exceptions.SyntaxException;
import me.topchetoeu.jscript.exceptions.UncheckedException;
import me.topchetoeu.jscript.lib.PromiseLib; import me.topchetoeu.jscript.lib.PromiseLib;
public class Values { public class Values {
@ -135,7 +134,6 @@ public class Values {
if (val instanceof String) { if (val instanceof String) {
try { return Double.parseDouble((String)val); } try { return Double.parseDouble((String)val); }
catch (NumberFormatException e) { return Double.NaN; } catch (NumberFormatException e) { return Double.NaN; }
catch (Throwable e) { throw new UncheckedException(e); }
} }
return Double.NaN; return Double.NaN;
} }

View File

@ -11,9 +11,6 @@ public class DataNotifier<T> implements Awaitable<T> {
isErr = true; isErr = true;
notifier.next(); notifier.next();
} }
public void error(Throwable t) {
error(new RuntimeException(t));
}
public void next(T val) { public void next(T val) {
this.val = val; this.val = val;
isErr = false; isErr = false;

View File

@ -1,7 +0,0 @@
package me.topchetoeu.jscript.exceptions;
public class UncheckedException extends RuntimeException {
public UncheckedException(Throwable err) {
super(err);
}
}

View File

@ -1,9 +0,0 @@
package me.topchetoeu.jscript.exceptions;
import java.io.IOException;
public class UncheckedIOException extends RuntimeException {
public UncheckedIOException(IOException e) {
super(e);
}
}