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