[Webkit-unassigned] [Bug 252538] New: Incorrect generated LLInt code for structs containing ref fields

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Sat Feb 18 16:31:20 PST 2023


https://bugs.webkit.org/show_bug.cgi?id=252538

            Bug ID: 252538
           Summary: Incorrect generated LLInt code for structs containing
                    ref fields
           Product: WebKit
           Version: WebKit Local Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: WebAssembly
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: tjc at igalia.com

The following test:

```
//@ runWebAssemblySuite("--useWebAssemblyTypedFunctionReferences=true", "--useWebAssemblyGC=true")

import * as assert from "../assert.js";
import { compile, instantiate } from "./wast-wrapper.js";

function module(bytes, valid = true) {
  let buffer = new ArrayBuffer(bytes.length);
  let view = new Uint8Array(buffer);
  for (let i = 0; i < bytes.length; ++i) {
    view[i] = bytes.charCodeAt(i);
  }
  return new WebAssembly.Module(buffer);
}

function testStructDeclaration() {

  let m = instantiate(`
    (module
      (type $a (array i32))
      (type $s (struct (field (ref $a)) (field (ref $a)) (field (ref $a))))

      (func $new (result (ref $s))
         (struct.new_canon $s (array.new_canon_default $a (i32.const 5))
                              (array.new_canon_default $a (i32.const 17))
                              (array.new_canon_default $a (i32.const 0))))

      (func (export "len0") (result i32)
         (struct.get $s 0 (call $new))
         (array.len))
      (func (export "len1") (result i32)
         (struct.get $s 1 (call $new))
         (array.len))
      (func (export "len2") (result i32)
         (struct.get $s 2 (call $new))
         (array.len)))`);

    assert.eq(m.exports.len0(), 5);
    assert.eq(m.exports.len1(), 17);
    assert.eq(m.exports.len2(), 0);
}

testStructDeclaration();
```

fails on the second `assert.eq` call. LLInt generates the following bytecode for the `$new` function:

```
<?>.wasm-function[0] : () -> [Ref]
wasm size: 20 bytes
bytecode: 10 instructions (0 16-bit instructions, 3 32-bit instructions); 85 bytes; 0 parameter(s); 18 local(s); 22 callee register(s)
[   0] enter              
[   1] **array_new        dst:loc18, size:5(const0), value:<invalid>, typeIndex:0, arrayNewKind:1
[  23] **array_new        dst:loc19, size:17(const1), value:<invalid>, typeIndex:0, arrayNewKind:1
[  45] **array_new        dst:loc20, size:0(const2), value:<invalid>, typeIndex:0, arrayNewKind:1
[  67] mov                dst:loc19, src:loc20
[  70] mov                dst:loc20, src:loc19
[  73] mov                dst:loc21, src:loc18
[  76] struct_new         dst:loc18, typeIndex:1, useDefault:false, firstValue:loc21
[  81] mov                dst:loc4, src:loc18
[  84] ret                
```

This assigns loc20 (the third argument to struct.new) into loc19, overwriting the second argument to struct.new. So if we write `(struct.new_canon $s e1 e2 e3)`, the result is the struct `{ e1, e3, e3 }`.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20230219/45f34245/attachment.htm>


More information about the webkit-unassigned mailing list