Skip to content

Commit

Permalink
feat(vm): std.panic/buzz_panic/vm.panic show buzz stack trace before …
Browse files Browse the repository at this point in the history
…panicking
  • Loading branch information
giann committed May 14, 2024
1 parent 18c44eb commit 4b8a805
Show file tree
Hide file tree
Showing 18 changed files with 951 additions and 407 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var value = from {
- works with `foreach`
- Tracing JIT (https://github.com/buzz-language/buzz/issues/134): will look for hot loops and compile them
- `list.fill`
- `std.panic` will panic and print current stack trace

## Changed
- Map type notation has changed from `{K, V}` to `{K: V}`. Similarly map expression with specified typed went from `{<K, V>, ...}` to `{<K: V>, ...}` (https://github.com/buzz-language/buzz/issues/253)
Expand Down
80 changes: 64 additions & 16 deletions src/Jit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4214,7 +4214,10 @@ fn generateFunction(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t {
}

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch @panic("Out of memory");
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(ctx_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -4295,7 +4298,10 @@ fn generateHotspotFunction(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t
var qualified_name = try self.getQualifiedName(node, false);
defer qualified_name.deinit();

const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch @panic("Out of memory");
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(ctx_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -4383,7 +4389,10 @@ fn generateNativeFn(self: *Self, node: Ast.Node.Index, raw_fn: m.MIR_item_t) !m.
defer nativefn_qualified_name.deinit();

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch @panic("Out of memory");
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(ctx_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -4894,7 +4903,10 @@ pub fn compileZdef(self: *Self, buzz_ast: Ast, zdef: Ast.Zdef.ZdefElement) Error

try wrapper_name.writer().print("zdef_{s}\x00", .{zdef.zdef.name});

const dupped_symbol = self.vm.gc.allocator.dupeZ(u8, zdef.zdef.name) catch @panic("Out of memory");
const dupped_symbol = self.vm.gc.allocator.dupeZ(u8, zdef.zdef.name) catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(dupped_symbol);

const module = m.MIR_new_module(self.ctx, @ptrCast(wrapper_name.items.ptr));
Expand Down Expand Up @@ -5026,11 +5038,17 @@ fn buildZdefWrapper(self: *Self, zdef_element: Ast.Zdef.ZdefElement) Error!m.MIR

try wrapper_protocol_name.writer().print("p_zdef_{s}\x00", .{zdef_element.zdef.name});

const dupped_symbol = self.vm.gc.allocator.dupeZ(u8, zdef_element.zdef.name) catch @panic("Out of memory");
const dupped_symbol = self.vm.gc.allocator.dupeZ(u8, zdef_element.zdef.name) catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(dupped_symbol);

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch @panic("Out of memory");
const ctx_name = self.vm.gc.allocator.dupeZ(u8, "ctx") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(ctx_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -5235,9 +5253,15 @@ fn buildZdefUnionGetter(
);

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch @panic("Out of memory");
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(vm_name);
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch @panic("Out of memory");
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(data_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -5339,11 +5363,20 @@ fn buildZdefUnionSetter(
);

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch @panic("Out of memory");
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(vm_name);
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch @panic("Out of memory");
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(data_name);
const new_value_name = self.vm.gc.allocator.dupeZ(u8, "new_value") catch @panic("Out of memory");
const new_value_name = self.vm.gc.allocator.dupeZ(u8, "new_value") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(new_value_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -5446,9 +5479,15 @@ fn buildZdefContainerGetter(
);

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch @panic("Out of memory");
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(vm_name);
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch @panic("Out of memory");
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(data_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down Expand Up @@ -5534,11 +5573,20 @@ fn buildZdefContainerSetter(
);

// FIXME: I don't get why we need this: a simple constant becomes rubbish as soon as we enter MIR_new_func_arr if we don't
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch @panic("Out of memory");
const vm_name = self.vm.gc.allocator.dupeZ(u8, "vm") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(vm_name);
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch @panic("Out of memory");
const data_name = self.vm.gc.allocator.dupeZ(u8, "data") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(data_name);
const new_value_name = self.vm.gc.allocator.dupeZ(u8, "new_value") catch @panic("Out of memory");
const new_value_name = self.vm.gc.allocator.dupeZ(u8, "new_value") catch {
self.vm.panic("Out of memory");
unreachable;
};
defer self.vm.gc.allocator.free(new_value_name);
const function = m.MIR_new_func_arr(
self.ctx,
Expand Down
2 changes: 0 additions & 2 deletions src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6971,8 +6971,6 @@ fn searchPaths(self: *Self, file_name: []const u8) ![][]const u8 {
try buzzLibPath(),
);

std.debug.print("> {s}\n", .{prefixed});

try paths.append(prefixed);
}

Expand Down
92 changes: 73 additions & 19 deletions src/builtin/list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ pub fn append(ctx: *NativeCtx) c_int {
list.rawAppend(
ctx.vm.gc,
value,
) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

return 0;
}
Expand All @@ -40,7 +43,10 @@ pub fn insert(ctx: *NativeCtx) c_int {
ctx.vm.gc,
@as(usize, @intCast(index)),
value,
) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

ctx.vm.push(value);

Expand All @@ -61,9 +67,15 @@ pub fn reverse(ctx: *NativeCtx) c_int {
var new_list = ctx.vm.gc.allocateObject(
ObjList,
ObjList.init(ctx.vm.gc.allocator, list.type_def),
) catch @panic("Out of memory");

new_list.items.appendSlice(list.items.items) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

new_list.items.appendSlice(list.items.items) catch {
ctx.vm.panic("Out of memory");
unreachable;
};
std.mem.reverse(Value, new_list.items.items);

ctx.vm.push(new_list.toValue());
Expand Down Expand Up @@ -94,7 +106,10 @@ pub fn remove(ctx: *NativeCtx) c_int {
}

ctx.vm.push(list.items.orderedRemove(@as(usize, @intCast(list_index))));
ctx.vm.gc.markObjDirty(&list.obj) catch @panic("Out of memory");
ctx.vm.gc.markObjDirty(&list.obj) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

return 1;
}
Expand Down Expand Up @@ -167,8 +182,14 @@ pub fn clone(ctx: *NativeCtx) c_int {
var new_list = ctx.vm.gc.allocateObject(
ObjList,
ObjList.init(ctx.vm.gc.allocator, self.type_def),
) catch @panic("Out of memory");
new_list.items.appendSlice(self.items.items) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};
new_list.items.appendSlice(self.items.items) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

ctx.vm.push(new_list.toValue());

Expand All @@ -183,15 +204,24 @@ pub fn join(ctx: *NativeCtx) c_int {
var writer = result.writer();
defer result.deinit();
for (self.items.items, 0..) |item, i| {
item.toString(&writer) catch @panic("Out of memory");
item.toString(&writer) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

if (i + 1 < self.items.items.len) {
writer.writeAll(separator.string) catch @panic("Out of memory");
writer.writeAll(separator.string) catch {
ctx.vm.panic("Out of memory");
unreachable;
};
}
}

ctx.vm.push(
(ctx.vm.gc.copyString(result.items) catch @panic("Out of memory")).toValue(),
(ctx.vm.gc.copyString(result.items) catch {
ctx.vm.panic("Out of memory");
unreachable;
}).toValue(),
);

return 1;
Expand Down Expand Up @@ -221,14 +251,23 @@ pub fn sub(ctx: *NativeCtx) c_int {
ObjList,
.{
.type_def = self.type_def,
.methods = self.methods.clone() catch @panic("Out of memory"),
.methods = self.methods.clone() catch {
ctx.vm.panic("Out of memory");
unreachable;
},
.items = std.ArrayList(Value).init(ctx.vm.gc.allocator),
},
) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

ctx.vm.push(list.toValue());

list.items.appendSlice(substr) catch @panic("Out of memory");
list.items.appendSlice(substr) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

return 1;
}
Expand All @@ -241,7 +280,10 @@ pub fn next(ctx: *NativeCtx) c_int {
const next_index: ?i32 = list.rawNext(
ctx.vm,
list_index.integerOrNull(),
) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

ctx.vm.push(
if (next_index) |unext_index|
Expand Down Expand Up @@ -314,7 +356,10 @@ pub fn filter(ctx: *NativeCtx) c_int {
ctx.vm.gc.allocator,
list.type_def,
),
) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

for (list.items.items, 0..) |item, index| {
const index_value = Value.fromInteger(@as(i32, @intCast(index)));
Expand All @@ -329,7 +374,10 @@ pub fn filter(ctx: *NativeCtx) c_int {
);

if (ctx.vm.pop().boolean()) {
new_list.rawAppend(ctx.vm.gc, item) catch @panic("Out of memory");
new_list.rawAppend(ctx.vm.gc, item) catch {
ctx.vm.panic("Out of memory");
unreachable;
};
}
}

Expand All @@ -349,7 +397,10 @@ pub fn map(ctx: *NativeCtx) c_int {
ctx.vm.gc.allocator,
mapped_type,
),
) catch @panic("Out of memory");
) catch {
ctx.vm.panic("Out of memory");
unreachable;
};

for (list.items.items, 0..) |item, index| {
const index_value = Value.fromInteger(@as(i32, @intCast(index)));
Expand All @@ -363,7 +414,10 @@ pub fn map(ctx: *NativeCtx) c_int {
null,
);

new_list.rawAppend(ctx.vm.gc, ctx.vm.pop()) catch @panic("Out of memory");
new_list.rawAppend(ctx.vm.gc, ctx.vm.pop()) catch {
ctx.vm.panic("Out of memory");
unreachable;
};
}

ctx.vm.push(new_list.toValue());
Expand Down
Loading

0 comments on commit 4b8a805

Please sign in to comment.