Fix double free and boxing bugs in VM
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
kayomn 2023-11-06 22:27:09 +00:00
parent eb9552c390
commit b28b1a86c9
3 changed files with 26 additions and 7 deletions

View File

@ -1,5 +1,9 @@
let test_param = "monkey wrench"
let wrench = "wrench"
var test_param = "monkey {wrench}"
test_param = "monkey"
let printer = lambda (pfx):
@print(test_param)

View File

@ -282,7 +282,7 @@ pub const RuntimeEnv = struct {
pub fn get_boxed(self: *RuntimeEnv, boxable: *RuntimeRef) RuntimeError!?*RuntimeRef {
return switch (boxable.object().payload) {
.boxed => |boxed| if (boxed) |boxed_value| boxed_value.acquire() else null,
else => self.raise(error.TypeMismatch, "{typename} is not boxable", .{.typename = boxable.typename()}),
else => self.raise(error.TypeMismatch, "{typename} is not box-gettable", .{.typename = boxable.typename()}),
};
}
@ -624,7 +624,7 @@ pub const RuntimeEnv = struct {
boxed.* = if (value) |ref| ref.acquire() else null;
},
else => return self.raise(error.TypeMismatch, "{typename} is not boxable", .{
else => return self.raise(error.TypeMismatch, "{typename} is not box-settable", .{
.typename = boxable.typename(),
}),
}

View File

@ -167,7 +167,14 @@ const Compiler = struct {
.declaration_get => |declaration_get| {
if (get_local_index(environment, declaration_get.declaration)) |index| {
return self.chunk.write(expression.line, .{.push_local = index});
if (is_declaration_boxed(declaration_get.declaration)) {
try self.chunk.write(expression.line, .{.push_local = index});
try self.chunk.write(expression.line, .get_box);
} else {
try self.chunk.write(expression.line, .{.push_local = index});
}
return;
}
if (try self.get_binding_index(environment, declaration_get.declaration)) |index| {
@ -187,12 +194,19 @@ const Compiler = struct {
if (get_local_index(environment, declaration_set.declaration)) |index| {
try self.compile_expression(environment, declaration_set.assign, null);
return self.chunk.write(expression.line, .{.set_local = index});
if (is_declaration_boxed(declaration_set.declaration)) {
try self.chunk.write(expression.line, .{.push_local = index});
try self.chunk.write(expression.line, .set_box);
} else {
try self.chunk.write(expression.line, .{.set_local = index});
}
return;
}
if (try self.get_binding_index(environment, declaration_set.declaration)) |index| {
try self.chunk.write(expression.line, .{.push_binding = index});
try self.compile_expression(environment, declaration_set.assign, null);
try self.chunk.write(expression.line, .{.push_binding = index});
if (is_declaration_boxed(declaration_set.declaration)) {
try self.chunk.write(expression.line, .set_box);
@ -730,7 +744,8 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv, frame: *const kym.Frame) kym.R
const value = try env.expect(try env.pop_local());
defer env.discard(box);
errdefer env.discard(value);
try env.set_boxed(box, value);
},