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/handles.h"
15 : #include "src/globals.h"
16 :
17 : namespace v8 {
18 : namespace internal {
19 :
20 : class Isolate;
21 :
22 : namespace wasm {
23 :
24 : // The overall result of decoding a function or a module.
25 : template <typename T>
26 48968 : class Result {
27 : public:
28 68124 : Result() = default;
29 :
30 : template <typename S>
31 106201 : explicit Result(S&& value) : val(value) {}
32 :
33 : template <typename S>
34 : Result(Result<S>&& other)
35 : : val(std::move(other.val)),
36 : error_offset(other.error_offset),
37 163570 : error_msg(std::move(other.error_msg)) {}
38 :
39 : Result& operator=(Result&& other) = default;
40 :
41 : T val = T{};
42 : uint32_t error_offset = 0;
43 : std::string error_msg;
44 :
45 : bool ok() const { return error_msg.empty(); }
46 : bool failed() const { return !ok(); }
47 :
48 : template <typename V>
49 2269 : void MoveErrorFrom(Result<V>& that) {
50 2269 : error_offset = that.error_offset;
51 : // Use {swap()} + {clear()} instead of move assign, as {that} might still be
52 : // used afterwards.
53 2269 : error_msg.swap(that.error_msg);
54 : that.error_msg.clear();
55 2269 : }
56 :
57 : void PRINTF_FORMAT(2, 3) error(const char* format, ...) {
58 : va_list args;
59 : va_start(args, format);
60 : verror(format, args);
61 : va_end(args);
62 : }
63 :
64 0 : void PRINTF_FORMAT(2, 0) verror(const char* format, va_list args) {
65 : size_t len = base::bits::RoundUpToPowerOfTwo32(
66 0 : static_cast<uint32_t>(strlen(format)));
67 : // Allocate increasingly large buffers until the message fits.
68 0 : for (;; len *= 2) {
69 : DCHECK_GE(kMaxInt, len);
70 0 : error_msg.resize(len);
71 : int written =
72 : VSNPrintF(Vector<char>(&error_msg.front(), static_cast<int>(len)),
73 0 : format, args);
74 0 : if (written < 0) continue; // not enough space.
75 0 : if (written == 0) error_msg = "Error"; // assign default message.
76 0 : return;
77 : }
78 : }
79 :
80 0 : static Result<T> PRINTF_FORMAT(1, 2) Error(const char* format, ...) {
81 : va_list args;
82 0 : va_start(args, format);
83 : Result<T> result;
84 0 : result.verror(format, args);
85 0 : va_end(args);
86 0 : return result;
87 : }
88 :
89 : private:
90 : DISALLOW_COPY_AND_ASSIGN(Result);
91 : };
92 :
93 : // A helper for generating error messages that bubble up to JS exceptions.
94 : class V8_EXPORT_PRIVATE ErrorThrower {
95 : public:
96 : ErrorThrower(i::Isolate* isolate, const char* context)
97 313982 : : isolate_(isolate), context_(context) {}
98 : ~ErrorThrower();
99 :
100 : PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
101 : PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
102 : PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
103 : PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
104 : PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
105 :
106 : template <typename T>
107 : void CompileFailed(const char* error, Result<T>& result) {
108 : DCHECK(result.failed());
109 1164 : CompileError("%s: %s @+%u", error, result.error_msg.c_str(),
110 : result.error_offset);
111 : }
112 :
113 : i::Handle<i::Object> Reify() {
114 10350 : i::Handle<i::Object> result = exception_;
115 10817 : exception_ = i::Handle<i::Object>::null();
116 : return result;
117 : }
118 :
119 : bool error() const { return !exception_.is_null(); }
120 : bool wasm_error() { return wasm_error_; }
121 :
122 : private:
123 : void Format(i::Handle<i::JSFunction> constructor, const char* fmt, va_list);
124 :
125 : i::Isolate* isolate_;
126 : const char* context_;
127 : i::Handle<i::Object> exception_;
128 : bool wasm_error_ = false;
129 : };
130 :
131 : } // namespace wasm
132 : } // namespace internal
133 : } // namespace v8
134 :
135 : #endif
|