From 4884fdb70a411f117db1752230f6a4c41221dc8c Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Tue, 20 Aug 2024 09:28:49 +0200 Subject: [PATCH] fix: Rationalizing and simplifying buzz_api - All functions operate on Values - Removed a bunch of useless functions - Consistant naming: bz_ --- src/Jit.zig | 182 +++++++------ src/builtin/list.zig | 14 +- src/builtin/map.zig | 14 +- src/buzz_api.zig | 566 +++++++++++++--------------------------- src/jit_extern_api.zig | 439 +++++++++++++++++-------------- src/lib/buzz_api.zig | 417 ++++++++++------------------- src/lib/buzz_buffer.zig | 211 ++++++++------- src/lib/buzz_crypto.zig | 8 +- src/lib/buzz_debug.zig | 6 +- src/lib/buzz_ffi.zig | 16 +- src/lib/buzz_fs.zig | 26 +- src/lib/buzz_gc.zig | 2 +- src/lib/buzz_http.zig | 124 ++++----- src/lib/buzz_io.zig | 47 ++-- src/lib/buzz_math.zig | 60 +++-- src/lib/buzz_os.zig | 102 ++++---- src/lib/buzz_std.zig | 45 ++-- 17 files changed, 1007 insertions(+), 1272 deletions(-) diff --git a/src/Jit.zig b/src/Jit.zig index aaeb9c2f..5f216ce1 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -1158,7 +1158,7 @@ fn buildValueToOptionalCString(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) fn buildValueFromCString(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) !void { try self.buildExternApiCall( - .bz_stringZ, + .bz_stringToValueZ, dest, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), @@ -1182,7 +1182,7 @@ fn buildValueFromOptionalCString(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_ ); try self.buildExternApiCall( - .bz_stringZ, + .bz_stringToValueZ, dest, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), @@ -1195,7 +1195,7 @@ fn buildValueFromOptionalCString(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_ fn buildValueToUserData(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) !void { try self.buildExternApiCall( - .bz_valueToUserData, + .bz_getUserDataPtr, dest, &[_]m.MIR_op_t{value}, ); @@ -1211,7 +1211,7 @@ fn buildValueToForeignContainerPtr(self: *Self, value: m.MIR_op_t, dest: m.MIR_o fn buildValueFromForeignContainerPtr(self: *Self, type_def: *o.ObjTypeDef, value: m.MIR_op_t, dest: m.MIR_op_t) !void { try self.buildExternApiCall( - .bz_containerFromSlice, + .bz_newForeignContainerFromSlice, dest, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), @@ -1237,7 +1237,7 @@ fn buildValueFromOptionalForeignContainerPtr(self: *Self, type_def: *o.ObjTypeDe ); try self.buildExternApiCall( - .bz_containerFromSlice, + .bz_newForeignContainerFromSlice, dest, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), @@ -1275,9 +1275,12 @@ fn buildValueToOptionalForeignContainerPtr(self: *Self, value: m.MIR_op_t, dest: fn buildValueFromUserData(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) !void { try self.buildExternApiCall( - .bz_userDataToValue, + .bz_newUserData, dest, - &[_]m.MIR_op_t{value}, + &[_]m.MIR_op_t{ + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + value, + }, ); } @@ -1296,9 +1299,12 @@ fn buildValueFromOptionalUserData(self: *Self, value: m.MIR_op_t, dest: m.MIR_op ); try self.buildExternApiCall( - .bz_userDataToValue, + .bz_newUserData, dest, - &[_]m.MIR_op_t{value}, + &[_]m.MIR_op_t{ + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + value, + }, ); self.append(null_label); @@ -1319,7 +1325,7 @@ fn buildValueToOptionalUserData(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t ); try self.buildExternApiCall( - .bz_valueToUserData, + .bz_getUserDataPtr, dest, &[_]m.MIR_op_t{value}, ); @@ -1642,11 +1648,11 @@ fn generateString(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { ); try self.buildExternApiCall( - .bz_toString, + .bz_valueCastToString, dest, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), value, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -1660,12 +1666,12 @@ fn generateString(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { ); try self.buildExternApiCall( - .bz_objStringConcat, + .bz_stringConcat, dest, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), uprevious, value, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -1783,9 +1789,9 @@ fn generateCall(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_getEnumCaseFromValue, m.MIR_new_reg_op(self.ctx, result_reg), &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, (try self.generateNode(components.arguments[0].value)).?, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -1834,20 +1840,20 @@ fn generateCall(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { break :instance try self.buildExternApiCall( if (field.method) - .bz_getInstanceMethod + .bz_getObjectInstanceMethod else - .bz_getInstanceProperty, + .bz_getObjectInstanceProperty, callee, if (field.method) &[_]m.MIR_op_t{ - // vm - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), // subject subject.?, // member m.MIR_new_uint_op(self.ctx, field.index), // bound m.MIR_new_uint_op(self.ctx, 0), + // vm + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), } else &[_]m.MIR_op_t{ @@ -1877,30 +1883,42 @@ fn generateCall(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { else => unreachable, }, callee, - &[_]m.MIR_op_t{ - // vm - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), - // subject - subject.?, - // member - m.MIR_new_uint_op( - self.ctx, - switch (invoked_on.?) { - .String => o.ObjString.members_name.get(member_lexeme).?, - .Pattern => o.ObjPattern.members_name.get(member_lexeme).?, - .Fiber => o.ObjFiber.members_name.get(member_lexeme).?, - .Range => o.ObjRange.members_name.get(member_lexeme).?, - .List => o.ObjList.members_name.get(member_lexeme).?, - .Map => o.ObjMap.members_name.get(member_lexeme).?, - .ProtocolInstance => (try self.vm.gc.copyString( + if (invoked_on.? != .ProtocolInstance) + &[_]m.MIR_op_t{ + // vm + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + // subject + subject.?, + // member + m.MIR_new_uint_op( + self.ctx, + switch (invoked_on.?) { + .String => o.ObjString.members_name.get(member_lexeme).?, + .Pattern => o.ObjPattern.members_name.get(member_lexeme).?, + .Fiber => o.ObjFiber.members_name.get(member_lexeme).?, + .Range => o.ObjRange.members_name.get(member_lexeme).?, + .List => o.ObjList.members_name.get(member_lexeme).?, + .Map => o.ObjMap.members_name.get(member_lexeme).?, + else => unreachable, + }, + ), + // bound + m.MIR_new_uint_op(self.ctx, 0), + } + else + &[_]m.MIR_op_t{ + // subject + subject.?, + // member + m.MIR_new_uint_op( + self.ctx, + (try self.vm.gc.copyString( self.state.?.ast.tokens.items(.lexeme)[node_components[dot.?].Dot.identifier], )).toValue().val, - else => unreachable, - }, - ), - // bound - m.MIR_new_uint_op(self.ctx, 0), - }, + ), + // vm + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + }, ), else => unreachable, } @@ -2616,12 +2634,12 @@ fn generateBinary(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { }, .String => { try self.buildExternApiCall( - .bz_objStringConcat, + .bz_stringConcat, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), left, right, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); }, @@ -2630,9 +2648,9 @@ fn generateBinary(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_listConcat, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), left, right, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); }, @@ -2641,9 +2659,9 @@ fn generateBinary(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_mapConcat, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), left, right, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); }, @@ -3076,9 +3094,9 @@ fn generateList(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_listAppend, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), new_list, (try self.generateNode(item)).?, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); } @@ -3135,10 +3153,10 @@ fn generateMap(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_mapSet, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), new_map, (try self.generateNode(entry.key)).?, (try self.generateNode(entry.value)).?, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); } @@ -3278,10 +3296,10 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_setObjectField, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op(self.ctx, field.index), gen_value, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3318,10 +3336,9 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { const gen_value = (try self.generateNode(components.value_or_call_or_enum.Value)).?; try self.buildExternApiCall( - .bz_setInstanceProperty, + .bz_setObjectInstanceProperty, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op( self.ctx, @@ -3330,6 +3347,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .get(member_lexeme).?.index, ), gen_value, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3351,18 +3369,18 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { if (field) |f| { if (f.method) { try self.buildExternApiCall( - .bz_getInstanceMethod, + .bz_getObjectInstanceMethod, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op(self.ctx, f.index), m.MIR_new_uint_op(self.ctx, 1), + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); } else { try self.buildExternApiCall( - .bz_getInstanceProperty, + .bz_getObjectInstanceProperty, res, &[_]m.MIR_op_t{ (try self.generateNode(components.callee)).?, @@ -3375,10 +3393,9 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_getProtocolMethod, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op(self.ctx, member_identifier), - m.MIR_new_uint_op(self.ctx, 1), + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); } @@ -3395,10 +3412,9 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { const gen_value = (try self.generateNode(components.value_or_call_or_enum.Value)).?; try self.buildExternApiCall( - .bz_containerSet, + .bz_foreignContainerSet, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op( self.ctx, @@ -3407,6 +3423,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .getIndex(member_lexeme).?, ), gen_value, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3419,10 +3436,9 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { ); try self.buildExternApiCall( - .bz_containerGet, + .bz_foreignContainerGet, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op( self.ctx, @@ -3430,6 +3446,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .fields .getIndex(member_lexeme).?, ), + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3447,9 +3464,9 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_getEnumCase, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), (try self.generateNode(components.callee)).?, m.MIR_new_uint_op(self.ctx, member_identifier), + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3462,7 +3479,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { try self.REG("res", m.MIR_T_I64), ); try self.buildExternApiCall( - .bz_getEnumCaseValue, + .bz_getEnumInstanceValue, res, &[_]m.MIR_op_t{ (try self.generateNode(components.callee)).?, @@ -3546,10 +3563,10 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_listSet, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), subscripted, index, val, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3583,16 +3600,16 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { ); try self.buildExternApiCall( - .bz_objStringSubscript, + .bz_stringSubscript, res, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), subscripted, index_val, m.MIR_new_uint_op( self.ctx, if (components.checked) 1 else 0, ), + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -3604,10 +3621,10 @@ fn generateSubscript(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_mapSet, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), subscripted, index_val, val, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -4020,7 +4037,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { try self.REG("instance", m.MIR_T_I64), ); try self.buildExternApiCall( - .bz_instance, + .bz_newObjectInstance, instance, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), @@ -4034,10 +4051,9 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { for (components.properties) |property| { try self.buildExternApiCall( - .bz_setInstanceProperty, + .bz_setObjectInstanceProperty, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), instance, m.MIR_new_uint_op( self.ctx, @@ -4046,6 +4062,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .get(lexemes[property.name]).?.index, ), (try self.generateNode(property.value)).?, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); } @@ -4066,7 +4083,7 @@ fn generateForeignContainerInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_ try self.REG("instance", m.MIR_T_I64), ); try self.buildExternApiCall( - .bz_containerInstance, + .bz_newForeignContainerInstance, instance, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), @@ -4079,10 +4096,9 @@ fn generateForeignContainerInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_ for (components.properties) |property| { try self.buildExternApiCall( - .bz_containerSet, + .bz_foreignContainerSet, null, &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), instance, m.MIR_new_uint_op( self.ctx, @@ -4091,6 +4107,7 @@ fn generateForeignContainerInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_ .getIndex(lexemes[property.name]).?, ), (try self.generateNode(property.value)).?, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); } @@ -4272,9 +4289,9 @@ fn generateForEach(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { .bz_enumNext, try self.LOAD(value_ptr), &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), iterable, try self.LOAD(value_ptr), + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), }, ); @@ -4310,12 +4327,19 @@ fn generateForEach(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { else => unreachable, }, try self.LOAD(value_ptr), - &[_]m.MIR_op_t{ - m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), - iterable, - // Pass ptr so the method can put he new key in it - key_ptr, - }, + if (iterable_type_def.?.def_type == .Map) + &[_]m.MIR_op_t{ + iterable, + // Pass ptr so the method can put he new key in it + key_ptr, + } + else + &[_]m.MIR_op_t{ + iterable, + // Pass ptr so the method can put he new key in it + key_ptr, + m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), + }, ); // If next key is null stop, otherwise loop @@ -5525,7 +5549,7 @@ fn buildZdefUnionGetter( switch (zig_type.*) { .Struct, .Union => { try self.buildExternApiCall( - .bz_containerFromSlice, + .bz_newForeignContainerFromSlice, result_value, &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?), diff --git a/src/builtin/list.zig b/src/builtin/list.zig index 60446b9d..6d6e4baa 100644 --- a/src/builtin/list.zig +++ b/src/builtin/list.zig @@ -117,7 +117,7 @@ pub fn remove(ctx: *NativeCtx) c_int { } const SortContext = struct { - sort_closure: *ObjClosure, + sort_closure: Value, ctx: *NativeCtx, }; @@ -138,7 +138,7 @@ fn lessThan(context: SortContext, lhs: Value, rhs: Value) bool { pub fn sort(ctx: *NativeCtx) c_int { var self = ObjList.cast(ctx.vm.peek(1).obj()).?; // fun compare(T lhs, T rhs) > bool - const sort_closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const sort_closure = ctx.vm.peek(0); std.sort.insertion( Value, @@ -310,7 +310,7 @@ pub fn next(ctx: *NativeCtx) c_int { pub fn forEach(ctx: *NativeCtx) c_int { const list = ObjList.cast(ctx.vm.peek(1).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const closure = ctx.vm.peek(0); for (list.items.items, 0..) |item, index| { const index_value = Value.fromInteger(@as(i32, @intCast(index))); @@ -331,7 +331,7 @@ pub fn forEach(ctx: *NativeCtx) c_int { pub fn reduce(ctx: *NativeCtx) c_int { const list = ObjList.cast(ctx.vm.peek(2).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(1).obj()).?; + const closure = ctx.vm.peek(1); var accumulator = ctx.vm.peek(0); for (list.items.items, 0..) |item, index| { @@ -361,7 +361,7 @@ pub fn reduce(ctx: *NativeCtx) c_int { pub fn filter(ctx: *NativeCtx) c_int { const list = ObjList.cast(ctx.vm.peek(1).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const closure = ctx.vm.peek(0); var new_list: *ObjList = ctx.vm.gc.allocateObject( ObjList, @@ -404,9 +404,9 @@ pub fn filter(ctx: *NativeCtx) c_int { pub fn map(ctx: *NativeCtx) c_int { const list = ObjList.cast(ctx.vm.peek(1).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const closure = ctx.vm.peek(0); - const mapped_type = closure.function.type_def.resolved_type.?.Function.return_type; + const mapped_type = ObjClosure.cast(closure.obj()).?.function.type_def.resolved_type.?.Function.return_type; var new_list: *ObjList = ctx.vm.gc.allocateObject( ObjList, ObjList.init( diff --git a/src/builtin/map.zig b/src/builtin/map.zig index d6861641..5ec15f39 100644 --- a/src/builtin/map.zig +++ b/src/builtin/map.zig @@ -41,7 +41,7 @@ pub fn clone(ctx: *NativeCtx) c_int { pub fn reduce(ctx: *NativeCtx) c_int { const self = ObjMap.cast(ctx.vm.peek(2).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(1).obj()).?; + const closure = ctx.vm.peek(1); var accumulator = ctx.vm.peek(0); var it = self.map.iterator(); @@ -66,7 +66,7 @@ pub fn reduce(ctx: *NativeCtx) c_int { pub fn filter(ctx: *NativeCtx) c_int { const self = ObjMap.cast(ctx.vm.peek(1).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const closure = ctx.vm.peek(0); var new_map: *ObjMap = ctx.vm.gc.allocateObject( ObjMap, @@ -109,7 +109,7 @@ pub fn filter(ctx: *NativeCtx) c_int { pub fn forEach(ctx: *NativeCtx) c_int { const self = ObjMap.cast(ctx.vm.peek(1).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const closure = ctx.vm.peek(0); var it = self.map.iterator(); while (it.next()) |kv| { @@ -129,9 +129,9 @@ pub fn forEach(ctx: *NativeCtx) c_int { pub fn map(ctx: *NativeCtx) c_int { const self = ObjMap.cast(ctx.vm.peek(1).obj()).?; - const closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const closure = ctx.vm.peek(0); - const mapped_type = closure.function.type_def.resolved_type.?.Function + const mapped_type = ObjClosure.cast(closure.obj()).?.function.type_def.resolved_type.?.Function .return_type.resolved_type.?.ObjectInstance .resolved_type.?.Object; @@ -196,7 +196,7 @@ pub fn map(ctx: *NativeCtx) c_int { } const SortContext = struct { - sort_closure: *ObjClosure, + sort_closure: Value, ctx: *NativeCtx, map: *ObjMap, @@ -221,7 +221,7 @@ const SortContext = struct { pub fn sort(ctx: *NativeCtx) c_int { const self: *ObjMap = ObjMap.cast(ctx.vm.peek(1).obj()).?; - const sort_closure = ObjClosure.cast(ctx.vm.peek(0).obj()).?; + const sort_closure = ctx.vm.peek(0); self.map.sort( SortContext{ diff --git a/src/buzz_api.zig b/src/buzz_api.zig index 077342ed..ea11ef5a 100644 --- a/src/buzz_api.zig +++ b/src/buzz_api.zig @@ -79,48 +79,6 @@ export fn bz_peek(vm: *VM, dist: u32) Value { return vm.peek(dist); } -// Value manipulations - -/// Push a boolean value on the stack -export fn bz_pushBool(self: *VM, value: bool) void { - self.push(Value.fromBoolean(value)); -} - -/// Push a float value on the stack -export fn bz_pushFloat(self: *VM, value: Float) void { - self.push(Value.fromFloat(value)); -} - -/// Push a integer value on the stack -export fn bz_pushInteger(self: *VM, value: Integer) void { - self.push(Value.fromInteger(value)); -} - -/// Push null on the stack -export fn bz_pushNull(self: *VM) void { - self.push(Value.Null); -} - -/// Push void on the stack -export fn bz_pushVoid(self: *VM) void { - self.push(Value.Void); -} - -/// Push string on the stack -export fn bz_pushString(self: *VM, value: *ObjString) void { - self.push(value.toValue()); -} - -/// Push list on the stack -export fn bz_pushList(self: *VM, value: *ObjList) void { - self.push(value.toValue()); -} - -/// Push a uesrdata value on the stack -export fn bz_pushUserData(self: *VM, value: *ObjUserData) void { - self.push(value.toValue()); -} - /// Converts a value to a string export fn bz_valueToString(value: Value, len: *usize) ?[*]const u8 { if (!value.isObj() or value.obj().obj_type != .String) { @@ -377,27 +335,22 @@ pub export fn bz_valueDump(value: Value, vm: *VM) void { valueDump(value, vm, &seen, 0); } -// Obj manipulations - -export fn bz_valueToUserData(value: Value) u64 { - return ObjUserData.cast(value.obj()).?.userdata; -} - -export fn bz_valueToObjUserData(value: Value) *ObjUserData { - return ObjUserData.cast(value.obj()).?; -} - -// FIXME: move this is ObjForeignContainer? export fn bz_valueToForeignContainerPtr(value: Value) [*]u8 { return ObjForeignContainer.cast(value.obj()).?.data.ptr; } /// Converts a c string to a *ObjString -export fn bz_string(vm: *VM, string: ?[*]const u8, len: usize) ?*ObjString { - return (if (string) |ustring| vm.gc.copyString(ustring[0..len]) else vm.gc.copyString("")) catch null; +export fn bz_stringToValue(vm: *VM, string: ?[*]const u8, len: usize) Value { + return ((if (string != null and len > 0) + vm.gc.copyString(string.?[0..len]) + else + vm.gc.copyString("")) catch { + vm.panic("Out of memory"); + unreachable; + }).toValue(); } -export fn bz_stringZ(vm: *VM, string: [*:0]const u8) Value { +export fn bz_stringToValueZ(vm: *VM, string: [*:0]const u8) Value { // Keeping the sentinel return (vm.gc.copyString(string[0..(std.mem.len(string) + 1)]) catch { vm.panic("Out of memory"); @@ -405,34 +358,14 @@ export fn bz_stringZ(vm: *VM, string: [*:0]const u8) Value { }).toValue(); } -export fn bz_valueToObjString(value: Value) *ObjString { - return ObjString.cast(value.obj()).?; -} - -export fn bz_valueToObjTypeDef(value: Value) *ObjTypeDef { - return ObjTypeDef.cast(value.obj()).?; -} - -/// ObjString -> [*]const u8 + len -export fn bz_objStringToString(obj_string: *ObjString, len: *usize) ?[*]const u8 { - len.* = obj_string.string.len; - - return if (obj_string.string.len > 0) @as([*]const u8, @ptrCast(obj_string.string)) else null; -} - -/// ObjString -> Value -export fn bz_objStringToValue(obj_string: *ObjString) Value { - return obj_string.toValue(); -} - -export fn bz_objStringConcat(vm: *VM, obj_string: Value, other: Value) Value { +export fn bz_stringConcat(obj_string: Value, other: Value, vm: *VM) Value { return (ObjString.cast(obj_string.obj()).?.concat( vm, ObjString.cast(other.obj()).?, ) catch @panic("Could not concat strings")).toValue(); } -export fn bz_objStringSubscript(vm: *VM, obj_string: Value, index_value: Value, checked: bool) Value { +export fn bz_stringSubscript(obj_string: Value, index_value: Value, checked: bool, vm: *VM) Value { const str = ObjString.cast(obj_string.obj()).?; const index = index_value.integer(); @@ -467,7 +400,7 @@ export fn bz_objStringSubscript(vm: *VM, obj_string: Value, index_value: Value, } } -export fn bz_toString(vm: *VM, value: Value) Value { +export fn bz_valueCastToString(value: Value, vm: *VM) Value { const str = value.toStringAlloc(vm.gc.allocator) catch { @panic("Could not convert value to string"); }; @@ -514,16 +447,18 @@ export fn bz_mapType(vm: *VM, key_type: Value, value_type: Value) Value { return typedef.toValue(); } -export fn bz_containerTypeSize(type_def: *ObjTypeDef) usize { - const struct_def = type_def.resolved_type.?.ForeignContainer; - - return struct_def.zig_type.size(); +export fn bz_containerTypeSize(type_def: Value) usize { + return ObjTypeDef.cast(type_def.obj()).? + .resolved_type.? + .ForeignContainer + .zig_type.size(); } -export fn bz_containerTypeAlign(type_def: *ObjTypeDef) usize { - const struct_def = type_def.resolved_type.?.ForeignContainer; - - return struct_def.zig_type.alignment(); +export fn bz_containerTypeAlign(type_def: Value) usize { + return ObjTypeDef.cast(type_def.obj()).? + .resolved_type.? + .ForeignContainer + .zig_type.alignment(); } export fn bz_allocated(self: *VM) usize { @@ -570,14 +505,10 @@ export fn bz_newList(vm: *VM, of_type: Value) Value { ) catch @panic("Could not create list")).toValue(); } -export fn bz_listAppend(vm: *VM, list: Value, value: Value) void { +export fn bz_listAppend(list: Value, value: Value, vm: *VM) void { ObjList.cast(list.obj()).?.rawAppend(vm.gc, value) catch @panic("Could not add element to list"); } -export fn bz_valueToList(value: Value) *ObjList { - return ObjList.cast(value.obj()).?; -} - export fn bz_listGet(self: Value, index: i32, checked: bool) Value { const list = ObjList.cast(self.obj()).?; @@ -592,7 +523,7 @@ export fn bz_listGet(self: Value, index: i32, checked: bool) Value { return list.items.items[@intCast(index)]; } -export fn bz_listSet(vm: *VM, self: Value, index: usize, value: Value) void { +export fn bz_listSet(self: Value, index: usize, value: Value, vm: *VM) void { ObjList.cast(self.obj()).?.set( vm.gc, index, @@ -600,11 +531,11 @@ export fn bz_listSet(vm: *VM, self: Value, index: usize, value: Value) void { ) catch @panic("Could not set element in list"); } -export fn bz_listLen(self: *ObjList) usize { - return self.items.items.len; +export fn bz_listLen(self: Value) usize { + return ObjList.cast(self.obj()).?.items.items.len; } -export fn bz_listConcat(vm: *VM, list: Value, other_list: Value) Value { +export fn bz_listConcat(list: Value, other_list: Value, vm: *VM) Value { const left: *ObjList = ObjList.cast(list.obj()).?; const right: *ObjList = ObjList.cast(other_list.obj()).?; @@ -622,7 +553,7 @@ export fn bz_listConcat(vm: *VM, list: Value, other_list: Value) Value { ) catch @panic("Could not concatenate lists")).toValue(); } -export fn bz_mapConcat(vm: *VM, map: Value, other_map: Value) Value { +export fn bz_mapConcat(map: Value, other_map: Value, vm: *VM) Value { const left: *ObjMap = ObjMap.cast(map.obj()).?; const right: *ObjMap = ObjMap.cast(other_map.obj()).?; @@ -643,21 +574,18 @@ export fn bz_mapConcat(vm: *VM, map: Value, other_map: Value) Value { }) catch @panic("Could not concatenate maps")).toValue(); } -export fn bz_newUserData(vm: *VM, userdata: u64) ?*ObjUserData { - return vm.gc.allocateObject( +export fn bz_newUserData(vm: *VM, userdata: u64) Value { + return (vm.gc.allocateObject( ObjUserData, ObjUserData{ .userdata = userdata }, ) catch { - return null; - }; -} - -export fn bz_getUserDataPtr(userdata: *ObjUserData) u64 { - return userdata.userdata; + vm.panic("Out of memory"); + unreachable; + }).toValue(); } -export fn bz_userDataToValue(userdata: *ObjUserData) Value { - return userdata.toValue(); +export fn bz_getUserDataPtr(userdata: Value) u64 { + return ObjUserData.cast(userdata.obj()).?.userdata; } export fn bz_newVM(self: *VM) ?*VM { @@ -693,53 +621,6 @@ export fn bz_panic(vm: *VM, msg: [*]const u8, len: usize) void { vm.panic(msg[0..len]); } -export fn bz_compile( - self: *VM, - source: ?[*]const u8, - source_len: usize, - file_name: ?[*]const u8, - file_name_len: usize, -) ?*ObjFunction { - if (source == null or file_name_len == 0 or source_len == 0 or file_name_len == 0) { - return null; - } - - var imports = std.StringHashMap(Parser.ScriptImport).init(self.gc.allocator); - var strings = std.StringHashMap(*ObjString).init(self.gc.allocator); - var parser = Parser.init( - self.gc, - &imports, - false, - self.flavor, - ); - var codegen = CodeGen.init( - self.gc, - &parser, - self.flavor, - null, - ); - defer { - codegen.deinit(); - imports.deinit(); - parser.deinit(); - strings.deinit(); - } - - if (parser.parse(source.?[0..source_len], file_name.?[0..file_name_len]) catch null) |ast| { - return codegen.generate(ast) catch null; - } else { - return null; - } -} - -export fn bz_interpret(self: *VM, ast: *anyopaque, function: *ObjFunction) bool { - self.interpret(@as(*Ast, @ptrCast(@alignCast(ast))).*, function, null) catch { - return false; - }; - - return true; -} - export fn bz_run( self: *VM, source: ?[*]const u8, @@ -843,12 +724,14 @@ pub export fn bz_invoke( pub export fn bz_call( self: *VM, - closure: *ObjClosure, + closure_value: Value, arguments: ?[*]const *const Value, len: u8, catch_value: ?*Value, ) void { - self.push(closure.toValue()); + std.debug.assert(closure_value.obj().obj_type == .Closure); + + self.push(closure_value); var i: usize = 0; while (i < len) : (i += 1) { self.push(arguments.?[i].*); @@ -856,18 +739,22 @@ pub export fn bz_call( // TODO: catch properly self.callValue( - closure.toValue(), + closure_value, len, if (catch_value) |v| v.* else null, ) catch unreachable; // If not compiled, run it with the VM loop - if (closure.function.native == null) { + if (closure_value.obj().access( + ObjClosure, + .Closure, + self.gc, + ).?.function.native == null) { self.run(); } } -export fn bz_instanceQualified(self: *VM, qualified_name: [*]const u8, len: usize) Value { +export fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize) Value { const object = ObjObject.cast(bz_getQualified(self, qualified_name, len).obj()).?; const instance: *ObjObjectInstance = self.gc.allocateObject( @@ -906,7 +793,7 @@ fn instanciateError( message: ?[*]const u8, mlen: usize, ) Value { - const instance = bz_instanceQualified(vm, qualified_name, len); + const instance = bz_newQualifiedObjectInstance(vm, qualified_name, len); if (message) |msg| { const obj_instance = ObjObjectInstance.cast(instance.obj()).?; @@ -945,14 +832,13 @@ export fn bz_pushError( } export fn bz_pushErrorEnum(self: *VM, qualified_name: [*]const u8, name_len: usize, case_str: [*]const u8, case_len: usize) void { - const enum_set = ObjEnum.cast(bz_getQualified(self, qualified_name, name_len).obj()).?; const case = self.gc.copyString(case_str[0..case_len]) catch @panic("Could not create error payload"); self.push( bz_getEnumCase( - self, - enum_set.toValue(), + bz_getQualified(self, qualified_name, name_len), case.toValue(), + self, ), ); } @@ -983,7 +869,7 @@ export fn bz_getQualified(self: *VM, qualified_name: [*]const u8, len: usize) Va std.debug.panic("bz_getQualified no name: {s}", .{qualified_name[0..len]}); } -export fn bz_instance(vm: *VM, object_value: Value, typedef_value: Value) Value { +export fn bz_newObjectInstance(vm: *VM, object_value: Value, typedef_value: Value) Value { const object = if (object_value.isObj()) ObjObject.cast(object_value.obj()).? else null; const typedef = ObjTypeDef.cast(typedef_value.obj()).?; @@ -1017,7 +903,7 @@ export fn bz_getObjectField(object_value: Value, field_idx: usize) Value { return ObjObject.cast(object_value.obj()).?.fields[field_idx]; } -export fn bz_setObjectField(vm: *VM, object_value: Value, field_idx: usize, value: Value) void { +export fn bz_setObjectField(object_value: Value, field_idx: usize, value: Value, vm: *VM) void { ObjObject.cast(object_value.obj()).?.setField( vm.gc, field_idx, @@ -1025,7 +911,7 @@ export fn bz_setObjectField(vm: *VM, object_value: Value, field_idx: usize, valu ) catch @panic("Could not set static field"); } -export fn bz_setInstanceProperty(vm: *VM, instance_value: Value, field_idx: usize, value: Value) void { +export fn bz_setObjectInstanceProperty(instance_value: Value, field_idx: usize, value: Value, vm: *VM) void { ObjObjectInstance.cast(instance_value.obj()).?.setField( vm.gc, field_idx, @@ -1033,12 +919,12 @@ export fn bz_setInstanceProperty(vm: *VM, instance_value: Value, field_idx: usiz ) catch @panic("Could not set instance field"); } -export fn bz_getInstanceProperty(instance_value: Value, property_idx: usize) Value { +export fn bz_getObjectInstanceProperty(instance_value: Value, property_idx: usize) Value { return ObjObjectInstance.cast(instance_value.obj()).? .fields[property_idx]; } -export fn bz_getInstanceMethod(vm: *VM, instance_value: Value, method_idx: usize, bind: bool) Value { +export fn bz_getObjectInstanceMethod(instance_value: Value, method_idx: usize, bind: bool, vm: *VM) Value { const method = ObjObjectInstance.cast(instance_value.obj()).? .object.? .fields[method_idx]; @@ -1054,7 +940,7 @@ export fn bz_getInstanceMethod(vm: *VM, instance_value: Value, method_idx: usize method; } -export fn bz_getProtocolMethod(vm: *VM, instance_value: Value, method_name: Value) Value { +export fn bz_getProtocolMethod(instance_value: Value, method_name: Value, vm: *VM) Value { const instance = instance_value.obj().access( ObjObjectInstance, .ObjectInstance, @@ -1088,39 +974,7 @@ export fn bz_bindMethod(vm: *VM, receiver: Value, method_value: Value, native_va ) catch @panic("Could not bind method")).toValue(); } -export fn bz_valueToObject(value: Value) *ObjObject { - return ObjObject.cast(value.obj()).?; -} - -export fn bz_valueToObjectInstance(value: Value) *ObjObjectInstance { - return ObjObjectInstance.cast(value.obj()).?; -} - -export fn bz_valueToObjEnumInstance(value: Value) *ObjEnumInstance { - return ObjEnumInstance.cast(value.obj()).?; -} - -export fn bz_valueToObjList(value: Value) *ObjList { - return ObjList.cast(value.obj()).?; -} - -export fn bz_valueToObjMap(value: Value) *ObjMap { - return ObjMap.cast(value.obj()).?; -} - -export fn bz_valueToObjFiber(value: Value) *ObjFiber { - return ObjFiber.cast(value.obj()).?; -} - -export fn bz_valueToObjPattern(value: Value) *ObjPattern { - return ObjPattern.cast(value.obj()).?; -} - -export fn bz_pushObjectInstance(vm: *VM, payload: *ObjObjectInstance) void { - vm.push(payload.toValue()); -} - -export fn bz_getEnumCase(vm: *VM, enum_value: Value, case_name_value: Value) Value { +export fn bz_getEnumCase(enum_value: Value, case_name_value: Value, vm: *VM) Value { const self = ObjEnum.cast(enum_value.obj()).?; const case = ObjString.cast(case_name_value.obj()).?.string; var case_index: usize = 0; @@ -1141,13 +995,13 @@ export fn bz_getEnumCase(vm: *VM, enum_value: Value, case_name_value: Value) Val ) catch @panic("Could not create enum case")).toValue(); } -export fn bz_getEnumCaseValue(enum_instance_value: Value) Value { +export fn bz_getEnumInstanceValue(enum_instance_value: Value) Value { const instance = ObjEnumInstance.cast(enum_instance_value.obj()).?; return instance.enum_ref.cases[instance.case]; } -export fn bz_getEnumCaseFromValue(vm: *VM, enum_value: Value, case_value: Value) Value { +export fn bz_getEnumCaseFromValue(enum_value: Value, case_value: Value, vm: *VM) Value { const enum_ = ObjEnum.cast(enum_value.obj()).?; for (enum_.cases, 0..) |case, index| { @@ -1164,18 +1018,6 @@ export fn bz_getEnumCaseFromValue(vm: *VM, enum_value: Value, case_value: Value) return Value.Null; } -export fn bz_pushEnumInstance(vm: *VM, payload: *ObjEnumInstance) void { - vm.push(payload.toValue()); -} - -export fn bz_valueToClosure(value: Value) *ObjClosure { - return ObjClosure.cast(value.obj()).?; -} - -export fn bz_toObjNative(value: Value) *ObjNative { - return ObjNative.cast(value.obj()).?; -} - export fn bz_valueEqual(self: Value, other: Value) Value { return Value.fromBoolean(self.eql(other)); } @@ -1199,7 +1041,7 @@ export fn bz_newMap(vm: *VM, map_type: Value) Value { return Value.fromObj(map.toObj()); } -export fn bz_mapSet(vm: *VM, map: Value, key: Value, value: Value) void { +export fn bz_mapSet(map: Value, key: Value, value: Value, vm: *VM) void { ObjMap.cast(map.obj()).?.set( vm.gc, key, @@ -1487,7 +1329,7 @@ export fn bz_getMapProperty(vm: *VM, map_value: Value, property_idx: usize, bind method; } -export fn bz_stringNext(vm: *VM, string_value: Value, index: *Value) Value { +export fn bz_stringNext(string_value: Value, index: *Value, vm: *VM) Value { const string = ObjString.cast(string_value.obj()).?; if (string.next( @@ -1503,7 +1345,7 @@ export fn bz_stringNext(vm: *VM, string_value: Value, index: *Value) Value { return Value.Null; } -export fn bz_listNext(vm: *VM, list_value: Value, index: *Value) Value { +export fn bz_listNext(list_value: Value, index: *Value, vm: *VM) Value { const list = ObjList.cast(list_value.obj()).?; if (list.rawNext( @@ -1538,7 +1380,7 @@ export fn bz_rangeNext(range_value: Value, index_slot: Value) Value { return Value.fromInteger(range.low); } -export fn bz_mapNext(_: *VM, map_value: Value, key: *Value) Value { +export fn bz_mapNext(map_value: Value, key: *Value) Value { const map = ObjMap.cast(map_value.obj()).?; if (map.rawNext(if (key.isNull()) null else key.*)) |new_key| { @@ -1551,7 +1393,7 @@ export fn bz_mapNext(_: *VM, map_value: Value, key: *Value) Value { return Value.Null; } -export fn bz_enumNext(vm: *VM, enum_value: Value, case: Value) Value { +export fn bz_enumNext(enum_value: Value, case: Value, vm: *VM) Value { const enum_ = ObjEnum.cast(enum_value.obj()).?; if (enum_.rawNext( @@ -1568,10 +1410,6 @@ export fn bz_clone(vm: *VM, value: Value) Value { return vm.cloneValue(value) catch @panic("Could not clone value"); } -export fn dumpInt(value: u64) void { - io.print("-> {x}\n", .{value}); -} - export fn bz_zigType(vm: *VM, ztype: [*]const u8, len: usize, expected_type: *Value) ?*const ZigType { if (is_wasm) { return null; @@ -1588,49 +1426,137 @@ export fn bz_zigType(vm: *VM, ztype: [*]const u8, len: usize, expected_type: *Va return null; } -pub export fn bz_zigValueSize(ztype: *ZigType) usize { - return ztype.size(); +export fn bz_foreignContainerGet(value: Value, field_idx: usize, vm: *VM) Value { + const container = ObjForeignContainer.cast(value.obj()).?; + + return container.type_def.resolved_type.? + .ForeignContainer + .fields.values()[field_idx] + .getter( + vm, + container.data.ptr, + ); } -export fn bz_checkBuzzType( - vm: *VM, - value: Value, - ztype: *ZigType, - btype: Value, -) bool { - if (!bz_valueIs(value, btype).boolean()) { - var err = std.ArrayList(u8).init(vm.gc.allocator); - defer err.deinit(); +export fn bz_foreignContainerSet(value: Value, field_idx: usize, new_value: Value, vm: *VM) void { + const container = ObjForeignContainer.cast(value.obj()).?; + // Oh right that's beautiful enough... + return container.type_def.resolved_type.?.ForeignContainer + .fields.values()[field_idx] + .setter( + vm, + container.data.ptr, + new_value, + ); +} - const typedef = ObjTypeDef.cast(btype.obj()).?.toStringAlloc(vm.gc.allocator) catch { - vm.panic("Out of memory"); - unreachable; - }; - defer typedef.deinit(); - - err.writer().print( - "Expected buzz value of type `{s}` to match FFI type `{}`", - .{ - typedef.items, - ztype.*, - }, +export fn bz_newForeignContainerInstance(vm: *VM, typedef_value: Value) Value { + return (vm.gc.allocateObject( + ObjForeignContainer, + ObjForeignContainer.init( + vm, + ObjTypeDef.cast(typedef_value.obj()).?, ) catch { vm.panic("Out of memory"); unreachable; - }; + }, + ) catch { + vm.panic("Out of memory"); + unreachable; + }).toValue(); +} - bz_pushError( - vm, - "ffi.FFITypeMismatchError", - "ffi.FFITypeMismatchError".len, - err.items.ptr, - err.items.len, - ); +export fn bz_foreignContainerSlice(container_value: Value, len: *usize) [*]u8 { + const container = ObjForeignContainer.cast(container_value.obj()).?; - return false; - } + len.* = container.data.len; - return true; + return container.data.ptr; +} + +export fn bz_newForeignContainerFromSlice(vm: *VM, type_def: Value, ptr: [*]u8, len: usize) Value { + var container = (vm.gc.allocateObject( + ObjForeignContainer, + .{ + .type_def = ObjTypeDef.cast(type_def.obj()).?, + .data = ptr[0..len], + }, + ) catch { + vm.panic("Out of memory"); + unreachable; + }); + + return container.toValue(); +} + +export fn bz_zigTypeSize(self: *ZigType) usize { + return self.size(); +} + +export fn bz_zigTypeAlignment(self: *ZigType) u16 { + return self.alignment(); +} + +export fn bz_zigTypeToCString(self: *ZigType, vm: *VM) [*:0]const u8 { + var out = std.ArrayList(u8).init(vm.gc.allocator); + + out.writer().print("{}\x00", .{self.*}) catch { + vm.panic("Out of memory"); + unreachable; + }; + + return @ptrCast(out.items.ptr); +} + +export fn bz_serialize(vm: *VM, value: Value, error_value: *Value) Value { + var seen = std.AutoHashMap(*Obj, void).init(vm.gc.allocator); + defer seen.deinit(); + + return value.serialize(vm, &seen) catch |err| s: { + switch (err) { + error.CircularReference => { + // TODO: not ideal to do this here, will fail if serialize was not imported in the script... + error_value.* = instanciateError( + vm, + "serialize.CircularReference", + "serialize.CircularReference".len, + null, + 0, + ); + break :s Value.Void; + }, + error.NotSerializable => { + error_value.* = instanciateError( + vm, + "serialize.NotSerializable", + "serialize.NotSerializable".len, + null, + 0, + ); + break :s Value.Void; + }, + else => { + vm.panic("Out of memory"); + unreachable; + }, + } + }; +} + +export fn bz_currentFiber(vm: *VM) Value { + return (vm.gc.allocateObject( + ObjFiber, + .{ + .fiber = vm.current_fiber, + }, + ) catch { + vm.panic("Out of memory"); + unreachable; + }).toValue(); +} + +export fn bz_memcpy(dest: [*]u8, dest_len: usize, source: [*]u8, source_len: usize) void { + @memcpy(dest[0..dest_len], source[0..source_len]); } export fn bz_readZigValueFromBuffer( @@ -1881,125 +1807,3 @@ export fn bz_writeZigValueToBuffer( else => {}, } } - -export fn bz_containerGet(vm: *VM, value: Value, field_idx: usize) Value { - const container = ObjForeignContainer.cast(value.obj()).?; - - return container.type_def.resolved_type.? - .ForeignContainer - .fields.values()[field_idx] - .getter( - vm, - container.data.ptr, - ); -} - -export fn bz_containerSet(vm: *VM, value: Value, field_idx: usize, new_value: Value) void { - const container = ObjForeignContainer.cast(value.obj()).?; - // Oh right that's beautiful enough... - return container.type_def.resolved_type.?.ForeignContainer - .fields.values()[field_idx] - .setter( - vm, - container.data.ptr, - new_value, - ); -} - -export fn bz_containerInstance(vm: *VM, typedef_value: Value) Value { - return (vm.gc.allocateObject( - ObjForeignContainer, - ObjForeignContainer.init( - vm, - ObjTypeDef.cast(typedef_value.obj()).?, - ) catch { - vm.panic("Out of memory"); - unreachable; - }, - ) catch { - vm.panic("Out of memory"); - unreachable; - }).toValue(); -} - -export fn bz_memcpy(dest: [*]u8, dest_len: usize, source: [*]u8, source_len: usize) void { - @memcpy(dest[0..dest_len], source[0..source_len]); -} - -export fn bz_containerSlice(container_value: Value, len: *usize) [*]u8 { - const container = ObjForeignContainer.cast(container_value.obj()).?; - - len.* = container.data.len; - - return container.data.ptr; -} - -export fn bz_containerFromSlice(vm: *VM, type_def: *ObjTypeDef, ptr: [*]u8, len: usize) Value { - var container = (vm.gc.allocateObject( - ObjForeignContainer, - .{ - .type_def = type_def, - .data = ptr[0..len], - }, - ) catch { - vm.panic("Out of memory"); - unreachable; - }); - - return container.toValue(); -} - -export fn bz_zigTypeSize(self: *ZigType) usize { - return self.size(); -} - -export fn bz_zigTypeAlignment(self: *ZigType) u16 { - return self.alignment(); -} - -export fn bz_serialize(vm: *VM, value: Value, error_value: *Value) Value { - var seen = std.AutoHashMap(*Obj, void).init(vm.gc.allocator); - defer seen.deinit(); - - return value.serialize(vm, &seen) catch |err| s: { - switch (err) { - error.CircularReference => { - // TODO: not ideal to do this here, will fail if serialize was not imported in the script... - error_value.* = instanciateError( - vm, - "serialize.CircularReference", - "serialize.CircularReference".len, - null, - 0, - ); - break :s Value.Void; - }, - error.NotSerializable => { - error_value.* = instanciateError( - vm, - "serialize.NotSerializable", - "serialize.NotSerializable".len, - null, - 0, - ); - break :s Value.Void; - }, - else => { - vm.panic("Out of memory"); - unreachable; - }, - } - }; -} - -export fn bz_currentFiber(vm: *VM) Value { - return (vm.gc.allocateObject( - ObjFiber, - .{ - .fiber = vm.current_fiber, - }, - ) catch { - vm.panic("Out of memory"); - unreachable; - }).toValue(); -} diff --git a/src/jit_extern_api.zig b/src/jit_extern_api.zig index 0ec7576d..059cc4af 100644 --- a/src/jit_extern_api.zig +++ b/src/jit_extern_api.zig @@ -14,9 +14,9 @@ pub const ExternApi = enum { nativefn, rawfn, - bz_objStringConcat, - bz_objStringSubscript, - bz_toString, + bz_stringConcat, + bz_stringSubscript, + bz_valueCastToString, bz_newList, bz_newRange, bz_listAppend, @@ -38,10 +38,10 @@ pub const ExternApi = enum { bz_setUpValue, bz_closure, bz_context, - bz_instance, - bz_setInstanceProperty, - bz_getInstanceProperty, - bz_getInstanceMethod, + bz_newObjectInstance, + bz_setObjectInstanceProperty, + bz_getObjectInstanceProperty, + bz_getObjectInstanceMethod, bz_getProtocolMethod, bz_getObjectField, bz_setObjectField, @@ -49,7 +49,7 @@ pub const ExternApi = enum { bz_getPatternProperty, bz_getFiberProperty, bz_getEnumCase, - bz_getEnumCaseValue, + bz_getEnumInstanceValue, bz_getListProperty, bz_getMapProperty, bz_getRangeProperty, @@ -62,15 +62,15 @@ pub const ExternApi = enum { bz_rangeNext, bz_clone, bz_valueToCString, - bz_valueToUserData, - bz_userDataToValue, + bz_getUserDataPtr, + bz_newUserData, bz_valueToForeignContainerPtr, - bz_stringZ, - bz_containerGet, - bz_containerSet, - bz_containerInstance, + bz_stringToValueZ, + bz_foreignContainerGet, + bz_foreignContainerSet, + bz_newForeignContainerInstance, bz_valueTypeOf, - bz_containerFromSlice, + bz_newForeignContainerFromSlice, bz_dumpStack, @@ -78,11 +78,10 @@ pub const ExternApi = enum { setjmp, // libc exit: https://man7.org/linux/man-pages/man3/exit.3.html exit, - memcpy, - dumpInt, bz_valueDump, fmod, + memcpy, pub fn declare(self: ExternApi, jit: *JIT) !m.MIR_item_t { const prototype = jit.state.?.prototypes.get(self) orelse self.proto(jit.ctx); @@ -96,20 +95,16 @@ pub const ExternApi = enum { return prototype; } + // FIXME: this could all be down at comptime by looking at each function type fn proto(self: ExternApi, ctx: m.MIR_context_t) m.MIR_item_t { return switch (self) { - .bz_objStringSubscript => m.MIR_new_proto_arr( + .bz_stringSubscript => m.MIR_new_proto_arr( ctx, self.pname(), 1, &[_]m.MIR_type_t{m.MIR_T_U64}, 4, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "obj_string", @@ -125,6 +120,11 @@ pub const ExternApi = enum { .name = "checked", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), .bz_closure => m.MIR_new_proto_arr( @@ -140,7 +140,7 @@ pub const ExternApi = enum { .size = undefined, }, .{ - .type = m.MIR_T_P, + .type = m.MIR_T_U32, .name = "function_node", .size = undefined, }, @@ -156,7 +156,7 @@ pub const ExternApi = enum { }, }, ), - .bz_toString, .bz_newList, .bz_newMap => m.MIR_new_proto_arr( + .bz_valueCastToString, .bz_newList, .bz_newMap => m.MIR_new_proto_arr( ctx, self.pname(), 1, @@ -164,13 +164,13 @@ pub const ExternApi = enum { 2, &[_]m.MIR_var_t{ .{ - .type = m.MIR_T_P, - .name = "vm", + .type = m.MIR_T_U64, + .name = "value", .size = undefined, }, .{ - .type = m.MIR_T_U64, - .name = "value", + .type = m.MIR_T_P, + .name = "vm", .size = undefined, }, }, @@ -206,11 +206,6 @@ pub const ExternApi = enum { null, 3, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "list", @@ -221,6 +216,11 @@ pub const ExternApi = enum { .name = "value", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), .bz_listGet => m.MIR_new_proto_arr( @@ -273,11 +273,6 @@ pub const ExternApi = enum { null, 4, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "list", @@ -293,6 +288,11 @@ pub const ExternApi = enum { .name = "value", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), .bz_valueEqual => m.MIR_new_proto_arr( @@ -316,8 +316,8 @@ pub const ExternApi = enum { ), .bz_listConcat, .bz_mapConcat, - .bz_objStringConcat, - .bz_instance, + .bz_stringConcat, + .bz_newObjectInstance, => m.MIR_new_proto_arr( ctx, self.pname(), @@ -325,11 +325,6 @@ pub const ExternApi = enum { &[_]m.MIR_type_t{m.MIR_T_U64}, 3, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "list", @@ -340,20 +335,22 @@ pub const ExternApi = enum { .name = "other_list", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), - .bz_getEnumCaseFromValue, .bz_getEnumCase => m.MIR_new_proto_arr( + .bz_getEnumCaseFromValue, + .bz_getEnumCase, + => m.MIR_new_proto_arr( ctx, self.pname(), 1, &[_]m.MIR_type_t{m.MIR_T_U64}, 3, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "enum", @@ -364,9 +361,14 @@ pub const ExternApi = enum { .name = "value", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), - .bz_getEnumCaseValue => m.MIR_new_proto_arr( + .bz_getEnumInstanceValue => m.MIR_new_proto_arr( ctx, self.pname(), 1, @@ -382,7 +384,7 @@ pub const ExternApi = enum { ), .bz_getObjectField, .bz_valueIs, - .bz_getInstanceProperty, + .bz_getObjectInstanceProperty, => m.MIR_new_proto_arr( ctx, self.pname(), @@ -408,8 +410,6 @@ pub const ExternApi = enum { .bz_getStringProperty, .bz_getPatternProperty, .bz_getFiberProperty, - .bz_getInstanceMethod, - .bz_getProtocolMethod, => m.MIR_new_proto_arr( ctx, self.pname(), @@ -439,21 +439,71 @@ pub const ExternApi = enum { }, }, ), - .bz_setInstanceProperty, - .bz_setObjectField, - .bz_bindMethod, + .bz_getProtocolMethod, => m.MIR_new_proto_arr( ctx, self.pname(), - 0, - null, + 1, + &[_]m.MIR_type_t{m.MIR_T_U64}, + 3, + &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_U64, + .name = "subject", + .size = undefined, + }, + .{ + .type = m.MIR_T_U64, + .name = "field", + .size = undefined, + }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, + }, + ), + .bz_getObjectInstanceMethod, + => m.MIR_new_proto_arr( + ctx, + self.pname(), + 1, + &[_]m.MIR_type_t{m.MIR_T_U64}, 4, &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_U64, + .name = "subject", + .size = undefined, + }, + .{ + .type = m.MIR_T_U64, + .name = "field", + .size = undefined, + }, + .{ + .type = m.MIR_T_U8, + .name = "bind", + .size = undefined, + }, .{ .type = m.MIR_T_P, .name = "vm", .size = undefined, }, + }, + ), + .bz_setObjectInstanceProperty, + .bz_setObjectField, + .bz_bindMethod, + => m.MIR_new_proto_arr( + ctx, + self.pname(), + 0, + null, + 4, + &[_]m.MIR_var_t{ .{ .type = m.MIR_T_U64, .name = "instance", @@ -469,6 +519,11 @@ pub const ExternApi = enum { .name = "value", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), .bz_getUpValue => m.MIR_new_proto_arr( @@ -678,7 +733,6 @@ pub const ExternApi = enum { ), .bz_stringNext, .bz_listNext, - .bz_mapNext, .bz_enumNext, => m.MIR_new_proto_arr( ctx, @@ -687,11 +741,30 @@ pub const ExternApi = enum { &[_]m.MIR_type_t{m.MIR_T_U64}, 3, &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_U64, + .name = "iterable", + .size = undefined, + }, + .{ + .type = m.MIR_T_P, + .name = "key", + .size = undefined, + }, .{ .type = m.MIR_T_P, .name = "vm", .size = undefined, }, + }, + ), + .bz_mapNext => m.MIR_new_proto_arr( + ctx, + self.pname(), + 1, + &[_]m.MIR_type_t{m.MIR_T_U64}, + 2, + &[_]m.MIR_var_t{ .{ .type = m.MIR_T_U64, .name = "iterable", @@ -751,20 +824,6 @@ pub const ExternApi = enum { }, }, ), - .dumpInt => m.MIR_new_proto_arr( - ctx, - self.pname(), - 0, - null, - 1, - &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_U64, - .name = "value", - .size = undefined, - }, - }, - ), .bz_valueDump => m.MIR_new_proto_arr( ctx, self.pname(), @@ -798,7 +857,7 @@ pub const ExternApi = enum { }, }, ), - .bz_valueToUserData => m.MIR_new_proto_arr( + .bz_getUserDataPtr => m.MIR_new_proto_arr( ctx, self.pname(), 1, @@ -812,13 +871,18 @@ pub const ExternApi = enum { }, }, ), - .bz_userDataToValue => m.MIR_new_proto_arr( + .bz_newUserData => m.MIR_new_proto_arr( ctx, self.pname(), 1, &[_]m.MIR_type_t{m.MIR_T_I64}, 1, &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, .{ .type = m.MIR_T_P, .name = "value", @@ -840,7 +904,7 @@ pub const ExternApi = enum { }, }, ), - .bz_stringZ => m.MIR_new_proto_arr( + .bz_stringToValueZ => m.MIR_new_proto_arr( ctx, self.pname(), 1, @@ -859,18 +923,13 @@ pub const ExternApi = enum { }, }, ), - .bz_containerGet => m.MIR_new_proto_arr( + .bz_foreignContainerGet => m.MIR_new_proto_arr( ctx, self.pname(), 1, &[_]m.MIR_type_t{m.MIR_T_I64}, 3, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "value", @@ -881,20 +940,20 @@ pub const ExternApi = enum { .name = "field_idx", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), - .bz_containerSet => m.MIR_new_proto_arr( + .bz_foreignContainerSet => m.MIR_new_proto_arr( ctx, self.pname(), 0, null, 4, &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_P, - .name = "vm", - .size = undefined, - }, .{ .type = m.MIR_T_U64, .name = "value", @@ -910,9 +969,14 @@ pub const ExternApi = enum { .name = "new_value", .size = undefined, }, + .{ + .type = m.MIR_T_P, + .name = "vm", + .size = undefined, + }, }, ), - .bz_containerInstance => m.MIR_new_proto_arr( + .bz_newForeignContainerInstance => m.MIR_new_proto_arr( ctx, self.pname(), 1, @@ -950,7 +1014,7 @@ pub const ExternApi = enum { }, }, ), - .bz_containerFromSlice => m.MIR_new_proto_arr( + .bz_newForeignContainerFromSlice => m.MIR_new_proto_arr( ctx, self.pname(), 1, @@ -979,6 +1043,25 @@ pub const ExternApi = enum { }, }, ), + .fmod => m.MIR_new_proto_arr( + ctx, + self.pname(), + 1, + &[_]m.MIR_type_t{m.MIR_T_I64}, + 2, + &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_D, + .name = "lhs", + .size = undefined, + }, + .{ + .type = m.MIR_T_D, + .name = "rhs", + .size = undefined, + }, + }, + ), .memcpy => m.MIR_new_proto_arr( ctx, self.pname(), @@ -1008,56 +1091,37 @@ pub const ExternApi = enum { }, }, ), - .fmod => m.MIR_new_proto_arr( - ctx, - self.pname(), - 1, - &[_]m.MIR_type_t{m.MIR_T_I64}, - 2, - &[_]m.MIR_var_t{ - .{ - .type = m.MIR_T_D, - .name = "lhs", - .size = undefined, - }, - .{ - .type = m.MIR_T_D, - .name = "rhs", - .size = undefined, - }, - }, - ), }; } pub fn ptr(self: ExternApi) *anyopaque { return switch (self) { - .bz_toString => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjString.bz_toString))), - .bz_objStringConcat => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjString.bz_objStringConcat))), - .bz_objStringSubscript => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjString.bz_objStringSubscript))), - .bz_stringNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjString.bz_stringNext))), - .bz_newList => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_newList))), - .bz_newRange => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjRange.bz_newRange))), - .bz_rangeNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjRange.bz_rangeNext))), - .bz_listAppend => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_listAppend))), - .bz_listGet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_listGet))), - .bz_listSet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_listSet))), - .bz_listConcat => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_listConcat))), - .bz_listNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_listNext))), - .bz_newMap => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjMap.bz_newMap))), - .bz_mapGet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjMap.bz_mapGet))), - .bz_mapSet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjMap.bz_mapSet))), - .bz_mapNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjMap.bz_mapNext))), - .bz_mapConcat => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjMap.bz_mapConcat))), + .bz_valueCastToString => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueCastToString))), + .bz_stringConcat => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_stringConcat))), + .bz_stringSubscript => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_stringSubscript))), + .bz_stringNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_stringNext))), + .bz_newList => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newList))), + .bz_newRange => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newRange))), + .bz_rangeNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_rangeNext))), + .bz_listAppend => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_listAppend))), + .bz_listGet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_listGet))), + .bz_listSet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_listSet))), + .bz_listConcat => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_listConcat))), + .bz_listNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_listNext))), + .bz_newMap => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newMap))), + .bz_mapGet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_mapGet))), + .bz_mapSet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_mapSet))), + .bz_mapNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_mapNext))), + .bz_mapConcat => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_mapConcat))), .bz_valueEqual => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueEqual))), .bz_valueIs => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueIs))), .bz_closure => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_closure))), .bz_context => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_context))), - .bz_instance => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_instance))), - .bz_setInstanceProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_setInstanceProperty))), - .bz_getInstanceProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_getInstanceProperty))), - .bz_getInstanceMethod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_getInstanceMethod))), - .bz_getProtocolMethod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_getProtocolMethod))), + .bz_newObjectInstance => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newObjectInstance))), + .bz_setObjectInstanceProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_setObjectInstanceProperty))), + .bz_getObjectInstanceProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getObjectInstanceProperty))), + .bz_getObjectInstanceMethod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getObjectInstanceMethod))), + .bz_getProtocolMethod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getProtocolMethod))), .bz_rethrow => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_rethrow))), .bz_throw => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_throw))), .bz_bindMethod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_bindMethod))), @@ -1066,31 +1130,30 @@ pub const ExternApi = enum { .bz_closeUpValues => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_closeUpValues))), .bz_clone => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_clone))), .bz_dumpStack => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_dumpStack))), - .bz_getEnumCaseFromValue => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjEnum.bz_getEnumCaseFromValue))), - .bz_getEnumCase => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjEnum.bz_getEnumCase))), - .bz_enumNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjEnum.bz_enumNext))), - .bz_getEnumCaseValue => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjEnumInstance.bz_getEnumCaseValue))), - .bz_setObjectField => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_setObjectField))), - .bz_getObjectField => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjObject.bz_getObjectField))), - .bz_getListProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjList.bz_getListProperty))), - .bz_getMapProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjMap.bz_getMapProperty))), - .bz_getRangeProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjRange.bz_getRangeProperty))), - .bz_getStringProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjString.bz_getStringProperty))), - .bz_getPatternProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjPattern.bz_getPatternProperty))), - .bz_getFiberProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjFiber.bz_getFiberProperty))), + .bz_getEnumCaseFromValue => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getEnumCaseFromValue))), + .bz_getEnumCase => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getEnumCase))), + .bz_enumNext => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_enumNext))), + .bz_getEnumInstanceValue => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getEnumInstanceValue))), + .bz_setObjectField => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_setObjectField))), + .bz_getObjectField => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getObjectField))), + .bz_getListProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_getListProperty))), + .bz_getMapProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_getMapProperty))), + .bz_getRangeProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getRangeProperty))), + .bz_getStringProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_getStringProperty))), + .bz_getPatternProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_getPatternProperty))), + .bz_getFiberProperty => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_getFiberProperty))), .bz_setTryCtx => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_setTryCtx))), .bz_popTryCtx => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_popTryCtx))), .bz_valueToCString => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueToCString))), - .bz_valueToUserData => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueToUserData))), - .bz_userDataToValue => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjUserData.bz_userDataToValue))), + .bz_getUserDataPtr => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_getUserDataPtr))), + .bz_newUserData => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newUserData))), .bz_valueToForeignContainerPtr => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueToForeignContainerPtr))), - .bz_stringZ => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjString.bz_stringZ))), - .bz_containerGet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjForeignContainer.bz_containerGet))), - .bz_containerSet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjForeignContainer.bz_containerSet))), - .bz_containerInstance => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjForeignContainer.bz_containerInstance))), + .bz_stringToValueZ => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_stringToValueZ))), + .bz_foreignContainerGet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_foreignContainerGet))), + .bz_foreignContainerSet => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_foreignContainerSet))), + .bz_newForeignContainerInstance => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newForeignContainerInstance))), .bz_valueTypeOf => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueTypeOf))), - .bz_containerFromSlice => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.ObjForeignContainer.bz_containerFromSlice))), - .memcpy => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.bz_memcpy))), + .bz_newForeignContainerFromSlice => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.VM.bz_newForeignContainerFromSlice))), .setjmp => @as( *anyopaque, @ptrFromInt( @@ -1099,9 +1162,9 @@ pub const ExternApi = enum { ), .exit => @as(*anyopaque, @ptrFromInt(@intFromPtr(&bz_exit))), - .dumpInt => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.dumpInt))), .bz_valueDump => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueDump))), .fmod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&JIT.fmod))), + .memcpy => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.bz_memcpy))), else => { io.print("{s}\n", .{self.name()}); unreachable; @@ -1115,9 +1178,9 @@ pub const ExternApi = enum { .nativefn => "NativeFn", .rawfn => "RawFn", - .bz_objStringConcat => "bz_objStringConcat", - .bz_objStringSubscript => "bz_objStringSubscript", - .bz_toString => "bz_toString", + .bz_stringConcat => "bz_stringConcat", + .bz_stringSubscript => "bz_stringSubscript", + .bz_valueCastToString => "bz_valueCastToString", .bz_newList => "bz_newList", .bz_newRange => "bz_newRange", .bz_rangeNext => "bz_rangeNext", @@ -1140,10 +1203,10 @@ pub const ExternApi = enum { .bz_closeUpValues => "bz_closeUpValues", .bz_closure => "bz_closure", .bz_context => "bz_context", - .bz_instance => "bz_instance", - .bz_setInstanceProperty => "bz_setInstanceProperty", - .bz_getInstanceProperty => "bz_getInstanceProperty", - .bz_getInstanceMethod => "bz_getInstanceMethod", + .bz_newObjectInstance => "bz_newObjectInstance", + .bz_setObjectInstanceProperty => "bz_setObjectInstanceProperty", + .bz_getObjectInstanceProperty => "bz_getObjectInstanceProperty", + .bz_getObjectInstanceMethod => "bz_getObjectInstanceMethod", .bz_getProtocolMethod => "bz_getProtocolMethod", .bz_setObjectField => "bz_setObjectField", .bz_getObjectField => "bz_getObjectField", @@ -1152,7 +1215,7 @@ pub const ExternApi = enum { .bz_getFiberProperty => "bz_getFiberProperty", .bz_getRangeProperty => "bz_getRangeProperty", .bz_getEnumCase => "bz_getEnumCase", - .bz_getEnumCaseValue => "bz_getEnumCaseValue", + .bz_getEnumInstanceValue => "bz_getEnumInstanceValue", .bz_getListProperty => "bz_getListProperty", .bz_getMapProperty => "bz_getMapProperty", .bz_getEnumCaseFromValue => "bz_getEnumCaseFromValue", @@ -1163,25 +1226,24 @@ pub const ExternApi = enum { .bz_enumNext => "bz_enumNext", .bz_clone => "bz_clone", .bz_valueToCString => "bz_valueToCString", - .bz_valueToUserData => "bz_valueToUserData", - .bz_userDataToValue => "bz_userDataToValue", + .bz_getUserDataPtr => "bz_getUserDataPtr", + .bz_newUserData => "bz_newUserData", .bz_valueToForeignContainerPtr => "bz_valueToForeignContainerPtr", - .bz_stringZ => "bz_stringZ", - .bz_containerGet => "bz_containerGet", - .bz_containerSet => "bz_containerSet", - .bz_containerInstance => "bz_containerInstance", + .bz_stringToValueZ => "bz_stringToValueZ", + .bz_foreignContainerGet => "bz_foreignContainerGet", + .bz_foreignContainerSet => "bz_foreignContainerSet", + .bz_newForeignContainerInstance => "bz_newForeignContainerInstance", .bz_valueTypeOf => "bz_valueTypeOf", - .bz_containerFromSlice => "bz_containerFromSlice", - .memcpy => "bz_memcpy", + .bz_newForeignContainerFromSlice => "bz_newForeignContainerFromSlice", .setjmp => if (builtin.os.tag == .macos or builtin.os.tag == .linux or builtin.os.tag == .windows) "_setjmp" else "setjmp", .exit => "bz_exit", .bz_dumpStack => "bz_dumpStack", - .dumpInt => "dumpInt", .bz_valueDump => "bz_valueDump", .fmod => "fmod", + .memcpy => "memcpy", }; } @@ -1190,9 +1252,9 @@ pub const ExternApi = enum { .nativefn => "p_NativeFn", .rawfn => "p_RawFn", - .bz_objStringConcat => "p_bz_objStringConcat", - .bz_objStringSubscript => "p_bz_objStringSubscript", - .bz_toString => "p_bz_toString", + .bz_stringConcat => "p_bconcatString", + .bz_stringSubscript => "p_bz_objStringSubscript", + .bz_valueCastToString => "p_bz_valueCastToString", .bz_newList => "p_bz_newList", .bz_newRange => "p_bz_newRange", .bz_rangeNext => "p_bz_rangeNext", @@ -1215,10 +1277,10 @@ pub const ExternApi = enum { .bz_closeUpValues => "p_bz_closeUpValues", .bz_closure => "p_bz_closure", .bz_context => "p_bz_context", - .bz_instance => "p_bz_instance", - .bz_setInstanceProperty => "p_bz_setInstanceProperty", - .bz_getInstanceProperty => "p_bz_getInstanceProperty", - .bz_getInstanceMethod => "p_bz_getInstanceMethod", + .bz_newObjectInstance => "p_bz_instance", + .bz_setObjectInstanceProperty => "p_bz_setInstanceProperty", + .bz_getObjectInstanceProperty => "p_bz_getInstanceProperty", + .bz_getObjectInstanceMethod => "p_bz_getInstanceMethod", .bz_getProtocolMethod => "p_bz_getProtocolMethod", .bz_setObjectField => "p_bz_setObjectField", .bz_getObjectField => "p_bz_getObjectField", @@ -1227,7 +1289,7 @@ pub const ExternApi = enum { .bz_getFiberProperty => "p_bz_getFiberProperty", .bz_getRangeProperty => "p_bz_getRangeProperty", .bz_getEnumCase => "p_bz_getEnumCase", - .bz_getEnumCaseValue => "p_bz_getEnumCaseValue", + .bz_getEnumInstanceValue => "p_bz_getEnumCaseValue", .bz_getListProperty => "p_bz_getListProperty", .bz_getMapProperty => "p_bz_getMapProperty", .bz_getEnumCaseFromValue => "p_bz_getEnumCaseFromValue", @@ -1238,25 +1300,24 @@ pub const ExternApi = enum { .bz_enumNext => "p_bz_enumNext", .bz_clone => "p_bz_clone", .bz_valueToCString => "p_bz_valueToCString", - .bz_valueToUserData => "p_bz_valueToUserData", - .bz_userDataToValue => "p_bz_userDataToValue", + .bz_getUserDataPtr => "p_bz_getUserDataPtr", + .bz_newUserData => "p_bz_userDataToValue", .bz_valueToForeignContainerPtr => "p_bz_valueToForeignContainerPtr", - .bz_stringZ => "p_bz_stringZ", - .bz_containerGet => "p_bz_containerGet", - .bz_containerSet => "p_bz_containerSet", - .bz_containerInstance => "p_bz_containerInstance", + .bz_stringToValueZ => "p_bz_stringZ", + .bz_foreignContainerGet => "p_bz_containerGet", + .bz_foreignContainerSet => "p_bz_containerSet", + .bz_newForeignContainerInstance => "p_bz_containerInstance", .bz_valueTypeOf => "p_bz_valueTypeOf", - .bz_containerFromSlice => "p_bz_containerFromSlice", - .memcpy => "p_bz_memcpy", + .bz_newForeignContainerFromSlice => "p_bz_containerFromSlice", .setjmp => if (builtin.os.tag == .macos or builtin.os.tag == .linux or builtin.os.windows) "p__setjmp" else "p_setjmp", .exit => "p_exit", .bz_dumpStack => "p_bz_dumpStack", - .dumpInt => "p_dumpInt", .bz_valueDump => "p_bz_valueDump", .fmod => "p_fmod", + .memcpy => "p_memcpy", }; } }; diff --git a/src/lib/buzz_api.zig b/src/lib/buzz_api.zig index 548a6b4f..e4c9bd36 100644 --- a/src/lib/buzz_api.zig +++ b/src/lib/buzz_api.zig @@ -12,201 +12,36 @@ else pub const Native = fn (ctx: *NativeCtx) callconv(.C) c_int; pub const NativeFn = *const Native; -// FIXME: all those should operate on Value -// FIXME: some should only be available to the JIT compiler -// FIXME: naming is not consistant - -pub extern fn bz_memcpy(dest: [*]u8, dest_len: usize, source: [*]u8, source_len: usize) void; - -pub const ObjUpValue = opaque {}; - -pub const ObjNative = opaque { - pub extern fn bz_toObjNative(value: Value) *ObjNative; -}; - -pub const ObjFunction = opaque {}; - -pub const NativeCtx = extern struct { - vm: *VM, - globals: [*]Value, - upvalues: [*]*ObjUpValue, - // Pointer to the stack_top field of the current fiber - // !! Needs to change when current fiber changes !! - stack_top: *[*]Value, -}; - -pub const TryCtx = extern struct { - previous: ?*TryCtx, - env: jmp.jmp_buf = undefined, -}; - -pub const ZigType = opaque { - pub extern fn bz_zigTypeSize(self: *ZigType) usize; - pub extern fn bz_zigTypeAlignment(self: *ZigType) u16; -}; - -var gpa = std.heap.GeneralPurposeAllocator(.{ - .safety = builtin.mode == .Debug, -}){}; - -pub const VM = opaque { - pub const allocator = if (builtin.mode == .Debug or is_wasm) - gpa.allocator() - else if (BuildOptions.mimalloc) - @import("mimalloc.zig").mim_allocator - else - std.heap.c_allocator; - - pub extern fn bz_newVM(self: *VM) *VM; - pub extern fn bz_deinitVM(self: *VM) void; - pub extern fn bz_panic(vm: *VM, msg: [*]const u8, len: usize) void; - pub extern fn bz_compile( - self: *VM, - source: ?[*]const u8, - source_len: usize, - file_name: ?[*]const u8, - file_name_len: usize, - ) ?*ObjFunction; - pub extern fn bz_interpret(self: *VM, ast: *anyopaque, function: *ObjFunction) bool; - pub extern fn bz_run( - self: *VM, - source: ?[*]const u8, - source_len: usize, - file_name: ?[*]const u8, - file_name_len: usize, - ) bool; - pub extern fn bz_call( - self: *VM, - closure: *ObjClosure, - arguments: ?[*]const *const Value, - len: usize, - catch_value: ?*Value, - ) void; - pub extern fn bz_push(self: *VM, value: Value) void; - pub extern fn bz_pop(self: *VM) Value; - pub extern fn bz_peek(self: *VM, distance: u32) Value; - pub extern fn bz_pushBool(self: *VM, value: bool) void; - pub extern fn bz_pushFloat(self: *VM, value: f64) void; - pub extern fn bz_pushInteger(self: *VM, value: i32) void; - pub extern fn bz_pushString(self: *VM, value: *ObjString) void; - pub extern fn bz_pushList(self: *VM, value: *ObjList) void; - pub extern fn bz_pushUserData(self: *VM, value: *ObjUserData) void; - pub extern fn bz_pushNull(self: *VM) void; - pub extern fn bz_pushVoid(self: *VM) void; - pub extern fn bz_pushObjectInstance(vm: *VM, payload: *ObjObjectInstance) void; - pub extern fn bz_pushEnumInstance(vm: *VM, payload: *ObjEnumInstance) void; - pub extern fn bz_pushError( - self: *VM, - qualified_name: [*]const u8, - len: usize, - message: ?[*]const u8, - mlen: usize, - ) void; - pub extern fn bz_pushErrorEnum(self: *VM, qualified_name: [*]const u8, name_len: usize, case: [*]const u8, case_len: usize) void; - pub extern fn bz_zigValueSize(ztype: *ZigType) usize; - pub extern fn bz_writeZigValueToBuffer( - vm: *VM, - value: Value, - ztype: *ZigType, - at: usize, - buf: [*]u8, - capacity: usize, - ) void; - pub extern fn bz_readZigValueFromBuffer( - vm: *VM, - ztype: *ZigType, - at: usize, - buf: [*]u8, - len: usize, - ) Value; - pub extern fn bz_checkBuzzType( - vm: *VM, - value: Value, - ztype: *ZigType, - btype: Value, - ) bool; - - pub inline fn pushError(self: *VM, qualified_name: []const u8, message: ?[]const u8) void { - self.bz_pushError( - qualified_name.ptr, - qualified_name.len, - if (message) |m| m.ptr else null, - if (message) |m| m.len else 0, - ); - } - - pub inline fn pushErrorEnum(self: *VM, qualified_name: []const u8, case: []const u8) void { - self.bz_pushErrorEnum( - qualified_name.ptr, - qualified_name.len, - case.ptr, - case.len, - ); - } - - pub extern fn bz_serialize(vm: *VM, value: Value, error_value: *Value) Value; - - pub extern fn bz_throw(vm: *VM, value: Value) void; - pub extern fn bz_rethrow(vm: *VM) void; - pub extern fn bz_getQualified(self: *VM, qualified_name: [*]const u8, len: usize) Value; - - pub extern fn bz_allocated(self: *VM) usize; - pub extern fn bz_collect(self: *VM) bool; - - pub extern fn bz_setTryCtx(self: *VM) *TryCtx; - pub extern fn bz_popTryCtx(self: *VM) void; - - pub extern fn bz_closeUpValues(vm: *VM, last: *Value) void; - pub extern fn bz_getUpValue(ctx: *NativeCtx, slot: usize) Value; - pub extern fn bz_setUpValue(ctx: *NativeCtx, slot: usize, value: Value) void; - pub extern fn bz_closure(ctx: *NativeCtx, function_node: *FunctionNode, native: *anyopaque, native_raw: *anyopaque) Value; - pub extern fn bz_bindMethod(vm: *VM, receiver: Value, method_value: Value, native_value: Value) Value; - pub extern fn bz_context(ctx: *NativeCtx, closure_value: Value, new_ctx: *NativeCtx, arg_count: usize) *anyopaque; - pub extern fn bz_clone(vm: *VM, value: Value) Value; - pub extern fn bz_currentFiber(vm: *VM) Value; - - pub extern fn bz_dumpStack(vm: *VM) void; - - pub extern fn bz_zigType( - vm: *VM, - ztype: [*]const u8, - len: usize, - expected_type: *Value, - ) ?*ZigType; -}; - -pub const FunctionNode = opaque {}; - // FIXME: can we avoid duplicating this code from value.zig? const Tag = u3; -pub const TagBoolean: Tag = 0; -pub const TagInteger: Tag = 1; -pub const TagNull: Tag = 2; -pub const TagVoid: Tag = 3; -pub const TagObj: Tag = 4; -pub const TagError: Tag = 5; +const TagBoolean: Tag = 0; +const TagInteger: Tag = 1; +const TagNull: Tag = 2; +const TagVoid: Tag = 3; +const TagObj: Tag = 4; +const TagError: Tag = 5; /// Most significant bit. -pub const SignMask: u64 = 1 << 63; +const SignMask: u64 = 1 << 63; /// QNAN and one extra bit to the right. -pub const TaggedValueMask: u64 = 0x7ffc000000000000; +const TaggedValueMask: u64 = 0x7ffc000000000000; /// TaggedMask + Sign bit indicates a pointer value. -pub const PointerMask: u64 = TaggedValueMask | SignMask; +const PointerMask: u64 = TaggedValueMask | SignMask; -pub const BooleanMask: u64 = TaggedValueMask | (@as(u64, TagBoolean) << 32); -pub const FalseMask: u64 = BooleanMask; -pub const TrueBitMask: u64 = 1; -pub const TrueMask: u64 = BooleanMask | TrueBitMask; +const BooleanMask: u64 = TaggedValueMask | (@as(u64, TagBoolean) << 32); +const FalseMask: u64 = BooleanMask; +const TrueBitMask: u64 = 1; +const TrueMask: u64 = BooleanMask | TrueBitMask; -pub const IntegerMask: u64 = TaggedValueMask | (@as(u64, TagInteger) << 32); -pub const NullMask: u64 = TaggedValueMask | (@as(u64, TagNull) << 32); -pub const VoidMask: u64 = TaggedValueMask | (@as(u64, TagVoid) << 32); -pub const ErrorMask: u64 = TaggedValueMask | (@as(u64, TagError) << 32); +const IntegerMask: u64 = TaggedValueMask | (@as(u64, TagInteger) << 32); +const NullMask: u64 = TaggedValueMask | (@as(u64, TagNull) << 32); +const VoidMask: u64 = TaggedValueMask | (@as(u64, TagVoid) << 32); +const ErrorMask: u64 = TaggedValueMask | (@as(u64, TagError) << 32); -pub const TagMask: u32 = (1 << 3) - 1; -pub const TaggedPrimitiveMask = TaggedValueMask | (@as(u64, TagMask) << 32); +const TagMask: u32 = (1 << 3) - 1; +const TaggedPrimitiveMask = TaggedValueMask | (@as(u64, TagMask) << 32); pub const Value = packed struct { val: u64, @@ -286,120 +121,142 @@ pub const Value = packed struct { return @ptrFromInt(self.val & ~PointerMask); } - pub extern fn bz_valueToObject(value: Value) *ObjObject; - pub extern fn bz_valueToObjectInstance(value: Value) *ObjObjectInstance; - pub extern fn bz_valueToObjEnumInstance(value: Value) *ObjEnumInstance; - pub extern fn bz_valueToObjFiber(value: Value) *ObjFiber; - pub extern fn bz_valueToObjList(value: Value) *ObjList; - pub extern fn bz_valueToObjMap(value: Value) *ObjMap; - pub extern fn bz_valueToObjPattern(value: Value) *ObjPattern; - pub extern fn bz_valueToObjString(value: Value) *ObjString; pub extern fn bz_valueToString(value: Value, len: *usize) ?[*]const u8; pub extern fn bz_valueToCString(value: Value) ?[*:0]const u8; - pub extern fn bz_valueToObjUserData(value: Value) *ObjUserData; - pub extern fn bz_valueToUserData(value: Value) u64; - pub extern fn bz_valueToObjTypeDef(value: Value) *ObjTypeDef; pub extern fn bz_valueToForeignContainerPtr(value: Value) [*]u8; - pub extern fn bz_valueDump(value: Value, vm: *VM) void; - - pub extern fn bz_valueToClosure(value: Value) *ObjClosure; pub extern fn bz_valueEqual(self: Value, other: Value) Value; pub extern fn bz_valueIs(self: Value, type_def: Value) Value; pub extern fn bz_valueTypeOf(self: Value, vm: *VM) Value; -}; - -pub const ObjClosure = opaque {}; - -pub const ObjTypeDef = opaque { - pub extern fn bz_stringType(vm: *VM) Value; - pub extern fn bz_mapType(vm: *VM, key_type: Value, value_type: Value) Value; - pub extern fn bz_containerTypeSize(self: *ObjTypeDef) usize; - pub extern fn bz_containerTypeAlign(type_def: *ObjTypeDef) usize; -}; - -pub const ObjString = opaque { - pub extern fn bz_string(vm: *VM, string: ?[*]const u8, len: usize) ?*ObjString; - pub extern fn bz_stringZ(vm: *VM, string: ?[*:0]const u8) ?*ObjString; - pub extern fn bz_objStringToString(obj_string: *ObjString, len: *usize) ?[*]const u8; - pub extern fn bz_objStringToValue(obj_string: *ObjString) Value; - pub extern fn bz_objStringConcat(vm: *VM, obj_string: Value, other: Value) Value; - pub extern fn bz_objStringSubscript(vm: *VM, obj_string: Value, index_value: Value, checked: bool) Value; - pub extern fn bz_toString(vm: *VM, value: Value) Value; - pub extern fn bz_getStringProperty(vm: *VM, method_idx: usize) Value; - pub extern fn bz_stringNext(vm: *VM, string_value: Value, index: *Value) Value; -}; - -pub const ObjRange = opaque { - pub extern fn bz_newRange(vm: *VM, low: i32, high: i32) Value; + pub extern fn bz_getUserDataPtr(userdata: Value) u64; + pub extern fn bz_containerTypeSize(container: Value) usize; + pub extern fn bz_containerTypeAlign(type_def: Value) usize; + pub extern fn bz_valueCastToString(value: Value, vm: *VM) Value; + pub extern fn bz_stringConcat(string: Value, other: Value, vm: *VM) Value; + pub extern fn bz_stringSubscript(obj_string: Value, index_value: Value, checked: bool, vm: *VM) Value; + pub extern fn bz_stringNext(string_value: Value, index: *Value, vm: *VM) Value; pub extern fn bz_rangeNext(range_value: Value, index_slot: Value) Value; - pub extern fn bz_getRangeProperty(vm: *VM, range_value: Value, property_idx: usize, bind: bool) Value; -}; - -pub const ObjList = opaque { - pub extern fn bz_newList(vm: *VM, of_type: Value) Value; - pub extern fn bz_listAppend(vm: *VM, list: Value, value: Value) void; - pub extern fn bz_valueToList(value: Value) *ObjList; - pub extern fn bz_listGet(self: Value, index: i32, checked: bool) Value; - pub extern fn bz_listSet(vm: *VM, self: Value, index: usize, value: Value) void; - pub extern fn bz_listLen(self: *ObjList) usize; - pub extern fn bz_listConcat(vm: *VM, list: Value, other_list: Value) Value; - pub extern fn bz_getListProperty(vm: *VM, list_value: Value, property_idx: usize, bind: bool) Value; - pub extern fn bz_listNext(vm: *VM, list_value: Value, index: *Value) Value; -}; - -pub const ObjMap = opaque { - pub extern fn bz_newMap(vm: *VM, map_type: Value) Value; - pub extern fn bz_mapSet(vm: *VM, map: Value, key: Value, value: Value) void; + pub extern fn bz_getRangeProperty(range_value: Value, property_idx: usize, bind: bool, vm: *VM) Value; + pub extern fn bz_listAppend(list: Value, value: Value, vm: *VM) void; + pub extern fn bz_listGet(list: Value, index: i32, checked: bool) Value; + pub extern fn bz_listSet(list: Value, index: usize, value: Value, vm: *VM) void; + pub extern fn bz_listLen(list: Value) usize; + pub extern fn bz_listConcat(list: Value, other_list: Value, vm: *VM) Value; + pub extern fn bz_listNext(list_value: Value, index: *Value, vm: *VM) Value; + pub extern fn bz_mapSet(map: Value, key: Value, value: Value, vm: *VM) void; pub extern fn bz_mapGet(map: Value, key: Value) Value; - pub extern fn bz_mapConcat(vm: *VM, map: Value, other_map: Value) Value; - pub extern fn bz_getMapProperty(vm: *VM, map_value: Value, property_idx: usize, bind: bool) Value; - pub extern fn bz_mapNext(vm: *VM, map_value: Value, index: *Value) Value; -}; - -pub const ObjUserData = opaque { - pub extern fn bz_newUserData(vm: *VM, userdata: u64) ?*ObjUserData; - pub extern fn bz_userDataToValue(userdata: *ObjUserData) Value; - pub extern fn bz_getUserDataPtr(userdata: *ObjUserData) u64; -}; - -pub const ObjObjectInstance = opaque {}; - -pub const ObjObject = opaque { - pub extern fn bz_instanceQualified(self: *VM, qualified_name: [*]const u8, len: usize) Value; - pub extern fn bz_instance(vm: *VM, object_value: Value, typedef_value: Value) Value; - pub extern fn bz_setInstanceProperty(vm: *VM, instance_value: Value, property_idx: usize, value: Value) void; - pub extern fn bz_getInstanceProperty(vm: *VM, instance_value: Value, property_idx: usize) Value; - pub extern fn bz_getInstanceMethod(vm: *VM, instance_value: Value, method_idx: usize, bind: bool) Value; - pub extern fn bz_getProtocolMethod(vm: *VM, instance_value: Value, method_name: Value) Value; + pub extern fn bz_mapConcat(map: Value, other_map: Value, vm: *VM) Value; + pub extern fn bz_mapNext(map_value: Value, index: *Value) Value; + pub extern fn bz_setObjectInstanceProperty(instance_value: Value, property_idx: usize, value: Value, vm: *VM) void; + pub extern fn bz_getObjectInstanceProperty(instance_value: Value, property_idx: usize) Value; + pub extern fn bz_getObjectInstanceMethod(instance_value: Value, method_idx: usize, bind: bool, vm: *VM) Value; + pub extern fn bz_getProtocolMethod(instance_value: Value, method_name: Value, vm: *VM) Value; pub extern fn bz_getObjectField(object_value: Value, field_idx: usize) Value; - pub extern fn bz_setObjectField(vm: *VM, object_value: Value, field_idx: usize, value: Value) void; + pub extern fn bz_setObjectField(object_value: Value, field_idx: usize, value: Value, vm: *VM) void; + pub extern fn bz_getEnumInstanceValue(enum_instance_value: Value) Value; + pub extern fn bz_getEnumCase(enum_value: Value, case_name_value: Value, vm: *VM) Value; + pub extern fn bz_getEnumCaseFromValue(enum_value: Value, case_value: Value, vm: *VM) Value; + pub extern fn bz_enumNext(enum_value: Value, case: Value, vm: *VM) Value; + pub extern fn bz_foreignContainerGet(value: Value, field_idx: usize, vm: *VM) Value; + pub extern fn bz_foreignContainerSet(value: Value, field_idx: usize, new_value: Value, vm: *VM) void; + pub extern fn bz_foreignContainerSlice(container_value: Value, len: *usize) [*]u8; }; -pub const ObjEnumInstance = opaque { - pub extern fn bz_getEnumCaseValue(enum_instance_value: Value) Value; +pub const NativeCtx = extern struct { + vm: *VM, + globals: [*]Value, + upvalues: [*]*anyopaque, + // Pointer to the stack_top field of the current fiber + // !! Needs to change when current fiber changes !! + stack_top: *[*]Value, }; -pub const ObjEnum = opaque { - pub extern fn bz_getEnumCase(vm: *VM, enum_value: Value, case_name_value: Value) Value; - pub extern fn bz_getEnumCaseFromValue(vm: *VM, enum_value: Value, case_value: Value) Value; - pub extern fn bz_enumNext(vm: *VM, enum_value: Value, case: Value) Value; +pub const TryCtx = extern struct { + previous: ?*TryCtx, + env: jmp.jmp_buf = undefined, }; -pub const ObjPattern = opaque { - pub extern fn bz_getPatternProperty(vm: *VM, property_idx: usize) Value; +pub const ZigType = opaque { + pub extern fn bz_zigTypeSize(self: *ZigType) usize; + pub extern fn bz_zigTypeAlignment(self: *ZigType) u16; + pub extern fn bz_zigTypeToCString(self: *ZigType, vm: *VM) [*:0]const u8; }; -pub const ObjFiber = opaque { - pub extern fn bz_getFiberProperty(vm: *VM, property_idx: usize) Value; -}; +pub const VM = opaque { + var gpa = std.heap.GeneralPurposeAllocator(.{ + .safety = builtin.mode == .Debug, + }){}; -pub const ObjForeignContainer = opaque { - pub extern fn bz_containerGet(vm: *VM, value: Value, field_idx: usize) Value; - pub extern fn bz_containerSet(vm: *VM, value: Value, field_idx: usize, new_value: Value) void; - pub extern fn bz_containerInstance(vm: *VM, typedef_value: Value) Value; - pub extern fn bz_containerSlice(container_value: Value, len: *usize) [*]u8; - pub extern fn bz_containerFromSlice(vm: *VM, type_def: *ObjTypeDef, ptr: [*]u8, len: usize) Value; + pub const allocator = if (builtin.mode == .Debug or is_wasm) + gpa.allocator() + else if (BuildOptions.mimalloc) + @import("mimalloc.zig").mim_allocator + else + std.heap.c_allocator; + + pub extern fn bz_newVM(self: *VM) *VM; + pub extern fn bz_deinitVM(self: *VM) void; + pub extern fn bz_panic(vm: *VM, msg: [*]const u8, len: usize) void; + pub extern fn bz_run(self: *VM, source: ?[*]const u8, source_len: usize, file_name: ?[*]const u8, file_name_len: usize) bool; + pub extern fn bz_call(self: *VM, closure: Value, arguments: ?[*]const *const Value, len: usize, catch_value: ?*Value) void; + pub extern fn bz_push(self: *VM, value: Value) void; + pub extern fn bz_pop(self: *VM) Value; + pub extern fn bz_peek(self: *VM, distance: u32) Value; + pub extern fn bz_pushError(self: *VM, qualified_name: [*]const u8, len: usize, message: ?[*]const u8, mlen: usize) void; + pub extern fn bz_pushErrorEnum(self: *VM, qualified_name: [*]const u8, name_len: usize, case: [*]const u8, case_len: usize) void; + pub extern fn bz_stringToValue(vm: *VM, string: ?[*]const u8, len: usize) Value; + pub extern fn bz_stringToValueZ(vm: *VM, string: ?[*:0]const u8) Value; + pub extern fn bz_newUserData(vm: *VM, userdata: u64) Value; + pub inline fn pushError(self: *VM, qualified_name: []const u8, message: ?[]const u8) void { + self.bz_pushError( + qualified_name.ptr, + qualified_name.len, + if (message) |m| m.ptr else null, + if (message) |m| m.len else 0, + ); + } + pub inline fn pushErrorEnum(self: *VM, qualified_name: []const u8, case: []const u8) void { + self.bz_pushErrorEnum( + qualified_name.ptr, + qualified_name.len, + case.ptr, + case.len, + ); + } + pub extern fn bz_serialize(vm: *VM, value: Value, error_value: *Value) Value; + pub extern fn bz_throw(vm: *VM, value: Value) void; + pub extern fn bz_rethrow(vm: *VM) void; + pub extern fn bz_getQualified(self: *VM, qualified_name: [*]const u8, len: usize) Value; + pub extern fn bz_allocated(self: *VM) usize; + pub extern fn bz_collect(self: *VM) bool; + pub extern fn bz_setTryCtx(self: *VM) *TryCtx; + pub extern fn bz_popTryCtx(self: *VM) void; + pub extern fn bz_closeUpValues(vm: *VM, last: *Value) void; + pub extern fn bz_getUpValue(ctx: *NativeCtx, slot: usize) Value; + pub extern fn bz_setUpValue(ctx: *NativeCtx, slot: usize, value: Value) void; + pub extern fn bz_closure(ctx: *NativeCtx, function_node: u32, native: *anyopaque, native_raw: *anyopaque) Value; + pub extern fn bz_bindMethod(vm: *VM, receiver: Value, method_value: Value, native_value: Value) Value; + pub extern fn bz_context(ctx: *NativeCtx, closure_value: Value, new_ctx: *NativeCtx, arg_count: usize) *anyopaque; + pub extern fn bz_clone(vm: *VM, value: Value) Value; + pub extern fn bz_currentFiber(vm: *VM) Value; + pub extern fn bz_dumpStack(vm: *VM) void; + pub extern fn bz_zigType(vm: *VM, ztype: [*]const u8, len: usize, expected_type: *Value) ?*ZigType; + pub extern fn bz_stringType(vm: *VM) Value; + pub extern fn bz_mapType(vm: *VM, key_type: Value, value_type: Value) Value; + pub extern fn bz_getStringProperty(vm: *VM, string: Value, method_idx: usize) Value; + pub extern fn bz_getListProperty(vm: *VM, list: Value, property_idx: usize, bind: bool) Value; + pub extern fn bz_getMapProperty(vm: *VM, map: Value, property_idx: usize, bind: bool) Value; + pub extern fn bz_getPatternProperty(vm: *VM, pattern: Value, property_idx: usize) Value; + pub extern fn bz_getFiberProperty(vm: *VM, fiber: Value, property_idx: usize) Value; + pub extern fn bz_newRange(vm: *VM, low: i32, high: i32) Value; + pub extern fn bz_newList(vm: *VM, of_type: Value) Value; + pub extern fn bz_newMap(vm: *VM, map_type: Value) Value; + pub extern fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize) Value; + pub extern fn bz_newObjectInstance(vm: *VM, object_value: Value, typedef_value: Value) Value; + pub extern fn bz_newForeignContainerInstance(vm: *VM, typedef_value: Value) Value; + pub extern fn bz_newForeignContainerFromSlice(vm: *VM, type_def: Value, ptr: [*]u8, len: usize) Value; + pub extern fn bz_readZigValueFromBuffer(vm: *VM, ztype: *ZigType, at: usize, buf: [*]u8, len: usize) Value; + pub extern fn bz_writeZigValueToBuffer(vm: *VM, value: Value, ztype: *const ZigType, at: usize, buf: [*]u8, capacity: usize) void; }; -pub extern fn dumpInt(value: u64) void; +pub extern fn bz_memcpy(dest: [*]u8, dest_len: usize, source: [*]u8, source_len: usize) void; diff --git a/src/lib/buzz_buffer.zig b/src/lib/buzz_buffer.zig index a4f49afb..48113cce 100644 --- a/src/lib/buzz_buffer.zig +++ b/src/lib/buzz_buffer.zig @@ -22,18 +22,18 @@ pub export fn BufferNew(ctx: *api.NativeCtx) c_int { unreachable; }; - if (api.ObjUserData.bz_newUserData(ctx.vm, @intFromPtr(buffer))) |userdata| { - ctx.vm.bz_pushUserData(userdata); + ctx.vm.bz_push( + api.VM.bz_newUserData( + ctx.vm, + @intFromPtr(buffer), + ), + ); - return 1; - } else { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - } + return 1; } pub export fn BufferDeinit(ctx: *api.NativeCtx) c_int { - const userdata = ctx.vm.bz_peek(0).bz_valueToUserData(); + const userdata = ctx.vm.bz_peek(0).bz_getUserDataPtr(); var buffer = Buffer.fromUserData(userdata); @@ -161,7 +161,7 @@ const Buffer = struct { try writer.writeInt(i32, integer, native_endian); } - pub fn readUserData(self: *Self, vm: *api.VM) !?*api.ObjUserData { + pub fn readUserData(self: *Self, vm: *api.VM) !?api.Value { if (self.cursor > self.buffer.items.len) { return null; } @@ -173,10 +173,10 @@ const Buffer = struct { self.cursor += @sizeOf(u64); - return api.ObjUserData.bz_newUserData(vm, number); + return vm.bz_newUserData(number); } - pub fn writeUserData(self: *Self, userdata: *api.ObjUserData) !void { + pub fn writeUserData(self: *Self, userdata: api.Value) !void { if (self.cursor > 0) { return Error.WriteWhileReading; } @@ -228,25 +228,29 @@ const Buffer = struct { }; pub export fn BufferRead(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const n = ctx.vm.bz_peek(0).integer(); const read_slice = buffer.read(@intCast(n)); if (read_slice) |uread_slice| { - if (api.ObjString.bz_string(ctx.vm, if (uread_slice.len > 0) @as([*]const u8, @ptrCast(uread_slice)) else null, uread_slice.len)) |obj_string| { - ctx.vm.bz_pushString(obj_string); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (uread_slice.len > 0) @as([*]const u8, @ptrCast(uread_slice)) else null, + uread_slice.len, + ), + ); - return 1; - } + return 1; } - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; } pub export fn BufferWrite(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); var len: usize = 0; var bytes = ctx.vm.bz_peek(0).bz_valueToString(&len); @@ -270,7 +274,7 @@ pub export fn BufferWrite(ctx: *api.NativeCtx) c_int { } pub export fn BufferSetAt(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_getUserDataPtr()); const index = ctx.vm.bz_peek(1).integer(); const value = ctx.vm.bz_peek(0).integer(); @@ -286,19 +290,19 @@ pub export fn BufferSetAt(ctx: *api.NativeCtx) c_int { } pub export fn BufferReadBoolean(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); if (buffer.readBool()) |value| { - ctx.vm.bz_pushBool(value); + ctx.vm.bz_push(api.Value.fromBoolean(value)); } else { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); } return 1; } pub export fn BufferWriteBoolean(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const value = ctx.vm.bz_peek(0).boolean(); buffer.writeBool(value) catch |err| { @@ -317,70 +321,70 @@ pub export fn BufferWriteBoolean(ctx: *api.NativeCtx) c_int { } pub export fn BufferReadInt(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); if (buffer.readInteger() catch |err| { switch (err) { error.EndOfStream => { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; }, } }) |value| { - ctx.vm.bz_pushInteger(value); + ctx.vm.bz_push(api.Value.fromInteger(value)); return 1; } - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; } pub export fn BufferReadUserData(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); if (buffer.readUserData(ctx.vm) catch |err| { switch (err) { error.EndOfStream => { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; }, } }) |value| { - ctx.vm.bz_push(value.bz_userDataToValue()); + ctx.vm.bz_push(value); return 1; } - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; } pub export fn BufferReadFloat(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); if (buffer.readFloat() catch |err| { switch (err) { error.EndOfStream => { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; }, } }) |value| { - ctx.vm.bz_pushFloat(value); + ctx.vm.bz_push(api.Value.fromFloat(value)); return 1; } - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; } pub export fn BufferWriteInt(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const number = ctx.vm.bz_peek(0); buffer.writeInteger(number.integer()) catch |err| { @@ -399,10 +403,10 @@ pub export fn BufferWriteInt(ctx: *api.NativeCtx) c_int { } pub export fn BufferWriteUserData(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const userdata = ctx.vm.bz_peek(0); - buffer.writeUserData(userdata.bz_valueToObjUserData()) catch |err| { + buffer.writeUserData(userdata) catch |err| { switch (err) { Buffer.Error.WriteWhileReading => ctx.vm.pushError("buffer.WriteWhileReadingError", null), error.OutOfMemory => { @@ -418,7 +422,7 @@ pub export fn BufferWriteUserData(ctx: *api.NativeCtx) c_int { } pub export fn BufferWriteFloat(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const number = ctx.vm.bz_peek(0); buffer.writeFloat(number.float()) catch |err| { @@ -437,7 +441,7 @@ pub export fn BufferWriteFloat(ctx: *api.NativeCtx) c_int { } pub export fn BufferEmpty(ctx: *api.NativeCtx) c_int { - var buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + var buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); buffer.empty(); @@ -445,71 +449,103 @@ pub export fn BufferEmpty(ctx: *api.NativeCtx) c_int { } pub export fn BufferLen(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const buf_align = ctx.vm.bz_peek(0).integer(); - ctx.vm.bz_pushInteger(@intCast(buffer.buffer.items.len / @as(usize, @intCast(buf_align)))); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(buffer.buffer.items.len / @as(usize, @intCast(buf_align))))); return 1; } pub export fn BufferCursor(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); - ctx.vm.bz_pushInteger(@intCast(buffer.cursor)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(buffer.cursor))); return 1; } pub export fn BufferBuffer(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); - if (api.ObjString.bz_string(ctx.vm, if (buffer.buffer.items.len > 0) @as( - [*]const u8, - @ptrCast(buffer.buffer.items), - ) else null, buffer.buffer.items.len)) |objstring| { - ctx.vm.bz_pushString(objstring); - } else { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - } + ctx.vm.bz_push( + ctx.vm.bz_stringToValue( + if (buffer.buffer.items.len > 0) + @as([*]const u8, @ptrCast(buffer.buffer.items)) + else + null, + buffer.buffer.items.len, + ), + ); return 1; } pub export fn BufferPtr(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_getUserDataPtr()); const at = ctx.vm.bz_peek(1).integer(); const alignment = ctx.vm.bz_peek(0).integer(); ctx.vm.bz_push( - api.ObjUserData.bz_newUserData( - ctx.vm, + ctx.vm.bz_newUserData( @intFromPtr(&buffer.buffer.items.ptr[@intCast(at * alignment)]), - ).?.bz_userDataToValue(), + ), ); return 1; } pub export fn BufferAt(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const number = ctx.vm.bz_peek(0).integer(); - ctx.vm.bz_pushInteger(buffer.at(@intCast(number))); + ctx.vm.bz_push(api.Value.fromInteger(buffer.at(@intCast(number)))); return 1; } +fn checkBuzzType( + vm: *api.VM, + value: api.Value, + ztype: *api.ZigType, + btype: api.Value, +) bool { + if (!value.bz_valueIs(btype).boolean()) { + var err = std.ArrayList(u8).init(api.VM.allocator); + defer err.deinit(); + + err.writer().print( + "Expected buzz value of type `{s}` to match FFI type `{s}`", + .{ + btype.bz_valueCastToString(vm).bz_valueToCString().?, + ztype.bz_zigTypeToCString(vm), + }, + ) catch { + const msg = "Out of memory"; + vm.bz_panic(msg.ptr, msg.len); + unreachable; + }; + + vm.bz_pushError( + "ffi.FFITypeMismatchError", + "ffi.FFITypeMismatchError".len, + err.items.ptr, + err.items.len, + ); + + return false; + } + + return true; +} + fn rawWriteZ( ctx: *api.NativeCtx, buffer: *Buffer, ztype: []const u8, at: usize, - values_value: api.Value, + values: api.Value, ) bool { - const values = api.Value.bz_valueToObjList(values_value); - var obj_typedef: api.Value = undefined; const zig_type = ctx.vm.bz_zigType( @ptrCast(ztype), @@ -519,17 +555,16 @@ fn rawWriteZ( var index = at; for (0..values.bz_listLen()) |i| { - const value = api.ObjList.bz_listGet( - values_value, + const value = values.bz_listGet( @intCast(i), false, ); - if (!ctx.vm.bz_checkBuzzType(value, zig_type.?, obj_typedef)) { + if (!checkBuzzType(ctx.vm, value, zig_type.?, obj_typedef)) { return false; } - const len = api.VM.bz_zigValueSize(zig_type.?); + const len = zig_type.?.bz_zigTypeSize(); buffer.buffer.ensureTotalCapacityPrecise(buffer.buffer.items.len + len) catch { ctx.vm.bz_panic("Out of memory", "Out of memory".len); @@ -554,9 +589,9 @@ fn rawWriteZ( } pub export fn BufferWriteZ(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_getUserDataPtr()); var len: usize = 0; - const ztype = ctx.vm.bz_peek(1).bz_valueToObjString().bz_objStringToString(&len).?; + const ztype = ctx.vm.bz_peek(1).bz_valueToString(&len).?; const values = ctx.vm.bz_peek(0); return if (!rawWriteZ( @@ -569,10 +604,10 @@ pub export fn BufferWriteZ(ctx: *api.NativeCtx) c_int { } pub export fn BufferWriteZAt(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(3).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(3).bz_getUserDataPtr()); const index = ctx.vm.bz_peek(2).integer(); var len: usize = 0; - const ztype = ctx.vm.bz_peek(1).bz_valueToObjString().bz_objStringToString(&len).?; + const ztype = ctx.vm.bz_peek(1).bz_valueToString(&len).?; const values = ctx.vm.bz_peek(0); return if (!rawWriteZ( @@ -589,14 +624,11 @@ fn rawWriteStruct( buffer: *Buffer, at: usize, type_def_value: api.Value, - values_value: api.Value, + values: api.Value, ) bool { - const values = api.Value.bz_valueToObjList(values_value); - var index = at; for (0..values.bz_listLen()) |i| { - const value = api.ObjList.bz_listGet( - values_value, + const value = values.bz_listGet( @intCast(i), false, ); @@ -616,7 +648,7 @@ fn rawWriteStruct( } var len: usize = 0; - const ptr = api.ObjForeignContainer.bz_containerSlice(value, &len); + const ptr = value.bz_foreignContainerSlice(&len); buffer.buffer.ensureTotalCapacityPrecise(buffer.buffer.items.len + len) catch { vm.bz_panic("Out of memory", "Out of memory".len); @@ -638,7 +670,7 @@ fn rawWriteStruct( } pub export fn BufferWriteStruct(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_getUserDataPtr()); const type_def = ctx.vm.bz_peek(1); const values = ctx.vm.bz_peek(0); @@ -652,7 +684,7 @@ pub export fn BufferWriteStruct(ctx: *api.NativeCtx) c_int { } pub export fn BufferWriteStructAt(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(3).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(3).bz_getUserDataPtr()); const type_def = ctx.vm.bz_peek(2); const index = ctx.vm.bz_peek(1).integer(); const values = ctx.vm.bz_peek(0); @@ -670,19 +702,18 @@ fn rawReadStruct( vm: *api.VM, buffer: *Buffer, at: ?usize, - type_def_value: api.Value, + type_def: api.Value, ) api.Value { - const type_def = type_def_value.bz_valueToObjTypeDef(); const size = type_def.bz_containerTypeSize(); const from = (at orelse buffer.cursor); const slice = buffer.buffer.items[from .. from + size]; - return api.ObjForeignContainer.bz_containerFromSlice(vm, type_def, slice.ptr, slice.len); + return vm.bz_newForeignContainerFromSlice(type_def, slice.ptr, slice.len); } pub export fn BufferReadStruct(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); const type_def = ctx.vm.bz_peek(0); ctx.vm.bz_push( @@ -698,7 +729,7 @@ pub export fn BufferReadStruct(ctx: *api.NativeCtx) c_int { } pub export fn BufferReadStructAt(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_getUserDataPtr()); const index: usize = @intCast(ctx.vm.bz_peek(1).integer()); const type_def = ctx.vm.bz_peek(0); @@ -722,7 +753,7 @@ fn rawReadZ(vm: *api.VM, buffer: *Buffer, at: ?usize, ztype: []const u8) c_int { &obj_typedef, ); - const len = api.VM.bz_zigValueSize(zig_type.?); + const len = api.ZigType.bz_zigTypeSize(zig_type.?); const value = vm.bz_readZigValueFromBuffer( zig_type.?, @@ -731,7 +762,7 @@ fn rawReadZ(vm: *api.VM, buffer: *Buffer, at: ?usize, ztype: []const u8) c_int { buffer.buffer.items.len, ); - if (!vm.bz_checkBuzzType(value, zig_type.?, obj_typedef)) { + if (!checkBuzzType(vm, value, zig_type.?, obj_typedef)) { return -1; } @@ -743,9 +774,9 @@ fn rawReadZ(vm: *api.VM, buffer: *Buffer, at: ?usize, ztype: []const u8) c_int { } pub export fn BufferReadZ(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(1).bz_getUserDataPtr()); var len: usize = 0; - const ztype = ctx.vm.bz_peek(0).bz_valueToObjString().bz_objStringToString(&len).?; + const ztype = ctx.vm.bz_peek(0).bz_valueToString(&len).?; return rawReadZ( ctx.vm, @@ -756,10 +787,10 @@ pub export fn BufferReadZ(ctx: *api.NativeCtx) c_int { } pub export fn BufferReadZAt(ctx: *api.NativeCtx) c_int { - const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_valueToUserData()); + const buffer = Buffer.fromUserData(ctx.vm.bz_peek(2).bz_getUserDataPtr()); const index: usize = @intCast(ctx.vm.bz_peek(1).integer()); var len: usize = 0; - const ztype = ctx.vm.bz_peek(0).bz_valueToObjString().bz_objStringToString(&len).?; + const ztype = ctx.vm.bz_peek(0).bz_valueToString(&len).?; return rawReadZ( ctx.vm, diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 628b5320..599c56ee 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -21,7 +21,7 @@ fn bin2hex(allocator: std.mem.Allocator, input: []const u8) std.ArrayList(u8) { } pub export fn hash(ctx: *api.NativeCtx) c_int { - const algo_index = api.ObjEnumInstance.bz_getEnumCaseValue(ctx.vm.bz_peek(1)).integer(); + const algo_index = ctx.vm.bz_peek(1).bz_getEnumInstanceValue().integer(); var data_len: usize = 0; const data = ctx.vm.bz_peek(0).bz_valueToString(&data_len) orelse @panic("Could not hash data"); @@ -97,13 +97,11 @@ pub export fn hash(ctx: *api.NativeCtx) c_int { else => @panic("Unknown hash algorithm"), } - ctx.vm.bz_pushString( - api.ObjString.bz_string( + ctx.vm.bz_push( + api.VM.bz_stringToValue( ctx.vm, result_hash.ptr, result_hash.len, - ) orelse @panic( - "Could not create hash", ), ); diff --git a/src/lib/buzz_debug.zig b/src/lib/buzz_debug.zig index 1f0619e8..9705f669 100644 --- a/src/lib/buzz_debug.zig +++ b/src/lib/buzz_debug.zig @@ -75,10 +75,8 @@ pub export fn dump(ctx: *api.NativeCtx) c_int { // return -1; // }; -// ctx.vm.bz_pushString( -// api.ObjString.bz_string(ctx.vm, if (out.items.len > 0) @as([*]const u8, @ptrCast(out.items)) else null, out.items.len) orelse { -// @panic("Out of memory"); -// }, +// ctx.vm.bz_push( +// api.VM.bz_stringToValue(ctx.vm, if (out.items.len > 0) @as([*]const u8, @ptrCast(out.items)) else null, out.items.len,), // ); // return 1; diff --git a/src/lib/buzz_ffi.zig b/src/lib/buzz_ffi.zig index 6dadb29a..7b2f8041 100644 --- a/src/lib/buzz_ffi.zig +++ b/src/lib/buzz_ffi.zig @@ -9,7 +9,7 @@ pub export fn alignOf(ctx: *api.NativeCtx) c_int { const zig_type = ctx.vm.bz_zigType(zig_type_str, len, &expected_type); if (zig_type) |ztype| { - ctx.vm.bz_pushInteger(@intCast(ztype.bz_zigTypeAlignment())); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(ztype.bz_zigTypeAlignment()))); } else { var msg = std.ArrayList(u8).init(api.VM.allocator); defer msg.deinit(); @@ -40,7 +40,7 @@ pub export fn sizeOf(ctx: *api.NativeCtx) c_int { const zig_type = ctx.vm.bz_zigType(zig_type_str, len, &expected_type); if (zig_type) |ztype| { - ctx.vm.bz_pushInteger(@intCast(ztype.bz_zigTypeSize())); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(ztype.bz_zigTypeSize()))); } else { var msg = std.ArrayList(u8).init(api.VM.allocator); defer msg.deinit(); @@ -65,17 +65,21 @@ pub export fn sizeOf(ctx: *api.NativeCtx) c_int { // FIXME: raise error if typedef is not .ForeignContainer pub export fn sizeOfStruct(ctx: *api.NativeCtx) c_int { - const type_def = ctx.vm.bz_peek(0).bz_valueToObjTypeDef(); + const type_def = ctx.vm.bz_peek(0); - ctx.vm.bz_push(api.Value.fromInteger(@intCast(type_def.bz_containerTypeSize()))); + ctx.vm.bz_push( + api.Value.fromInteger(@intCast(type_def.bz_containerTypeSize())), + ); return 1; } pub export fn alignOfStruct(ctx: *api.NativeCtx) c_int { - const type_def = ctx.vm.bz_peek(0).bz_valueToObjTypeDef(); + const type_def = ctx.vm.bz_peek(0); - ctx.vm.bz_push(api.Value.fromInteger(@intCast(type_def.bz_containerTypeAlign()))); + ctx.vm.bz_push( + api.Value.fromInteger(@intCast(type_def.bz_containerTypeAlign())), + ); return 1; } diff --git a/src/lib/buzz_fs.zig b/src/lib/buzz_fs.zig index 3df2e546..b3ffaf49 100644 --- a/src/lib/buzz_fs.zig +++ b/src/lib/buzz_fs.zig @@ -302,10 +302,7 @@ pub export fn list(ctx: *api.NativeCtx) c_int { return -1; }; - const file_list = api.ObjList.bz_newList( - ctx.vm, - api.ObjTypeDef.bz_stringType(ctx.vm), - ); + const file_list = ctx.vm.bz_newList(ctx.vm.bz_stringType()); ctx.vm.bz_push(file_list); @@ -316,16 +313,15 @@ pub export fn list(ctx: *api.NativeCtx) c_int { return -1; }) |element| { - ctx.vm.bz_pushString(api.ObjString.bz_string( - ctx.vm, - if (element.name.len > 0) @as([*]const u8, @ptrCast(element.name)) else null, - element.name.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); - - api.ObjList.bz_listAppend(ctx.vm, file_list, ctx.vm.bz_pop()); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (element.name.len > 0) @as([*]const u8, @ptrCast(element.name)) else null, + element.name.len, + ), + ); + + file_list.bz_listAppend(ctx.vm.bz_pop(), ctx.vm); } return 1; @@ -348,7 +344,7 @@ pub export fn exists(ctx: *api.NativeCtx) c_int { }; } - ctx.vm.bz_pushBool(accessed); + ctx.vm.bz_push(api.Value.fromBoolean(accessed)); return 1; } diff --git a/src/lib/buzz_gc.zig b/src/lib/buzz_gc.zig index ae19a2b5..a8e30438 100644 --- a/src/lib/buzz_gc.zig +++ b/src/lib/buzz_gc.zig @@ -10,7 +10,7 @@ else std.os; pub export fn allocated(ctx: *api.NativeCtx) c_int { - ctx.vm.bz_pushInteger(@intCast(ctx.vm.bz_allocated())); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(ctx.vm.bz_allocated()))); return 1; } diff --git a/src/lib/buzz_http.zig b/src/lib/buzz_http.zig index 8134cb51..44869829 100644 --- a/src/lib/buzz_http.zig +++ b/src/lib/buzz_http.zig @@ -17,18 +17,18 @@ pub export fn HttpClientNew(ctx: *api.NativeCtx) c_int { unreachable; }; - if (api.ObjUserData.bz_newUserData(ctx.vm, @intFromPtr(client))) |userdata| { - ctx.vm.bz_pushUserData(userdata); + ctx.vm.bz_push( + api.VM.bz_newUserData( + ctx.vm, + @intFromPtr(client), + ), + ); - return 1; - } else { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - } + return 1; } pub export fn HttpClientDeinit(ctx: *api.NativeCtx) c_int { - const userdata = ctx.vm.bz_peek(0).bz_valueToUserData(); + const userdata = ctx.vm.bz_peek(0).bz_getUserDataPtr(); const client = @as(*http.Client, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata))))); client.deinit(); @@ -38,15 +38,15 @@ pub export fn HttpClientDeinit(ctx: *api.NativeCtx) c_int { } pub export fn HttpClientSend(ctx: *api.NativeCtx) c_int { - const userdata = ctx.vm.bz_peek(3).bz_valueToUserData(); + const userdata = ctx.vm.bz_peek(3).bz_getUserDataPtr(); const client: *http.Client = @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata)))); var len: usize = 0; - const method_str = api.ObjEnumInstance.bz_getEnumCaseValue(ctx.vm.bz_peek(2)).bz_valueToString(&len); + const method_str = ctx.vm.bz_peek(2).bz_getEnumInstanceValue().bz_valueToString(&len); const method: http.Method = @enumFromInt(http.Method.parse(method_str.?[0..len])); var uri_len: usize = 0; - const uri = ctx.vm.bz_peek(1).bz_valueToObjString().bz_objStringToString(&uri_len); + const uri = ctx.vm.bz_peek(1).bz_valueToString(&uri_len); if (uri == null) { ctx.vm.bz_panic("Out of memory", "Out of memory".len); unreachable; @@ -55,16 +55,8 @@ pub export fn HttpClientSend(ctx: *api.NativeCtx) c_int { const header_values = ctx.vm.bz_peek(0); var headers = std.ArrayList(http.Header).init(api.VM.allocator); var next_header_key = api.Value.Null; - var next_header_value = api.ObjMap.bz_mapNext( - ctx.vm, - header_values, - &next_header_key, - ); - while (next_header_key.val != api.Value.Null.val) : (next_header_value = api.ObjMap.bz_mapNext( - ctx.vm, - header_values, - &next_header_key, - )) { + var next_header_value = header_values.bz_mapNext(&next_header_key); + while (next_header_key.val != api.Value.Null.val) : (next_header_value = header_values.bz_mapNext(&next_header_key)) { var key_len: usize = 0; const key = next_header_key.bz_valueToString(&key_len); var value_len: usize = 0; @@ -118,19 +110,19 @@ pub export fn HttpClientSend(ctx: *api.NativeCtx) c_int { return -1; }; - if (api.ObjUserData.bz_newUserData(ctx.vm, @intFromPtr(request))) |request_ud| { - ctx.vm.bz_pushUserData(request_ud); + ctx.vm.bz_push( + api.VM.bz_newUserData( + ctx.vm, + @intFromPtr(request), + ), + ); - return 1; - } else { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - } + return 1; } pub export fn HttpRequestWait(ctx: *api.NativeCtx) c_int { const userdata_value = ctx.vm.bz_peek(0); - const userdata = userdata_value.bz_valueToUserData(); + const userdata = userdata_value.bz_getUserDataPtr(); const request = @as( *http.Client.Request, @ptrCast( @@ -153,7 +145,7 @@ pub export fn HttpRequestWait(ctx: *api.NativeCtx) c_int { pub export fn HttpRequestDeinit(ctx: *api.NativeCtx) c_int { const userdata_value = ctx.vm.bz_peek(0); - const userdata = userdata_value.bz_valueToUserData(); + const userdata = userdata_value.bz_getUserDataPtr(); const request = @as( *http.Client.Request, @ptrCast( @@ -171,7 +163,7 @@ pub export fn HttpRequestDeinit(ctx: *api.NativeCtx) c_int { pub export fn HttpRequestRead(ctx: *api.NativeCtx) c_int { const userdata_value = ctx.vm.bz_peek(0); - const userdata = userdata_value.bz_valueToUserData(); + const userdata = userdata_value.bz_getUserDataPtr(); const request = @as( *http.Client.Request, @ptrCast( @@ -191,83 +183,61 @@ pub export fn HttpRequestRead(ctx: *api.NativeCtx) c_int { }; // Create http.Response instance - const response = api.ObjObject.bz_instanceQualified( - ctx.vm, + const response = ctx.vm.bz_newQualifiedObjectInstance( "http.Response", "http.Response".len, ); // Set body - api.ObjObject.bz_setInstanceProperty( - ctx.vm, - response, + response.bz_setObjectInstanceProperty( 2, if (body_raw.items.len == 0) api.Value.Null else - api.ObjString.bz_objStringToValue( - api.ObjString.bz_string( - ctx.vm, - body_raw.items.ptr, - body_raw.items.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }, + api.VM.bz_stringToValue( + ctx.vm, + body_raw.items.ptr, + body_raw.items.len, ), + ctx.vm, ); // Set status - api.ObjObject.bz_setInstanceProperty( - ctx.vm, - response, + response.bz_setObjectInstanceProperty( 0, api.Value.fromInteger(@intFromEnum(request.response.status)), + ctx.vm, ); // Set headers - const string_type = api.ObjTypeDef.bz_stringType(ctx.vm); - const headers = api.ObjMap.bz_newMap( - ctx.vm, - api.ObjTypeDef.bz_mapType( - ctx.vm, + const string_type = ctx.vm.bz_stringType(); + const headers = ctx.vm.bz_newMap( + ctx.vm.bz_mapType( string_type, string_type, ), ); - api.ObjObject.bz_setInstanceProperty( - ctx.vm, - response, + response.bz_setObjectInstanceProperty( 1, headers, + ctx.vm, ); var header_it = request.response.iterateHeaders(); while (header_it.next()) |header| { - api.ObjMap.bz_mapSet( - ctx.vm, - headers, - api.ObjString.bz_objStringToValue( - api.ObjString.bz_string( - ctx.vm, - header.name.ptr, - header.name.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }, + headers.bz_mapSet( + api.VM.bz_stringToValue( + ctx.vm, + header.name.ptr, + header.name.len, ), - api.ObjString.bz_objStringToValue( - api.ObjString.bz_string( - ctx.vm, - header.value.ptr, - header.value.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }, + api.VM.bz_stringToValue( + ctx.vm, + header.value.ptr, + header.value.len, ), + ctx.vm, ); } diff --git a/src/lib/buzz_io.zig b/src/lib/buzz_io.zig index feea888a..97044c37 100644 --- a/src/lib/buzz_io.zig +++ b/src/lib/buzz_io.zig @@ -3,19 +3,19 @@ const api = @import("buzz_api.zig"); const io = @import("io.zig"); pub export fn getStdIn(ctx: *api.NativeCtx) c_int { - ctx.vm.bz_pushInteger(@intCast(std.io.getStdIn().handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(std.io.getStdIn().handle))); return 1; } pub export fn getStdOut(ctx: *api.NativeCtx) c_int { - ctx.vm.bz_pushInteger(@intCast(std.io.getStdOut().handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(std.io.getStdOut().handle))); return 1; } pub export fn getStdErr(ctx: *api.NativeCtx) c_int { - ctx.vm.bz_pushInteger(@intCast(std.io.getStdErr().handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(std.io.getStdErr().handle))); return 1; } @@ -25,7 +25,7 @@ pub export fn FileIsTTY(ctx: api.NativeCtx) c_int { ctx.vm.bz_peek(0).integer(), ); - ctx.vm.bz_pushBool(std.posix.isatty(handle)); + ctx.vm.bz_push(api.Value.fromBoolean(std.posix.isatty(handle))); return 1; } @@ -94,7 +94,7 @@ pub export fn FileOpen(ctx: *api.NativeCtx) c_int { }, }; - ctx.vm.bz_pushInteger(@intCast(file.handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(file.handle))); return 1; } @@ -159,10 +159,13 @@ pub export fn FileReadAll(ctx: *api.NativeCtx) c_int { return -1; }; - ctx.vm.bz_pushString(api.ObjString.bz_string(ctx.vm, if (content.len > 0) @as([*]const u8, @ptrCast(content)) else null, content.len) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (content.len > 0) @as([*]const u8, @ptrCast(content)) else null, + content.len, + ), + ); return 1; } @@ -217,18 +220,15 @@ pub export fn FileReadLine(ctx: *api.NativeCtx) c_int { }; if (buffer) |ubuffer| { - ctx.vm.bz_pushString( - api.ObjString.bz_string( + ctx.vm.bz_push( + api.VM.bz_stringToValue( ctx.vm, if (ubuffer.len > 0) @as([*]const u8, @ptrCast(ubuffer)) else null, ubuffer.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }, + ), ); } else { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); } return 1; @@ -275,7 +275,7 @@ pub export fn FileRead(ctx: *api.NativeCtx) c_int { unreachable; }; - // bz_string will copy it + // bz_stringToValue will copy it defer api.VM.allocator.free(buffer); const read = reader.readAll(buffer) catch |err| { @@ -285,12 +285,15 @@ pub export fn FileRead(ctx: *api.NativeCtx) c_int { }; if (read == 0) { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); } else { - ctx.vm.bz_pushString(api.ObjString.bz_string(ctx.vm, if (buffer[0..read].len > 0) @as([*]const u8, @ptrCast(buffer[0..read])) else null, read) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (buffer[0..read].len > 0) @as([*]const u8, @ptrCast(buffer[0..read])) else null, + read, + ), + ); } return 1; diff --git a/src/lib/buzz_math.zig b/src/lib/buzz_math.zig index bfe08150..f9b1e2b8 100644 --- a/src/lib/buzz_math.zig +++ b/src/lib/buzz_math.zig @@ -12,7 +12,7 @@ else pub export fn abs(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(if (n_f < 0) n_f * -1 else n_f); + ctx.vm.bz_push(api.Value.fromFloat(if (n_f < 0) n_f * -1 else n_f)); return 1; } @@ -20,7 +20,7 @@ pub export fn abs(ctx: *api.NativeCtx) c_int { pub export fn acos(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.acos(n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.acos(n_f))); return 1; } @@ -28,7 +28,7 @@ pub export fn acos(ctx: *api.NativeCtx) c_int { pub export fn asin(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.asin(n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.asin(n_f))); return 1; } @@ -36,7 +36,7 @@ pub export fn asin(ctx: *api.NativeCtx) c_int { pub export fn atan(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.atan(n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.atan(n_f))); return 1; } @@ -44,7 +44,7 @@ pub export fn atan(ctx: *api.NativeCtx) c_int { pub export fn bzceil(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushInteger(@intFromFloat(std.math.ceil(n_f))); + ctx.vm.bz_push(api.Value.fromInteger(@intFromFloat(std.math.ceil(n_f)))); return 1; } @@ -52,7 +52,7 @@ pub export fn bzceil(ctx: *api.NativeCtx) c_int { pub export fn bzcos(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.cos(n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.cos(n_f))); return 1; } @@ -60,7 +60,7 @@ pub export fn bzcos(ctx: *api.NativeCtx) c_int { pub export fn bzexp(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.exp(n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.exp(n_f))); return 1; } @@ -68,7 +68,7 @@ pub export fn bzexp(ctx: *api.NativeCtx) c_int { pub export fn bzfloor(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushInteger(@intFromFloat(std.math.floor(n_f))); + ctx.vm.bz_push(api.Value.fromInteger(@intFromFloat(std.math.floor(n_f)))); return 1; } @@ -77,7 +77,7 @@ pub export fn bzlog(ctx: *api.NativeCtx) c_int { const base_i: f64 = ctx.vm.bz_peek(1).float(); const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.log(f64, base_i, n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.log(f64, base_i, n_f))); return 1; } @@ -86,7 +86,7 @@ pub export fn maxFloat(ctx: *api.NativeCtx) c_int { const a_f = ctx.vm.bz_peek(0).float(); const b_f = ctx.vm.bz_peek(1).float(); - ctx.vm.bz_pushFloat(@max(a_f, b_f)); + ctx.vm.bz_push(api.Value.fromFloat(@max(a_f, b_f))); return 1; } @@ -95,7 +95,7 @@ pub export fn minFloat(ctx: *api.NativeCtx) c_int { const a_f = ctx.vm.bz_peek(0).float(); const b_f = ctx.vm.bz_peek(1).float(); - ctx.vm.bz_pushFloat(@min(a_f, b_f)); + ctx.vm.bz_push(api.Value.fromFloat(@min(a_f, b_f))); return 1; } @@ -104,7 +104,7 @@ pub export fn maxInt(ctx: *api.NativeCtx) c_int { const a_f = ctx.vm.bz_peek(0).integer(); const b_f = ctx.vm.bz_peek(1).integer(); - ctx.vm.bz_pushInteger(@max(a_f, b_f)); + ctx.vm.bz_push(api.Value.fromInteger(@max(a_f, b_f))); return 1; } @@ -113,7 +113,7 @@ pub export fn minInt(ctx: *api.NativeCtx) c_int { const a_f = ctx.vm.bz_peek(0).integer(); const b_f = ctx.vm.bz_peek(1).integer(); - ctx.vm.bz_pushInteger(@min(a_f, b_f)); + ctx.vm.bz_push(api.Value.fromInteger(@min(a_f, b_f))); return 1; } @@ -121,7 +121,7 @@ pub export fn minInt(ctx: *api.NativeCtx) c_int { pub export fn bzsin(ctx: *api.NativeCtx) c_int { const n: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.sin(n)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.sin(n))); return 1; } @@ -129,7 +129,7 @@ pub export fn bzsin(ctx: *api.NativeCtx) c_int { pub export fn bzsqrt(ctx: *api.NativeCtx) c_int { const n_f: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.sqrt(n_f)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.sqrt(n_f))); return 1; } @@ -137,7 +137,7 @@ pub export fn bzsqrt(ctx: *api.NativeCtx) c_int { pub export fn bztan(ctx: *api.NativeCtx) c_int { const n: f64 = ctx.vm.bz_peek(0).float(); - ctx.vm.bz_pushFloat(std.math.tan(n)); + ctx.vm.bz_push(api.Value.fromFloat(std.math.tan(n))); return 1; } @@ -153,23 +153,25 @@ pub export fn pow(ctx: *api.NativeCtx) c_int { const p_f: ?f64 = if (p.isFloat()) p.float() else null; if (p_f) |pf| { - ctx.vm.bz_pushFloat( + ctx.vm.bz_push(api.Value.fromFloat( std.math.pow(f64, n_f orelse @as(f64, @floatFromInt(n_i.?)), pf), - ); + )); } else if (n_f) |nf| { - ctx.vm.bz_pushFloat( + ctx.vm.bz_push(api.Value.fromFloat( std.math.pow(f64, nf, p_f orelse @as(f64, @floatFromInt(p_i.?))), - ); + )); } else { - ctx.vm.bz_pushInteger( - std.math.powi(i32, n_i.?, p_i.?) catch |err| { - switch (err) { - error.Overflow => ctx.vm.pushError("errors.OverflowError", null), - error.Underflow => ctx.vm.pushError("errors.UnderflowError", null), - } - - return -1; - }, + ctx.vm.bz_push( + api.Value.fromInteger( + std.math.powi(i32, n_i.?, p_i.?) catch |err| { + switch (err) { + error.Overflow => ctx.vm.pushError("errors.OverflowError", null), + error.Underflow => ctx.vm.pushError("errors.UnderflowError", null), + } + + return -1; + }, + ), ); } diff --git a/src/lib/buzz_os.zig b/src/lib/buzz_os.zig index ab155f02..d4815f43 100644 --- a/src/lib/buzz_os.zig +++ b/src/lib/buzz_os.zig @@ -19,7 +19,7 @@ pub export fn env(ctx: *api.NativeCtx) c_int { const key = ctx.vm.bz_peek(0).bz_valueToString(&len); if (len == 0) { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; } @@ -32,21 +32,18 @@ pub export fn env(ctx: *api.NativeCtx) c_int { // FIXME: don't use std.posix directly if (std.posix.getenv(key_slice)) |value| { - ctx.vm.bz_pushString( - api.ObjString.bz_string( + ctx.vm.bz_push( + api.VM.bz_stringToValue( ctx.vm, if (value.len > 0) @as([*]const u8, @ptrCast(value)) else null, value.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }, + ), ); return 1; } - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); return 1; } @@ -65,10 +62,13 @@ fn sysTempDir() []const u8 { pub export fn tmpDir(ctx: *api.NativeCtx) c_int { const tmp_dir: []const u8 = sysTempDir(); - ctx.vm.bz_pushString(api.ObjString.bz_string(ctx.vm, if (tmp_dir.len > 0) @as([*]const u8, @ptrCast(tmp_dir)) else null, tmp_dir.len) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (tmp_dir.len > 0) @as([*]const u8, @ptrCast(tmp_dir)) else null, + tmp_dir.len, + ), + ); return 1; } @@ -107,18 +107,15 @@ pub export fn tmpFilename(ctx: *api.NativeCtx) c_int { unreachable; }; - ctx.vm.bz_pushString( - api.ObjString.bz_string( + ctx.vm.bz_push( + api.VM.bz_stringToValue( ctx.vm, if (final.items.len > 0) @as([*]const u8, @ptrCast(final.items)) else null, final.items.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }, + ), ); return 1; @@ -176,13 +173,11 @@ pub export fn execute(ctx: *api.NativeCtx) c_int { var command = std.ArrayList([]const u8).init(api.VM.allocator); defer command.deinit(); - const argv_value = ctx.vm.bz_peek(0); - const argv = api.ObjList.bz_valueToList(argv_value); + const argv = ctx.vm.bz_peek(0); const len = argv.bz_listLen(); var i: usize = 0; while (i < len) : (i += 1) { - const arg = api.ObjList.bz_listGet( - argv_value, + const arg = argv.bz_listGet( @intCast(i), false, ); @@ -207,10 +202,10 @@ pub export fn execute(ctx: *api.NativeCtx) c_int { }; switch (term) { - .Exited => ctx.vm.bz_pushInteger(@intCast(term.Exited)), - .Signal => ctx.vm.bz_pushInteger(@intCast(term.Signal)), - .Stopped => ctx.vm.bz_pushInteger(@intCast(term.Stopped)), - .Unknown => ctx.vm.bz_pushInteger(@intCast(term.Unknown)), + .Exited => ctx.vm.bz_push(api.Value.fromInteger(@intCast(term.Exited))), + .Signal => ctx.vm.bz_push(api.Value.fromInteger(@intCast(term.Signal))), + .Stopped => ctx.vm.bz_push(api.Value.fromInteger(@intCast(term.Stopped))), + .Unknown => ctx.vm.bz_push(api.Value.fromInteger(@intCast(term.Unknown))), } return 1; @@ -346,7 +341,7 @@ pub export fn SocketConnect(ctx: *api.NativeCtx) c_int { return -1; }; - ctx.vm.bz_pushInteger(@intCast(stream.handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(stream.handle))); return 1; }, @@ -363,7 +358,7 @@ pub export fn SocketConnect(ctx: *api.NativeCtx) c_int { return -1; }; - ctx.vm.bz_pushInteger(@intCast(stream.handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(stream.handle))); return 1; }, @@ -432,7 +427,7 @@ pub export fn SocketRead(ctx: *api.NativeCtx) c_int { unreachable; }; - // bz_string will copy it + // bz_stringToValue will copy it defer api.VM.allocator.free(buffer); const read = reader.readAll(buffer) catch |err| { @@ -442,12 +437,15 @@ pub export fn SocketRead(ctx: *api.NativeCtx) c_int { }; if (read == 0) { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); } else { - ctx.vm.bz_pushString(api.ObjString.bz_string(ctx.vm, if (buffer[0..read].len > 0) @as([*]const u8, @ptrCast(buffer[0..read])) else null, read) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (buffer[0..read].len > 0) @as([*]const u8, @ptrCast(buffer[0..read])) else null, + read, + ), + ); } return 1; @@ -510,19 +508,16 @@ pub export fn SocketReadLine(ctx: *api.NativeCtx) c_int { // EOF? if (buffer.len == 0) { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); } else { - ctx.vm.bz_pushString(api.ObjString.bz_string( + ctx.vm.bz_push(api.VM.bz_stringToValue( ctx.vm, if (buffer.len > 0) @as([*]const u8, @ptrCast(buffer)) else null, buffer.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); + )); } return 1; @@ -555,19 +550,18 @@ pub export fn SocketReadAll(ctx: *api.NativeCtx) c_int { // EOF? if (buffer.len == 0) { - ctx.vm.bz_pushNull(); + ctx.vm.bz_push(api.Value.Null); } else { - ctx.vm.bz_pushString(api.ObjString.bz_string( - ctx.vm, - if (buffer.len > 0) - @as([*]const u8, @ptrCast(buffer)) - else - null, - buffer.len, - ) orelse { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - }); + ctx.vm.bz_push( + api.VM.bz_stringToValue( + ctx.vm, + if (buffer.len > 0) + @as([*]const u8, @ptrCast(buffer)) + else + null, + buffer.len, + ), + ); } return 1; @@ -677,7 +671,7 @@ pub export fn SocketServerStart(ctx: *api.NativeCtx) c_int { return -1; }; - ctx.vm.bz_pushInteger(@intCast(server.stream.handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(server.stream.handle))); return 1; } @@ -713,7 +707,7 @@ pub export fn SocketServerAccept(ctx: *api.NativeCtx) c_int { return -1; }; - ctx.vm.bz_pushInteger(@intCast(connection.stream.handle)); + ctx.vm.bz_push(api.Value.fromInteger(@intCast(connection.stream.handle))); return 1; } diff --git a/src/lib/buzz_std.zig b/src/lib/buzz_std.zig index 3256cb37..f84e35d6 100644 --- a/src/lib/buzz_std.zig +++ b/src/lib/buzz_std.zig @@ -83,19 +83,15 @@ pub export fn toFloat(ctx: *api.NativeCtx) c_int { pub export fn toUd(ctx: *api.NativeCtx) c_int { const value = ctx.vm.bz_peek(0); - const ud: u64 = if (value.isInteger()) - @intCast(value.integer()) - else if (value.isFloat()) - @intFromFloat(value.float()) - else - 0; - const userdata = api.ObjUserData.bz_newUserData( - ctx.vm, - ud, - ).?.bz_userDataToValue(); - - ctx.vm.bz_push(userdata); + ctx.vm.bz_push( + ctx.vm.bz_newUserData(if (value.isInteger()) + @intCast(value.integer()) + else if (value.isFloat()) + @intFromFloat(value.float()) + else + 0), + ); return 1; } @@ -145,14 +141,14 @@ pub export fn parseUd(ctx: *api.NativeCtx) c_int { return 1; }; - if (api.ObjUserData.bz_newUserData(ctx.vm, number)) |userdata| { - ctx.vm.bz_pushUserData(userdata); + ctx.vm.bz_push( + api.VM.bz_newUserData( + ctx.vm, + number, + ), + ); - return 1; - } else { - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; - } + return 1; } pub export fn parseFloat(ctx: *api.NativeCtx) c_int { @@ -193,14 +189,11 @@ pub export fn char(ctx: *api.NativeCtx) c_int { const str = [_]u8{@as(u8, @intCast(byte))}; - if (api.ObjString.bz_string(ctx.vm, str[0..], 1)) |obj_string| { - ctx.vm.bz_push(obj_string.bz_objStringToValue()); - - return 1; - } + ctx.vm.bz_push( + api.VM.bz_stringToValue(ctx.vm, str[0..], 1), + ); - ctx.vm.bz_panic("Out of memory", "Out of memory".len); - unreachable; + return 1; } pub export fn assert(ctx: *api.NativeCtx) c_int {