Skip to content

Commit

Permalink
Initial support for new element section format
Browse files Browse the repository at this point in the history
- The element section if backwards compatible, so take the code
  after reading the table index and put that in a case for elem
  type 0
- All other elem types not yet implemented
- Adds RefType and NumType enums and expands ValueType
  • Loading branch information
malcolmstill committed Sep 4, 2022
1 parent 5bc6fcf commit 8344d85
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 34 deletions.
16 changes: 16 additions & 0 deletions src/common.zig
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,27 @@ pub const Mutability = enum(u8) {
Mutable,
};

pub const NumType = enum(u8) {
I32 = 0x7F,
I64 = 0x7E,
F32 = 0x7D,
F64 = 0x7C,
V128 = 0x7B,
};

pub const RefType = enum(u8) {
FuncRef = 0x70,
ExternRef = 0x6F,
};

pub const ValueType = enum(u8) {
I32 = 0x7F,
I64 = 0x7E,
F32 = 0x7D,
F64 = 0x7C,
V128 = 0x7B,
FuncRef = 0x70,
ExternRef = 0x6F,
};

pub fn valueTypeFromBlockType(block_type: i32) !ValueType {
Expand Down
12 changes: 12 additions & 0 deletions src/instruction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ const I32_OUT = [1]ValueType{.I32} ** 1;
const I64_OUT = [1]ValueType{.I64} ** 1;
const F32_OUT = [1]ValueType{.F32} ** 1;
const F64_OUT = [1]ValueType{.F64} ** 1;
const V128_OUT = [1]ValueType{.V128} ** 1;
const FUNCREF_OUT = [1]ValueType{.FuncRef} ** 1;
const EXTERNREF_OUT = [1]ValueType{.ExternRef} ** 1;

pub const ParseIterator = struct {
function: []const u8,
Expand Down Expand Up @@ -592,6 +595,9 @@ pub const ParseIterator = struct {
.I64 => try self.validator.validateBlock(EMPTY[0..], I64_OUT[0..]),
.F32 => try self.validator.validateBlock(EMPTY[0..], F32_OUT[0..]),
.F64 => try self.validator.validateBlock(EMPTY[0..], F64_OUT[0..]),
.V128 => try self.validator.validateBlock(EMPTY[0..], V128_OUT[0..]),
.FuncRef => try self.validator.validateBlock(EMPTY[0..], FUNCREF_OUT[0..]),
.ExternRef => try self.validator.validateBlock(EMPTY[0..], EXTERNREF_OUT[0..]),
}
}
}
Expand Down Expand Up @@ -625,6 +631,9 @@ pub const ParseIterator = struct {
.I64 => try self.validator.validateLoop(EMPTY[0..], I64_OUT[0..]),
.F32 => try self.validator.validateLoop(EMPTY[0..], F32_OUT[0..]),
.F64 => try self.validator.validateLoop(EMPTY[0..], F64_OUT[0..]),
.V128 => try self.validator.validateBlock(EMPTY[0..], V128_OUT[0..]),
.FuncRef => try self.validator.validateBlock(EMPTY[0..], FUNCREF_OUT[0..]),
.ExternRef => try self.validator.validateBlock(EMPTY[0..], EXTERNREF_OUT[0..]),
}
}
}
Expand Down Expand Up @@ -663,6 +672,9 @@ pub const ParseIterator = struct {
.I64 => try self.validator.validateIf(EMPTY[0..], I64_OUT[0..]),
.F32 => try self.validator.validateIf(EMPTY[0..], F32_OUT[0..]),
.F64 => try self.validator.validateIf(EMPTY[0..], F64_OUT[0..]),
.V128 => try self.validator.validateBlock(EMPTY[0..], V128_OUT[0..]),
.FuncRef => try self.validator.validateBlock(EMPTY[0..], FUNCREF_OUT[0..]),
.ExternRef => try self.validator.validateBlock(EMPTY[0..], EXTERNREF_OUT[0..]),
}
}
}
Expand Down
77 changes: 43 additions & 34 deletions src/module.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const Opcode = @import("opcode.zig").Opcode;
const ParseIterator = instruction.ParseIterator;
const OpcodeIterator = instruction.OpcodeIterator;
const FuncType = common.FuncType;
const NumType = common.NumType;
const RefType = common.ValueType;
const ValueType = common.ValueType;
const Import = common.Import;
const Export = common.Export;
Expand Down Expand Up @@ -608,49 +610,56 @@ pub const Module = struct {

var i: usize = 0;
while (i < count) : (i += 1) {
const table_index = leb.readULEB128(u32, rd) catch |err| switch (err) {
const elem_type = leb.readULEB128(u32, rd) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};

if (table_index >= self.tables.list.items.len) return error.ValidatorElemUnknownTable;
switch (elem_type) {
0 => {
const table_index = 0;

const expr_start = rd.context.pos;
const expr = self.module[expr_start..];
const meta = try opcode.findExprEnd(expr);
if (table_index >= self.tables.list.items.len) return error.ValidatorElemUnknownTable;

rd.skipBytes(meta.offset + 1, .{}) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};
const expr_start = rd.context.pos;
const expr = self.module[expr_start..];
const meta = try opcode.findExprEnd(expr);

// Number of u32's in our data (not the length in bytes!)
const data_length = leb.readULEB128(u32, rd) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};
const data_start = rd.context.pos;

var j: usize = 0;
while (j < data_length) : (j += 1) {
// When we pre-process all this data we can just store this
// but for the moment we're just using it to skip over
const func_index = leb.readULEB128(u32, rd) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};
rd.skipBytes(meta.offset + 1, .{}) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};

if (func_index >= self.functions.list.items.len) return error.ValidatorElemUnknownFunctionIndex;
// Number of u32's in our data (not the length in bytes!)
const data_length = leb.readULEB128(u32, rd) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};
const data_start = rd.context.pos;

var j: usize = 0;
while (j < data_length) : (j += 1) {
// When we pre-process all this data we can just store this
// but for the moment we're just using it to skip over
const func_index = leb.readULEB128(u32, rd) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEndOfInput,
else => return err,
};

if (func_index >= self.functions.list.items.len) return error.ValidatorElemUnknownFunctionIndex;
}

const parsed_code = try self.parseConstantCode(self.module[expr_start .. expr_start + meta.offset + 1], .I32);

try self.elements.list.append(Segment{
.index = table_index,
.start = parsed_code.start,
.count = data_length,
.data = self.module[data_start..rd.context.pos],
});
},
else => return error.ValidatorElemTypeNotImplemented,
}

const parsed_code = try self.parseConstantCode(self.module[expr_start .. expr_start + meta.offset + 1], .I32);

try self.elements.list.append(Segment{
.index = table_index,
.start = parsed_code.start,
.count = data_length,
.data = self.module[data_start..rd.context.pos],
});
}
}

Expand Down

0 comments on commit 8344d85

Please sign in to comment.