Line data Source code
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 <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 233866 : class V8_EXPORT_PRIVATE ResultBase {
26 : protected:
27 1256702 : ResultBase() = default;
28 :
29 : ResultBase& operator=(ResultBase&& other) = default;
30 :
31 : public:
32 : ResultBase(ResultBase&& other)
33 : : error_offset_(other.error_offset_),
34 2829290 : error_msg_(std::move(other.error_msg_)) {}
35 :
36 : void error(uint32_t offset, std::string error_msg);
37 :
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 :
47 147062 : void MoveErrorFrom(ResultBase& that) {
48 147062 : error_offset_ = that.error_offset_;
49 : // Use {swap()} + {clear()} instead of move assign, as {that} might still
50 : // be used afterwards.
51 147062 : error_msg_.swap(that.error_msg_);
52 : that.error_msg_.clear();
53 147062 : }
54 :
55 : bool ok() const { return error_msg_.empty(); }
56 : bool failed() const { return !ok(); }
57 :
58 : uint32_t error_offset() const { return error_offset_; }
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 4542462 : class Result : public ResultBase {
69 : public:
70 542387 : Result() = default;
71 :
72 : template <typename S>
73 405708 : explicit Result(S&& value) : val(std::forward<S>(value)) {}
74 :
75 : template <typename S>
76 : Result(Result<S>&& other)
77 969788 : : ResultBase(std::move(other)), val(std::move(other.val)) {}
78 :
79 : Result& operator=(Result&& other) = default;
80 :
81 0 : static Result<T> PRINTF_FORMAT(1, 2) Error(const char* format, ...) {
82 : va_list args;
83 0 : va_start(args, format);
84 : Result<T> result;
85 0 : result.verror(format, args);
86 0 : va_end(args);
87 0 : 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:
99 : ErrorThrower(Isolate* isolate, const char* context)
100 26955645 : : isolate_(isolate), context_(context) {}
101 : // Explicitly allow move-construction. Disallow copy (below).
102 : ErrorThrower(ErrorThrower&& other);
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>
112 : void CompileFailed(const char* error, Result<T>& result) {
113 : DCHECK(result.failed());
114 18577 : CompileError("%s: %s @+%u", error, result.error_msg().c_str(),
115 : result.error_offset());
116 : }
117 :
118 : // Create and return exception object.
119 : MUST_USE_RESULT Handle<Object> Reify();
120 :
121 : // Reset any error which was set on this thrower.
122 : void Reset();
123 :
124 51527 : bool error() const { return error_type_ != kNone; }
125 12400 : bool wasm_error() { return error_type_ >= kFirstWasmError; }
126 :
127 : Isolate* isolate() const { return isolate_; }
128 :
129 : private:
130 : enum ErrorType {
131 : kNone,
132 : // General errors.
133 : kTypeError,
134 : kRangeError,
135 : // Wasm errors.
136 : kCompileError,
137 : kLinkError,
138 : kRuntimeError,
139 :
140 : // Marker.
141 : kFirstWasmError = kCompileError
142 : };
143 :
144 : void Format(ErrorType error_type_, const char* fmt, va_list);
145 :
146 : Isolate* isolate_;
147 : const char* context_;
148 : ErrorType error_type_ = kNone;
149 : std::string error_msg_;
150 :
151 : DISALLOW_COPY_AND_ASSIGN(ErrorThrower);
152 : // ErrorThrower should always be stack-allocated, since it constitutes a scope
153 : // (things happen in the destructor).
154 : DISALLOW_NEW_AND_DELETE();
155 : };
156 :
157 : } // namespace wasm
158 : } // namespace internal
159 : } // namespace v8
160 :
161 : #endif
|