• 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 "src/base/compiler-specific.h"
9 #include "src/base/smart-pointers.h"
10 
11 #include "src/handles.h"
12 #include "src/globals.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 class Isolate;
18 
19 namespace wasm {
20 
21 // Error codes for programmatic checking of the decoder's verification.
22 enum ErrorCode {
23   kSuccess,
24   kError,                 // TODO(titzer): remove me
25   kOutOfMemory,           // decoder ran out of memory
26   kEndOfCode,             // end of code reached prematurely
27   kInvalidOpcode,         // found invalid opcode
28   kUnreachableCode,       // found unreachable code
29   kImproperContinue,      // improperly nested continue
30   kImproperBreak,         // improperly nested break
31   kReturnCount,           // return count mismatch
32   kTypeError,             // type mismatch
33   kInvalidLocalIndex,     // invalid local
34   kInvalidGlobalIndex,    // invalid global
35   kInvalidFunctionIndex,  // invalid function
36   kInvalidMemType         // invalid memory type
37 };
38 
39 // The overall result of decoding a function or a module.
40 template <typename T>
41 struct Result {
ResultResult42   Result() : val(), error_code(kSuccess), start(nullptr), error_pc(nullptr) {
43     error_msg.Reset(nullptr);
44   }
45 
46   T val;
47   ErrorCode error_code;
48   const byte* start;
49   const byte* error_pc;
50   const byte* error_pt;
51   base::SmartArrayPointer<char> error_msg;
52 
okResult53   bool ok() const { return error_code == kSuccess; }
failedResult54   bool failed() const { return error_code != kSuccess; }
55 
56   template <typename V>
CopyFromResult57   void CopyFrom(Result<V>& that) {
58     error_code = that.error_code;
59     start = that.start;
60     error_pc = that.error_pc;
61     error_pt = that.error_pt;
62     error_msg = that.error_msg;
63   }
64 };
65 
66 template <typename T>
67 std::ostream& operator<<(std::ostream& os, const Result<T>& result) {
68   os << "Result = ";
69   if (result.ok()) {
70     if (result.val != nullptr) {
71       os << *result.val;
72     } else {
73       os << "success (no value)";
74     }
75   } else if (result.error_msg.get() != nullptr) {
76     ptrdiff_t offset = result.error_pc - result.start;
77     if (offset < 0) {
78       os << result.error_msg.get() << " @" << offset;
79     } else {
80       os << result.error_msg.get() << " @+" << offset;
81     }
82   } else {
83     os << result.error_code;
84   }
85   os << std::endl;
86   return os;
87 }
88 
89 std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code);
90 
91 // A helper for generating error messages that bubble up to JS exceptions.
92 class ErrorThrower {
93  public:
ErrorThrower(Isolate * isolate,const char * context)94   ErrorThrower(Isolate* isolate, const char* context)
95       : isolate_(isolate), context_(context) {}
96   ~ErrorThrower();
97 
98   PRINTF_FORMAT(2, 3) void Error(const char* fmt, ...);
99 
100   template <typename T>
Failed(const char * error,Result<T> & result)101   void Failed(const char* error, Result<T>& result) {
102     std::ostringstream str;
103     str << error << result;
104     return Error("%s", str.str().c_str());
105   }
106 
Reify()107   i::Handle<i::String> Reify() {
108     auto result = message_;
109     message_ = i::Handle<i::String>();
110     return result;
111   }
112 
error()113   bool error() const { return !message_.is_null(); }
114 
115  private:
116   Isolate* isolate_;
117   const char* context_;
118   i::Handle<i::String> message_;
119 };
120 }  // namespace wasm
121 }  // namespace internal
122 }  // namespace v8
123 
124 #endif
125