Skip to content

Commit

Permalink
Update for zig 0.10 (stage 2) (#139)
Browse files Browse the repository at this point in the history
* math.cast now returns ?u16 (?u32, etc) instead of !u16

* Use master for workflow

* Omit empty test name

* args.nextPosix -> args.next

* Update README to reflect zig version

* Move fib.wasm into src/ (otherwise it complains about an import from outside package)

* fn (*Interpreter) WasmError!void -> *const fn (*Interpreter) WasmError!void

* Bump @setEvalBranchQuota again

* @clz, @ctz, @popcount

* We have a table of function pointers

* Just switching the table to be *const gave me:

    unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'

The problem that seems to give with 0.10 stage2 is that I had been inlining
the dispatch call, but also calling that with .always_tail. This was nice
in that I could easily switch between inline dispatch and noinline dispatch
to compare the two. With the type check that now fails, because the inline
dispatch function type includes the fact that its calling convention is .Noinline
which is not _exactly_ the same as all of the instruction handlers.

To get around this for the moment I will just opt for only using inline.
I then need to just directly call dispatch (not with @call .always_tail).

The reason I can't now quickly check out switching dispatch to noinline
is that it will work yes, but it will cause stack frame allocations
which we absolutely do not want.

If Sema remains unchanged, one we might handle both is by having some
compile time flag that can be set that will directly call inline dispatch
in the case of wanting inline, and calling a noinline dispatch via @call
.always_tail if that's what we want.

The other alternative is that Sema is wrong and that instead of comparing
the complete function type (including calling convention) it should only
compare arg types and return types, in other words don't consider the
calling convention

* Fix source code test

* Fix module.zig tests

* Fix setEvalBranchQuota

* mem.set table
  • Loading branch information
malcolmstill authored Sep 2, 2022
1 parent 08ef0ca commit 02d4a40
Show file tree
Hide file tree
Showing 15 changed files with 264 additions and 252 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ jobs:
- uses: actions/checkout@v2
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.9.1
version: master
- run: zig build test
testsuite:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.9.1
version: master
- run: zig build --build-file test/build.zig --prefix ./
- run: cp bin/testrunner testrunner
- run: cp test/testsuite-generated/* ./
Expand Down Expand Up @@ -101,5 +101,5 @@ jobs:
- uses: actions/checkout@v2
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.9.1
version: master
- run: zig fmt --check src/*.zig
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
zig-cache
zig-out
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn main() !void {

### Compile-time

- Zig 0.9.1
- Zig 0.10.0

### Run-time

Expand Down Expand Up @@ -93,4 +93,4 @@ zig build --build-file test/build.zig --prefix ./

```
sh test/run-generated.sh
```
```
Binary file added examples/fib/src/fib.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion examples/fib/src/fib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn main() !void {

const alloc = arena.allocator();

const bytes = @embedFile("../../../test/fib.wasm");
const bytes = @embedFile("fib.wasm");

var store: Store = Store.init(alloc);

Expand Down
2 changes: 1 addition & 1 deletion src/function.zig
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub const Function = union(enum) {
instance: usize,
},
host_function: struct {
func: fn (*Interpreter) WasmError!void,
func: *const fn (*Interpreter) WasmError!void,
params: []const ValueType,
results: []const ValueType,
},
Expand Down
22 changes: 11 additions & 11 deletions src/instruction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,8 @@ pub const ParseIterator = struct {

if (block_type >= 0) {
const func_type = self.module.types.list.items[@intCast(usize, block_type)];
block_params = try math.cast(u16, func_type.params.len);
block_returns = try math.cast(u16, func_type.results.len);
block_params = math.cast(u16, func_type.params.len) orelse return error.FailedCast;
block_returns = math.cast(u16, func_type.results.len) orelse return error.FailedCast;
try self.validator.validateBlock(func_type.params, func_type.results);
} else {
if (block_type == -0x40) {
Expand Down Expand Up @@ -599,8 +599,8 @@ pub const ParseIterator = struct {
var block_returns: u16 = if (block_type == -0x40) 0 else 1;
if (block_type >= 0) {
const func_type = self.module.types.list.items[@intCast(usize, block_type)];
block_params = try math.cast(u16, func_type.params.len);
block_returns = try math.cast(u16, func_type.results.len);
block_params = math.cast(u16, func_type.params.len) orelse return error.FailedCast;
block_returns = math.cast(u16, func_type.results.len) orelse return error.FailedCast;
try self.validator.validateLoop(func_type.params, func_type.results);
} else {
if (block_type == -0x40) {
Expand All @@ -621,7 +621,7 @@ pub const ParseIterator = struct {
.loop = .{
.param_arity = block_params,
.return_arity = block_params,
.branch_target = try math.cast(u32, self.code_ptr),
.branch_target = math.cast(u32, self.code_ptr) orelse return error.FailedCast,
},
};
},
Expand All @@ -637,8 +637,8 @@ pub const ParseIterator = struct {
var block_returns: u16 = if (block_type == -0x40) 0 else 1;
if (block_type >= 0) {
const func_type = self.module.types.list.items[@intCast(usize, block_type)];
block_params = try math.cast(u16, func_type.params.len);
block_returns = try math.cast(u16, func_type.results.len);
block_params = math.cast(u16, func_type.params.len) orelse return error.FailedCast;
block_returns = math.cast(u16, func_type.results.len) orelse return error.FailedCast;
try self.validator.validateIf(func_type.params, func_type.results);
} else {
if (block_type == -0x40) {
Expand Down Expand Up @@ -673,7 +673,7 @@ pub const ParseIterator = struct {
.param_arity = b.param_arity,
.return_arity = b.return_arity,
.branch_target = 0,
.else_ip = try math.cast(u32, self.code_ptr + 1),
.else_ip = math.cast(u32, self.code_ptr + 1) orelse return error.FailedCast,
},
};
},
Expand All @@ -688,16 +688,16 @@ pub const ParseIterator = struct {
const parsed_code_offset = try self.popContinuationStack();

switch (self.parsed.items[parsed_code_offset]) {
.block => |*b| b.branch_target = try math.cast(u32, self.code_ptr + 1),
.block => |*b| b.branch_target = math.cast(u32, self.code_ptr + 1) orelse return error.FailedCast,
.loop => {},
.@"if" => |*b| {
b.branch_target = try math.cast(u32, self.code_ptr + 1);
b.branch_target = math.cast(u32, self.code_ptr + 1) orelse return error.FailedCast;
},
.if_no_else => |*b| {
// We have an if with no else, check that this works arity-wise and replace with fast if
if (b.param_arity -% b.return_arity != 0) return error.ValidatorElseBranchExpected;

b.branch_target = try math.cast(u32, self.code_ptr + 1);
b.branch_target = math.cast(u32, self.code_ptr + 1) orelse return error.FailedCast;
},
else => return error.UnexpectedInstruction,
}
Expand Down
Loading

0 comments on commit 02d4a40

Please sign in to comment.