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 { ResultResult40 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 okResult52 bool ok() const { return error_code == kSuccess; } failedResult53 bool failed() const { return error_code != kSuccess; } 54 55 template <typename V> CopyFromResult56 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: ErrorThrower(Isolate * isolate,const char * context)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> Failed(const char * error,Result<T> & result)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 error()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