ejrgilbert / whamm

5 stars 2 forks source link

when predicate not specified, the default behavior should be PredIs_True #65

Closed ahuoguo closed 1 week ago

ahuoguo commented 1 week ago

Fixes the very first issue of #62

The type error of

whamm instr --script tests/scripts/instr.mm --app tests/apps/handwritten/add.wasm && wasm2wat output/output.wasm

for script

i32 i;
wasm:bytecode:call:before {
    i = 2;
}

is due to the fact that we did not encode the PredIs_true branch if the predicate is trivially true. So it will fall back to EmitIf, leaving no predicate to be emitted and causing a type error

The erroneous .wat file emitted before

(module
  (type (;0;) (func))
  (type (;1;) (func (result i32)))
  (type (;2;) (func (param i32 i32)))
  (type (;3;) (func (param i32 i32) (result i32)))
  (type (;4;) (func (param i32 i32 i32 i32) (result i32)))
  (type (;5;) (func (param i32 i32 i32 i32 i32 i32 i32 i32)))
  (import "bogus" "hi" (func (;0;) (type 2)))
  (func (;1;) (type 4) (param i32 i32 i32 i32) (result i32)
    (local i32 i32 i32)
    block  ;; label = @1
      block  ;; label = @2
        local.get 1
        local.get 3
        i32.ne
        br_if 1 (;@1;)
        local.get 0
        local.get 2
        i32.eq
        br_if 0 (;@2;)
        i32.const 0
        local.set 4
        loop  ;; label = @3
          local.get 4
          local.get 1
          i32.lt_u
          i32.const 0
          i32.eq
          br_if 1 (;@2;)
          local.get 0
          local.get 4
          i32.add
          i32.load8_u
          local.set 5
          local.get 2
          local.get 4
          i32.add
          i32.load8_u
          local.set 6
          local.get 5
          local.get 6
          i32.ne
          br_if 2 (;@1;)
          local.get 4
          i32.const 1
          i32.add
          local.set 4
          br 0 (;@3;)
        end
        br 0 (;@2;)
      end
      i32.const 1
      return
    end
    i32.const 0
    return)
  (func (;2;) (type 0)
    (local i32 i32)
    i32.const 1
    i32.const 2
    call 3
    drop
    i32.const 1
    i32.const 2
    local.set 0
    local.set 1
    block  ;; label = @1
      i32.const 0
      i32.eq
      br_if 0 (;@1;)
      block  ;; label = @2
        i32.const 2
        global.set 0
      end
    end
    call 0)
  (func (;3;) (type 3) (param i32 i32) (result i32)
    local.get 0
    local.get 1
    i32.add)
  (memory (;0;) 1)
  (global (;0;) (mut i32) (i32.const 0))
  (export "add" (func 3))
  (export "memory" (memory 0)))