Bug 1316614 - add Op lookahead to wasm iterator. r=sunfish
authorLars T Hansen <lhansen@mozilla.com>
Wed, 23 Nov 2016 18:32:14 +0100
changeset 324172 f4b4df249c38cf91484629eb3d59f5482f6e377c
parent 324171 6c26d0bd467bb05e38055eca393f0efaa252417c
child 324173 f9e3af2b0e9913d87e031ec993bd25a41d82cafb
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerssunfish
bugs1316614
milestone53.0a1
Bug 1316614 - add Op lookahead to wasm iterator. r=sunfish
js/src/wasm/WasmBinaryIterator.h
js/src/wasm/WasmValidate.h
--- a/js/src/wasm/WasmBinaryIterator.h
+++ b/js/src/wasm/WasmBinaryIterator.h
@@ -624,16 +624,21 @@ class MOZ_STACK_CLASS OpIter : private P
                                      Value* falseValue,
                                      Value* condition);
     MOZ_MUST_USE bool readSimdCtor();
     MOZ_MUST_USE bool readSimdCtorArg(ValType elementType, uint32_t numElements, uint32_t argIndex,
                                       Value* arg);
     MOZ_MUST_USE bool readSimdCtorArgsEnd(uint32_t numElements);
     MOZ_MUST_USE bool readSimdCtorReturn(ValType simdType);
 
+    // At a location where readOp is allowed, peek at the next opcode
+    // without consuming it or updating any internal state.
+    // Never fails: returns uint16_t(Op::Limit) if it can't read.
+    uint16_t peekOp();
+
     // ------------------------------------------------------------------------
     // Stack management.
 
     // Set the result value of the current top-of-value-stack expression.
     void setResult(Value value) {
         if (MOZ_LIKELY(reachable_))
             valueStack_.back().setValue(value);
     }
@@ -854,16 +859,35 @@ OpIter<Policy>::readOp(uint16_t* op)
     }
 
     op_ = Op(*op);  // debug-only
 
     return true;
 }
 
 template <typename Policy>
+inline uint16_t
+OpIter<Policy>::peekOp()
+{
+    const uint8_t* pos = d_.currentPosition();
+    uint16_t op;
+
+    if (Validate) {
+        if (MOZ_UNLIKELY(!d_.readOp(&op)))
+            op = uint16_t(Op::Limit);
+    } else {
+        op = uint16_t(d_.uncheckedReadOp());
+    }
+
+    d_.rollbackPosition(pos);
+
+    return op;
+}
+
+template <typename Policy>
 inline bool
 OpIter<Policy>::readFunctionStart(ExprType ret)
 {
     MOZ_ASSERT(valueStack_.empty());
     MOZ_ASSERT(controlStack_.empty());
     MOZ_ASSERT(Op(op_) == Op::Limit);
     MOZ_ASSERT(reachable_);
 
--- a/js/src/wasm/WasmValidate.h
+++ b/js/src/wasm/WasmValidate.h
@@ -335,16 +335,20 @@ class Decoder
         MOZ_ASSERT(cur_ <= end_);
         return cur_ == end_;
     }
 
     size_t bytesRemain() const {
         MOZ_ASSERT(end_ >= cur_);
         return size_t(end_ - cur_);
     }
+    // pos must be a value previously returned from currentPosition.
+    void rollbackPosition(const uint8_t* pos) {
+        cur_ = pos;
+    }
     const uint8_t* currentPosition() const {
         return cur_;
     }
     size_t currentOffset() const {
         return cur_ - beg_;
     }
     const uint8_t* begin() const {
         return beg_;