Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: infer ZigType(ZT) from SSZType (ST) #10

Merged
merged 2 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/type/bit_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ pub fn createBitListType(comptime limit_bits: usize) type {
block_bytes: BlockBytes,
mix_in_length_block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return BitArray;
}

pub fn getZigTypeAlignment() usize {
return @alignOf(BitArray);
}

pub fn init(allocator: std.mem.Allocator, init_capacity: usize) !@This() {
const limit_bytes = (limit_bits + 7) / 8;
const max_chunk_count: usize = (limit_bytes + 31) / 32;
Expand Down
9 changes: 9 additions & 0 deletions src/type/bit_vector.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ pub const BitVectorType = struct {
// this should always be a multiple of 64 bytes
block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return BitArray;
}

pub fn getZigTypeAlignment() usize {
return @alignOf(BitArray);
}

pub fn init(allocator: std.mem.Allocator, comptime length_bits: usize) !@This() {
if (length_bits <= 0) {
return error.InvalidLength;
Expand Down
9 changes: 9 additions & 0 deletions src/type/boolean.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ pub const BooleanType = struct {
min_size: usize,
max_size: usize,

/// Zig type definition
pub fn getZigType() type {
return bool;
}

pub fn getZigTypeAlignment() usize {
return 1;
}

pub fn init() @This() {
return @This(){ .fixed_size = 1, .byte_len = 1, .items_per_chunk = 32, .min_size = 1, .max_size = 1 };
}
Expand Down
9 changes: 9 additions & 0 deletions src/type/byte_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ pub fn createByteListType(comptime limit_bytes: usize) type {
block_bytes: BlockBytes,
mix_in_length_block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return []u8;
}

pub fn getZigTypeAlignment() usize {
return @alignOf([]u8);
}

pub fn init(allocator: std.mem.Allocator, init_capacity: usize) !@This() {
return @This(){ .allocator = allocator, .block_bytes = try BlockBytes.initCapacity(allocator, init_capacity), .mix_in_length_block_bytes = try allocator.alloc(u8, 64) };
}
Expand Down
9 changes: 9 additions & 0 deletions src/type/byte_vector_type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ pub const ByteVectorType = struct {
// this should always be a multiple of 64 bytes
block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return []u8;
}

pub fn getZigTypeAlignment() usize {
return @alignOf([]u8);
}

pub fn init(allocator: std.mem.Allocator, length_bytes: usize) !@This() {
const max_chunk_count: usize = (length_bytes + 31) / 32;
const chunk_depth = maxChunksToDepth(max_chunk_count);
Expand Down
69 changes: 53 additions & 16 deletions src/type/container.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,41 @@ const BytesRange = struct {
/// TODO: defaultValue() for all types
// create a ssz type from type of an ssz object
// type of zig type will be used once and checked inside hashTreeRoot() function
pub fn createContainerType(comptime ST: type, comptime ZT: type, hashFn: HashFn) type {
pub fn createContainerType(comptime ST: type, hashFn: HashFn) type {
const ssz_struct_info = switch (@typeInfo(ST)) {
.Struct => |struct_info| struct_info,
else => @compileError("Expected a struct type."),
};

comptime var new_fields: [ssz_struct_info.fields.len]std.builtin.Type.StructField = undefined;
comptime var alignment: usize = 0;
inline for (ssz_struct_info.fields, 0..) |field, i| {
if (field.type.getZigTypeAlignment() > alignment) {
alignment = field.type.getZigTypeAlignment();
}
new_fields[i] = .{
.name = field.name,
.type = field.type.getZigType(),
// TODO: implement this
.default_value = null,
.is_comptime = false,
.alignment = field.type.getZigTypeAlignment(),
};
}

// this works for Zig 0.13
// syntax in 0.14 or later could change, see https://github.com/ziglang/zig/issues/10710
const ZT = comptime @Type(.{
.Struct = .{
.layout = .auto,
.backing_integer = null,
.fields = new_fields[0..],
// TODO: do we need to assign this value?
.decls = &[_]std.builtin.Type.Declaration{},
.is_tuple = false,
},
});

const zig_fields_info = @typeInfo(ZT).Struct.fields;
const max_chunk_count = zig_fields_info.len;
const native_endian = @import("builtin").target.cpu.arch.endian();
Expand All @@ -40,6 +74,17 @@ pub fn createContainerType(comptime ST: type, comptime ZT: type, hashFn: HashFn)
fixed_end: usize,
variable_field_count: usize,

/// Zig Type definition
pub fn getZigType() type {
return ZT;
}

/// to be used by parent
/// an alignment of struct is max of all fields' alignment
pub fn getZigTypeAlignment() usize {
return alignment;
}

/// public function for consumers
/// TODO: consider returning *@This(), see BitArray
pub fn init(allocator: Allocator, ssz_fields: ST) !@This() {
Expand Down Expand Up @@ -340,6 +385,7 @@ pub fn createContainerType(comptime ST: type, comptime ZT: type, hashFn: HashFn)
}

test "basic ContainerType {x: uint, y:bool}" {
std.debug.print("basic ContainerType x: uint, y:bool\n", .{});
var allocator = std.testing.allocator;
const UintType = @import("./uint.zig").createUintType(8);
const uintType = try UintType.init();
Expand All @@ -351,11 +397,8 @@ test "basic ContainerType {x: uint, y:bool}" {
x: UintType,
y: BooleanType,
};
const ZigType = struct {
x: u64,
y: bool,
};
const ContainerType = createContainerType(SszType, ZigType, sha256Hash);
const ContainerType = createContainerType(SszType, sha256Hash);
const ZigType = ContainerType.getZigType();
var containerType = try ContainerType.init(allocator, SszType{
.x = uintType,
.y = booleanType,
Expand Down Expand Up @@ -404,11 +447,8 @@ test "ContainerType with embedded struct" {
x: UintType,
y: UintType,
};
const ZigType0 = struct {
x: u64,
y: u64,
};
const ContainerType0 = createContainerType(SszType0, ZigType0, sha256Hash);
const ContainerType0 = createContainerType(SszType0, sha256Hash);
const ZigType0 = ContainerType0.getZigType();
const containerType0 = try ContainerType0.init(allocator, SszType0{
.x = uintType,
.y = uintType,
Expand All @@ -419,11 +459,8 @@ test "ContainerType with embedded struct" {
a: ContainerType0,
b: ContainerType0,
};
const ZigType1 = struct {
a: ZigType0,
b: ZigType0,
};
const ContainerType1 = createContainerType(SszType1, ZigType1, sha256Hash);
const ContainerType1 = createContainerType(SszType1, sha256Hash);
const ZigType1 = ContainerType1.getZigType();
var containerType1 = try ContainerType1.init(allocator, SszType1{
.a = containerType0,
.b = containerType0,
Expand Down
16 changes: 13 additions & 3 deletions src/type/list_basic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ const Parsed = @import("./type.zig").Parsed;
/// List: ordered variable-length homogeneous collection, limited to N values
/// ST: ssz element type
/// ZT: zig element type
pub fn createListBasicType(comptime ST: type, comptime ZT: type) type {
pub fn createListBasicType(comptime ST: type) type {
const BlockBytes = ArrayList(u8);
const ZT = ST.getZigType();
const ArrayBasic = @import("./array_basic.zig").withElementTypes(ST, ZT);
const ParsedResult = Parsed([]ZT);

Expand All @@ -38,6 +39,15 @@ pub fn createListBasicType(comptime ST: type, comptime ZT: type) type {
block_bytes: BlockBytes,
mix_in_length_block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return []ZT;
}

pub fn getZigTypeAlignment() usize {
return @alignOf([]ZT);
}

/// init_capacity is the initial capacity of elements, not bytes
pub fn init(allocator: std.mem.Allocator, element_type: *ST, limit: usize, init_capacity: usize) !@This() {
const elem_byte_length = element_type.byte_length;
Expand Down Expand Up @@ -146,7 +156,7 @@ test "deserializeFromBytes" {

// uint of 8 bytes = u64
const UintType = @import("./uint.zig").createUintType(8);
const ListBasicType = createListBasicType(UintType, u64);
const ListBasicType = createListBasicType(UintType);
var uintType = try UintType.init();
var listType = try ListBasicType.init(allocator, &uintType, 128, 128);
defer uintType.deinit();
Expand Down Expand Up @@ -204,7 +214,7 @@ test "deserializeFromJson" {

// uint of 8 bytes = u64
const UintType = @import("./uint.zig").createUintType(8);
const ListBasicType = createListBasicType(UintType, u64);
const ListBasicType = createListBasicType(UintType);
var uintType = try UintType.init();
var listType = try ListBasicType.init(allocator, &uintType, 4, 2);
defer uintType.deinit();
Expand Down
31 changes: 18 additions & 13 deletions src/type/list_composite.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ const Parsed = @import("./type.zig").Parsed;
/// List: ordered variable-length homogeneous collection, limited to N values
/// ST: ssz element type
/// ZT: zig element type
pub fn createListCompositeType(comptime ST: type, comptime ZT: type) type {
pub fn createListCompositeType(comptime ST: type) type {
const BlockBytes = ArrayList(u8);
const ZT = ST.getZigType();
const ArrayComposite = @import("./array_composite.zig").withElementTypes(ST, ZT);
const ParsedResult = Parsed([]ZT);

Expand All @@ -38,6 +39,15 @@ pub fn createListCompositeType(comptime ST: type, comptime ZT: type) type {
block_bytes: BlockBytes,
mix_in_length_block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return []ZT;
}

pub fn getZigTypeAlignment() usize {
return @alignOf([]ZT);
}

/// init_capacity is the initial capacity of elements, not bytes
pub fn init(allocator: std.mem.Allocator, element_type: *ST, limit: usize, init_capacity: usize) !@This() {
const max_chunk_count = limit;
Expand Down Expand Up @@ -163,7 +173,7 @@ test "ListCompositeType - element type ByteVectorType" {
var byteVectorType = try ByteVectorType.init(allocator, 32);
defer byteVectorType.deinit();

const ListCompositeType = createListCompositeType(ByteVectorType, []u8);
const ListCompositeType = createListCompositeType(ByteVectorType);
var list = try ListCompositeType.init(allocator, &byteVectorType, 128, 4);
defer list.deinit();

Expand Down Expand Up @@ -202,13 +212,9 @@ test "ListCompositeType - element type is ContainerType" {
b: UintType,
};

const ZigContainerType = struct {
a: u64,
b: u64,
};

const SSZContainerType = @import("./container.zig").createContainerType(SSZElementType, ZigContainerType, sha256Hash);
const ListCompositeType = createListCompositeType(SSZContainerType, ZigContainerType);
const SSZContainerType = @import("./container.zig").createContainerType(SSZElementType, sha256Hash);
const ZigContainerType = SSZContainerType.getZigType();
const ListCompositeType = createListCompositeType(SSZContainerType);

const uintType = try UintType.init();
defer uintType.deinit();
Expand Down Expand Up @@ -291,11 +297,10 @@ test "ListCompositeType - element type is ListBasicType" {

const UintType = @import("./uint.zig").createUintType(2);

const ZigListBasicType = []u16;

const SSZListBasicType = @import("./list_basic.zig").createListBasicType(UintType, u16);
const SSZListBasicType = @import("./list_basic.zig").createListBasicType(UintType);
const ZigListBasicType = SSZListBasicType.getZigType();

const ListCompositeType = createListCompositeType(SSZListBasicType, ZigListBasicType);
const ListCompositeType = createListCompositeType(SSZListBasicType);

var uintType = try UintType.init();
defer uintType.deinit();
Expand Down
9 changes: 9 additions & 0 deletions src/type/uint.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ pub fn createUintType(comptime num_bytes: usize) type {
min_size: usize,
max_size: usize,

/// Zig Type definition
pub fn getZigType() type {
return T;
}

pub fn getZigTypeAlignment() usize {
return num_bytes;
}

pub fn init() !@This() {
return @This(){ .fixed_size = num_bytes, .byte_length = num_bytes, .min_size = 0, .max_size = num_bytes };
}
Expand Down
16 changes: 13 additions & 3 deletions src/type/vector_basic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const Parsed = @import("./type.zig").Parsed;
/// Vector: Ordered fixed-length homogeneous collection, with N values
/// ST: ssz element type
/// ZT: zig element type
pub fn createVectorBasicType(comptime ST: type, comptime ZT: type) type {
pub fn createVectorBasicType(comptime ST: type) type {
const ZT = ST.getZigType();
const ArrayBasic = @import("./array_basic.zig").withElementTypes(ST, ZT);
const ParsedResult = Parsed([]ZT);

Expand All @@ -33,6 +34,15 @@ pub fn createVectorBasicType(comptime ST: type, comptime ZT: type) type {
// this should always be a multiple of 64 bytes
block_bytes: []u8,

/// Zig Type definition
pub fn getZigType() type {
return []ZT;
}

pub fn getZigTypeAlignment() usize {
return @alignOf([]ZT);
}

pub fn init(allocator: std.mem.Allocator, element_type: *ST, length: usize) !@This() {
const elem_byte_length = element_type.byte_length;
const byte_len = elem_byte_length * length;
Expand Down Expand Up @@ -145,7 +155,7 @@ test "deserializeFromBytes" {

// uint of 8 bytes = u64
const UintType = @import("./uint.zig").createUintType(8);
const VectorBasicType = createVectorBasicType(UintType, u64);
const VectorBasicType = createVectorBasicType(UintType);
var uintType = try UintType.init();
var vectorType = try VectorBasicType.init(allocator, &uintType, 8);
defer uintType.deinit();
Expand Down Expand Up @@ -199,7 +209,7 @@ test "deserializeFromJson" {

// uint of 8 bytes = u64
const UintType = @import("./uint.zig").createUintType(8);
const VectorBasicType = createVectorBasicType(UintType, u64);
const VectorBasicType = createVectorBasicType(UintType);
var uintType = try UintType.init();
var vectorType = try VectorBasicType.init(allocator, &uintType, 4);
defer uintType.deinit();
Expand Down
Loading
Loading