(module
 (type $0 (func (param i64) (result i64)))
 (memory $0 0)
 (export "fac-rec" (func $0))
 (export "fac-rec-named" (func $1))
 (export "fac-iter" (func $2))
 (export "fac-iter-named" (func $3))
 (export "fac-opt" (func $4))
 (func $0 (; 0 ;) (type $0) (param $0 i64) (result i64)
  (if (result i64)
   (i64.eq
    (get_local $0)
    (i64.const 0)
   )
   (i64.const 1)
   (i64.mul
    (get_local $0)
    (call $0
     (i64.sub
      (get_local $0)
      (i64.const 1)
     )
    )
   )
  )
 )
 (func $1 (; 1 ;) (type $0) (param $0 i64) (result i64)
  (if (result i64)
   (i64.eq
    (get_local $0)
    (i64.const 0)
   )
   (i64.const 1)
   (i64.mul
    (get_local $0)
    (call $1
     (i64.sub
      (get_local $0)
      (i64.const 1)
     )
    )
   )
  )
 )
 (func $2 (; 2 ;) (type $0) (param $0 i64) (result i64)
  (unreachable)
 )
 (func $3 (; 3 ;) (type $0) (param $0 i64) (result i64)
  (local $1 i64)
  (set_local $1
   (i64.const 1)
  )
  (loop $label$3
   (if
    (i64.ne
     (get_local $0)
     (i64.const 0)
    )
    (block
     (set_local $1
      (i64.mul
       (get_local $0)
       (get_local $1)
      )
     )
     (set_local $0
      (i64.sub
       (get_local $0)
       (i64.const 1)
      )
     )
     (br $label$3)
    )
   )
  )
  (get_local $1)
 )
 (func $4 (; 4 ;) (type $0) (param $0 i64) (result i64)
  (local $1 i64)
  (set_local $1
   (i64.const 1)
  )
  (if
   (i64.ge_s
    (get_local $0)
    (i64.const 2)
   )
   (loop $label$3
    (set_local $1
     (i64.mul
      (get_local $1)
      (get_local $0)
     )
    )
    (br_if $label$3
     (i64.gt_s
      (tee_local $0
       (i64.add
        (get_local $0)
        (i64.const -1)
       )
      )
      (i64.const 1)
     )
    )
   )
  )
  (get_local $1)
 )
)
