WebAssembly / binaryen

Optimizer and compiler/toolchain library for WebAssembly

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WATParser bug when parse implicit type definition

qilinO-o opened this issue · comments

I'm trying to use the experimental wat parser wasm::WATParser::parseModule() in my project. It read in the following wat:

(module
 (type $0 (func))
 (type $1 (func (param i32)))
 (type $2 (func (param i32 i32 i32 i32) (result i32)))
 (type $3 (func (result i32)))
 (import "om" "omg" (global $impg f32))
 (import "wasi_snapshot_preview1" "proc_exit" (func $fimport$0 (param i32)))
 (import "wasi_snapshot_preview1" "fd_write" (func $fimport$1 (param i32 i32 i32 i32) (result i32)))
 (import "om" "omf" (func $impf))
 (global $global$0 (mut i32) (i32.const 66592))
 (global $g i64 (i64.const 100000))
 (memory $0 256 256)
 (data $0 (i32.const 1024) "hello world!\n")
 (table $0 2 2 funcref)
 (elem $0 (i32.const 1) $0)
 (export "memory" (memory $0))
 (export "__indirect_function_table" (table $0))
 (export "_start" (func $1))
 (export "stackSave" (func $2))
 (export "stackRestore" (func $3))
 (export "expg" (global $g))
 (func $0
 )
 (func $1
  (local $0 i32)
  (local $1 i32)
  global.get $global$0
  i32.const 16
  i32.sub
  local.tee $0
  global.set $global$0
  local.get $0
  i32.const 13
  i32.store offset=12
  local.get $0
  i32.const 1024
  i32.store offset=8
  i32.const 1
  local.get $0
  i32.const 8
  i32.add
  i32.const 1
  local.get $0
  i32.const 4
  i32.add
  call $fimport$1
  local.tee $1
  if
   i32.const 1040
   local.get $1
   i32.store
  end
  local.get $0
  i32.load offset=4
  drop
  local.get $0
  i32.const 16
  i32.add
  global.set $global$0
  i32.const 0
  call $fimport$0
  unreachable
 )
 (func $2 (result i32)
  global.get $global$0
 )
 (func $3 (param $0 i32)
  local.get $0
  global.set $global$0
 )
 (func $donothing (param i32) (result i32)
  local.get 0
  i32.const 100000
  i32.add
 )
 (func $donothing2 (param i32) (result i32)
  local.get 0
  global.get $g
  i32.wrap_i64
  i32.add
 )
)

There are four explicit type definitions as above, and two implicit type (func (param i32) (result i32)) for the last $donothing() and $donothing2() functions.
After the parse I called BinaryenModulePrint() and the following wat showed up:

(module
 (type $0 (func))
 (type $1 (func (param i32)))
 (type $2 (func (param i32) (result i32)))
 (type $2 (func (param i32 i32 i32 i32) (result i32)))
 (type $3 (func (result i32)))
 (import "om" "omg" (global $impg f32))
 (import "wasi_snapshot_preview1" "proc_exit" (func $fimport$0 (param i32)))
 (import "wasi_snapshot_preview1" "fd_write" (func $fimport$1 (param i32 i32 i32 i32) (result i32)))
 (import "om" "omf" (func $impf))
 (global $global$0 (mut i32) (i32.const 66592))
 (global $g i64 (i64.const 100000))
 (memory $0 256 256)
 (data $0 (i32.const 1024) "hello world!\n")
 (table $0 2 2 funcref)
 (elem $0 (i32.const 1) $0)
 (export "memory" (memory $0))
 (export "__indirect_function_table" (table $0))
 (export "_start" (func $1))
 (export "stackSave" (func $2))
 (export "stackRestore" (func $3))
 (export "expg" (global $g))
 (func $0 (; has Stack IR ;)
  (nop)
 )
 (func $1 (; has Stack IR ;)
  (local $0 i32)
  (local $1 i32)
  (global.set $global$0
   (local.tee $0
    (i32.sub
     (global.get $global$0)
     (i32.const 16)
    )
   )
  )
  (i32.store offset=12
   (local.get $0)
   (i32.const 13)
  )
  (i32.store offset=8
   (local.get $0)
   (i32.const 1024)
  )
  (if
   (local.tee $1
    (call $fimport$1
     (i32.const 1)
     (i32.add
      (local.get $0)
      (i32.const 8)
     )
     (i32.const 1)
     (i32.add
      (local.get $0)
      (i32.const 4)
     )
    )
   )
   (then
    (i32.store
     (i32.const 1040)
     (local.get $1)
    )
   )
  )
  (drop
   (i32.load offset=4
    (local.get $0)
   )
  )
  (global.set $global$0
   (i32.add
    (local.get $0)
    (i32.const 16)
   )
  )
  (call $fimport$0
   (i32.const 0)
  )
  (unreachable)
 )
 (func $2 (; has Stack IR ;) (result i32)
  (global.get $global$0)
 )
 (func $3 (; has Stack IR ;) (param $0 i32)
  (global.set $global$0
   (local.get $0)
  )
 )
 (func $donothing (; has Stack IR ;) (param $0 i32) (result i32)
  (i32.add
   (local.get $0)
   (i32.const 100000)
  )
 )
 (func $donothing2 (; has Stack IR ;) (param $0 i32) (result i32)
  (i32.add
   (local.get $0)
   (i32.wrap_i64
    (global.get $g)
   )
  )
 )
)

So type name duplicated and when I wanted to read in the generated wat again, I got an error: duplicate element name. I want to figure out if I misused the new parser or it is a bug.

Looks like a bug. When printing a name for the implicitly-defined type, the printer should have used a name that was not already used.