diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index b503b0a818a..407043cc7b7 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -226,6 +226,16 @@ class EvallingModuleRunner : public ModuleRunnerBase { throw FailToEvalException("TODO: table.get"); } + Flow visitTableSet(TableSet* curr) { + // When changes occur to the table, give up. + throw FailToEvalException("TODO: table.set"); + } + + Flow visitTableGrow(TableGrow* curr) { + // When changes occur to the table, give up. + throw FailToEvalException("TODO: table.grow"); + } + bool allowContNew = true; Flow visitContNew(ContNew* curr) { diff --git a/test/lit/ctor-eval/start-table.wast b/test/lit/ctor-eval/start-table.wast new file mode 100644 index 00000000000..9d33ae42137 --- /dev/null +++ b/test/lit/ctor-eval/start-table.wast @@ -0,0 +1,102 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: foreach %s %t wasm-ctor-eval --ctors=test --kept-exports=test --quiet -all -S -o - | filecheck %s + +;; The table.set in the start alters what is called indirectly later. We do not +;; handle this yet, but at least do not misoptimize. TODO +(module + ;; CHECK: (type $func (func)) + (type $func (func)) + + ;; CHECK: (table $t 48 48 funcref) + (table $t 48 48 funcref) + + ;; CHECK: (elem $e (i32.const 0) $target) + (elem $e (i32.const 0) $target) + + ;; CHECK: (export "test" (func $test)) + + ;; CHECK: (start $start) + (start $start) + + ;; CHECK: (func $start (type $func) + ;; CHECK-NEXT: (table.set $t + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (ref.null nofunc) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $start + (table.set $t + (i32.const 0) + (ref.null nofunc) + ) + ) + + ;; CHECK: (func $test (type $func) + ;; CHECK-NEXT: (call_indirect $t (type $func) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (export "test") + (call_indirect (type $func) + (i32.const 0) + ) + ) + + ;; CHECK: (func $target (type $func) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $target + ) +) + +;; Similar, but with grow. We also do not optimize TODO +(module + ;; CHECK: (type $func (func)) + (type $func (func)) + + ;; CHECK: (table $t 48 48 funcref) + (table $t 48 48 funcref) + + ;; CHECK: (elem $e (i32.const 0) $target) + (elem $e (i32.const 0) $target) + + ;; CHECK: (export "test" (func $test)) + + ;; CHECK: (start $start) + (start $start) + + ;; CHECK: (func $start (type $func) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (table.grow $t + ;; CHECK-NEXT: (ref.null nofunc) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $start + (drop + (table.grow $t + (ref.null nofunc) + (i32.const 0) + ) + ) + ) + + ;; CHECK: (func $test (type $func) + ;; CHECK-NEXT: (call_indirect $t (type $func) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (export "test") + (call_indirect (type $func) + (i32.const 0) + ) + ) + + ;; CHECK: (func $target (type $func) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $target + ) +) +