• 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_RESULT_H_
6 #define V8_WASM_RESULT_H_
7 
8 #include <memory>
9 
10 #include "src/base/compiler-specific.h"
11 
12 #include "src/handles.h"
13 #include "src/globals.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 class Isolate;
19 
20 namespace wasm {
21 
22 // Error codes for programmatic checking of the decoder's verification.
23 enum ErrorCode {
24   kSuccess,
25   kError,  // TODO(titzer): introduce real error codes
26 };
27 
28 // The overall result of decoding a function or a module.
29 template <typename T>
30 struct Result {
ResultResult31   Result() : val(), error_code(kSuccess), start(nullptr), error_pc(nullptr) {}
ResultResult32   Result(Result&& other) { *this = std::move(other); }
33   Result& operator=(Result&& other) {
34     MoveFrom(other);
35     val = other.val;
36     return *this;
37   }
38 
39   T val;
40   ErrorCode error_code;
41   const byte* start;
42   const byte* error_pc;
43   const byte* error_pt;
44   std::unique_ptr<char[]> error_msg;
45 
okResult46   bool ok() const { return error_code == kSuccess; }
failedResult47   bool failed() const { return error_code != kSuccess; }
48 
49   template <typename V>
MoveFromResult50   void MoveFrom(Result<V>& that) {
51     error_code = that.error_code;
52     start = that.start;
53     error_pc = that.error_pc;
54     error_pt = that.error_pt;
55     error_msg = std::move(that.error_msg);
56   }
57 
58  private:
59   DISALLOW_COPY_AND_ASSIGN(Result);
60 };
61 
62 template <typename T>
63 std::ostream& operator<<(std::ostream& os, const Result<T>& result) {
64   os << "Result = ";
65   if (result.ok()) {
66     if (result.val != nullptr) {
67       os << *result.val;
68     } else {
69       os << "success (no value)";
70     }
71   } else if (result.error_msg.get() != nullptr) {
72     ptrdiff_t offset = result.error_pc - result.start;
73     if (offset < 0) {
74       os << result.error_msg.get() << " @" << offset;
75     } else {
76       os << result.error_msg.get() << " @+" << offset;
77     }
78   } else {
79     os << result.error_code;
80   }
81   os << std::endl;
82   return os;
83 }
84 
85 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
86                                            const ErrorCode& error_code);
87 
88 // A helper for generating error messages that bubble up to JS exceptions.
89 class V8_EXPORT_PRIVATE ErrorThrower {
90  public:
ErrorThrower(i::Isolate * isolate,const char * context)91   ErrorThrower(i::Isolate* isolate, const char* context)
92       : isolate_(isolate), context_(context) {}
93   ~ErrorThrower();
94 
95   PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
96   PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
97   PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
98   PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
99   PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
100 
101   template <typename T>
CompileFailed(const char * error,Result<T> & result)102   void CompileFailed(const char* error, Result<T>& result) {
103     std::ostringstream str;
104     str << error << result;
105     CompileError("%s", str.str().c_str());
106   }
107 
Reify()108   i::Handle<i::Object> Reify() {
109     i::Handle<i::Object> result = exception_;
110     exception_ = i::Handle<i::Object>::null();
111     return result;
112   }
113 
error()114   bool error() const { return !exception_.is_null(); }
wasm_error()115   bool wasm_error() { return wasm_error_; }
116 
117  private:
118   void Format(i::Handle<i::JSFunction> constructor, const char* fmt, va_list);
119 
120   i::Isolate* isolate_;
121   const char* context_;
122   i::Handle<i::Object> exception_;
123   bool wasm_error_ = false;
124 };
125 }  // namespace wasm
126 }  // namespace internal
127 }  // namespace v8
128 
129 #endif
130