Bug 1496582 - add required flags to bulk memory/table operations. r=jseward
authorLars T Hansen <lhansen@mozilla.com>
Wed, 17 Oct 2018 13:25:58 +0200
changeset 490261 fe962bfc351a0f198e3fa990693973eee5fbcf81
parent 490260 bb430eaf5521aa8ab233a45b585ff9e5dfecf4c9
child 490262 a25a1dd8a9f58ee74fe2922c0611d3013be00091
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersjseward
bugs1496582
milestone64.0a1
Bug 1496582 - add required flags to bulk memory/table operations. r=jseward The encodings are specified at the very bottom of https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md I have opted to call the byte memOrTableFlags because that is the meaning it will eventually have, even though currently the spec calls it a "memory" (even when the subject is a table).
js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
js/src/wasm/WasmOpIter.h
js/src/wasm/WasmTextToBinary.cpp
--- a/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
+++ b/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
@@ -351,31 +351,31 @@ const v2vSigSection = sigSection([v2vSig
 
 function checkMiscPrefixed(opcode, expect_failure) {
     let binary = moduleWithSections(
            [v2vSigSection, declSection([0]), memorySection(1),
             bodySection(
                 [funcBody(
                     {locals:[],
                      body:[0x41, 0x0, 0x41, 0x0, 0x41, 0x0, // 3 x const.i32 0
-                           MiscPrefix, opcode]})])]);
+                           MiscPrefix, ...opcode]})])]);
     if (expect_failure) {
         assertErrorMessage(() => new WebAssembly.Module(binary),
                            WebAssembly.CompileError, /unrecognized opcode/);
     } else {
-        assertEq(true, WebAssembly.validate(binary));
+        assertEq(WebAssembly.validate(binary), true);
     }
 }
 
 //-----------------------------------------------------------
 // Verification cases for memory.copy/fill opcode encodings
 
-checkMiscPrefixed(0x0a, false); // memory.copy
-checkMiscPrefixed(0x0b, false); // memory.fill
-checkMiscPrefixed(0x0f, true);  // table.copy+1, which is currently unassigned
+checkMiscPrefixed([0x0a, 0x00], false); // memory.copy, flags=0
+checkMiscPrefixed([0x0b, 0x00], false); // memory.fill, flags=0
+checkMiscPrefixed([0x0f], true);        // table.copy+1, which is currently unassigned
 
 //-----------------------------------------------------------
 // Verification cases for memory.copy/fill arguments
 
 // Invalid argument types
 {
     const tys = ['i32', 'f32', 'i64', 'f64'];
     const ops = ['copy', 'fill'];
--- a/js/src/wasm/WasmOpIter.h
+++ b/js/src/wasm/WasmOpIter.h
@@ -2050,16 +2050,24 @@ OpIter<Policy>::readMemOrTableCopy(bool 
             return fail("can't touch memory without memory");
         }
     } else {
         if (env_.tables.length() == 0) {
             return fail("can't table.copy without a table");
         }
     }
 
+    uint8_t memOrTableFlags;
+    if (!readFixedU8(&memOrTableFlags)) {
+        return fail(isMem ? "unable to read memory flags" : "unable to read table flags");
+    }
+    if (memOrTableFlags != 0) {
+        return fail(isMem ? "memory flags must be zero" : "table flags must be zero");
+    }
+
     if (!popWithType(ValType::I32, len)) {
         return false;
     }
 
     if (!popWithType(ValType::I32, src)) {
         return false;
     }
 
@@ -2109,16 +2117,24 @@ inline bool
 OpIter<Policy>::readMemFill(Value* start, Value* val, Value* len)
 {
     MOZ_ASSERT(Classify(op_) == OpKind::MemFill);
 
     if (!env_.usesMemory()) {
         return fail("can't touch memory without memory");
     }
 
+    uint8_t memoryFlags;
+    if (!readFixedU8(&memoryFlags)) {
+        return fail("unable to read memory flags");
+    }
+    if (memoryFlags != 0) {
+        return fail("memory flags must be zero");
+    }
+
     if (!popWithType(ValType::I32, len)) {
         return false;
     }
 
     if (!popWithType(ValType::I32, val)) {
         return false;
     }
 
@@ -2153,16 +2169,24 @@ OpIter<Policy>::readMemOrTableInit(bool 
     if (!popWithType(ValType::I32, src)) {
         return false;
     }
 
     if (!popWithType(ValType::I32, dst)) {
         return false;
     }
 
+    uint8_t memOrTableFlags;
+    if (!readFixedU8(&memOrTableFlags)) {
+        return fail(isMem ? "unable to read memory flags" : "unable to read table flags");
+    }
+    if (memOrTableFlags != 0) {
+        return fail(isMem ? "memory flags must be zero" : "table flags must be zero");
+    }
+
     if (!readVarU32(segIndex)) {
         return false;
     }
 
     if (isMem) {
         // Same comment as for readMemOrTableDrop.
         dvs_.lock()->notifyDataSegmentIndex(*segIndex, d_.currentOffset());
     } else {
--- a/js/src/wasm/WasmTextToBinary.cpp
+++ b/js/src/wasm/WasmTextToBinary.cpp
@@ -6285,48 +6285,53 @@ EncodeWake(Encoder& e, AstWake& s)
 {
     return EncodeLoadStoreAddress(e, s.address()) &&
            EncodeExpr(e, s.count()) &&
            e.writeOp(ThreadOp::Wake) &&
            EncodeLoadStoreFlags(e, s.address());
 }
 
 #ifdef ENABLE_WASM_BULKMEM_OPS
+static const uint8_t DEFAULT_MEM_TABLE_FLAGS = 0;
+
 static bool
 EncodeMemOrTableCopy(Encoder& e, AstMemOrTableCopy& s)
 {
     return EncodeExpr(e, s.dest()) &&
            EncodeExpr(e, s.src()) &&
            EncodeExpr(e, s.len()) &&
-           e.writeOp(s.isMem() ? MiscOp::MemCopy : MiscOp::TableCopy);
+           e.writeOp(s.isMem() ? MiscOp::MemCopy : MiscOp::TableCopy) &&
+           e.writeFixedU8(DEFAULT_MEM_TABLE_FLAGS);
 }
 
 static bool
 EncodeMemOrTableDrop(Encoder& e, AstMemOrTableDrop& s)
 {
     return e.writeOp(s.isMem() ? MiscOp::MemDrop : MiscOp::TableDrop) &&
            e.writeVarU32(s.segIndex());
 }
 
 static bool
 EncodeMemFill(Encoder& e, AstMemFill& s)
 {
     return EncodeExpr(e, s.start()) &&
            EncodeExpr(e, s.val()) &&
            EncodeExpr(e, s.len()) &&
-           e.writeOp(MiscOp::MemFill);
+           e.writeOp(MiscOp::MemFill) &&
+           e.writeFixedU8(DEFAULT_MEM_TABLE_FLAGS);
 }
 
 static bool
 EncodeMemOrTableInit(Encoder& e, AstMemOrTableInit& s)
 {
     return EncodeExpr(e, s.dst()) &&
            EncodeExpr(e, s.src()) &&
            EncodeExpr(e, s.len()) &&
            e.writeOp(s.isMem() ? MiscOp::MemInit : MiscOp::TableInit) &&
+           e.writeFixedU8(DEFAULT_MEM_TABLE_FLAGS) &&
            e.writeVarU32(s.segIndex());
 }
 #endif
 
 #ifdef ENABLE_WASM_GC
 static bool
 EncodeStructNew(Encoder& e, AstStructNew& s)
 {