v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
wasm-result.h
Go to the documentation of this file.
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#if !V8_ENABLE_WEBASSEMBLY
9#error This header should only be included if WebAssembly is enabled.
10#endif // !V8_ENABLE_WEBASSEMBLY
11
12#include <cstdarg>
13#include <memory>
14
16#include "src/base/macros.h"
18
19#include "src/common/globals.h"
20
21namespace v8 {
22namespace internal {
23
24namespace wasm {
25
27 public:
28 WasmError() = default;
29
30 WasmError(uint32_t offset, std::string message)
31 : offset_(offset), message_(std::move(message)) {
32 DCHECK_NE(kNoErrorOffset, offset);
33 DCHECK(!message_.empty());
34 }
35
36 PRINTF_FORMAT(3, 4)
37 WasmError(uint32_t offset, const char* format, ...) : offset_(offset) {
38 DCHECK_NE(kNoErrorOffset, offset);
39 va_list args;
40 va_start(args, format);
41 message_ = FormatError(format, args);
42 va_end(args);
43 DCHECK(!message_.empty());
44 }
45
46 bool has_error() const {
47 DCHECK_EQ(offset_ == kNoErrorOffset, message_.empty());
48 return offset_ != kNoErrorOffset;
49 }
50
51 operator bool() const { return has_error(); }
52
53 uint32_t offset() const { return offset_; }
54 const std::string& message() const& { return message_; }
55 std::string&& message() && { return std::move(message_); }
56
57 protected:
58 static std::string FormatError(const char* format, va_list args);
59
60 private:
61 static constexpr uint32_t kNoErrorOffset = kMaxUInt32;
62 uint32_t offset_ = kNoErrorOffset;
63 std::string message_;
64};
65
66// Either a result of type T, or a WasmError.
67template <typename T>
68class Result {
69 public:
70 static_assert(!std::is_same<T, WasmError>::value);
71 static_assert(!std::is_reference<T>::value,
72 "Holding a reference in a Result looks like a mistake; remove "
73 "this assertion if you know what you are doing");
74
75 Result() = default;
76 // Allow moving.
77 Result(Result<T>&&) = default;
78 Result& operator=(Result<T>&&) = default;
79 // Disallow copying.
80 Result& operator=(const Result<T>&) = delete;
81 Result(const Result&) = delete;
82
83 // Construct a Result from anything that can be used to construct a T value.
84 template <typename U>
85 explicit Result(U&& value) : value_(std::forward<U>(value)) {}
86
87 explicit Result(WasmError error) : error_(std::move(error)) {}
88
89 // Implicitly convert a Result<T> to Result<U> if T implicitly converts to U.
90 // Only provide that for r-value references (i.e. temporary objects) though,
91 // to be used if passing or returning a result by value.
92 template <typename U>
93 operator Result<U>() const&&
94 requires(std::is_assignable_v<U, T &&>)
95 {
96 return ok() ? Result<U>{std::move(value_)} : Result<U>{error_};
97 }
98
99 bool ok() const { return !failed(); }
100 bool failed() const { return error_.has_error(); }
101 const WasmError& error() const& { return error_; }
102 WasmError&& error() && { return std::move(error_); }
103
104 // Accessor for the value. Returns const reference if {this} is l-value or
105 // const, and returns r-value reference if {this} is r-value. This allows to
106 // extract non-copyable values like {std::unique_ptr} by using
107 // {std::move(result).value()}.
108 const T& value() const & {
109 DCHECK(ok());
110 return value_;
111 }
112 T&& value() && {
113 DCHECK(ok());
114 return std::move(value_);
115 }
116
117 private:
118 T value_ = T{};
120};
121
122// A helper for generating error messages that bubble up to JS exceptions.
124 public:
125 ErrorThrower(Isolate* isolate, const char* context)
126 : isolate_(isolate), context_(context) {}
127 // Disallow copy.
128 ErrorThrower(const ErrorThrower&) = delete;
131
132 PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
133 PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
134 PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
135 PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
136 PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
137
138 void CompileFailed(const WasmError& error) {
139 DCHECK(error.has_error());
140 CompileError("%s @+%u", error.message().c_str(), error.offset());
141 }
142
143 // Create and return exception object.
145
146 // Reset any error which was set on this thrower.
147 void Reset();
148
149 bool error() const { return error_type_ != kNone; }
150 bool wasm_error() { return error_type_ >= kFirstWasmError; }
151 const char* error_msg() { return error_msg_.c_str(); }
152
153 Isolate* isolate() const { return isolate_; }
154
155 constexpr const char* context_name() const { return context_; }
156
157 private:
160 // General errors.
163 // Wasm errors.
167
168 // Marker.
169 kFirstWasmError = kCompileError
170 };
171
172 void Format(ErrorType error_type_, const char* fmt, va_list);
173
175 const char* const context_;
176 ErrorType error_type_ = kNone;
177 std::string error_msg_;
178
179 // ErrorThrower should always be stack-allocated, since it constitutes a scope
180 // (things happen in the destructor).
182};
183
184// Use {nullptr_t} as data value to indicate that this only stores the error,
185// but no result value (the only valid value is {nullptr}).
186// [Storing {void} would require template specialization.]
188
189} // namespace wasm
190} // namespace internal
191} // namespace v8
192
193#endif // V8_WASM_WASM_RESULT_H_
Isolate * isolate_
ErrorThrower & operator=(const ErrorThrower &)=delete
ErrorThrower(Isolate *isolate, const char *context)
PRINTF_FORMAT(2, 3) void TypeError(const char *fmt
ErrorThrower(const ErrorThrower &)=delete
constexpr const char * context_name() const
Result & operator=(const Result< T > &)=delete
const WasmError & error() const &
Result & operator=(Result< T > &&)=default
const T & value() const &
Result(const Result &)=delete
Result(Result< T > &&)=default
WasmError && error() &&
Result(WasmError error)
Definition wasm-result.h:87
std::string && message() &&
Definition wasm-result.h:55
const std::string & message() const &
Definition wasm-result.h:54
WasmError(uint32_t offset, std::string message)
Definition wasm-result.h:30
Operand const offset_
Handle< Context > context_
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
int32_t offset
STL namespace.
constexpr int U
constexpr uint32_t kMaxUInt32
Definition globals.h:387
Definition c-api.cc:87
#define PRINTF_FORMAT(format_param, dots_param)
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DISALLOW_NEW_AND_DELETE()
Definition macros.h:155
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671