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 "src/base/smart-pointers.h"
      9 
     10 #include "src/globals.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 
     15 class Isolate;
     16 
     17 namespace wasm {
     18 
     19 // Error codes for programmatic checking of the decoder's verification.
     20 enum ErrorCode {
     21   kSuccess,
     22   kError,                 // TODO(titzer): remove me
     23   kOutOfMemory,           // decoder ran out of memory
     24   kEndOfCode,             // end of code reached prematurely
     25   kInvalidOpcode,         // found invalid opcode
     26   kUnreachableCode,       // found unreachable code
     27   kImproperContinue,      // improperly nested continue
     28   kImproperBreak,         // improperly nested break
     29   kReturnCount,           // return count mismatch
     30   kTypeError,             // type mismatch
     31   kInvalidLocalIndex,     // invalid local
     32   kInvalidGlobalIndex,    // invalid global
     33   kInvalidFunctionIndex,  // invalid function
     34   kInvalidMemType         // invalid memory type
     35 };
     36 
     37 // The overall result of decoding a function or a module.
     38 template <typename T>
     39 struct Result {
     40   Result()
     41       : val(nullptr), error_code(kSuccess), start(nullptr), error_pc(nullptr) {
     42     error_msg.Reset(nullptr);
     43   }
     44 
     45   T val;
     46   ErrorCode error_code;
     47   const byte* start;
     48   const byte* error_pc;
     49   const byte* error_pt;
     50   base::SmartArrayPointer<char> error_msg;
     51 
     52   bool ok() const { return error_code == kSuccess; }
     53   bool failed() const { return error_code != kSuccess; }
     54 
     55   template <typename V>
     56   void CopyFrom(Result<V>& that) {
     57     error_code = that.error_code;
     58     start = that.start;
     59     error_pc = that.error_pc;
     60     error_pt = that.error_pt;
     61     error_msg = that.error_msg;
     62   }
     63 };
     64 
     65 template <typename T>
     66 std::ostream& operator<<(std::ostream& os, const Result<T>& result) {
     67   os << "Result = ";
     68   if (result.ok()) {
     69     if (result.val != nullptr) {
     70       os << *result.val;
     71     } else {
     72       os << "success (no value)";
     73     }
     74   } else if (result.error_msg.get() != nullptr) {
     75     ptrdiff_t offset = result.error_pc - result.start;
     76     if (offset < 0) {
     77       os << result.error_msg.get() << " @" << offset;
     78     } else {
     79       os << result.error_msg.get() << " @+" << offset;
     80     }
     81   } else {
     82     os << result.error_code;
     83   }
     84   os << std::endl;
     85   return os;
     86 }
     87 
     88 std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code);
     89 
     90 // A helper for generating error messages that bubble up to JS exceptions.
     91 class ErrorThrower {
     92  public:
     93   ErrorThrower(Isolate* isolate, const char* context)
     94       : isolate_(isolate), context_(context), error_(false) {}
     95 
     96   void Error(const char* fmt, ...);
     97 
     98   template <typename T>
     99   void Failed(const char* error, Result<T>& result) {
    100     std::ostringstream str;
    101     str << error << result;
    102     return Error(str.str().c_str());
    103   }
    104 
    105   bool error() const { return error_; }
    106 
    107  private:
    108   Isolate* isolate_;
    109   const char* context_;
    110   bool error_;
    111 };
    112 }  // namespace wasm
    113 }  // namespace internal
    114 }  // namespace v8
    115 
    116 #endif
    117