Skip to content

Implement elem.drop - #7658

Merged
tlively merged 7 commits into
WebAssembly:mainfrom
osa1:elem_drop_rebase
Jun 17, 2025
Merged

tlively merged 7 commits into
WebAssembly:mainfrom
osa1:elem_drop_rebase

Conversation

@osa1

@osa1 osa1 commented Jun 16, 2025

Copy link
Copy Markdown
Contributor

Fixes #7209.

@osa1
osa1 force-pushed the elem_drop_rebase branch from 1a040e4 to 4a2d4ff Compare June 16, 2025 13:25
@osa1

osa1 commented Jun 16, 2025

Copy link
Copy Markdown
Contributor Author

@tlively I think this is ready, but it changes ids of some existing instructions (see CI failure). Is this a problem? I can't find where/how the ids are defined. Could you point me to the right code if we need to revert the id changes?

@osa1
osa1 marked this pull request as ready for review June 16, 2025 14:19
@tlively

tlively commented Jun 16, 2025 •

Copy link
Copy Markdown
Member

The IDs are just the Expression::ID values from wasm.h, so it is expected that they have changed. You can update the binaryen.js tests by running emcmake cmake -G Ninja . && ninja binaryen_js && ./scripts/auto_update_tests.py binaryenjs.

Comment thread src/ir/effects.h Outdated
Comment thread src/wasm/wasm-binary.cpp Outdated
Comment thread src/wasm/wasm-ir-builder.cpp Outdated
Comment thread src/wasm/wasm.cpp Outdated
Comment thread src/wasm/wasm-validator.cpp Outdated
@osa1
osa1 requested review from kripken and tlively June 17, 2025 09:54

@tlively tlively left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM. Can you add a test in test/lit/basic showing that the parsing and printing work as expected? You can use e.g. test/lit/basic/f16.wast as an example. The new test should also be added to the list of unfuzzable tests in scripts/test/fuzzing.py until we have fuzzing support for elem.drop.

@tlively
tlively merged commit e73224a into WebAssembly:main Jun 17, 2025
@osa1
osa1 deleted the elem_drop_rebase branch June 17, 2025 19:01
@kripken

kripken commented Jun 18, 2025

Copy link
Copy Markdown
Member

The fuzzer errors on this:

(module          
 (type $0 (func))
 (rec               
  (type $1 (sub (struct (field i64) (field i8) (field f32) (field (mut (ref $6))))))
  (type $2 (array (mut i64)))
  (type $3 (sub (array (ref $10))))
  (type $4 (array (mut (ref null $2))))
  (type $5 (sub (array (mut v128))))
  (type $6 (struct (field v128) (field i16)))
  (type $7 (sub (func (param f32 i64))))
  (type $8 (func (param (ref null $3))))
  (type $9 (sub (func (result (ref null $6))))) 
  (type $10 (sub (struct (field (mut i64)) (field (mut (ref struct))))))
 )              
 (type $11 (func (param i32)))
 (type $12 (func (param f32)))
 (rec                                                                                          
  (type $13 (sub (array (mut v128))))
  (type $14 (sub (array (mut anyref))))
  (type $15 (sub $9 (func (result (ref $6)))))
  (type $16 (sub (struct)))
  (type $17 (sub $14 (array (mut anyref))))
  (type $18 (sub final $9 (func (result (ref $6)))))
  (type $19 (sub $7 (func (param f32 i64))))
  (type $20 (sub (func (param (ref $17)) (result nullexternref))))
  (type $21 (sub final $9 (func (result (ref $6)))))
  (type $22 (sub $14 (array (mut anyref))))
 )
 (type $23 (func (param f32) (result (ref $21))))
 (import "fuzzing-support" "log-f32" (func $fimport$0 (type $12) (param f32)))
 (import "fuzzing-support" "wasmtag" (tag $eimport$0 (type $11) (param i32)))
 (table $0 68 funcref)
 (elem $0 (i32.const 0) $0)
 (export "drop_active_invoker" (func $2))
 (export "func_47" (func $1))
 (func $0 (type $0)
 )
 (func $1 (type $23) (param $0 f32) (result (ref $21))
  (try
   (do
    (call_indirect $0 (type $0)
     (i32.const 0)
    )
    (call $fimport$0
     (f32.const 0)
    )
    (unreachable)
   )
   (catch $eimport$0
    (drop
     (pop i32)
    )
   )
   (catch_all
   )
  )
  (unreachable)
 )
 (func $2 (type $0)
  (elem.drop $0)
 )
)
$ bin/wasm-opt a.wat -all --fuzz-exec
[fuzz-exec] calling drop_active_invoker
[fuzz-exec] calling func_47
[LoggingExternalInterface logging 0]
[trap unreachable]
warning: no passes specified, not doing any work
[fuzz-exec] calling drop_active_invoker
[fuzz-exec] calling func_47
[trap uninitialized table element]
[fuzz-exec] comparing drop_active_invoker
[fuzz-exec] comparing func_47
logging counts not identical!
[fuzz-exec] optimization passes changed results

--fuzz-exec without any optimizations means that we are just executing the wasm twice, and it runs differently the second time. Is the implementation of elem.drop setting some global state somehow that affects the instance later?

@kripken

kripken commented Jun 18, 2025

Copy link
Copy Markdown
Member

(btw @osa1 you can run the fuzzer locally, see docs at the top here: https://github.com/WebAssembly/binaryen/blob/main/scripts/fuzz_opt.py )

@osa1

osa1 commented Jun 18, 2025

Copy link
Copy Markdown
Contributor Author

Thanks for the ping. I'll have a look tomorrow.

(Sorry I forgot to add this to the unfuzzable tests as @tlively suggested, but I'll see if it's easy to implement. If not I'll add it to the list.)

tlively pushed a commit that referenced this pull request Jun 20, 2025
Don't drop the segment in the module as the module can be used again
later.

Instead add the segment to the dropped segments set.

Fixes the fuzzing issue described in
#7658 (comment).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement elem.drop

3 participants