From 84d86362aeeea749af149831ea0cafb7ba2fe046 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 11:55:11 -0700 Subject: [PATCH 1/9] go --- src/tools/wasm-ctor-eval.cpp | 15 +- test/lit/ctor-eval/gc-cycle.wast | 264 +++++++++++++-------------- test/lit/ctor-eval/partial-local.wat | 75 ++++++++ 3 files changed, 216 insertions(+), 138 deletions(-) create mode 100644 test/lit/ctor-eval/partial-local.wat diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index c8fe1d5e385..bcdc4dfa25a 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -288,6 +288,9 @@ std::unique_ptr buildEnvModule(Module& wasm) { // that there are not arguments passed to main, etc. static bool ignoreExternalInput = false; +// Whether to emit informative logging to stdout about the eval process. +static bool quiet = false; + struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { Module* wasm; EvallingModuleRunner* instance; @@ -328,8 +331,6 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { firstApplication = false; } - clearApplyState(); - // If nothing was ever written to memories then there is nothing to update. if (!memories.empty()) { applyMemoryToModule(); @@ -529,8 +530,10 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { return Bits::readLE(getMemory(address, memoryName, sizeof(T))); } +public: // Clear the state of the operation of applying the interpreter's runtime - // information into the module. + // information into the module. This must be done before we start to serialize + // content. After this, seriqli // // This happens each time we apply contents to the module, which is basically // once per ctor function, but can be more fine-grained also if we execute a @@ -545,6 +548,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { // them). clearStartBlock(); } +private: void applyMemoryToModule() { // Memory must have already been flattened into the standard form: one @@ -1062,9 +1066,6 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { } }; -// Whether to emit informative logging to stdout about the eval process. -static bool quiet = false; - // The outcome of evalling a ctor is one of three states: // // 1. We failed to eval it completely (but perhaps we succeeded partially). In @@ -1211,6 +1212,7 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance, // Serialize the arguments for the new function and save the module // state in case we fail to eval the new function. + interface.clearApplyState(); localExprs.clear(); for (auto& param : params) { auto* serialized = interface.getSerialization(param); @@ -1241,6 +1243,7 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance, // of them, and leave it to the optimizer to remove redundant or // unnecessary operations. We just recompute the entire local // serialization sets from scratch each time here, for all locals. + interface.clearApplyState(); localExprs.clear(); for (Index i = 0; i < func->getNumLocals(); i++) { auto* serialized = interface.getSerialization(scope.locals[i]); diff --git a/test/lit/ctor-eval/gc-cycle.wast b/test/lit/ctor-eval/gc-cycle.wast index faf26c4adec..6d4f0726730 100644 --- a/test/lit/ctor-eval/gc-cycle.wast +++ b/test/lit/ctor-eval/gc-cycle.wast @@ -9,12 +9,12 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_3 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_2 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_3)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_2)) (global $a (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -64,8 +64,8 @@ ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_3) -;; CHECK-NEXT: (global.get $ctor-eval$global_3) +;; CHECK-NEXT: (global.get $ctor-eval$global_2) +;; CHECK-NEXT: (global.get $ctor-eval$global_2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -84,12 +84,12 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_3 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_2 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_3)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_2)) (global $a (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -132,8 +132,8 @@ ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 1 -;; CHECK-NEXT: (global.get $ctor-eval$global_3) -;; CHECK-NEXT: (global.get $ctor-eval$global_3) +;; CHECK-NEXT: (global.get $ctor-eval$global_2) +;; CHECK-NEXT: (global.get $ctor-eval$global_2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -151,20 +151,20 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_7 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_5 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_8 (ref (exact $A)) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_7) + ;; CHECK: (global $ctor-eval$global_6 (ref (exact $A)) (struct.new $A + ;; CHECK-NEXT: (global.get $ctor-eval$global_5) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_5)) (global $a (mut (ref null $A)) (ref.null $A)) - ;; CHECK: (global $b (mut (ref null $A)) (global.get $ctor-eval$global_8)) + ;; CHECK: (global $b (mut (ref null $A)) (global.get $ctor-eval$global_6)) (global $b (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -223,8 +223,8 @@ ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_7) -;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -250,20 +250,20 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_7 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_5 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_8 (ref (exact $B)) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_7) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_5)) + (global $a (mut (ref null $A)) (ref.null $A)) + + ;; CHECK: (global $ctor-eval$global_6 (ref (exact $B)) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_5) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) - (global $a (mut (ref null $A)) (ref.null $A)) - - ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_8)) + ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_6)) (global $b (mut (ref null $B)) (ref.null $B)) (func $test (export "test") @@ -321,8 +321,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_7) -;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -348,19 +348,19 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_7 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_5 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_8 (ref (exact $B)) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_7) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_5)) + + ;; CHECK: (global $ctor-eval$global_6 (ref (exact $B)) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_5) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) - - ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_8)) + ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_6)) (global $b (mut (ref null $B)) (ref.null $B)) (global $a (mut (ref null $A)) (ref.null $A)) @@ -420,8 +420,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_7) -;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -446,17 +446,12 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_7 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_5 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_8 (ref (exact $B)) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_7) - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_5)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -486,6 +481,11 @@ ) ) + ;; CHECK: (global $ctor-eval$global_6 (ref (exact $B)) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_5) + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: )) + ;; CHECK: (export "test" (func $test_3)) ;; CHECK: (export "keepalive" (func $keepalive)) @@ -506,8 +506,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_7) -;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -536,17 +536,12 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_7 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_5 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_8 (ref (exact $B)) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_7) - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_5)) (global $a (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -574,6 +569,11 @@ ) ) + ;; CHECK: (global $ctor-eval$global_6 (ref (exact $B)) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_5) + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: )) + ;; CHECK: (export "test" (func $test_3)) ;; CHECK: (export "keepalive" (func $keepalive)) @@ -594,8 +594,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_7) -;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -614,22 +614,22 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_12 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_9 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_14 (ref (exact $A)) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK: (global $ctor-eval$global_11 (ref (exact $A)) (struct.new $A + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_13 (ref (exact $A)) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK: (global $ctor-eval$global_10 (ref (exact $A)) (struct.new $A + ;; CHECK-NEXT: (global.get $ctor-eval$global_11) ;; CHECK-NEXT: (i32.const 99999) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_12)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_9)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $A)) (ref.null $A)) @@ -690,8 +690,8 @@ ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_12) -;; CHECK-NEXT: (global.get $ctor-eval$global_13) +;; CHECK-NEXT: (global.get $ctor-eval$global_9) +;; CHECK-NEXT: (global.get $ctor-eval$global_10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -725,25 +725,12 @@ ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_12 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_9 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_14 (ref (exact $B)) (array.new_fixed $B 10 - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_12)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_9)) (global $a (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -780,9 +767,22 @@ ) ) - ;; CHECK: (global $ctor-eval$global_13 (ref (exact $C)) (array.new_fixed $C 2 - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK: (global $ctor-eval$global_11 (ref (exact $B)) (array.new_fixed $B 10 + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $ctor-eval$global_10 (ref (exact $C)) (array.new_fixed $C 2 + ;; CHECK-NEXT: (global.get $ctor-eval$global_11) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) ;; CHECK-NEXT: )) ;; CHECK: (export "test" (func $test_3)) @@ -805,8 +805,8 @@ ;; CHECK: (func $start (type $3) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_12) -;; CHECK-NEXT: (global.get $ctor-eval$global_13) +;; CHECK-NEXT: (global.get $ctor-eval$global_9) +;; CHECK-NEXT: (global.get $ctor-eval$global_10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -833,25 +833,12 @@ ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_12 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_9 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_14 (ref (exact $B)) (array.new_fixed $B 10 - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_12)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_9)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -892,9 +879,22 @@ ) ) - ;; CHECK: (global $ctor-eval$global_13 (ref (exact $C)) (array.new_fixed $C 2 - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK: (global $ctor-eval$global_11 (ref (exact $B)) (array.new_fixed $B 10 + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $ctor-eval$global_10 (ref (exact $C)) (array.new_fixed $C 2 + ;; CHECK-NEXT: (global.get $ctor-eval$global_11) + ;; CHECK-NEXT: (global.get $ctor-eval$global_9) ;; CHECK-NEXT: )) ;; CHECK: (export "test" (func $test_3)) @@ -917,8 +917,8 @@ ;; CHECK: (func $start (type $3) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_12) -;; CHECK-NEXT: (global.get $ctor-eval$global_13) +;; CHECK-NEXT: (global.get $ctor-eval$global_9) +;; CHECK-NEXT: (global.get $ctor-eval$global_10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -944,7 +944,7 @@ ;; CHECK: (type $3 (func (result anyref))) - ;; CHECK: (global $ctor-eval$global_17 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_11 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) @@ -956,13 +956,13 @@ ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_18 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_15 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_14)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_11)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -994,15 +994,15 @@ ) ) - ;; CHECK: (global $ctor-eval$global_16 (ref (exact $B)) (array.new_fixed $B 3 - ;; CHECK-NEXT: (global.get $ctor-eval$global_17) + ;; CHECK: (global $ctor-eval$global_13 (ref (exact $B)) (array.new_fixed $B 3 ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_18) + ;; CHECK-NEXT: (global.get $ctor-eval$global_11) + ;; CHECK-NEXT: (global.get $ctor-eval$global_15) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_15 (ref (exact $B)) (array.new_fixed $B 0)) + ;; CHECK: (global $ctor-eval$global_12 (ref (exact $B)) (array.new_fixed $B 0)) - ;; CHECK: (global $ctor-eval$global_19 (ref (exact $B)) (array.new_fixed $B 0)) + ;; CHECK: (global $ctor-eval$global_16 (ref (exact $B)) (array.new_fixed $B 0)) ;; CHECK: (export "test" (func $test_3)) @@ -1024,16 +1024,16 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_14) -;; CHECK-NEXT: (global.get $ctor-eval$global_15) +;; CHECK-NEXT: (global.get $ctor-eval$global_11) +;; CHECK-NEXT: (global.get $ctor-eval$global_12) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.set $A 1 -;; CHECK-NEXT: (global.get $ctor-eval$global_14) -;; CHECK-NEXT: (global.get $ctor-eval$global_16) +;; CHECK-NEXT: (global.get $ctor-eval$global_11) +;; CHECK-NEXT: (global.get $ctor-eval$global_13) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.set $A 2 -;; CHECK-NEXT: (global.get $ctor-eval$global_14) -;; CHECK-NEXT: (global.get $ctor-eval$global_19) +;; CHECK-NEXT: (global.get $ctor-eval$global_11) +;; CHECK-NEXT: (global.get $ctor-eval$global_16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1056,23 +1056,23 @@ ;; CHECK: (type $3 (func (result anyref))) - ;; CHECK: (global $ctor-eval$global_17 (ref (exact $B)) (array.new_fixed $B 0)) - - ;; CHECK: (global $ctor-eval$global_14 (ref (exact $B)) (array.new_fixed $B 3 + ;; CHECK: (global $ctor-eval$global_11 (ref (exact $B)) (array.new_fixed $B 3 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_18 (ref (exact $B)) (array.new_fixed $B 0)) + ;; CHECK: (global $ctor-eval$global_14 (ref (exact $B)) (array.new_fixed $B 0)) - ;; CHECK: (global $ctor-eval$global_16 (ref (exact $A)) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_17) + ;; CHECK: (global $ctor-eval$global_15 (ref (exact $B)) (array.new_fixed $B 0)) + + ;; CHECK: (global $ctor-eval$global_13 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_18) + ;; CHECK-NEXT: (global.get $ctor-eval$global_11) + ;; CHECK-NEXT: (global.get $ctor-eval$global_15) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_16)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_13)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -1105,13 +1105,13 @@ ) ) - ;; CHECK: (global $ctor-eval$global_15 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_12 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_19 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_16 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) @@ -1137,19 +1137,19 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (array.set $B -;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (global.get $ctor-eval$global_11) ;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: (global.get $ctor-eval$global_15) +;; CHECK-NEXT: (global.get $ctor-eval$global_12) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (array.set $B -;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (global.get $ctor-eval$global_11) ;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: (global.get $ctor-eval$global_16) +;; CHECK-NEXT: (global.get $ctor-eval$global_13) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (array.set $B -;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (global.get $ctor-eval$global_11) ;; CHECK-NEXT: (i32.const 2) -;; CHECK-NEXT: (global.get $ctor-eval$global_19) +;; CHECK-NEXT: (global.get $ctor-eval$global_16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1169,12 +1169,12 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_4 (ref (exact $A)) (struct.new $A + ;; CHECK: (global $ctor-eval$global_3 (ref (exact $A)) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_4)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_3)) (global $a (mut (ref null $A)) (ref.null $A)) ;; CHECK: (global $b (mut (ref null $A)) (ref.null none)) @@ -1234,8 +1234,8 @@ ;; CHECK: (func $start_3 (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_4) -;; CHECK-NEXT: (global.get $ctor-eval$global_4) +;; CHECK-NEXT: (global.get $ctor-eval$global_3) +;; CHECK-NEXT: (global.get $ctor-eval$global_3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/ctor-eval/partial-local.wat b/test/lit/ctor-eval/partial-local.wat new file mode 100644 index 00000000000..9680eef15c8 --- /dev/null +++ b/test/lit/ctor-eval/partial-local.wat @@ -0,0 +1,75 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-ctor-eval %s --ctors=test --kept-exports=test --quiet -all -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (sub (struct (field i32) (field i32) (field (mut (ref null $0))) (field exnref)))) + (type $0 (sub (struct (field i32) (field i32) (field (mut (ref null $0))) (field exnref)))) + ;; CHECK: (type $1 (func)) + (type $1 (func)) + (import "__fuzz_import" "extern$" (global $gimport$0 externref)) + (global $global$0 (ref null $0) (struct.new $0 + (i32.const 0) + (i32.const 0) + (struct.new_default $0) + (ref.null noexn) + )) + (export "test" (func $0)) + (func $0 + (local $0 (ref $0)) + (local $1 (ref $0)) + (local $2 (ref $0)) + (local $3 (ref $0)) + (local $4 (ref $0)) + (local $5 (ref $0)) + (local.set $5 + (ref.as_non_null + (global.get $global$0) + ) + ) + (nop) + (drop + (global.get $gimport$0) + ) + (drop + (ref.as_non_null + (struct.get $0 2 + (local.get $5) + ) + ) + ) + ) +) +;; CHECK: (global $ctor-eval$global_4 (ref (exact $0)) (struct.new $0 +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: (ref.null noexn) +;; CHECK-NEXT: )) + +;; CHECK: (global $ctor-eval$global_5 (ref (exact $0)) (struct.new $0 +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (ref.null none) +;; CHECK-NEXT: (ref.null noexn) +;; CHECK-NEXT: )) + +;; CHECK: (export "test" (func $0_2)) + +;; CHECK: (start $start) + +;; CHECK: (func $start (type $1) +;; CHECK-NEXT: (struct.set $0 2 +;; CHECK-NEXT: (global.get $ctor-eval$global_4) +;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $0_2 (type $1) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (ref.as_non_null +;; CHECK-NEXT: (struct.get $0 2 +;; CHECK-NEXT: (global.get $ctor-eval$global_4) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) From ae44518b14dfd524a1074279c968f960f7a6903b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 11:56:45 -0700 Subject: [PATCH 2/9] clean --- src/tools/wasm-ctor-eval.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index bcdc4dfa25a..52042676972 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -533,11 +533,8 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { public: // Clear the state of the operation of applying the interpreter's runtime // information into the module. This must be done before we start to serialize - // content. After this, seriqli - // - // This happens each time we apply contents to the module, which is basically - // once per ctor function, but can be more fine-grained also if we execute a - // line at a time. + // content. After this, serialization can happen, and after that, a call to + // applyToModule() can be done. void clearApplyState() { // The process of allocating "defining globals" begins here, from scratch // each time (things live before may no longer be). @@ -1204,6 +1201,10 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance, break; } + // We are about to serialize content (the code paths below call + // getSerialization). Clear the state. + interface.clearApplyState(); + if (flow.breakTo == RETURN_CALL_FLOW) { // The return-called function is stored in the last value. func = wasm.getFunction(flow.values.back().getFunc()); @@ -1212,7 +1213,6 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance, // Serialize the arguments for the new function and save the module // state in case we fail to eval the new function. - interface.clearApplyState(); localExprs.clear(); for (auto& param : params) { auto* serialized = interface.getSerialization(param); @@ -1243,7 +1243,6 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance, // of them, and leave it to the optimizer to remove redundant or // unnecessary operations. We just recompute the entire local // serialization sets from scratch each time here, for all locals. - interface.clearApplyState(); localExprs.clear(); for (Index i = 0; i < func->getNumLocals(); i++) { auto* serialized = interface.getSerialization(scope.locals[i]); From 7667ca617b3e1c84380db5e0b1009549447fa75f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 11:56:51 -0700 Subject: [PATCH 3/9] format --- src/tools/wasm-ctor-eval.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 52042676972..017a85687a1 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -545,8 +545,8 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { // them). clearStartBlock(); } -private: +private: void applyMemoryToModule() { // Memory must have already been flattened into the standard form: one // segment at offset 0, or none. From b4dc15d60ce3d504d1b3f6bc5d0b0c18c6a03460 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 12:07:47 -0700 Subject: [PATCH 4/9] nice --- test/lit/ctor-eval/partial-local.wat | 50 ++++++++++++++++------------ 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/test/lit/ctor-eval/partial-local.wat b/test/lit/ctor-eval/partial-local.wat index 9680eef15c8..203b6a1426b 100644 --- a/test/lit/ctor-eval/partial-local.wat +++ b/test/lit/ctor-eval/partial-local.wat @@ -1,19 +1,30 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: wasm-ctor-eval %s --ctors=test --kept-exports=test --quiet -all -S -o - | filecheck %s +;; When executed, the single export reads from $global, and makes sure +;; the value is non-null. It then reads an imported global, then reads something +;; from the first global, and makes sure that is non-null. This code executes +;; without error. + +;; wasm-ctor-eval evals away the get of $global$0`, since it sees all the data +;; It stops at the read of the imported global, since that value depends on run +;; We should leave the module in a valid state: globals appear, and a start +;; function which applies one to the other. It should apply to the same global +;; that is then read from the remaining code in the export. + (module - ;; CHECK: (type $0 (sub (struct (field i32) (field i32) (field (mut (ref null $0))) (field exnref)))) - (type $0 (sub (struct (field i32) (field i32) (field (mut (ref null $0))) (field exnref)))) - ;; CHECK: (type $1 (func)) - (type $1 (func)) + ;; CHECK: (type $0 (sub (struct (field i32) (field (mut (ref null $0)))))) + (type $0 (sub (struct (field i32) (field (mut (ref null $0)))))) + (import "__fuzz_import" "extern$" (global $gimport$0 externref)) - (global $global$0 (ref null $0) (struct.new $0 - (i32.const 0) + + (global $global (ref null $0) (struct.new $0 (i32.const 0) (struct.new_default $0) - (ref.null noexn) )) + (export "test" (func $0)) + (func $0 (local $0 (ref $0)) (local $1 (ref $0)) @@ -23,34 +34,31 @@ (local $5 (ref $0)) (local.set $5 (ref.as_non_null - (global.get $global$0) + (global.get $global) ) ) - (nop) (drop (global.get $gimport$0) ) (drop (ref.as_non_null - (struct.get $0 2 + (struct.get $0 1 (local.get $5) ) ) ) ) ) -;; CHECK: (global $ctor-eval$global_4 (ref (exact $0)) (struct.new $0 -;; CHECK-NEXT: (i32.const 0) +;; CHECK: (type $1 (func)) + +;; CHECK: (global $ctor-eval$global (ref (exact $0)) (struct.new $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (ref.null none) -;; CHECK-NEXT: (ref.null noexn) ;; CHECK-NEXT: )) -;; CHECK: (global $ctor-eval$global_5 (ref (exact $0)) (struct.new $0 -;; CHECK-NEXT: (i32.const 0) +;; CHECK: (global $ctor-eval$global_3 (ref (exact $0)) (struct.new $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (ref.null none) -;; CHECK-NEXT: (ref.null noexn) ;; CHECK-NEXT: )) ;; CHECK: (export "test" (func $0_2)) @@ -58,17 +66,17 @@ ;; CHECK: (start $start) ;; CHECK: (func $start (type $1) -;; CHECK-NEXT: (struct.set $0 2 -;; CHECK-NEXT: (global.get $ctor-eval$global_4) -;; CHECK-NEXT: (global.get $ctor-eval$global_5) +;; CHECK-NEXT: (struct.set $0 1 +;; CHECK-NEXT: (global.get $ctor-eval$global) +;; CHECK-NEXT: (global.get $ctor-eval$global_3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK: (func $0_2 (type $1) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null -;; CHECK-NEXT: (struct.get $0 2 -;; CHECK-NEXT: (global.get $ctor-eval$global_4) +;; CHECK-NEXT: (struct.get $0 1 +;; CHECK-NEXT: (global.get $ctor-eval$global) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) From 447f3ef6beb2e7fcc0629f4c48b4b2fc49f6478d Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 12:09:13 -0700 Subject: [PATCH 5/9] nice --- test/lit/ctor-eval/partial-local.wat | 33 ++++++++++------------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/test/lit/ctor-eval/partial-local.wat b/test/lit/ctor-eval/partial-local.wat index 203b6a1426b..cda7d1c1aef 100644 --- a/test/lit/ctor-eval/partial-local.wat +++ b/test/lit/ctor-eval/partial-local.wat @@ -1,22 +1,11 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: wasm-ctor-eval %s --ctors=test --kept-exports=test --quiet -all -S -o - | filecheck %s -;; When executed, the single export reads from $global, and makes sure -;; the value is non-null. It then reads an imported global, then reads something -;; from the first global, and makes sure that is non-null. This code executes -;; without error. - -;; wasm-ctor-eval evals away the get of $global$0`, since it sees all the data -;; It stops at the read of the imported global, since that value depends on run -;; We should leave the module in a valid state: globals appear, and a start -;; function which applies one to the other. It should apply to the same global -;; that is then read from the remaining code in the export. - (module ;; CHECK: (type $0 (sub (struct (field i32) (field (mut (ref null $0)))))) (type $0 (sub (struct (field i32) (field (mut (ref null $0)))))) - (import "__fuzz_import" "extern$" (global $gimport$0 externref)) + (import "__fuzz_import" "extern$" (global $gimport externref)) (global $global (ref null $0) (struct.new $0 (i32.const 0) @@ -26,19 +15,19 @@ (export "test" (func $0)) (func $0 - (local $0 (ref $0)) - (local $1 (ref $0)) - (local $2 (ref $0)) - (local $3 (ref $0)) - (local $4 (ref $0)) - (local $5 (ref $0)) + (local $5 (ref null $0)) + ;; wasm-ctor-eval evals away the get of $global, since it sees all the data. (local.set $5 - (ref.as_non_null - (global.get $global) - ) + (global.get $global) ) + ;; It stops at the read of the imported global, since that value depends on + ;; runtime info. + ;; + ;; We should leave the module in a valid state: globals appear, and a start + ;; function which applies one to the other. It should apply to the same global + ;; that is then read from the remaining code in the export. (drop - (global.get $gimport$0) + (global.get $gimport) ) (drop (ref.as_non_null From e5b9a93663bded036f8fd270aca71c7259947015 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 12:09:28 -0700 Subject: [PATCH 6/9] nice --- test/lit/ctor-eval/partial-local.wat | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/lit/ctor-eval/partial-local.wat b/test/lit/ctor-eval/partial-local.wat index cda7d1c1aef..284c73746fc 100644 --- a/test/lit/ctor-eval/partial-local.wat +++ b/test/lit/ctor-eval/partial-local.wat @@ -15,9 +15,9 @@ (export "test" (func $0)) (func $0 - (local $5 (ref null $0)) + (local $temp (ref null $0)) ;; wasm-ctor-eval evals away the get of $global, since it sees all the data. - (local.set $5 + (local.set $temp (global.get $global) ) ;; It stops at the read of the imported global, since that value depends on @@ -32,7 +32,7 @@ (drop (ref.as_non_null (struct.get $0 1 - (local.get $5) + (local.get $temp) ) ) ) From d6f8b5b7df5a9fbfe27bd031dd759f3b03fc33e0 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 12:09:57 -0700 Subject: [PATCH 7/9] nice --- test/lit/ctor-eval/partial-local.wat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/lit/ctor-eval/partial-local.wat b/test/lit/ctor-eval/partial-local.wat index 284c73746fc..643f9750f92 100644 --- a/test/lit/ctor-eval/partial-local.wat +++ b/test/lit/ctor-eval/partial-local.wat @@ -16,10 +16,12 @@ (func $0 (local $temp (ref null $0)) + ;; wasm-ctor-eval evals away the get of $global, since it sees all the data. (local.set $temp (global.get $global) ) + ;; It stops at the read of the imported global, since that value depends on ;; runtime info. ;; @@ -29,6 +31,7 @@ (drop (global.get $gimport) ) + (drop (ref.as_non_null (struct.get $0 1 From 3f9e91a72ff4f38be942b4373bb9ff464b536a1b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 14:32:56 -0700 Subject: [PATCH 8/9] comment --- src/tools/wasm-ctor-eval.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 017a85687a1..0dbeb57772a 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -533,8 +533,9 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { public: // Clear the state of the operation of applying the interpreter's runtime // information into the module. This must be done before we start to serialize - // content. After this, serialization can happen, and after that, a call to - // applyToModule() can be done. + // content (as the serialization uses this state - defining globals must be + // set and are latter used, etc.). After this, serialization can happen, and + // after that, a call to applyToModule() can be done. void clearApplyState() { // The process of allocating "defining globals" begins here, from scratch // each time (things live before may no longer be). From 4366d05b2254a49b4fb0a3daf32432d22b8269c3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 26 May 2026 14:35:11 -0700 Subject: [PATCH 9/9] comment --- test/lit/ctor-eval/partial-local.wat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/lit/ctor-eval/partial-local.wat b/test/lit/ctor-eval/partial-local.wat index 643f9750f92..a1bc8a6725b 100644 --- a/test/lit/ctor-eval/partial-local.wat +++ b/test/lit/ctor-eval/partial-local.wat @@ -28,6 +28,9 @@ ;; We should leave the module in a valid state: globals appear, and a start ;; function which applies one to the other. It should apply to the same global ;; that is then read from the remaining code in the export. + ;; + ;; Note that this get of the import vanishes in the final output, not because + ;; we eval it, but because we run vacuum after. (drop (global.get $gimport) )