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 { ResultResult31 Result() : val(), error_code(kSuccess), start(nullptr), error_pc(nullptr) {} ResultResult32 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 okResult46 bool ok() const { return error_code == kSuccess; } failedResult47 bool failed() const { return error_code != kSuccess; } 48 49 template <typename V> MoveFromResult50 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: ErrorThrower(i::Isolate * isolate,const char * context)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 RuntimeError(const char* fmt, ...); 99 100 template <typename T> CompileFailed(const char * error,Result<T> & result)101 void CompileFailed(const char* error, Result<T>& result) { 102 std::ostringstream str; 103 str << error << result; 104 CompileError("%s", str.str().c_str()); 105 } 106 Reify()107 i::Handle<i::Object> Reify() { 108 i::Handle<i::Object> result = exception_; 109 exception_ = i::Handle<i::Object>::null(); 110 return result; 111 } 112 error()113 bool error() const { return !exception_.is_null(); } 114 115 private: 116 void Format(i::Handle<i::JSFunction> constructor, const char* fmt, va_list); 117 118 i::Isolate* isolate_; 119 const char* context_; 120 i::Handle<i::Object> exception_; 121 }; 122 } // namespace wasm 123 } // namespace internal 124 } // namespace v8 125 126 #endif 127