Compare commits
No commits in common. "c990de5ad653d86e57b0057d98490f73572949fc" and "0531387498a23fb1725bc73620ee9e956c167b70" have entirely different histories.
c990de5ad6
...
0531387498
5 changed files with 13 additions and 198 deletions
|
|
@ -1018,11 +1018,6 @@ typedef struct JSBreakpoint {
|
||||||
JS_BOOL enabled;
|
JS_BOOL enabled;
|
||||||
} JSBreakpoint;
|
} JSBreakpoint;
|
||||||
|
|
||||||
typedef struct JSDebugContext {
|
|
||||||
JSContext *ctx;
|
|
||||||
JSStackFrame *sf;
|
|
||||||
} JSDebugContext;
|
|
||||||
|
|
||||||
static int JS_InitAtoms(JSRuntime *rt);
|
static int JS_InitAtoms(JSRuntime *rt);
|
||||||
static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len,
|
static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len,
|
||||||
int atom_type);
|
int atom_type);
|
||||||
|
|
@ -6508,7 +6503,6 @@ static void get_frame_debug_position(JSContext *ctx, JSStackFrame *sf,
|
||||||
|
|
||||||
*backtrace_barrier = FALSE;
|
*backtrace_barrier = FALSE;
|
||||||
*function = get_func_name(ctx, sf->cur_func);
|
*function = get_func_name(ctx, sf->cur_func);
|
||||||
|
|
||||||
p = JS_VALUE_GET_OBJ(sf->cur_func);
|
p = JS_VALUE_GET_OBJ(sf->cur_func);
|
||||||
if (js_class_has_bytecode(p->class_id)) {
|
if (js_class_has_bytecode(p->class_id)) {
|
||||||
JSFunctionBytecode *b;
|
JSFunctionBytecode *b;
|
||||||
|
|
@ -6516,6 +6510,7 @@ static void get_frame_debug_position(JSContext *ctx, JSStackFrame *sf,
|
||||||
|
|
||||||
b = p->u.func.function_bytecode;
|
b = p->u.func.function_bytecode;
|
||||||
*backtrace_barrier = b->backtrace_barrier;
|
*backtrace_barrier = b->backtrace_barrier;
|
||||||
|
*function = JS_AtomToCString(ctx, b->func_name);
|
||||||
if (b->has_debug) {
|
if (b->has_debug) {
|
||||||
line_num1 = find_line_num(ctx, b, sf->cur_pc - b->byte_code_buf - 1);
|
line_num1 = find_line_num(ctx, b, sf->cur_pc - b->byte_code_buf - 1);
|
||||||
|
|
||||||
|
|
@ -33780,24 +33775,6 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
|
||||||
goto fail1;
|
goto fail1;
|
||||||
fun_obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m));
|
fun_obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->rt->debug_callback) {
|
|
||||||
JSDebugContext dctx;
|
|
||||||
dctx.ctx = ctx;
|
|
||||||
dctx.sf = sf;
|
|
||||||
|
|
||||||
JSDebugEvent evt;
|
|
||||||
evt.reason = JS_BREAK_CODE_LOADED;
|
|
||||||
evt.u.loaded.filename = filename;
|
|
||||||
|
|
||||||
/* TODO: Handle the step/resume/what-have-you. Step from here will
|
|
||||||
be complicated because the function we need to step into will be
|
|
||||||
the one we just parsed, kinda- unless it's a module? Even then
|
|
||||||
it's not clear where the break will go if we're loading a
|
|
||||||
module... yikes. */
|
|
||||||
/* resume = */ctx->rt->debug_callback(&dctx, &evt, ctx->rt->debug_opaque);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & JS_EVAL_FLAG_COMPILE_ONLY) {
|
if (flags & JS_EVAL_FLAG_COMPILE_ONLY) {
|
||||||
ret_val = fun_obj;
|
ret_val = fun_obj;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -54170,12 +54147,6 @@ void JS_SetSourceMapFunc(JSRuntime *rt, JSMapSourceFunc *map_func, void *opaque)
|
||||||
|
|
||||||
/* Debugger */
|
/* Debugger */
|
||||||
|
|
||||||
void JS_SetDebugCallbackFunc(JSRuntime *rt, JSDebugCallbackFunc *func, void *opaque)
|
|
||||||
{
|
|
||||||
rt->debug_callback = func;
|
|
||||||
rt->debug_opaque = opaque;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL find_pc_offset(JSFunctionBytecode *b, int target_line, int *break_pc, int *actual_line)
|
static BOOL find_pc_offset(JSFunctionBytecode *b, int target_line, int *break_pc, int *actual_line)
|
||||||
{
|
{
|
||||||
const uint8_t *p_end, *p;
|
const uint8_t *p_end, *p;
|
||||||
|
|
@ -54228,8 +54199,7 @@ static BOOL find_pc_offset(JSFunctionBytecode *b, int target_line, int *break_pc
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBreakpoint *find_existing_breakpoint(JSContext *ctx, JSFunctionBytecode *func, int pc)
|
static JSBreakpoint *find_existing_breakpoint(JSContext *ctx, JSFunctionBytecode *func, int pc) {
|
||||||
{
|
|
||||||
struct list_head *el;
|
struct list_head *el;
|
||||||
list_for_each(el, &ctx->rt->breakpoint_list) {
|
list_for_each(el, &ctx->rt->breakpoint_list) {
|
||||||
JSBreakpoint *bp = list_entry(el, JSBreakpoint, link);
|
JSBreakpoint *bp = list_entry(el, JSBreakpoint, link);
|
||||||
|
|
@ -54240,8 +54210,12 @@ static JSBreakpoint *find_existing_breakpoint(JSContext *ctx, JSFunctionBytecode
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_offset)
|
typedef struct JSDebugContext {
|
||||||
{
|
JSContext *ctx;
|
||||||
|
JSStackFrame *sf;
|
||||||
|
} JSDebugContext;
|
||||||
|
|
||||||
|
static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_offset) {
|
||||||
int next_op;
|
int next_op;
|
||||||
/* JSResumeMode resume = JS_RESUME_MODE_CONTINUE; */
|
/* JSResumeMode resume = JS_RESUME_MODE_CONTINUE; */
|
||||||
JSRuntime *rt = ctx->rt;
|
JSRuntime *rt = ctx->rt;
|
||||||
|
|
@ -54253,11 +54227,7 @@ static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_
|
||||||
dctx.ctx = ctx;
|
dctx.ctx = ctx;
|
||||||
dctx.sf = ctx->rt->current_stack_frame;
|
dctx.sf = ctx->rt->current_stack_frame;
|
||||||
|
|
||||||
JSDebugEvent evt;
|
/* resume = */rt->debug_callback(&dctx, JS_BREAK_BREAKPOINT, bp, rt->debug_opaque);
|
||||||
evt.reason = JS_BREAK_BREAKPOINT;
|
|
||||||
evt.u.breakpoint = bp;
|
|
||||||
|
|
||||||
/* resume = */rt->debug_callback(&dctx, &evt, rt->debug_opaque);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next_op = bp->replaced_byte;
|
next_op = bp->replaced_byte;
|
||||||
|
|
@ -54271,11 +54241,8 @@ static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_
|
||||||
JSDebugContext dctx;
|
JSDebugContext dctx;
|
||||||
dctx.ctx = ctx;
|
dctx.ctx = ctx;
|
||||||
dctx.sf = ctx->rt->current_stack_frame;
|
dctx.sf = ctx->rt->current_stack_frame;
|
||||||
|
|
||||||
JSDebugEvent evt;
|
|
||||||
evt.reason = JS_BREAK_STEP;
|
|
||||||
|
|
||||||
/* resume = */rt->debug_callback(&dctx, &evt, rt->debug_opaque);
|
/* resume = */rt->debug_callback(&dctx, JS_BREAK_STEP, NULL, rt->debug_opaque);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54304,7 +54271,7 @@ void JS_DebugGetFrameSourcePosition(JSDebugContext *dctx, JSDebugFrame *frame,
|
||||||
JSStackFrame *sf = (JSStackFrame *)frame;
|
JSStackFrame *sf = (JSStackFrame *)frame;
|
||||||
JSContext *ctx = dctx->ctx;
|
JSContext *ctx = dctx->ctx;
|
||||||
BOOL backtrace_barrier;
|
BOOL backtrace_barrier;
|
||||||
|
|
||||||
get_frame_debug_position(ctx, sf, function, file, line, &backtrace_barrier);
|
get_frame_debug_position(ctx, sf, function, file, line, &backtrace_barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1070,25 +1070,15 @@ typedef enum JSResumeMode {
|
||||||
} JSResumeMode;
|
} JSResumeMode;
|
||||||
|
|
||||||
typedef enum JSBreakReason {
|
typedef enum JSBreakReason {
|
||||||
JS_BREAK_CODE_LOADED,
|
|
||||||
JS_BREAK_BREAKPOINT,
|
JS_BREAK_BREAKPOINT,
|
||||||
JS_BREAK_STEP,
|
JS_BREAK_STEP,
|
||||||
} JSBreakReason;
|
} JSBreakReason;
|
||||||
|
|
||||||
typedef struct JSBreakpoint JSBreakpoint;
|
typedef struct JSBreakpoint JSBreakpoint;
|
||||||
|
|
||||||
typedef struct JSDebugEvent {
|
|
||||||
JSBreakReason reason;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
const char *filename;
|
|
||||||
} loaded;
|
|
||||||
JSBreakpoint *breakpoint;
|
|
||||||
} u;
|
|
||||||
} JSDebugEvent;
|
|
||||||
|
|
||||||
typedef JSResumeMode JSDebugCallbackFunc(JSDebugContext *ctx,
|
typedef JSResumeMode JSDebugCallbackFunc(JSDebugContext *ctx,
|
||||||
JSDebugEvent *event,
|
JSBreakReason reason,
|
||||||
|
JSBreakpoint *breakpoint,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
void JS_SetDebugCallbackFunc(JSRuntime *rt, JSDebugCallbackFunc *bp_func,
|
void JS_SetDebugCallbackFunc(JSRuntime *rt, JSDebugCallbackFunc *bp_func,
|
||||||
void *opqaue);
|
void *opqaue);
|
||||||
|
|
|
||||||
|
|
@ -1376,8 +1376,6 @@ fn main_thread(event_loop: EventLoopProxy<OdenEvent>, state: State, reciever: Re
|
||||||
let mut script = script::ScriptContext::new(None, script_reload_send.clone())
|
let mut script = script::ScriptContext::new(None, script_reload_send.clone())
|
||||||
.expect("Unable to create initial script context");
|
.expect("Unable to create initial script context");
|
||||||
|
|
||||||
let _debugger = script::debugger::start_debugger();
|
|
||||||
|
|
||||||
const SPF: f64 = 1.0 / 60.0;
|
const SPF: f64 = 1.0 / 60.0;
|
||||||
loop {
|
loop {
|
||||||
frame_mark();
|
frame_mark();
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ use std::time::Instant;
|
||||||
use tracy_client::span;
|
use tracy_client::span;
|
||||||
use winit::event::*;
|
use winit::event::*;
|
||||||
|
|
||||||
pub mod debugger;
|
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
mod input;
|
mod input;
|
||||||
mod io;
|
mod io;
|
||||||
|
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::io;
|
|
||||||
use std::io::{BufRead, BufReader, Write};
|
|
||||||
use std::net::{TcpListener, TcpStream};
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
pub struct Debugger {
|
|
||||||
_thread: thread::JoinHandle<()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_http_response(
|
|
||||||
stream: &mut TcpStream,
|
|
||||||
code: u16,
|
|
||||||
phrase: &str,
|
|
||||||
content_type: &str,
|
|
||||||
data: &[u8],
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let length = data.len();
|
|
||||||
let buffer = format!(
|
|
||||||
"HTTP/1.1 {code} {phrase}\r\n\
|
|
||||||
content-length: {length}\r\n\
|
|
||||||
content-type: {content_type}\r\n\
|
|
||||||
\r\n"
|
|
||||||
);
|
|
||||||
stream.write_all(buffer.as_bytes())?;
|
|
||||||
stream.write_all(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_http_error(stream: &mut TcpStream, code: u16, phrase: &str) -> io::Result<()> {
|
|
||||||
write_http_response(stream, code, phrase, "text/plain", phrase.as_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_http_ok(stream: &mut TcpStream, content_type: &str, data: &[u8]) -> io::Result<()> {
|
|
||||||
write_http_response(stream, 200, "OK", content_type, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_connection(mut stream: TcpStream) -> io::Result<()> {
|
|
||||||
let mut buf_reader = BufReader::new(&mut stream);
|
|
||||||
|
|
||||||
let mut buffer = String::new();
|
|
||||||
buf_reader.read_line(&mut buffer)?;
|
|
||||||
|
|
||||||
let parts: Vec<_> = buffer.trim().split(" ").collect();
|
|
||||||
if parts.len() != 3 {
|
|
||||||
eprintln!("Invalid request line: {buffer}");
|
|
||||||
write_http_error(&mut stream, 400, "Invalid request")?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let method = parts[0];
|
|
||||||
let path = parts[1];
|
|
||||||
eprintln!("Debugger: {method} {path}");
|
|
||||||
|
|
||||||
let mut headers = HashMap::new();
|
|
||||||
let mut header_line_buffer = String::new();
|
|
||||||
loop {
|
|
||||||
header_line_buffer.clear();
|
|
||||||
buf_reader.read_line(&mut header_line_buffer)?;
|
|
||||||
let header_line = header_line_buffer.trim();
|
|
||||||
if header_line.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sep_idx = match header_line.find(":") {
|
|
||||||
Some(idx) => idx,
|
|
||||||
None => {
|
|
||||||
write_http_error(&mut stream, 400, "Invalid request")?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let header = &header_line[0..sep_idx];
|
|
||||||
let value = &header_line[sep_idx + 1..];
|
|
||||||
eprintln!("HEADER: {header} {value}");
|
|
||||||
headers.insert(header.trim().to_string(), value.trim().to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if method == "GET" {
|
|
||||||
if path == "/json/version" {
|
|
||||||
// NOTE: Deno spits out a V8 version here but we're not running v8.
|
|
||||||
write_http_ok(
|
|
||||||
&mut stream,
|
|
||||||
"application/json",
|
|
||||||
"{\"Browser\": \"Oden/0.0.1\", \"Protocol-Version\": \"1.3\"}".as_bytes(),
|
|
||||||
)?;
|
|
||||||
} else if path == "/json" || path == "/json/list" {
|
|
||||||
// [
|
|
||||||
// {
|
|
||||||
// "description": "deno",
|
|
||||||
// "devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/ws/01b9bd23-8810-43ed-86f7-5feef5d120fa&experiments=true&v8only=true",
|
|
||||||
// "faviconUrl": "https://deno.land/favicon.ico",
|
|
||||||
// "id": "01b9bd23-8810-43ed-86f7-5feef5d120fa",
|
|
||||||
// "title": "deno - main [pid: 40483]",
|
|
||||||
// "type": "node",
|
|
||||||
// "url": "file:///Users/doty/src/ioniq/status.ts",
|
|
||||||
// "webSocketDebuggerUrl": "ws://127.0.0.1:9229/ws/01b9bd23-8810-43ed-86f7-5feef5d120fa"
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
} else if path == "/ws/dd5cfe85-f0b1-4241-a643-8ed81e436188" {
|
|
||||||
// I don't feel like making a new guid for each thing.
|
|
||||||
// Websocket upgrade and then debugger messages.
|
|
||||||
} else {
|
|
||||||
write_http_error(&mut stream, 404, "Not Found")?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
write_http_error(&mut stream, 404, "Not Found")?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn debugger_listener() -> io::Result<()> {
|
|
||||||
let listener = TcpListener::bind("127.0.0.1:0")?;
|
|
||||||
let port = listener.local_addr()?.port();
|
|
||||||
println!("Debugger listening on http://127.0.0.1:{port}");
|
|
||||||
for stream in listener.incoming() {
|
|
||||||
let stream = match stream {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Error accepting incoming connection: {:?}", e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Thread pool extraction here.
|
|
||||||
if let Err(e) = handle_connection(stream) {
|
|
||||||
eprintln!("Error handling incoming connection: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn start_debugger() -> Debugger {
|
|
||||||
let thread = thread::spawn(move || {
|
|
||||||
if let Err(e) = debugger_listener() {
|
|
||||||
eprintln!("ERROR STARTING DEBUGGER: {:?}", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Debugger { _thread: thread }
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue