• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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