Native "Syscall" Interface for Kym #21

Merged
kayomn merged 6 commits from kym-native-function into main 2023-07-22 15:03:22 +02:00
3 changed files with 48 additions and 22 deletions
Showing only changes of commit 8137f2b474 - Show all commits

View File

@ -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)) {

View File

@ -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};

View File

@ -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{
kayomn marked this conversation as resolved Outdated

Does this need to be public?

Does this need to be public?
@ -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 {