Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/wasm/decoder.h b/src/wasm/decoder.h
new file mode 100644
index 0000000..698919d
--- /dev/null
+++ b/src/wasm/decoder.h
@@ -0,0 +1,233 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_WASM_DECODER_H_
+#define V8_WASM_DECODER_H_
+
+#include "src/base/smart-pointers.h"
+#include "src/flags.h"
+#include "src/signature.h"
+#include "src/wasm/wasm-result.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace wasm {
+
+#if DEBUG
+#define TRACE(...)                                    \
+  do {                                                \
+    if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
+  } while (false)
+#else
+#define TRACE(...)
+#endif
+
+// A helper utility to decode bytes, integers, fields, varints, etc, from
+// a buffer of bytes.
+class Decoder {
+ public:
+  Decoder(const byte* start, const byte* end)
+      : start_(start),
+        pc_(start),
+        limit_(end),
+        error_pc_(nullptr),
+        error_pt_(nullptr) {}
+
+  virtual ~Decoder() {}
+
+  // Reads a 8-bit unsigned integer (byte) and advances {pc_}.
+  uint8_t u8(const char* name = nullptr) {
+    TRACE("  +%d  %-20s: ", static_cast<int>(pc_ - start_),
+          name ? name : "uint8_t");
+    if (checkAvailable(1)) {
+      byte val = *(pc_++);
+      TRACE("%02x = %d\n", val, val);
+      return val;
+    } else {
+      error("expected 1 byte, but fell off end");
+      return traceOffEnd<uint8_t>();
+    }
+  }
+
+  // Reads a 16-bit unsigned integer (little endian) and advances {pc_}.
+  uint16_t u16(const char* name = nullptr) {
+    TRACE("  +%d  %-20s: ", static_cast<int>(pc_ - start_),
+          name ? name : "uint16_t");
+    if (checkAvailable(2)) {
+#ifdef V8_TARGET_LITTLE_ENDIAN
+      byte b0 = pc_[0];
+      byte b1 = pc_[1];
+#else
+      byte b1 = pc_[0];
+      byte b0 = pc_[1];
+#endif
+      uint16_t val = static_cast<uint16_t>(b1 << 8) | b0;
+      TRACE("%02x %02x = %d\n", pc_[0], pc_[1], val);
+      pc_ += 2;
+      return val;
+    } else {
+      error("expected 2 bytes, but fell off end");
+      return traceOffEnd<uint16_t>();
+    }
+  }
+
+  // Reads a single 32-bit unsigned integer (little endian) and advances {pc_}.
+  uint32_t u32(const char* name = nullptr) {
+    TRACE("  +%d  %-20s: ", static_cast<int>(pc_ - start_),
+          name ? name : "uint32_t");
+    if (checkAvailable(4)) {
+#ifdef V8_TARGET_LITTLE_ENDIAN
+      byte b0 = pc_[0];
+      byte b1 = pc_[1];
+      byte b2 = pc_[2];
+      byte b3 = pc_[3];
+#else
+      byte b3 = pc_[0];
+      byte b2 = pc_[1];
+      byte b1 = pc_[2];
+      byte b0 = pc_[3];
+#endif
+      uint32_t val = static_cast<uint32_t>(b3 << 24) |
+                     static_cast<uint32_t>(b2 << 16) |
+                     static_cast<uint32_t>(b1 << 8) | b0;
+      TRACE("%02x %02x %02x %02x = %u\n", pc_[0], pc_[1], pc_[2], pc_[3], val);
+      pc_ += 4;
+      return val;
+    } else {
+      error("expected 4 bytes, but fell off end");
+      return traceOffEnd<uint32_t>();
+    }
+  }
+
+  // Reads a LEB128 variable-length 32-bit integer and advances {pc_}.
+  uint32_t u32v(int* length, const char* name = nullptr) {
+    TRACE("  +%d  %-20s: ", static_cast<int>(pc_ - start_),
+          name ? name : "varint");
+
+    if (!checkAvailable(1)) {
+      error("expected at least 1 byte, but fell off end");
+      return traceOffEnd<uint32_t>();
+    }
+
+    const byte* pos = pc_;
+    const byte* end = pc_ + 5;
+    if (end > limit_) end = limit_;
+
+    uint32_t result = 0;
+    int shift = 0;
+    byte b = 0;
+    while (pc_ < end) {
+      b = *pc_++;
+      TRACE("%02x ", b);
+      result = result | ((b & 0x7F) << shift);
+      if ((b & 0x80) == 0) break;
+      shift += 7;
+    }
+
+    *length = static_cast<int>(pc_ - pos);
+    if (pc_ == end && (b & 0x80)) {
+      error(pc_ - 1, "varint too large");
+    } else {
+      TRACE("= %u\n", result);
+    }
+    return result;
+  }
+
+  // Check that at least {size} bytes exist between {pc_} and {limit_}.
+  bool checkAvailable(int size) {
+    if (pc_ < start_ || (pc_ + size) > limit_) {
+      error(pc_, nullptr, "expected %d bytes, fell off end", size);
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  void error(const char* msg) { error(pc_, nullptr, msg); }
+
+  void error(const byte* pc, const char* msg) { error(pc, nullptr, msg); }
+
+  // Sets internal error state.
+  void error(const byte* pc, const byte* pt, const char* format, ...) {
+    if (ok()) {
+#if DEBUG
+      if (FLAG_wasm_break_on_decoder_error) {
+        base::OS::DebugBreak();
+      }
+#endif
+      const int kMaxErrorMsg = 256;
+      char* buffer = new char[kMaxErrorMsg];
+      va_list arguments;
+      va_start(arguments, format);
+      base::OS::VSNPrintF(buffer, kMaxErrorMsg - 1, format, arguments);
+      va_end(arguments);
+      error_msg_.Reset(buffer);
+      error_pc_ = pc;
+      error_pt_ = pt;
+      onFirstError();
+    }
+  }
+
+  // Behavior triggered on first error, overridden in subclasses.
+  virtual void onFirstError() {}
+
+  // Debugging helper to print bytes up to the end.
+  template <typename T>
+  T traceOffEnd() {
+    T t = 0;
+    for (const byte* ptr = pc_; ptr < limit_; ptr++) {
+      TRACE("%02x ", *ptr);
+    }
+    TRACE("<end>\n");
+    pc_ = limit_;
+    return t;
+  }
+
+  // Converts the given value to a {Result}, copying the error if necessary.
+  template <typename T>
+  Result<T> toResult(T val) {
+    Result<T> result;
+    if (error_pc_) {
+      result.error_code = kError;
+      result.start = start_;
+      result.error_pc = error_pc_;
+      result.error_pt = error_pt_;
+      result.error_msg = error_msg_;
+      error_msg_.Reset(nullptr);
+    } else {
+      result.error_code = kSuccess;
+    }
+    result.val = val;
+    return result;
+  }
+
+  // Resets the boundaries of this decoder.
+  void Reset(const byte* start, const byte* end) {
+    start_ = start;
+    pc_ = start;
+    limit_ = end;
+    error_pc_ = nullptr;
+    error_pt_ = nullptr;
+    error_msg_.Reset(nullptr);
+  }
+
+  bool ok() const { return error_pc_ == nullptr; }
+  bool failed() const { return error_pc_ != nullptr; }
+
+ protected:
+  const byte* start_;
+  const byte* pc_;
+  const byte* limit_;
+  const byte* error_pc_;
+  const byte* error_pt_;
+  base::SmartArrayPointer<char> error_msg_;
+};
+
+#undef TRACE
+}  // namespace wasm
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_WASM_DECODER_H_