Skip to content

Commit

Permalink
Add clGetField.
Browse files Browse the repository at this point in the history
  • Loading branch information
fubark committed Sep 2, 2024
1 parent 4f2ca7e commit 601b31d
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 11 deletions.
14 changes: 7 additions & 7 deletions src/builtins/cy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,15 @@ pub fn UserVM_evalExt(vm: *cy.VM) anyerror!cy.Value {
const uvm = vm.getValue(0).castHostObject(*UserVM);
const uri = vm.getString(1);
const src = vm.getString(2);
const config = &vm.getValue(3).asHeapObject().object;
const config = vm.getValue(3);

const config_c = C.EvalConfig{
.single_run = (try vm.getObjectField(config, "single_run")).asBool(),
.file_modules = (try vm.getObjectField(config, "file_modules")).asBool(),
.gen_all_debug_syms = (try vm.getObjectField(config, "gen_all_debug_syms")).asBool(),
.backend = (try vm.getObjectField(config, "backend")).getEnumValue(),
.reload = (try vm.getObjectField(config, "reload")).asBool(),
.spawn_exe = (try vm.getObjectField(config, "spawn_exe")).asBool(),
.single_run = (try vm.getFieldName(config, "single_run")).asBool(),
.file_modules = (try vm.getFieldName(config, "file_modules")).asBool(),
.gen_all_debug_syms = (try vm.getFieldName(config, "gen_all_debug_syms")).asBool(),
.backend = (try vm.getFieldName(config, "backend")).getEnumValue(),
.reload = (try vm.getFieldName(config, "reload")).asBool(),
.spawn_exe = (try vm.getFieldName(config, "spawn_exe")).asBool(),
};

var res: C.Value = @bitCast(cy.Value.Void);
Expand Down
4 changes: 4 additions & 0 deletions src/capi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ pub const ZVM = struct {
return c.clFindType(@ptrCast(self), toStr(path));
}

pub fn getField(self: *ZVM, rec: Value, name: []const u8) Value {
return c.clGetField(@ptrCast(self), rec, toStr(name));
}

pub fn expandTemplateType(self: *ZVM, template: Sym, args: []const Value, res: *Type) bool {
return c.clExpandTemplateType(@ptrCast(self), template, args.ptr, args.len, res);
}
Expand Down
4 changes: 4 additions & 0 deletions src/include/cyber.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,10 @@ CLValue clNewVmObject(CLVM* vm, CLType typeId);
// Returns the type of boxed value.
CLType clGetType(CLValue val);

// Returns the field value of the receiver object `rec`.
// If the field can not be retrieved, the VM panics and `CL_INTERRUPT` is returned.
CLValue clGetField(CLVM* vm, CLValue rec, CLStr name);

bool clIsFuture(CLVM* vm, CLValue val);
CLStr clNewValueDump(CLVM* vm, CLValue val);

Expand Down
22 changes: 22 additions & 0 deletions src/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,28 @@ export fn clSymbol(vm: *cy.VM, str: c.Str) Value {
return Value.initSymbol(@intCast(id));
}

export fn clGetField(vm: *cy.VM, val: cy.Value, name: c.Str) cy.Value {
return vm.getFieldName(val, c.fromStr(name)) catch {
return vm.prepPanic("Can not access field.");
};
}

test "clGetField()" {
const vm = c.create();
defer vm.destroy();

var res: c.Value = undefined;
_ = vm.eval(
\\type Foo:
\\ a int
\\ b String
\\Foo{a=123, b='abc'}
, &res);
defer vm.release(res);
try t.eq(vm.getField(res, "a"), 123);
try t.eqStr(c.asString(vm.getField(res, "b")), "abc");
}

export fn clNewPointerVoid(vm: *cy.VM, ptr: ?*anyopaque) Value {
const bt_data = vm.getData(*cy.builtins.BuiltinsData, "builtins");
return cy.heap.allocPointer(vm, bt_data.PtrVoid, ptr) catch fatal();
Expand Down
12 changes: 8 additions & 4 deletions src/vm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1259,14 +1259,18 @@ pub const VM = struct {
}

/// Does not invoke `getFieldFallback`.
pub fn getObjectField(self: *VM, obj: *cy.heap.Object, field: []const u8) !Value {
pub fn getFieldName(self: *VM, rec: cy.Value, field: []const u8) !Value {
const field_id = try self.ensureField(field);
const base: *cy.heap.HeapObject = @ptrCast(obj);
const res = self.getTypeField(base.getTypeId(), field_id);
const obj = rec.asHeapObject();
const res = self.getTypeField(obj.getTypeId(), field_id);
if (res.offset == cy.NullU16) {
return error.MissingField;
}
return obj.getValue(res.offset);
const val = obj.object.getValue(res.offset);
if (res.boxed) {
self.retain(val);
}
return val;
}

fn setFieldFallback(self: *VM, obj: *HeapObject, nameId: vmc.NameId, val: cy.Value) !void {
Expand Down

0 comments on commit 601b31d

Please sign in to comment.