cranelift-wasm: support multi-value Wasm (#1049)

This commit introduces initial support for multi-value Wasm. Wasm blocks and
calls can now take and return an arbitrary number of values.

The encoding for multi-value blocks means that we need to keep the contents of
the "Types" section around when translating function bodies. To do this, we
introduce a `WasmTypesMap` type that maps the type indices to their parameters
and returns, construct it when parsing the "Types" section, and shepherd it
through a bunch of functions and methods when translating function bodies.
This commit is contained in:
Nick Fitzgerald
2019-10-02 12:40:35 -07:00
committed by GitHub
parent f9d802fb1d
commit 10be3e4ba8
30 changed files with 610 additions and 138 deletions

View File

@@ -0,0 +1,19 @@
(module
;; Iterative factorial without locals.
(func $pick0 (param i64) (result i64 i64)
(get_local 0) (get_local 0)
)
(func $pick1 (param i64 i64) (result i64 i64 i64)
(get_local 0) (get_local 1) (get_local 0)
)
(func (export "fac-ssa") (param i64) (result i64)
(i64.const 1) (get_local 0)
(loop $l (param i64 i64) (result i64)
(call $pick1) (call $pick1) (i64.mul)
(call $pick1) (i64.const 1) (i64.sub)
(call $pick0) (i64.const 0) (i64.gt_u)
(br_if $l)
(drop) (return)
)
)
)

View File

@@ -0,0 +1,3 @@
(module
(func (export "i64.dup") (param i64) (result i64 i64)
(get_local 0) (get_local 0)))

View File

@@ -0,0 +1,6 @@
(module
(func (export "multiBlock") (param i64 i32) (result i32 i64 f64)
(local.get 1)
(local.get 0)
(block (param i32 i64) (result i32 i64 f64)
(f64.const 1234.5))))

View File

@@ -0,0 +1,10 @@
(module
(func (export "f") (param i64 i32) (result i64 i64)
(local.get 0)
(local.get 1)
;; If with else. Fewer params than results.
(if (param i64) (result i64 i64)
(then
(i64.const -1))
(else
(i64.const -2)))))

View File

@@ -0,0 +1,7 @@
(module
(func (export "multiLoop") (param i64) (result i64 i64)
(local.get 0)
;; Fewer params than results.
(loop (param i64) (result i64 i64)
i64.const 42
return)))

View File

@@ -0,0 +1,9 @@
(module
(func (export "multiLoop") (param i64 i64 i64) (result i64 i64)
(local.get 2)
(local.get 1)
(local.get 0)
;; More params than results.
(loop (param i64 i64 i64) (result i64 i64)
drop
return)))

View File

@@ -0,0 +1,10 @@
(module
(func (export "as-if-then") (param i32 i32) (result i32)
(block (result i32)
(if (result i32) (local.get 0)
(then (br 1 (i32.const 3)))
(else (local.get 1))
)
)
)
)

View File

@@ -0,0 +1,10 @@
(module
(func (export "as-if-else") (param i32 i32) (result i32)
(block (result i32)
(if (result i32) (local.get 0)
(then (local.get 1))
(else (br 1 (i32.const 4)))
)
)
)
)

View File

@@ -0,0 +1,22 @@
(module
(func (export "large-sig")
(param i32 i64 f32 f32 i32 f64 f32 i32 i32 i32 f32 f64 f64 f64 i32 i32 f32)
(result f64 f32 i32 i32 i32 i64 f32 i32 i32 f32 f64 f64 i32 f32 i32 f64)
(local.get 5)
(local.get 2)
(local.get 0)
(local.get 8)
(local.get 7)
(local.get 1)
(local.get 3)
(local.get 9)
(local.get 4)
(local.get 6)
(local.get 13)
(local.get 11)
(local.get 15)
(local.get 16)
(local.get 14)
(local.get 12)
)
)

View File

@@ -0,0 +1,6 @@
(module
(func (export "multiLoop") (param i64 i64) (result i64 i64)
(local.get 1)
(local.get 0)
(loop (param i64 i64) (result i64 i64)
return)))

View File

@@ -0,0 +1,13 @@
(module
(func (export "multiIf") (param i32 i64 i64) (result i64 i64)
(local.get 2)
(local.get 1)
(local.get 0)
(if (param i64 i64) (result i64 i64)
(then return)
;; Hits the code path for an `else` after a block that ends unreachable.
(else
(drop)
(drop)
(i64.const 0)
(i64.const 0)))))

View File

@@ -0,0 +1,13 @@
(module
(func (export "multiIf2") (param i32 i64 i64) (result i64 i64)
(local.get 2)
(local.get 1)
(local.get 0)
(if (param i64 i64) (result i64 i64)
(then
i64.add
i64.const 1)
;; Hits the code path for an `else` after a block that does not end unreachable.
(else
i64.sub
i64.const 2))))

View File

@@ -0,0 +1,11 @@
(module
(func (export "foo")
i32.const 1
i64.const 2
;; More params than results.
(block (param i32 i64) (result i32)
drop
)
drop
)
)

View File

@@ -0,0 +1,11 @@
(module
(func (export "foo")
i32.const 1
;; Fewer params than results.
(block (param i32) (result i32 i64)
i64.const 2
)
drop
drop
)
)

View File

@@ -0,0 +1,9 @@
(module
(func (export "f") (param i64 i32) (result i64)
(local.get 0)
(local.get 1)
;; If with no else. Same number of params and results.
(if (param i64) (result i64)
(then
(drop)
(i64.const -1)))))

View File

@@ -0,0 +1,12 @@
(module
(func (export "f") (param i64 i32) (result i64)
(local.get 0)
(local.get 1)
;; If with else. Same number of params and results.
(if (param i64) (result i64)
(then
(drop)
(i64.const -1))
(else
(drop)
(i64.const -2)))))

View File

@@ -0,0 +1,15 @@
(module
(func (export "f") (param i64 i32) (result i64)
(local.get 0)
(local.get 1)
(local.get 1)
;; If with else. More params than results.
(if (param i64 i32) (result i64)
(then
(drop)
(drop)
(i64.const -1))
(else
(drop)
(drop)
(i64.const -2)))))