Bug 1308056: Allow to index memory/table owner in elem/data sections; r=luke
☠☠ backed out by 089d15228b41 ☠ ☠
authorBenjamin Bouvier <benj@benj.me>
Fri, 07 Oct 2016 16:22:24 +0200
changeset 360368 27bec108f660f219747e0626cfa61a57cfce14f0
parent 360367 913ccaec26d5f0f137f088482f6fd02d8e99b323
child 360369 5aaf29ab8c30d593674c97389a33e6e81f9b1358
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1308056
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1308056: Allow to index memory/table owner in elem/data sections; r=luke MozReview-Commit-ID: 1Sk7OJkbKxi
js/src/asmjs/WasmTextToBinary.cpp
js/src/jit-test/tests/wasm/basic.js
js/src/jit-test/tests/wasm/bce.js
js/src/jit-test/tests/wasm/import-export.js
js/src/jit-test/tests/wasm/memory-aliasing.js
js/src/jit-test/tests/wasm/memory.js
js/src/jit-test/tests/wasm/regress/teavm-bugs.js
--- a/js/src/asmjs/WasmTextToBinary.cpp
+++ b/js/src/asmjs/WasmTextToBinary.cpp
@@ -2694,25 +2694,36 @@ ParseTypeDef(WasmParseContext& c)
         return nullptr;
 
     if (!c.ts.match(WasmToken::CloseParen, c.error))
         return nullptr;
 
     return new(c.lifo) AstSig(name, Move(sig));
 }
 
+static bool
+MaybeParseOwnerIndex(WasmParseContext& c)
+{
+    if (c.ts.peek().kind() == WasmToken::Index) {
+        WasmToken elemIndex = c.ts.get();
+        if (elemIndex.index()) {
+            c.ts.generateError(elemIndex, "can't handle non-default memory/table yet", c.error);
+            return false;
+        }
+    }
+    return true;
+}
+
 static AstDataSegment*
 ParseDataSegment(WasmParseContext& c)
 {
-    AstExpr* offset;
-    WasmToken dstOffset;
-    if (c.ts.getIf(WasmToken::Index, &dstOffset))
-        offset = new(c.lifo) AstConst(Val(dstOffset.index()));
-    else
-        offset = ParseExpr(c, true);
+    if (!MaybeParseOwnerIndex(c))
+        return nullptr;
+
+    AstExpr* offset = ParseExpr(c, true);
     if (!offset)
         return nullptr;
 
     WasmToken text;
     if (!c.ts.getIf(WasmToken::Text, &text))
         return new(c.lifo) AstDataSegment(offset, AstName());
 
     return new(c.lifo) AstDataSegment(offset, text.text());
@@ -2956,20 +2967,24 @@ ParseExport(WasmParseContext& c)
                 return new(c.lifo) AstExport(name.text(), DefinitionKind::Function,
                                              AstRef(exportee.name(), AstNoIndex));
               default:
                 break;
             }
             break;
           }
           case WasmToken::Table:
+            if (!MaybeParseOwnerIndex(c))
+                return nullptr;
             if (!c.ts.match(WasmToken::CloseParen, c.error))
                 return nullptr;
             return new(c.lifo) AstExport(name.text(), DefinitionKind::Table);
           case WasmToken::Memory:
+            if (!MaybeParseOwnerIndex(c))
+                return nullptr;
             if (!c.ts.match(WasmToken::CloseParen, c.error))
                 return nullptr;
             return new(c.lifo) AstExport(name.text(), DefinitionKind::Memory);
           case WasmToken::Global: {
             AstRef ref;
             if (!c.ts.matchRef(&ref, c.error))
                 return nullptr;
             if (!c.ts.match(WasmToken::CloseParen, c.error))
@@ -3072,16 +3087,19 @@ ParseTable(WasmParseContext& c, WasmToke
 
     AstElemSegment* segment = new(c.lifo) AstElemSegment(zero, Move(elems));
     return segment && module->append(segment);
 }
 
 static AstElemSegment*
 ParseElemSegment(WasmParseContext& c)
 {
+    if (!MaybeParseOwnerIndex(c))
+        return nullptr;
+
     AstExpr* offset = ParseExpr(c, true);
     if (!offset)
         return nullptr;
 
     AstRefVector elems(c.lifo);
 
     AstRef elem;
     while (c.ts.getIfRef(&elem)) {
--- a/js/src/jit-test/tests/wasm/basic.js
+++ b/js/src/jit-test/tests/wasm/basic.js
@@ -144,36 +144,36 @@ assertEq(buf.byteLength, 65536);
 var obj = wasmEvalText('(module (memory 1) (func (result i32) (i32.const 42)) (func (nop)) (export "memory" memory) (export "b" 0) (export "c" 1))').exports;
 assertEq(obj.memory.buffer instanceof ArrayBuffer, true);
 assertEq(obj.b instanceof Function, true);
 assertEq(obj.c instanceof Function, true);
 assertEq(obj.memory.buffer.byteLength, 65536);
 assertEq(obj.b(), 42);
 assertEq(obj.c(), undefined);
 
-var buf = wasmEvalText('(module (memory 1) (data 0 "") (export "memory" memory))').exports.memory.buffer;
+var buf = wasmEvalText('(module (memory 1) (data (i32.const 0) "") (export "memory" memory))').exports.memory.buffer;
 assertEq(new Uint8Array(buf)[0], 0);
 
-var buf = wasmEvalText('(module (memory 1) (data 65536 "") (export "memory" memory))').exports.memory.buffer;
+var buf = wasmEvalText('(module (memory 1) (data (i32.const 65536) "") (export "memory" memory))').exports.memory.buffer;
 assertEq(new Uint8Array(buf)[0], 0);
 
-var buf = wasmEvalText('(module (memory 1) (data 0 "a") (export "memory" memory))').exports.memory.buffer;
+var buf = wasmEvalText('(module (memory 1) (data (i32.const 0) "a") (export "memory" memory))').exports.memory.buffer;
 assertEq(new Uint8Array(buf)[0], 'a'.charCodeAt(0));
 
-var buf = wasmEvalText('(module (memory 1) (data 0 "a") (data 2 "b") (export "memory" memory))').exports.memory.buffer;
+var buf = wasmEvalText('(module (memory 1) (data (i32.const 0) "a") (data (i32.const 2) "b") (export "memory" memory))').exports.memory.buffer;
 assertEq(new Uint8Array(buf)[0], 'a'.charCodeAt(0));
 assertEq(new Uint8Array(buf)[1], 0);
 assertEq(new Uint8Array(buf)[2], 'b'.charCodeAt(0));
 
-var buf = wasmEvalText('(module (memory 1) (data 65535 "c") (export "memory" memory))').exports.memory.buffer;
+var buf = wasmEvalText('(module (memory 1) (data (i32.const 65535) "c") (export "memory" memory))').exports.memory.buffer;
 assertEq(new Uint8Array(buf)[0], 0);
 assertEq(new Uint8Array(buf)[65535], 'c'.charCodeAt(0));
 
-wasmFailValidateText('(module (memory 1) (data 65536 "a") (export "memory" memory))', /data segment does not fit/);
-wasmFailValidateText('(module (memory 1) (data 65535 "ab") (export "memory" memory))', /data segment does not fit/);
+wasmFailValidateText('(module (memory 1) (data (i32.const 65536) "a") (export "memory" memory))', /data segment does not fit/);
+wasmFailValidateText('(module (memory 1) (data (i32.const 65535) "ab") (export "memory" memory))', /data segment does not fit/);
 
 // ----------------------------------------------------------------------------
 // locals
 
 assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](), 0);
 assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](42), 42);
 assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](42, 43), 42);
 assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 1)) (export "" 0))').exports[""](42, 43), 43);
--- a/js/src/jit-test/tests/wasm/bce.js
+++ b/js/src/jit-test/tests/wasm/bce.js
@@ -60,19 +60,19 @@ function getInt(width, offset, mem) {
   return res;
 }
 
 function loadTwiceModule(type, ext, offset, align) {
     // TODO: Generate memory from byte string
     return wasmEvalText(
     `(module
        (memory 1)
-       (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-       (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
-       (data 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+       (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 65520) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
        (func (param i32) (param i32) (result ${type})
          (drop (${type}.load${ext}
           offset=${offset}
           ${align != 0 ? 'align=' + align : ''}
           (get_local 0)
          ))
          (${type}.load${ext}
           offset=${offset}
@@ -82,19 +82,19 @@ function loadTwiceModule(type, ext, offs
        ) (export "" 0))`
     ).exports[""];
 }
 
 function loadTwiceSameBasePlusConstModule(type, ext, offset, align, addConst) {
     return wasmEvalText(
     `(module
        (memory 1)
-       (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-       (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
-       (data 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+       (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 65520) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
        (func (param i32) (result ${type})
          (drop (${type}.load${ext}
           offset=${offset}
           ${align != 0 ? 'align=' + align : ''}
           (get_local 0)
          ))
          (${type}.load${ext}
           offset=${offset}
@@ -104,19 +104,19 @@ function loadTwiceSameBasePlusConstModul
        ) (export "" 0))`
     ).exports[""];
 }
 
 function loadTwiceSameBasePlusNonConstModule(type, ext, offset, align) {
     return wasmEvalText(
     `(module
        (memory 1)
-       (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-       (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
-       (data 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+       (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 65520) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
        (func (param i32) (param i32) (result ${type})
          (drop (${type}.load${ext}
           offset=${offset}
           ${align != 0 ? 'align=' + align : ''}
           (get_local 0)
          ))
          (${type}.load${ext}
           offset=${offset}
--- a/js/src/jit-test/tests/wasm/import-export.js
+++ b/js/src/jit-test/tests/wasm/import-export.js
@@ -335,18 +335,18 @@ wasmFailValidateText('(module (import "a
 wasmFailValidateText('(module (import "a" "b" (table 1 1 anyfunc)) (table 1 1 anyfunc))', /already have default table/);
 wasmFailValidateText('(module (import "a" "b" (table 1 1 anyfunc)) (import "x" "y" (table 2 2 anyfunc)))', /already have default table/);
 
 // Data segments on imports
 
 var m = new Module(wasmTextToBinary(`
     (module
         (import "a" "b" (memory 1 1))
-        (data 0 "\\0a\\0b")
-        (data 100 "\\0c\\0d")
+        (data (i32.const 0) "\\0a\\0b")
+        (data (i32.const 100) "\\0c\\0d")
         (func $get (param $p i32) (result i32)
             (i32.load8_u (get_local $p)))
         (export "get" $get))
 `));
 var mem = new Memory({initial:1, maximum:1});
 var {get} = new Instance(m, {a:{b:mem}}).exports;
 assertEq(get(0), 0xa);
 assertEq(get(1), 0xb);
--- a/js/src/jit-test/tests/wasm/memory-aliasing.js
+++ b/js/src/jit-test/tests/wasm/memory-aliasing.js
@@ -1,14 +1,14 @@
 // |jit-test| test-also-wasm-baseline
 load(libdir + "wasm.js");
 
 var i = wasmEvalText(
 `(module
-   (memory 1) (data 0 "\\01\\02\\03\\04\\05\\06\\07\\08")
+   (memory 1) (data (i32.const 0) "\\01\\02\\03\\04\\05\\06\\07\\08")
    (func $off1 (param $base i32) (result i32)
      (i32.add
        (i32.load8_u (get_local $base))
        (i32.load8_u offset=1 (get_local $base)))
    )
    (export "off1" $off1)
    (func $off2 (param $base i32) (result i32)
      (i32.add
--- a/js/src/jit-test/tests/wasm/memory.js
+++ b/js/src/jit-test/tests/wasm/memory.js
@@ -1,34 +1,34 @@
 // |jit-test| test-also-wasm-baseline
 load(libdir + "wasm.js");
 
 function loadModule(type, ext, offset, align) {
     return wasmEvalText(
     `(module
        (memory 1)
-       (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-       (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+       (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
        (func (param i32) (result ${type})
          (${type}.load${ext}
           offset=${offset}
           ${align != 0 ? 'align=' + align : ''}
           (get_local 0)
          )
        ) (export "" 0))`
     ).exports[""];
 }
 
 function storeModule(type, ext, offset, align) {
     var load_ext = ext === '' ? '' : ext + '_s';
     return wasmEvalText(
     `(module
        (memory 1)
-       (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-       (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+       (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
        (func (param i32) (param ${type})
          (${type}.store${ext}
           offset=${offset}
           ${align != 0 ? 'align=' + align : ''}
           (get_local 0)
           (get_local 1)
          )
        ) (export "store" 0)
@@ -42,18 +42,18 @@ function storeModule(type, ext, offset, 
     ).exports;
 }
 
 function storeModuleCst(type, ext, offset, align, value) {
     var load_ext = ext === '' ? '' : ext + '_s';
     return wasmEvalText(
     `(module
        (memory 1)
-       (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-       (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+       (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+       (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
        (func (param i32)
          (${type}.store${ext}
           offset=${offset}
           ${align != 0 ? 'align=' + align : ''}
           (get_local 0)
           (${type}.const ${value})
          )
        ) (export "store" 0)
@@ -276,18 +276,18 @@ for (var foldOffsets = 0; foldOffsets <=
     wasmEvalText('(module (memory 0 65535))')
     wasmFailValidateText('(module (memory 0 65536))', /maximum memory size too big/);
 
     // Test high charge of registers
     function testRegisters() {
         assertEq(wasmEvalText(
             `(module
               (memory 1)
-              (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
-              (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
+              (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+              (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
               (func (param i32) (local i32 i32 i32 i32 f32 f64) (result i32)
                (set_local 1 (i32.load8_s offset=4 (get_local 0)))
                (set_local 2 (i32.load16_s (get_local 1)))
                (i32.store8 offset=4 (get_local 0) (get_local 1))
                (set_local 3 (i32.load16_u (get_local 2)))
                (i32.store16 (get_local 1) (get_local 2))
                (set_local 4 (i32.load (get_local 2)))
                (i32.store (get_local 1) (get_local 2))
--- a/js/src/jit-test/tests/wasm/regress/teavm-bugs.js
+++ b/js/src/jit-test/tests/wasm/regress/teavm-bugs.js
@@ -46,11 +46,11 @@ assertEq(wasmEvalText(`(module
         (set_local $l
            (i32.add
               (get_local $l)
               (i32.load8_s (get_local $p))
            )
         )
         (get_local $l)
     )
-    (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+    (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
     (export "test" 0)
 )`).exports["test"](3), 6);