Native "Syscall" Interface for Kym #21
|
@ -142,8 +142,17 @@ pub const RuntimeEnv = struct {
|
||||||
|
|
||||||
coral.debug.assert(frame != null);
|
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);
|
return caller.invoke(self);
|
||||||
|
@ -160,7 +169,13 @@ pub const RuntimeEnv = struct {
|
||||||
if (ref_data.ref_count == 0) {
|
if (ref_data.ref_count == 0) {
|
||||||
switch (ref_data.object) {
|
switch (ref_data.object) {
|
||||||
.string => |string| self.allocator.deallocate(string),
|
.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 => {},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -208,6 +223,12 @@ pub const RuntimeEnv = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn free(self: *RuntimeEnv) void {
|
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.local_refs.free();
|
||||||
self.ref_values.free();
|
self.ref_values.free();
|
||||||
}
|
}
|
||||||
|
@ -362,7 +383,7 @@ pub const TestContext = struct {
|
||||||
pub const Typeinfo = struct {
|
pub const Typeinfo = struct {
|
||||||
name: []const coral.io.Byte,
|
name: []const coral.io.Byte,
|
||||||
call: *const fn (env: *RuntimeEnv) RuntimeError!?*RuntimeRef = default_call,
|
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,
|
get: *const fn (context: IndexContext) RuntimeError!?*RuntimeRef = default_get,
|
||||||
set: *const fn (context: IndexContext, value: ?*const RuntimeRef) RuntimeError!void = default_set,
|
set: *const fn (context: IndexContext, value: ?*const RuntimeRef) RuntimeError!void = default_set,
|
||||||
test_difference: *const fn (context: TestContext) RuntimeError!Float = default_test_difference,
|
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");
|
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.
|
// Nothing to clean by default.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,13 +494,7 @@ pub fn set_field(
|
||||||
return set(env, indexable_ref, field_name_ref, value_ref);
|
return set(env, indexable_ref, field_name_ref, value_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_table(env: *RuntimeEnv) RuntimeError!?*RuntimeRef {
|
pub const new_table = Table.new;
|
||||||
var table = Table.make(env);
|
|
||||||
|
|
||||||
errdefer table.free();
|
|
||||||
|
|
||||||
return try env.new_dynamic(coral.io.bytes_of(&table), &Table.typeinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn test_difference(env: *RuntimeEnv, lhs_ref: ?*const RuntimeRef, rhs_ref: ?*const RuntimeRef) RuntimeError!Float {
|
pub fn test_difference(env: *RuntimeEnv, lhs_ref: ?*const RuntimeRef, rhs_ref: ?*const RuntimeRef) RuntimeError!Float {
|
||||||
return switch (env.unbox(lhs_ref)) {
|
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 {
|
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));
|
try self.constant_refs.grow(coral.math.max_int(@typeInfo(u16).Int));
|
||||||
|
|
||||||
var compiler = AstCompiler{.chunk = self};
|
var compiler = AstCompiler{.chunk = self};
|
||||||
|
|
|
@ -11,14 +11,16 @@ const FieldTable = coral.map.StringTable(struct {
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn free(self: *Self) void {
|
pub fn new(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeRef {
|
||||||
self.fields.free();
|
var self = Self{
|
||||||
}
|
|
||||||
|
|
||||||
pub fn make(env: *kym.RuntimeEnv) Self {
|
|
||||||
return .{
|
|
||||||
.fields = FieldTable.make(env.allocator),
|
.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{
|
pub const typeinfo = kym.Typeinfo{
|
||||||
kayomn marked this conversation as resolved
Outdated
|
|||||||
|
@ -28,8 +30,19 @@ pub const typeinfo = kym.Typeinfo{
|
||||||
.set = typeinfo_set,
|
.set = typeinfo_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn typeinfo_clean(userdata: []u8) void {
|
fn typeinfo_clean(env: *kym.RuntimeEnv, userdata: []coral.io.Byte) void {
|
||||||
@as(*Self, @ptrCast(@alignCast(userdata.ptr))).free();
|
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 {
|
fn typeinfo_get(context: kym.IndexContext) kym.RuntimeError!?*kym.RuntimeRef {
|
||||||
|
|
Loading…
Reference in New Issue
Does this need to be public?