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_WASM_RESULT_H_ 6 #define V8_WASM_WASM_RESULT_H_ 7 8 #include <cstdarg> 9 #include <memory> 10 11 #include "src/base/compiler-specific.h" 12 #include "src/utils.h" 13 14 #include "src/globals.h" 15 #include "src/handles.h" 16 17 namespace v8 { 18 namespace internal { 19 20 class Isolate; 21 22 namespace wasm { 23 24 // Base class for Result<T>. 25 class V8_EXPORT_PRIVATE ResultBase { 26 protected: 27 ResultBase() = default; 28 29 ResultBase& operator=(ResultBase&& other) V8_NOEXCEPT = default; 30 31 public: ResultBase(ResultBase && other)32 ResultBase(ResultBase&& other) V8_NOEXCEPT 33 : error_offset_(other.error_offset_), 34 error_msg_(std::move(other.error_msg_)) {} 35 36 void error(uint32_t offset, std::string error_msg); 37 error(const char * format,...)38 void PRINTF_FORMAT(2, 3) error(const char* format, ...) { 39 va_list args; 40 va_start(args, format); 41 verror(format, args); 42 va_end(args); 43 } 44 45 void PRINTF_FORMAT(2, 0) verror(const char* format, va_list args); 46 MoveErrorFrom(ResultBase & that)47 void MoveErrorFrom(ResultBase& that) { 48 error_offset_ = that.error_offset_; 49 // Use {swap()} + {clear()} instead of move assign, as {that} might still 50 // be used afterwards. 51 error_msg_.swap(that.error_msg_); 52 that.error_msg_.clear(); 53 } 54 ok()55 bool ok() const { return error_msg_.empty(); } failed()56 bool failed() const { return !ok(); } 57 error_offset()58 uint32_t error_offset() const { return error_offset_; } error_msg()59 const std::string& error_msg() const { return error_msg_; } 60 61 private: 62 uint32_t error_offset_ = 0; 63 std::string error_msg_; 64 }; 65 66 // The overall result of decoding a function or a module. 67 template <typename T> 68 class Result : public ResultBase { 69 public: 70 Result() = default; 71 72 template <typename S> Result(S && value)73 explicit Result(S&& value) : val(std::forward<S>(value)) {} 74 75 template <typename S> Result(Result<S> && other)76 Result(Result<S>&& other) V8_NOEXCEPT : ResultBase(std::move(other)), 77 val(std::move(other.val)) {} 78 79 Result& operator=(Result&& other) V8_NOEXCEPT = default; 80 Error(const char * format,...)81 static Result<T> PRINTF_FORMAT(1, 2) Error(const char* format, ...) { 82 va_list args; 83 va_start(args, format); 84 Result<T> result; 85 result.verror(format, args); 86 va_end(args); 87 return result; 88 } 89 90 T val = T{}; 91 92 private: 93 DISALLOW_COPY_AND_ASSIGN(Result); 94 }; 95 96 // A helper for generating error messages that bubble up to JS exceptions. 97 class V8_EXPORT_PRIVATE ErrorThrower { 98 public: ErrorThrower(Isolate * isolate,const char * context)99 ErrorThrower(Isolate* isolate, const char* context) 100 : isolate_(isolate), context_(context) {} 101 // Explicitly allow move-construction. Disallow copy (below). 102 ErrorThrower(ErrorThrower&& other) V8_NOEXCEPT; 103 ~ErrorThrower(); 104 105 PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...); 106 PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...); 107 PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...); 108 PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...); 109 PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...); 110 111 template <typename T> CompileFailed(const char * error,Result<T> & result)112 void CompileFailed(const char* error, Result<T>& result) { 113 DCHECK(result.failed()); 114 CompileError("%s: %s @+%u", error, result.error_msg().c_str(), 115 result.error_offset()); 116 } 117 118 // Create and return exception object. 119 V8_WARN_UNUSED_RESULT Handle<Object> Reify(); 120 121 // Reset any error which was set on this thrower. 122 void Reset(); 123 error()124 bool error() const { return error_type_ != kNone; } wasm_error()125 bool wasm_error() { return error_type_ >= kFirstWasmError; } error_msg()126 const char* error_msg() { return error_msg_.c_str(); } 127 isolate()128 Isolate* isolate() const { return isolate_; } 129 130 private: 131 enum ErrorType { 132 kNone, 133 // General errors. 134 kTypeError, 135 kRangeError, 136 // Wasm errors. 137 kCompileError, 138 kLinkError, 139 kRuntimeError, 140 141 // Marker. 142 kFirstWasmError = kCompileError 143 }; 144 145 void Format(ErrorType error_type_, const char* fmt, va_list); 146 147 Isolate* isolate_; 148 const char* context_; 149 ErrorType error_type_ = kNone; 150 std::string error_msg_; 151 152 DISALLOW_COPY_AND_ASSIGN(ErrorThrower); 153 // ErrorThrower should always be stack-allocated, since it constitutes a scope 154 // (things happen in the destructor). 155 DISALLOW_NEW_AND_DELETE(); 156 }; 157 158 } // namespace wasm 159 } // namespace internal 160 } // namespace v8 161 162 #endif // V8_WASM_WASM_RESULT_H_ 163