binaryen
binaryen copied to clipboard
wasm-ctor-eval: Handle cycles with non-nullable content
(module
(type $A (sub final (struct (field (mut (ref struct))))))
(type $B (struct ))
(import "a" "b" (func $import))
(func "test"
(local $temp (ref $A))
(struct.set $A 0
(local.tee $temp
(struct.new $A
(struct.new_default $B)
)
)
(local.get $temp)
)
;; Stop evalling here, forcing us to serialize what we've seen so far in this
;; function, including its locals
;;
;; The local $temp contains a struct with a cycle now, and the cycle is on a
;; field that is mutable but *non*-nullable, so we can't use the usual trick
;; of writing a null initial value and fixing it up later. Instead, we need to
;; write some other type of value initially.
(call $import)
)
)
$ wasm-ctor-eval a.wat -all --ctors=test --kept-exports=test
trying to eval test
wasm-ctor-eval: wasm-ctor-eval.cpp:757: bool {anonymous}::CtorEvalExternalInterface::applyGlobalsToModule()::InitFixer::handleChild(wasm::Expression*&, wasm::Expression*, wasm::Index): Assertion `isNullableAndMutable(parent, fieldIndex)' failed.
Aborted
The input module cleverly creates a cycle using a non-nullable field by creating a temporary object just for that purpose. wasm-ctor-eval would need to be similarly clever, which seems difficult in general...