Home | History | Annotate | Download | only in wasm
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_WASM_RESULT_H_
      6 #define V8_WASM_RESULT_H_
      7 
      8 #include <memory>
      9 
     10 #include "src/base/compiler-specific.h"
     11 
     12 #include "src/handles.h"
     13 #include "src/globals.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 
     18 class Isolate;
     19 
     20 namespace wasm {
     21 
     22 // Error codes for programmatic checking of the decoder's verification.
     23 enum ErrorCode {
     24   kSuccess,
     25   kError,  // TODO(titzer): introduce real error codes
     26 };
     27 
     28 // The overall result of decoding a function or a module.
     29 template <typename T>
     30 struct Result {
     31   Result() : val(), error_code(kSuccess), start(nullptr), error_pc(nullptr) {}
     32   Result(Result&& other) { *this = std::move(other); }
     33   Result& operator=(Result&& other) {
     34     MoveFrom(other);
     35     val = other.val;
     36     return *this;
     37   }
     38 
     39   T val;
     40   ErrorCode error_code;
     41   const byte* start;
     42   const byte* error_pc;
     43   const byte* error_pt;
     44   std::unique_ptr<char[]> error_msg;
     45 
     46   bool ok() const { return error_code == kSuccess; }
     47   bool failed() const { return error_code != kSuccess; }
     48 
     49   template <typename V>
     50   void MoveFrom(Result<V>& that) {
     51     error_code = that.error_code;
     52     start = that.start;
     53     error_pc = that.error_pc;
     54     error_pt = that.error_pt;
     55     error_msg = std::move(that.error_msg);
     56   }
     57 
     58  private:
     59   DISALLOW_COPY_AND_ASSIGN(Result);
     60 };
     61 
     62 template <typename T>
     63 std::ostream& operator<<(std::ostream& os, const Result<T>& result) {
     64   os << "Result = ";
     65   if (result.ok()) {
     66     if (result.val != nullptr) {
     67       os << *result.val;
     68     } else {
     69       os << "success (no value)";
     70     }
     71   } else if (result.error_msg.get() != nullptr) {
     72     ptrdiff_t offset = result.error_pc - result.start;
     73     if (offset < 0) {
     74       os << result.error_msg.get() << " @" << offset;
     75     } else {
     76       os << result.error_msg.get() << " @+" << offset;
     77     }
     78   } else {
     79     os << result.error_code;
     80   }
     81   os << std::endl;
     82   return os;
     83 }
     84 
     85 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
     86                                            const ErrorCode& error_code);
     87 
     88 // A helper for generating error messages that bubble up to JS exceptions.
     89 class V8_EXPORT_PRIVATE ErrorThrower {
     90  public:
     91   ErrorThrower(i::Isolate* isolate, const char* context)
     92       : isolate_(isolate), context_(context) {}
     93   ~ErrorThrower();
     94 
     95   PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
     96   PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
     97   PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
     98   PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
     99   PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
    100 
    101   template <typename T>
    102   void CompileFailed(const char* error, Result<T>& result) {
    103     std::ostringstream str;
    104     str << error << result;
    105     CompileError("%s", str.str().c_str());
    106   }
    107 
    108   i::Handle<i::Object> Reify() {
    109     i::Handle<i::Object> result = exception_;
    110     exception_ = i::Handle<i::Object>::null();
    111     return result;
    112   }
    113 
    114   bool error() const { return !exception_.is_null(); }
    115   bool wasm_error() { return wasm_error_; }
    116 
    117  private:
    118   void Format(i::Handle<i::JSFunction> constructor, const char* fmt, va_list);
    119 
    120   i::Isolate* isolate_;
    121   const char* context_;
    122   i::Handle<i::Object> exception_;
    123   bool wasm_error_ = false;
    124 };
    125 }  // namespace wasm
    126 }  // namespace internal
    127 }  // namespace v8
    128 
    129 #endif
    130