haku2: VM logging
This commit is contained in:
parent
5de4f9d7c6
commit
7658e0d4e8
5 changed files with 105 additions and 2 deletions
|
@ -8,13 +8,21 @@ const render = @import("render.zig");
|
||||||
const Scratch = @import("scratch.zig");
|
const Scratch = @import("scratch.zig");
|
||||||
const value = @import("value.zig");
|
const value = @import("value.zig");
|
||||||
const Vm = @import("vm.zig");
|
const Vm = @import("vm.zig");
|
||||||
|
const log = @import("log.zig");
|
||||||
|
|
||||||
const allocator =
|
const vm_trace = true;
|
||||||
|
|
||||||
|
pub const allocator =
|
||||||
if (builtin.cpu.arch == .wasm32)
|
if (builtin.cpu.arch == .wasm32)
|
||||||
std.heap.wasm_allocator
|
std.heap.wasm_allocator
|
||||||
else
|
else
|
||||||
@import("allocator.zig").hostAllocator;
|
@import("allocator.zig").hostAllocator;
|
||||||
|
|
||||||
|
pub const std_options: std.Options = .{
|
||||||
|
.log_level = if (vm_trace) .debug else .info,
|
||||||
|
.logFn = log.logFn,
|
||||||
|
};
|
||||||
|
|
||||||
// Scratch
|
// Scratch
|
||||||
|
|
||||||
export fn haku2_scratch_new(max: usize) ?*Scratch {
|
export fn haku2_scratch_new(max: usize) ?*Scratch {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::{
|
||||||
marker::{PhantomData, PhantomPinned},
|
marker::{PhantomData, PhantomPinned},
|
||||||
mem::forget,
|
mem::forget,
|
||||||
ptr::{self, NonNull},
|
ptr::{self, NonNull},
|
||||||
|
slice,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
|
@ -40,6 +41,54 @@ unsafe extern "C" fn __haku2_dealloc(ptr: *mut u8, size: usize, align: usize) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
unsafe extern "C" fn __haku2_log_err(
|
||||||
|
scope: *const u8,
|
||||||
|
scope_len: usize,
|
||||||
|
msg: *const u8,
|
||||||
|
len: usize,
|
||||||
|
) {
|
||||||
|
let scope = String::from_utf8_lossy(slice::from_raw_parts(scope, scope_len));
|
||||||
|
let msg = String::from_utf8_lossy(slice::from_raw_parts(msg, len));
|
||||||
|
log::error!("{scope}: {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
unsafe extern "C" fn __haku2_log_warn(
|
||||||
|
scope: *const u8,
|
||||||
|
scope_len: usize,
|
||||||
|
msg: *const u8,
|
||||||
|
len: usize,
|
||||||
|
) {
|
||||||
|
let scope = String::from_utf8_lossy(slice::from_raw_parts(scope, scope_len));
|
||||||
|
let msg = String::from_utf8_lossy(slice::from_raw_parts(msg, len));
|
||||||
|
log::warn!("{scope}: {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
unsafe extern "C" fn __haku2_log_info(
|
||||||
|
scope: *const u8,
|
||||||
|
scope_len: usize,
|
||||||
|
msg: *const u8,
|
||||||
|
len: usize,
|
||||||
|
) {
|
||||||
|
let scope = String::from_utf8_lossy(slice::from_raw_parts(scope, scope_len));
|
||||||
|
let msg = String::from_utf8_lossy(slice::from_raw_parts(msg, len));
|
||||||
|
log::info!("{scope}: {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
unsafe extern "C" fn __haku2_log_debug(
|
||||||
|
scope: *const u8,
|
||||||
|
scope_len: usize,
|
||||||
|
msg: *const u8,
|
||||||
|
len: usize,
|
||||||
|
) {
|
||||||
|
let scope = String::from_utf8_lossy(slice::from_raw_parts(scope, scope_len));
|
||||||
|
let msg = String::from_utf8_lossy(slice::from_raw_parts(msg, len));
|
||||||
|
log::debug!("{scope}: {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ScratchC {
|
struct ScratchC {
|
||||||
_data: (),
|
_data: (),
|
||||||
|
|
42
crates/haku2/src/log.zig
Normal file
42
crates/haku2/src/log.zig
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const log = std.log;
|
||||||
|
|
||||||
|
const root = @import("root");
|
||||||
|
|
||||||
|
pub fn logFn(
|
||||||
|
comptime level: log.Level,
|
||||||
|
comptime scope: @TypeOf(.enum_literal),
|
||||||
|
comptime fmt: []const u8,
|
||||||
|
args: anytype,
|
||||||
|
) void {
|
||||||
|
const stack_buf_size = 1024;
|
||||||
|
var stack_buf: [stack_buf_size]u8 = undefined;
|
||||||
|
var heap_buf: ?[]u8 = null;
|
||||||
|
|
||||||
|
// Tricky code ahead: when the heap allocation fails, we still want to fall back to
|
||||||
|
// logging _something_.
|
||||||
|
|
||||||
|
const len: usize = @truncate(std.fmt.count(fmt, args));
|
||||||
|
if (len > stack_buf_size) {
|
||||||
|
heap_buf = root.allocator.alloc(u8, len) catch null;
|
||||||
|
}
|
||||||
|
defer if (heap_buf) |buf| {
|
||||||
|
root.allocator.free(buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
const buf: []u8 = if (heap_buf) |b| b else stack_buf[0..len];
|
||||||
|
const msg = std.fmt.bufPrint(buf, fmt, args) catch buf[0..len]; // no space? yeah whatever print as much as you can
|
||||||
|
|
||||||
|
const scope_name = @tagName(scope);
|
||||||
|
switch (level) {
|
||||||
|
.err => __haku2_log_err(scope_name.ptr, scope_name.len, msg.ptr, msg.len),
|
||||||
|
.warn => __haku2_log_warn(scope_name.ptr, scope_name.len, msg.ptr, msg.len),
|
||||||
|
.info => __haku2_log_info(scope_name.ptr, scope_name.len, msg.ptr, msg.len),
|
||||||
|
.debug => __haku2_log_debug(scope_name.ptr, scope_name.len, msg.ptr, msg.len),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern fn __haku2_log_err(scope: [*]const u8, scope_len: usize, msg: [*]const u8, len: usize) void;
|
||||||
|
extern fn __haku2_log_warn(scope: [*]const u8, scope_len: usize, msg: [*]const u8, len: usize) void;
|
||||||
|
extern fn __haku2_log_info(scope: [*]const u8, scope_len: usize, msg: [*]const u8, len: usize) void;
|
||||||
|
extern fn __haku2_log_debug(scope: [*]const u8, scope_len: usize, msg: [*]const u8, len: usize) void;
|
|
@ -1,6 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const debug = std.debug;
|
const debug = std.debug;
|
||||||
|
const log = std.log;
|
||||||
const testAllocator = std.testing.allocator;
|
const testAllocator = std.testing.allocator;
|
||||||
|
|
||||||
const bytecode = @import("bytecode.zig");
|
const bytecode = @import("bytecode.zig");
|
||||||
|
@ -54,6 +55,8 @@ pub fn init(a: mem.Allocator, defs: *const bytecode.Defs, limits: *const Limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn throw(vm: *Vm, comptime fmt: []const u8, args: anytype) Error {
|
pub fn throw(vm: *Vm, comptime fmt: []const u8, args: anytype) Error {
|
||||||
|
log.debug("throw: fmt={s}", .{fmt});
|
||||||
|
|
||||||
const Args = @TypeOf(args);
|
const Args = @TypeOf(args);
|
||||||
const max_args_size = @sizeOf(@TypeOf(vm.exception.?.args));
|
const max_args_size = @sizeOf(@TypeOf(vm.exception.?.args));
|
||||||
if (@sizeOf(Args) > max_args_size) {
|
if (@sizeOf(Args) > max_args_size) {
|
||||||
|
@ -75,6 +78,7 @@ pub fn throw(vm: *Vm, comptime fmt: []const u8, args: anytype) Error {
|
||||||
.args = undefined,
|
.args = undefined,
|
||||||
};
|
};
|
||||||
@memcpy(exn.args[0..@sizeOf(Args)], mem.asBytes(&args));
|
@memcpy(exn.args[0..@sizeOf(Args)], mem.asBytes(&args));
|
||||||
|
vm.exception = exn;
|
||||||
|
|
||||||
return error.Exception;
|
return error.Exception;
|
||||||
}
|
}
|
||||||
|
|
|
@ -574,7 +574,7 @@ fn jumpstart_trampoline<'a>(
|
||||||
fn jumpstart_trampoline2(haku: &mut Haku) {
|
fn jumpstart_trampoline2(haku: &mut Haku) {
|
||||||
if !haku.has_cont2() {
|
if !haku.has_cont2() {
|
||||||
if let Err(e) = haku.eval_brush2() {
|
if let Err(e) = haku.eval_brush2() {
|
||||||
error!("eval_brush2: {e}");
|
error!("eval_brush2: {e:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue