Skip to content

asm2wasm: incorrect translation of switch for big 64 bit values #1109

Closed
@pepyakin

Description

@pepyakin

Source: rust-lang/rust#42630 (comment)

For example:

function () {
  "use asm";

  var abort=env.abort;

  function main() {
    var $0 = i64(), $x = i64();
    $x = i64_const(0,0);
    $0 = $x;
    switch (i64($0)) {
      case i64_const(0,2146435072):  {
          abort();
	  break;
      }
      default: {
        return;
      }
    }
  }
  return { main: main };
}

gets translated to

(module
 (type $FUNCSIG$v (func))
 (import "env" "abort" (func $abort))
 (import "env" "memory" (memory $0 256 256))
 (import "env" "table" (table 0 0 anyfunc))
 (import "env" "memoryBase" (global $memoryBase i32))
 (import "env" "tableBase" (global $tableBase i32))
 (export "main" (func $main))
 (func $main
  (local $$0 i64)
  (local $$x i64)
  (set_local $$x
   (i64.const 0)
  )
  (set_local $$0
   (get_local $$x)
  )
  (block $switch
   (block $switch-default
    (block $switch-case
     (br_table $switch-case $switch-default
      (i32.wrap/i64
       (i64.sub
        (get_local $$0)
        (i64.const 9218868437227405312)
       )
      )
     )
    )
    (block
     (call $abort)
     (br $switch)
    )
   )
   (return)
  )
 )
)

IIUC, i32.wrap/i64 takes i64 and trunctates it to only lower 32 bits. So in this case, result of i32.wrap/i64 will be 0, meaning first switch-case will be taken and then program aborted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions