compiler: save conditional values at ref.func (#717)

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Takeshi Yoneda
2022-07-25 13:58:15 +09:00
committed by GitHub
parent 939403c10b
commit 143b2be398
5 changed files with 38 additions and 0 deletions

View File

@@ -4096,6 +4096,10 @@ func (c *amd64Compiler) compileTableFill(o *wazeroir.OperationTableFill) error {
// compileRefFunc implements compiler.compileRefFunc for the amd64 architecture.
func (c *amd64Compiler) compileRefFunc(o *wazeroir.OperationRefFunc) error {
if err := c.maybeCompileMoveTopConditionalToGeneralPurposeRegister(); err != nil {
return err
}
ref, err := c.allocateRegister(registerTypeGeneralPurpose)
if err != nil {
return err

View File

@@ -3696,6 +3696,10 @@ func (c *arm64Compiler) compileLoadElemInstanceAddress(elemIndex uint32, dst asm
// compileRefFunc implements compiler.compileRefFunc for the arm64 architecture.
func (c *arm64Compiler) compileRefFunc(o *wazeroir.OperationRefFunc) error {
if err := c.maybeCompileMoveTopConditionalToGeneralPurposeRegister(); err != nil {
return err
}
ref, err := c.allocateRegister(registerTypeGeneralPurpose)
if err != nil {
return err

View File

@@ -29,6 +29,8 @@ var (
case709 []byte
//go:embed testdata/715.wasm
case715 []byte
//go:embed testdata/716.wasm
case716 []byte
)
func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
@@ -159,3 +161,17 @@ func Test715(t *testing.T) {
require.Equal(t, uint64(1), res[0])
})
}
func Test716(t *testing.T) {
run(t, func(t *testing.T, r wazero.Runtime) {
mod, err := r.InstantiateModuleFromBinary(ctx, case716)
require.NoError(t, err)
f := mod.ExportedFunction("select on ref.func")
require.NotNil(t, f)
res, err := f.Call(ctx)
require.NoError(t, err)
require.Equal(t, uint64(1), res[0])
})
}

Binary file not shown.

View File

@@ -0,0 +1,14 @@
(module
(func (result i32)
i32.const 123
ref.null func
ref.is_null ;; -> 1
;; At this point, the result of ref.is_null (=1) is on the conditional register.
;; If table.size doesn't save the value into a general purpose register,
;; the result of select below becomes incorrect.
ref.func 0
ref.is_null ;; -> 0
select ;; should select 1
)
(export "select on ref.func" (func 0))
)