Fix leaks and double-frees in Kym VM environment
This commit is contained in:
parent
08785b5b54
commit
331d862246
|
@ -69,21 +69,6 @@ const Object = struct {
|
||||||
|
|
||||||
self.ref_count += 1;
|
self.ref_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn release(self: *Object, env: *Self) bool {
|
|
||||||
coral.debug.assert(self.ref_count != 0);
|
|
||||||
|
|
||||||
self.ref_count -= 1;
|
|
||||||
|
|
||||||
if (self.ref_count == 0) {
|
|
||||||
coral.io.deallocate(env.allocator, self.state.userdata);
|
|
||||||
self.state.fields.deinit(env.allocator);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ObjectInfo = struct {
|
pub const ObjectInfo = struct {
|
||||||
|
@ -185,14 +170,7 @@ pub fn check(self: *Self, condition: bool, failure_message: []const u8) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
var global_data = self.heap.fetch(self.global_object);
|
self.discard(.{.object = self.global_object});
|
||||||
|
|
||||||
if (global_data.release(self)) {
|
|
||||||
self.heap.remove(self.global_object);
|
|
||||||
} else {
|
|
||||||
self.heap.assign(self.global_object, global_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.values.deinit(self.allocator);
|
self.values.deinit(self.allocator);
|
||||||
self.calls.deinit(self.allocator);
|
self.calls.deinit(self.allocator);
|
||||||
self.heap.deinit(self.allocator);
|
self.heap.deinit(self.allocator);
|
||||||
|
@ -203,7 +181,19 @@ pub fn discard(self: *Self, val: types.Val) void {
|
||||||
.object => |object| {
|
.object => |object| {
|
||||||
var data = self.heap.fetch(object);
|
var data = self.heap.fetch(object);
|
||||||
|
|
||||||
if (data.release(self)) {
|
coral.debug.assert(data.ref_count != 0);
|
||||||
|
|
||||||
|
data.ref_count -= 1;
|
||||||
|
|
||||||
|
if (data.ref_count == 0) {
|
||||||
|
data.state.info.deinitializer(.{
|
||||||
|
.env = self,
|
||||||
|
.obj = val.as_ref(),
|
||||||
|
});
|
||||||
|
|
||||||
|
coral.io.deallocate(self.allocator, data.state.userdata);
|
||||||
|
data.state.fields.deinit(self.allocator);
|
||||||
|
|
||||||
self.heap.remove(object);
|
self.heap.remove(object);
|
||||||
} else {
|
} else {
|
||||||
self.heap.assign(object, data);
|
self.heap.assign(object, data);
|
||||||
|
@ -223,17 +213,21 @@ pub fn execute_data(self: *Self, source: DataSource) types.RuntimeError!types.Va
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var chunk = try Chunk.init(self, source.name);
|
var compiled_chunk = init_compiled_chunk: {
|
||||||
|
var chunk = try Chunk.init(self, source.name);
|
||||||
|
|
||||||
errdefer chunk.deinit();
|
errdefer chunk.deinit();
|
||||||
|
|
||||||
chunk.compile(source.data) catch |compile_error| {
|
chunk.compile(source.data) catch |compile_error| {
|
||||||
self.reporter.invoke(chunk.error_details());
|
self.reporter.invoke(chunk.error_details());
|
||||||
|
|
||||||
return compile_error;
|
return compile_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
break: init_compiled_chunk chunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
const script = try self.new_object(coral.io.bytes_of(&chunk), .{
|
const script = try self.new_object(coral.io.bytes_of(&compiled_chunk), .{
|
||||||
.identity = typeid,
|
.identity = typeid,
|
||||||
.deinitializer = Behaviors.deinitialize,
|
.deinitializer = Behaviors.deinitialize,
|
||||||
});
|
});
|
||||||
|
@ -355,12 +349,11 @@ pub fn native_cast(self: *Self, castable: types.Ref, id: *const anyopaque, compt
|
||||||
try self.check(castable == .object, "invalid type conversion: object");
|
try self.check(castable == .object, "invalid type conversion: object");
|
||||||
|
|
||||||
const object = self.heap.fetch(castable.object);
|
const object = self.heap.fetch(castable.object);
|
||||||
const alignment = @alignOf(Type);
|
const is_expected_type = (object.state.info.identity == id) and (object.state.userdata.len == @sizeOf(Type));
|
||||||
const is_expected_type = (object.state.info.identity == id) and (object.state.userdata.len == alignment);
|
|
||||||
|
|
||||||
try self.check(is_expected_type, "invalid object cast: native type");
|
try self.check(is_expected_type, "invalid object cast: native type");
|
||||||
|
|
||||||
return @ptrCast(*Type, @alignCast(alignment, object.state.userdata));
|
return @ptrCast(*Type, @alignCast(@alignOf(Type), object.state.userdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_array(self: *Self) coral.io.AllocationError!types.Val {
|
pub fn new_array(self: *Self) coral.io.AllocationError!types.Val {
|
||||||
|
|
Loading…
Reference in New Issue