WIP: Put a pin in this. It's broken but I'm moving on for a minute
This commit is contained in:
parent
819a6dc1b6
commit
f88d632767
4 changed files with 309 additions and 179 deletions
76
Cargo.lock
generated
76
Cargo.lock
generated
|
|
@ -150,7 +150,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -180,6 +180,12 @@ version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "better_scoped_tls"
|
name = "better_scoped_tls"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -295,7 +301,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -304,6 +310,12 @@ version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "calloop"
|
name = "calloop"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
|
|
@ -521,7 +533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "577ec3850834c2578eb44afa9250f9a807f8497664e6e2aaae19cea0aac2fe3b"
|
checksum = "577ec3850834c2578eb44afa9250f9a807f8497664e6e2aaae19cea0aac2fe3b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64 0.13.1",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"dprint-swc-ext",
|
"dprint-swc-ext",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -716,7 +728,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -749,7 +761,7 @@ dependencies = [
|
||||||
"pmutil",
|
"pmutil",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1034,7 +1046,7 @@ dependencies = [
|
||||||
"pmutil",
|
"pmutil",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1536,7 +1548,9 @@ name = "oden"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"base64 0.21.4",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"bytes",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"fontdue",
|
"fontdue",
|
||||||
|
|
@ -1546,7 +1560,9 @@ dependencies = [
|
||||||
"notify",
|
"notify",
|
||||||
"oden-js",
|
"oden-js",
|
||||||
"pollster",
|
"pollster",
|
||||||
|
"sha-1",
|
||||||
"sourcemap 7.0.0",
|
"sourcemap 7.0.0",
|
||||||
|
"thiserror",
|
||||||
"tracy-client",
|
"tracy-client",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
"winit",
|
"winit",
|
||||||
|
|
@ -1712,7 +1728,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1764,9 +1780,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.59"
|
version = "1.0.67"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"
|
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
@ -1788,9 +1804,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.28"
|
version = "1.0.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
@ -2006,7 +2022,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2211,7 +2227,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2277,7 +2293,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2326,7 +2342,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2409,7 +2425,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2438,7 +2454,7 @@ version = "0.178.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "675b5c755b0448268830e85e59429095d3423c0ce4a850b209c6f0eeab069f63"
|
checksum = "675b5c755b0448268830e85e59429095d3423c0ce4a850b209c6f0eeab069f63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.13.1",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
@ -2513,7 +2529,7 @@ dependencies = [
|
||||||
"pmutil",
|
"pmutil",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2525,7 +2541,7 @@ dependencies = [
|
||||||
"pmutil",
|
"pmutil",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2549,7 +2565,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"swc_macros_common",
|
"swc_macros_common",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2565,9 +2581,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.18"
|
version = "2.0.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
|
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2594,22 +2610,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.40"
|
version = "1.0.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.40"
|
version = "1.0.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2699,7 +2715,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2907,7 +2923,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2941,7 +2957,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn 2.0.37",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ tracing = ["tracy-client/enable"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
base64 = "0.21.4"
|
||||||
bytemuck = { version = "1.13", features = ["derive"] }
|
bytemuck = { version = "1.13", features = ["derive"] }
|
||||||
|
bytes = "1.5.0"
|
||||||
deno_ast = { version = "0.29.3", features = ["transpiling", "typescript"] }
|
deno_ast = { version = "0.29.3", features = ["transpiling", "typescript"] }
|
||||||
env_logger = "0.10"
|
env_logger = "0.10"
|
||||||
fontdue = "0.7.3"
|
fontdue = "0.7.3"
|
||||||
|
|
@ -20,7 +22,9 @@ lru = "0.11.0"
|
||||||
notify = "6"
|
notify = "6"
|
||||||
oden-js = { path = "oden-js" }
|
oden-js = { path = "oden-js" }
|
||||||
pollster = "0.3"
|
pollster = "0.3"
|
||||||
|
sha-1 = "0.10.0"
|
||||||
sourcemap = "7.0.0"
|
sourcemap = "7.0.0"
|
||||||
|
thiserror = "1.0.49"
|
||||||
tracy-client = { version = "0.15.2", default-features = false }
|
tracy-client = { version = "0.15.2", default-features = false }
|
||||||
wgpu = "0.17"
|
wgpu = "0.17"
|
||||||
winit = "0.28"
|
winit = "0.28"
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ else
|
||||||
LDEXPORT=-rdynamic
|
LDEXPORT=-rdynamic
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PROGS=qjs$(EXE) qjsc$(EXE) run-test262
|
PROGS=qjs$(EXE) qjsc$(EXE) qjsd$(EXE) run-test262
|
||||||
ifneq ($(CROSS_PREFIX),)
|
ifneq ($(CROSS_PREFIX),)
|
||||||
QJSC_CC=gcc
|
QJSC_CC=gcc
|
||||||
QJSC=./host-qjsc
|
QJSC=./host-qjsc
|
||||||
|
|
@ -196,6 +196,12 @@ qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS)
|
||||||
qjsc-debug$(EXE): $(OBJDIR)/qjsc.debug.o $(patsubst %.o, %.debug.o, $(QJS_LIB_OBJS))
|
qjsc-debug$(EXE): $(OBJDIR)/qjsc.debug.o $(patsubst %.o, %.debug.o, $(QJS_LIB_OBJS))
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
qjsd$(EXE): $(OBJDIR)/qjsd.o $(QJS_LIB_OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
qjsd-debug$(EXE): $(OBJDIR)/qjsd.debug.o $(patsubst %.o, %.debug.o, $(QJS_LIB_OBJS))
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
ifneq ($(CROSS_PREFIX),)
|
ifneq ($(CROSS_PREFIX),)
|
||||||
|
|
||||||
$(QJSC): $(OBJDIR)/qjsc.host.o \
|
$(QJSC): $(OBJDIR)/qjsc.host.o \
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,146 @@
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use bytes::buf::BufMut;
|
use bytes::buf::BufMut;
|
||||||
use oden_js::{Context, Runtime, ValueRef};
|
use oden_js::{Context, ContextRef, Runtime, ValueRef};
|
||||||
use sha1::{Digest, Sha1};
|
use sha1::{Digest, Sha1};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufRead, BufReader, Read, Write};
|
use std::io::{BufRead, BufReader, Read, Write};
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
|
use std::sync::{
|
||||||
|
mpsc::{channel, Receiver, Sender},
|
||||||
|
Arc, Mutex,
|
||||||
|
};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub enum DebuggerMethod {
|
||||||
|
UnknownMethod,
|
||||||
|
DebuggerEnable,
|
||||||
|
DebuggerSetAsyncCallStackDepth,
|
||||||
|
DebuggerSetBlackboxPatterns,
|
||||||
|
DebuggerSetPauseOnExceptions,
|
||||||
|
ProfilerEnable,
|
||||||
|
RuntimeEvaluate,
|
||||||
|
RuntimeEnable,
|
||||||
|
RuntimeRunIfWaitingForDebugger,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebuggerMethod {
|
||||||
|
pub fn from_request(method: &str, _params: &ValueRef) -> Result<Self> {
|
||||||
|
let evt = match method {
|
||||||
|
"Profiler.enable" => DebuggerMethod::ProfilerEnable,
|
||||||
|
"Runtime.enable" => DebuggerMethod::RuntimeEnable,
|
||||||
|
"Runtime.evaluate" => DebuggerMethod::RuntimeEvaluate,
|
||||||
|
"Runtime.runIfWaitingForDebugger" => DebuggerMethod::RuntimeRunIfWaitingForDebugger,
|
||||||
|
"Debugger.enable" => DebuggerMethod::DebuggerEnable,
|
||||||
|
"Debugger.setAsyncCallStackDepth" => DebuggerMethod::DebuggerSetAsyncCallStackDepth,
|
||||||
|
"Debugger.setBlackboxPatterns" => DebuggerMethod::DebuggerSetBlackboxPatterns,
|
||||||
|
"Debugger.setPauseOnExceptions" => DebuggerMethod::DebuggerSetPauseOnExceptions,
|
||||||
|
_ => {
|
||||||
|
eprintln!("Unsupported method: {method}");
|
||||||
|
DebuggerMethod::UnknownMethod
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(evt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DebuggerMessage {
|
||||||
|
pub id: String,
|
||||||
|
pub session_id: Option<String>,
|
||||||
|
pub method: DebuggerMethod,
|
||||||
|
pub response: Websocket,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebuggerMessage {
|
||||||
|
pub fn from_message(
|
||||||
|
context: &ContextRef,
|
||||||
|
message: &ValueRef,
|
||||||
|
response: Websocket,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let session_id = {
|
||||||
|
let session_id = message.get_property(&context, "sessionId")?;
|
||||||
|
if session_id.is_undefined() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(session_id.to_string(&context)?)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let id = {
|
||||||
|
let id = message.get_property(context, "id")?;
|
||||||
|
id.to_string(&context)?
|
||||||
|
};
|
||||||
|
let method = {
|
||||||
|
let method = message.get_property(&context, "method")?;
|
||||||
|
method.to_string(&context)?
|
||||||
|
};
|
||||||
|
let params = message.get_property(&context, "params")?;
|
||||||
|
|
||||||
|
let method = DebuggerMethod::from_request(&method, ¶ms)?;
|
||||||
|
Ok(DebuggerMessage {
|
||||||
|
id,
|
||||||
|
session_id,
|
||||||
|
method,
|
||||||
|
response,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum DebuggerEvent {
|
||||||
|
Error {
|
||||||
|
id: String,
|
||||||
|
code: i32,
|
||||||
|
message: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Debugger {
|
pub struct Debugger {
|
||||||
_thread: thread::JoinHandle<()>,
|
_thread: thread::JoinHandle<()>,
|
||||||
|
messages: Receiver<DebuggerMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn start_debugger() -> Debugger {
|
pub fn start_debugger() -> Debugger {
|
||||||
|
let (send_message, receive_message) = channel();
|
||||||
let thread = thread::spawn(move || {
|
let thread = thread::spawn(move || {
|
||||||
if let Err(e) = debugger_listener() {
|
if let Err(e) = debugger_listener(send_message) {
|
||||||
eprintln!("ERROR STARTING DEBUGGER: {:?}", e);
|
eprintln!("Error in debug listener: {:?}", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Debugger { _thread: thread }
|
Debugger {
|
||||||
|
_thread: thread,
|
||||||
|
messages: receive_message,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debugger_listener() -> Result<()> {
|
#[allow(dead_code)]
|
||||||
|
impl Debugger {
|
||||||
|
pub fn handle_debugger_messages(&self, _context: &Context) {
|
||||||
|
while let Ok(msg) = self.messages.try_recv() {
|
||||||
|
let event = match msg.method {
|
||||||
|
// TODO
|
||||||
|
_ => DebuggerEvent::Error {
|
||||||
|
id: msg.id.clone(),
|
||||||
|
code: -32601,
|
||||||
|
message: "Unsupported method".to_string(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// msg.response.send_json_response(context, context.new_string(msg.id)?
|
||||||
|
// let _ = msg.response.send(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_debug_event(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn debugger_listener(send: Sender<DebuggerMessage>) -> Result<()> {
|
||||||
let listener = TcpListener::bind("127.0.0.1:9229")?;
|
let listener = TcpListener::bind("127.0.0.1:9229")?;
|
||||||
let port = listener.local_addr()?.port();
|
let port = listener.local_addr()?.port();
|
||||||
println!("Debugger listening on http://127.0.0.1:{port}");
|
println!("Debugger listening on http://127.0.0.1:{port}");
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
let stream = match stream {
|
let stream = match stream {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
|
|
@ -37,42 +150,57 @@ pub fn debugger_listener() -> Result<()> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DebuggerConnection::start(stream);
|
DebuggerConnection::start(stream, send.clone());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DebuggerConnection {
|
struct DebuggerConnection {
|
||||||
stream: TcpStream,
|
stream: TcpStream,
|
||||||
|
send: Sender<DebuggerMessage>,
|
||||||
|
event_send: Sender<DebuggerEvent>,
|
||||||
|
events: Receiver<DebuggerEvent>,
|
||||||
context: Context,
|
context: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebuggerConnection {
|
impl DebuggerConnection {
|
||||||
fn start(stream: TcpStream) {
|
fn start(stream: TcpStream, send: Sender<DebuggerMessage>) -> Sender<DebuggerEvent> {
|
||||||
|
let (event_send, event_receive) = channel();
|
||||||
|
let result = event_send.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut connection = DebuggerConnection {
|
let mut connection = DebuggerConnection {
|
||||||
stream,
|
stream,
|
||||||
|
send,
|
||||||
|
event_send,
|
||||||
|
events: event_receive,
|
||||||
context: Context::new(Runtime::new()),
|
context: Context::new(Runtime::new()),
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
if let Err(e) = connection.handle_connection() {
|
match connection.handle_connection() {
|
||||||
eprintln!("Closing connection: {e}");
|
Ok(keep_open) => {
|
||||||
break;
|
if !keep_open {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Closing connection: {e}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Dumb HTTP stuff
|
// Dumb HTTP stuff
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
fn handle_connection(&mut self) -> Result<()> {
|
fn handle_connection(&mut self) -> Result<bool> {
|
||||||
let port = self.stream.local_addr()?.port();
|
let port = self.stream.local_addr()?.port();
|
||||||
let id = "dd5cfe85-f0b1-4241-a643-8ed81e436188";
|
let id = "dd5cfe85-f0b1-4241-a643-8ed81e436188";
|
||||||
|
|
||||||
let mut buf_reader = BufReader::new(&mut self.stream);
|
|
||||||
|
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
|
let mut buf_reader = BufReader::new(&mut self.stream);
|
||||||
while buffer.trim().is_empty() {
|
while buffer.trim().is_empty() {
|
||||||
buf_reader.read_line(&mut buffer)?;
|
buf_reader.read_line(&mut buffer)?;
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +209,7 @@ impl DebuggerConnection {
|
||||||
if parts.len() != 3 {
|
if parts.len() != 3 {
|
||||||
eprintln!("Invalid request line: {buffer}");
|
eprintln!("Invalid request line: {buffer}");
|
||||||
self.write_http_error(400, "Invalid request")?;
|
self.write_http_error(400, "Invalid request")?;
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let method = parts[0];
|
let method = parts[0];
|
||||||
|
|
@ -102,7 +230,7 @@ impl DebuggerConnection {
|
||||||
Some(idx) => idx,
|
Some(idx) => idx,
|
||||||
None => {
|
None => {
|
||||||
self.write_http_error(400, "Invalid request")?;
|
self.write_http_error(400, "Invalid request")?;
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let header = &header_line[0..sep_idx];
|
let header = &header_line[0..sep_idx];
|
||||||
|
|
@ -148,7 +276,7 @@ impl DebuggerConnection {
|
||||||
Some(v) => v.clone(),
|
Some(v) => v.clone(),
|
||||||
None => {
|
None => {
|
||||||
self.write_http_error(400, "Invalid request")?;
|
self.write_http_error(400, "Invalid request")?;
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
key.push_str("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
key.push_str("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
||||||
|
|
@ -165,13 +293,14 @@ impl DebuggerConnection {
|
||||||
self.stream.write_all(response.as_bytes())?;
|
self.stream.write_all(response.as_bytes())?;
|
||||||
|
|
||||||
self.handle_websocket_connection()?;
|
self.handle_websocket_connection()?;
|
||||||
|
return Ok(false);
|
||||||
} else {
|
} else {
|
||||||
self.write_http_error(404, "Not Found")?;
|
self.write_http_error(404, "Not Found")?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.write_http_error(404, "Not Found")?;
|
self.write_http_error(404, "Not Found")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_http_response(
|
fn write_http_response(
|
||||||
|
|
@ -201,23 +330,68 @@ impl DebuggerConnection {
|
||||||
self.write_http_response(200, "OK", content_type, data)
|
self.write_http_response(200, "OK", content_type, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// Dumb Websocket stuff
|
|
||||||
// ============================================================================
|
|
||||||
fn handle_websocket_connection(&mut self) -> Result<()> {
|
fn handle_websocket_connection(&mut self) -> Result<()> {
|
||||||
// BLARG: https://datatracker.ietf.org/doc/html/rfc6455
|
let websocket = Websocket::new(&self.stream)?;
|
||||||
|
|
||||||
let mut payload: Vec<u8> = Vec::new();
|
let mut payload: Vec<u8> = Vec::new();
|
||||||
let mut opcode: WebsocketOp = WebsocketOp::Continue;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let frame = WebsocketFrameHeader::read(&mut self.stream)?;
|
let op = websocket.read_websocket_message(&mut payload)?;
|
||||||
|
if let WebsocketOp::Close = op {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let text = String::from_utf8_lossy(&payload);
|
||||||
|
eprintln!("Received: {text}");
|
||||||
|
|
||||||
|
let message = match self.context.parse_json(&text, "<debugger message>") {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("error parsing json {e}");
|
||||||
|
websocket.send_websocket_close(1007, "invalid json")?;
|
||||||
|
return Err("invalid json".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let message =
|
||||||
|
DebuggerMessage::from_message(&self.context, &message, websocket.clone())?;
|
||||||
|
let _ = self.send.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Dumb Websocket stuff
|
||||||
|
// ============================================================================
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Websocket {
|
||||||
|
// TODO: Atomic close
|
||||||
|
send: Arc<Mutex<TcpStream>>,
|
||||||
|
receive: Arc<Mutex<TcpStream>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Websocket {
|
||||||
|
pub fn new(stream: &TcpStream) -> Result<Websocket> {
|
||||||
|
let send = stream.try_clone()?;
|
||||||
|
let receive = stream.try_clone()?;
|
||||||
|
Ok(Websocket {
|
||||||
|
send: Arc::new(Mutex::new(send)),
|
||||||
|
receive: Arc::new(Mutex::new(receive)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_websocket_message(&self, payload: &mut Vec<u8>) -> Result<WebsocketOp> {
|
||||||
|
// BLARG: https://datatracker.ietf.org/doc/html/rfc6455
|
||||||
|
payload.clear();
|
||||||
|
|
||||||
|
let mut stream = self.receive.lock().unwrap();
|
||||||
|
let mut opcode: WebsocketOp = WebsocketOp::Continue;
|
||||||
|
loop {
|
||||||
|
let frame = WebsocketFrameHeader::read(&mut stream)?;
|
||||||
eprintln!("FRAME: {:?}", frame);
|
eprintln!("FRAME: {:?}", frame);
|
||||||
let mask = match frame.mask {
|
let mask = match frame.mask {
|
||||||
Some(m) => m,
|
Some(m) => m,
|
||||||
None => {
|
None => {
|
||||||
eprintln!("Client sent unmasked frame");
|
eprintln!("Client sent unmasked frame");
|
||||||
return Ok(()); // TODO: _Fail the WebSocket Connection_
|
self.send_websocket_close(1002, "client sent unmasked frame")?;
|
||||||
|
return Err(DebuggerError::WebsocketError);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -227,14 +401,15 @@ impl DebuggerConnection {
|
||||||
// This is a control frame, handle it on its own.
|
// This is a control frame, handle it on its own.
|
||||||
if frame.length > 125 {
|
if frame.length > 125 {
|
||||||
eprintln!("Control frame too big ({})", frame.length);
|
eprintln!("Control frame too big ({})", frame.length);
|
||||||
return Ok(()); // TODO: _Fail the WebSocket Connection_
|
self.send_websocket_close(1002, "control frame too big")?;
|
||||||
|
return Err(DebuggerError::WebsocketError);
|
||||||
}
|
}
|
||||||
let mut buffer: [u8; 125] = [0; 125];
|
let mut buffer: [u8; 125] = [0; 125];
|
||||||
self.stream.read_exact(&mut buffer[0..frame.length])?;
|
stream.read_exact(&mut buffer[0..frame.length])?;
|
||||||
|
|
||||||
if frame.opcode == WebsocketOp::Close {
|
if frame.opcode == WebsocketOp::Close {
|
||||||
self.send_websocket_message(frame.opcode, &buffer[..frame.length])?;
|
self.send_websocket_message(frame.opcode, &buffer[..frame.length])?;
|
||||||
return Ok(());
|
return Ok(WebsocketOp::Close);
|
||||||
} else if frame.opcode == WebsocketOp::Ping {
|
} else if frame.opcode == WebsocketOp::Ping {
|
||||||
self.send_websocket_message(WebsocketOp::Pong, &buffer[..frame.length])?;
|
self.send_websocket_message(WebsocketOp::Pong, &buffer[..frame.length])?;
|
||||||
} else if frame.opcode == WebsocketOp::Pong {
|
} else if frame.opcode == WebsocketOp::Pong {
|
||||||
|
|
@ -245,13 +420,14 @@ impl DebuggerConnection {
|
||||||
let last_tail = payload.len();
|
let last_tail = payload.len();
|
||||||
if last_tail + frame.length > 1 * 1024 * 1024 {
|
if last_tail + frame.length > 1 * 1024 * 1024 {
|
||||||
eprintln!("Message too big ({})", frame.length);
|
eprintln!("Message too big ({})", frame.length);
|
||||||
return Ok(()); // TODO: _Fail the WebSocket Connection_
|
self.send_websocket_close(1009, "message too big")?;
|
||||||
|
return Err(DebuggerError::WebsocketError);
|
||||||
}
|
}
|
||||||
payload.resize(last_tail + frame.length, 0);
|
payload.resize(last_tail + frame.length, 0);
|
||||||
let slice = payload.as_mut_slice();
|
let slice = payload.as_mut_slice();
|
||||||
let mut slice = &mut slice[last_tail..];
|
let mut slice = &mut slice[last_tail..];
|
||||||
// eprintln!("Reading {} bytes", slice.len());
|
// eprintln!("Reading {} bytes", slice.len());
|
||||||
self.stream.read_exact(&mut slice)?;
|
stream.read_exact(&mut slice)?;
|
||||||
for i in 0..frame.length {
|
for i in 0..frame.length {
|
||||||
slice[i] = slice[i] ^ mask[i % 4];
|
slice[i] = slice[i] ^ mask[i % 4];
|
||||||
}
|
}
|
||||||
|
|
@ -264,27 +440,26 @@ impl DebuggerConnection {
|
||||||
if frame.fin {
|
if frame.fin {
|
||||||
// Dispatch.
|
// Dispatch.
|
||||||
// eprintln!("Dispatching: {:?} {}", opcode, payload.len());
|
// eprintln!("Dispatching: {:?} {}", opcode, payload.len());
|
||||||
self.handle_websocket_message(opcode, &payload)?;
|
return Ok(opcode);
|
||||||
payload.clear();
|
|
||||||
opcode = WebsocketOp::Continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_websocket_message(&mut self, opcode: WebsocketOp, payload: &[u8]) -> Result<()> {
|
pub fn send_websocket_message(&self, opcode: WebsocketOp, payload: &[u8]) -> Result<()> {
|
||||||
|
let mut stream = self.send.lock().unwrap();
|
||||||
WebsocketFrameHeader {
|
WebsocketFrameHeader {
|
||||||
fin: true,
|
fin: true,
|
||||||
opcode,
|
opcode,
|
||||||
length: payload.len(),
|
length: payload.len(),
|
||||||
mask: None,
|
mask: None,
|
||||||
}
|
}
|
||||||
.write(&mut self.stream)?;
|
.write(&mut stream)?;
|
||||||
self.stream.write_all(payload)?;
|
stream.write_all(payload)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_websocket_close(&mut self, close_code: u16, reason: &str) -> Result<()> {
|
pub fn send_websocket_close(&self, close_code: u16, reason: &str) -> Result<()> {
|
||||||
if reason.len() > 123 {
|
if reason.len() > 123 {
|
||||||
return Err("reason doesn't fit in close packet".into());
|
return Err("reason doesn't fit in close packet".into());
|
||||||
}
|
}
|
||||||
|
|
@ -299,103 +474,41 @@ impl DebuggerConnection {
|
||||||
self.send_websocket_message(WebsocketOp::Close, &body[0..body_len])
|
self.send_websocket_message(WebsocketOp::Close, &body[0..body_len])
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
pub fn send_json_event(
|
||||||
// Actual debugger stuff?
|
&self,
|
||||||
// ============================================================================
|
context: &ContextRef,
|
||||||
fn handle_websocket_message(&mut self, _op: WebsocketOp, data: &[u8]) -> Result<()> {
|
event: &str,
|
||||||
let text = String::from_utf8_lossy(data);
|
params: &ValueRef,
|
||||||
eprintln!("Received: {text}");
|
) -> Result<()> {
|
||||||
|
self.send_json_message(
|
||||||
let message = match self.context.parse_json(&text, "<deubgger message>") {
|
&context,
|
||||||
Ok(v) => v,
|
context
|
||||||
Err(e) => {
|
.new_object_props([
|
||||||
eprintln!("error parsing json {e}");
|
("method", context.new_string(event)?.as_ref()),
|
||||||
self.send_websocket_close(1007, "invalid json")?;
|
("params", params),
|
||||||
return Err("invalid json".into());
|
])?
|
||||||
}
|
.as_ref(),
|
||||||
};
|
)
|
||||||
|
|
||||||
// Oh no.
|
|
||||||
let _ = message.get_property(&self.context, "sessionId")?;
|
|
||||||
let id = message.get_property(&self.context, "id")?;
|
|
||||||
let method = {
|
|
||||||
let method = message.get_property(&self.context, "method")?;
|
|
||||||
method.to_string(&self.context)?
|
|
||||||
};
|
|
||||||
let _ = message.get_property(&self.context, "params")?;
|
|
||||||
|
|
||||||
match method.as_str() {
|
|
||||||
"Profiler.enable" => {
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
"Runtime.enable" => {
|
|
||||||
self.send_json_event(
|
|
||||||
"Runtime.executionContextCreated",
|
|
||||||
self.context
|
|
||||||
.new_object_props([(
|
|
||||||
"context",
|
|
||||||
self.context.new_object_props([
|
|
||||||
("id", self.context.new_i32(7)?),
|
|
||||||
("origin", self.context.new_string("something")?),
|
|
||||||
("name", self.context.new_string("main")?),
|
|
||||||
("uniqueId", self.context.new_string("aaa-aaa-aaa")?),
|
|
||||||
])?,
|
|
||||||
)])?
|
|
||||||
.as_ref(),
|
|
||||||
)?;
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
"Runtime.evaluate" => {
|
|
||||||
// OHHHHHHHHHH
|
|
||||||
eprintln!("****** EVALUATE *******");
|
|
||||||
self.send_debugger_error(&id, -32601, "method does not exist")?
|
|
||||||
}
|
|
||||||
|
|
||||||
"Runtime.runIfWaitingForDebugger" => {
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
"Debugger.enable" => {
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
"Debugger.setAsyncCallStackDepth" => {
|
|
||||||
// TODO: Do I need to respect this?
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
"Debugger.setBlackboxPatterns" => {
|
|
||||||
// TODO: Do I need to respect this?
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
"Debugger.setPauseOnExceptions" => {
|
|
||||||
// TODO: Respect this.
|
|
||||||
self.send_json_response(&id, self.context.new_object()?.as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
eprintln!("Unsupported method: {method}");
|
|
||||||
self.send_debugger_error(&id, -32601, "method does not exist")?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_debugger_error(&mut self, id: &ValueRef, code: i32, msg: &str) -> Result<()> {
|
pub fn send_json_error(
|
||||||
|
&self,
|
||||||
|
context: &ContextRef,
|
||||||
|
id: &ValueRef,
|
||||||
|
code: i32,
|
||||||
|
msg: &str,
|
||||||
|
) -> Result<()> {
|
||||||
self.send_json_message(
|
self.send_json_message(
|
||||||
self.context
|
&context,
|
||||||
|
context
|
||||||
.new_object_props([
|
.new_object_props([
|
||||||
("id", id),
|
("id", id),
|
||||||
(
|
(
|
||||||
"error",
|
"error",
|
||||||
self.context
|
context
|
||||||
.new_object_props([
|
.new_object_props([
|
||||||
("code", self.context.new_i32(code)?),
|
("code", context.new_i32(code)?),
|
||||||
("message", self.context.new_string(msg)?),
|
("message", context.new_string(msg)?),
|
||||||
])?
|
])?
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
),
|
),
|
||||||
|
|
@ -404,29 +517,18 @@ impl DebuggerConnection {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_json_event(&mut self, event: &str, params: &ValueRef) -> Result<()> {
|
pub fn send_json_response(
|
||||||
self.send_json_message(
|
&self,
|
||||||
self.context
|
context: &ContextRef,
|
||||||
.new_object_props([
|
id: &ValueRef,
|
||||||
("method", self.context.new_string(event)?.as_ref()),
|
result: &ValueRef,
|
||||||
("params", params),
|
) -> Result<()> {
|
||||||
])?
|
let response = context.new_object_props([("id", id), ("result", result)])?;
|
||||||
.as_ref(),
|
self.send_json_message(&context, &response)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_json_response(&mut self, id: &ValueRef, result: &ValueRef) -> Result<()> {
|
pub fn send_json_message(&self, context: &ContextRef, value: &ValueRef) -> Result<()> {
|
||||||
let response = self
|
let txt = context.json_stringify(&value)?.to_string(&context)?;
|
||||||
.context
|
|
||||||
.new_object_props([("id", id), ("result", result)])?;
|
|
||||||
self.send_json_message(&response)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_json_message(&mut self, value: &ValueRef) -> Result<()> {
|
|
||||||
let txt = self
|
|
||||||
.context
|
|
||||||
.json_stringify(&value)?
|
|
||||||
.to_string(&self.context)?;
|
|
||||||
eprintln!("Send: {txt}");
|
eprintln!("Send: {txt}");
|
||||||
self.send_websocket_message(WebsocketOp::Text, txt.as_bytes())
|
self.send_websocket_message(WebsocketOp::Text, txt.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
@ -568,6 +670,8 @@ pub enum DebuggerError {
|
||||||
JsError(oden_js::Error),
|
JsError(oden_js::Error),
|
||||||
#[error("an io error has occurred: {0}")]
|
#[error("an io error has occurred: {0}")]
|
||||||
IoError(io::Error),
|
IoError(io::Error),
|
||||||
|
#[error("the websocket encountered a protocol error")]
|
||||||
|
WebsocketError,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result<T> = core::result::Result<T, DebuggerError>;
|
type Result<T> = core::result::Result<T, DebuggerError>;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue