Fix memory leaks
This commit is contained in:
parent
7b4b827dc2
commit
8137f2b474
|
@ -142,8 +142,17 @@ pub const RuntimeEnv = struct {
|
|||
|
||||
coral.debug.assert(frame != null);
|
||||
|
||||
coral.debug.assert(self.local_refs.drop(
|
||||
(self.local_refs.values.len - frame.?.locals_top) + frame.?.arg_count));
|
||||
{
|
||||
var pops_remaining = (self.local_refs.values.len - frame.?.locals_top) + frame.?.arg_count;
|
||||
|
||||
while (pops_remaining != 0) : (pops_remaining -= 1) {
|
||||
const local = self.local_refs.pop();
|
||||
|
||||
coral.debug.assert(local != null);
|
||||
|
||||
self.discard(local.?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return caller.invoke(self);
|
||||
|
@ -160,7 +169,13 @@ pub const RuntimeEnv = struct {
|
|||
if (ref_data.ref_count == 0) {
|
||||
switch (ref_data.object) {
|
||||
.string => |string| self.allocator.deallocate(string),
|
||||
.dynamic => |virtual| self.allocator.deallocate(virtual),
|
||||
|
||||
.dynamic => |dynamic| {
|
||||
dynamic.typeinfo.clean(self, dynamic.userdata);
|
||||
self.allocator.deallocate(dynamic.userdata);
|
||||
self.allocator.deallocate(dynamic);
|
||||
},
|
||||
|
||||
else => {},
|
||||
}
|
||||
} else {
|
||||
|
@ -208,6 +223,12 @@ pub const RuntimeEnv = struct {
|
|||
}
|
||||
|
||||
pub fn free(self: *RuntimeEnv) void {
|
||||
for (self.local_refs.values) |ref| {
|
||||
self.discard(ref);
|
||||
}
|
||||
|
||||
self.frames.free();
|
||||
self.syscallers.free();
|
||||
self.local_refs.free();
|
||||
self.ref_values.free();
|
||||
}
|
||||
|
@ -362,7 +383,7 @@ pub const TestContext = struct {
|
|||
pub const Typeinfo = struct {
|
||||
name: []const coral.io.Byte,
|
||||
call: *const fn (env: *RuntimeEnv) RuntimeError!?*RuntimeRef = default_call,
|
||||
clean: *const fn (userdata: []coral.io.Byte) void = default_clean,
|
||||
clean: *const fn (env: *RuntimeEnv, userdata: []coral.io.Byte) void = default_clean,
|
||||
get: *const fn (context: IndexContext) RuntimeError!?*RuntimeRef = default_get,
|
||||
set: *const fn (context: IndexContext, value: ?*const RuntimeRef) RuntimeError!void = default_set,
|
||||
test_difference: *const fn (context: TestContext) RuntimeError!Float = default_test_difference,
|
||||
|
@ -372,7 +393,7 @@ pub const Typeinfo = struct {
|
|||
return env.raise(error.TypeMismatch, "object is not callable");
|
||||
}
|
||||
|
||||
fn default_clean(_: []coral.io.Byte) void {
|
||||
fn default_clean(_: *RuntimeEnv, _: []coral.io.Byte) void {
|
||||
// Nothing to clean by default.
|
||||
}
|
||||
|
||||
|
@ -473,13 +494,7 @@ pub fn set_field(
|
|||
return set(env, indexable_ref, field_name_ref, value_ref);
|
||||
}
|
||||
|
||||
pub fn new_table(env: *RuntimeEnv) RuntimeError!?*RuntimeRef {
|
||||
var table = Table.make(env);
|
||||
|
||||
errdefer table.free();
|
||||
|
||||
return try env.new_dynamic(coral.io.bytes_of(&table), &Table.typeinfo);
|
||||
}
|
||||
pub const new_table = Table.new;
|
||||
|
||||
pub fn test_difference(env: *RuntimeEnv, lhs_ref: ?*const RuntimeRef, rhs_ref: ?*const RuntimeRef) RuntimeError!Float {
|
||||
return switch (env.unbox(lhs_ref)) {
|
||||
|
|
|
@ -211,8 +211,6 @@ pub fn as_caller(self: *Self) kym.Caller {
|
|||
}
|
||||
|
||||
pub fn compile_ast(self: *Self, ast: Ast) kym.RuntimeError!void {
|
||||
self.free();
|
||||
|
||||
try self.constant_refs.grow(coral.math.max_int(@typeInfo(u16).Int));
|
||||
|
||||
var compiler = AstCompiler{.chunk = self};
|
||||
|
|
|
@ -11,14 +11,16 @@ const FieldTable = coral.map.StringTable(struct {
|
|||
|
||||
const Self = @This();
|
||||
|
||||
pub fn free(self: *Self) void {
|
||||
self.fields.free();
|
||||
}
|
||||
|
||||
pub fn make(env: *kym.RuntimeEnv) Self {
|
||||
return .{
|
||||
pub fn new(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeRef {
|
||||
var self = Self{
|
||||
.fields = FieldTable.make(env.allocator),
|
||||
};
|
||||
|
||||
errdefer {
|
||||
self.fields.free();
|
||||
}
|
||||
|
||||
return try env.new_dynamic(coral.io.bytes_of(&self), &typeinfo);
|
||||
}
|
||||
|
||||
pub const typeinfo = kym.Typeinfo{
|
||||
|
@ -28,8 +30,19 @@ pub const typeinfo = kym.Typeinfo{
|
|||
.set = typeinfo_set,
|
||||
};
|
||||
|
||||
fn typeinfo_clean(userdata: []u8) void {
|
||||
@as(*Self, @ptrCast(@alignCast(userdata.ptr))).free();
|
||||
fn typeinfo_clean(env: *kym.RuntimeEnv, userdata: []coral.io.Byte) void {
|
||||
const table = @as(*Self, @ptrCast(@alignCast(userdata.ptr)));
|
||||
|
||||
{
|
||||
var field_iterable = table.fields.as_iterable();
|
||||
|
||||
while (field_iterable.next()) |entry| {
|
||||
env.discard(entry.value.key_ref);
|
||||
env.discard(entry.value.value_ref);
|
||||
}
|
||||
}
|
||||
|
||||
table.fields.free();
|
||||
}
|
||||
|
||||
fn typeinfo_get(context: kym.IndexContext) kym.RuntimeError!?*kym.RuntimeRef {
|
||||
|
|
Loading…
Reference in New Issue