blob: e741de8e5e187e8a4fef4053f910128f61235e73 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
Ben Murdochc5610432016-08-08 18:44:38 +01008#include "src/base/compiler-specific.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/base/smart-pointers.h"
10
Ben Murdoch61f157c2016-09-16 13:49:30 +010011#include "src/handles.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/globals.h"
13
14namespace v8 {
15namespace internal {
16
17class Isolate;
18
19namespace wasm {
20
21// Error codes for programmatic checking of the decoder's verification.
22enum 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.
40template <typename T>
41struct Result {
Ben Murdoch61f157c2016-09-16 13:49:30 +010042 Result() : val(), error_code(kSuccess), start(nullptr), error_pc(nullptr) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043 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
53 bool ok() const { return error_code == kSuccess; }
54 bool failed() const { return error_code != kSuccess; }
55
56 template <typename V>
57 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
66template <typename T>
67std::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
89std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code);
90
91// A helper for generating error messages that bubble up to JS exceptions.
92class ErrorThrower {
93 public:
94 ErrorThrower(Isolate* isolate, const char* context)
Ben Murdoch61f157c2016-09-16 13:49:30 +010095 : isolate_(isolate), context_(context) {}
96 ~ErrorThrower();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097
Ben Murdochc5610432016-08-08 18:44:38 +010098 PRINTF_FORMAT(2, 3) void Error(const char* fmt, ...);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000099
100 template <typename T>
101 void Failed(const char* error, Result<T>& result) {
102 std::ostringstream str;
103 str << error << result;
Ben Murdochc5610432016-08-08 18:44:38 +0100104 return Error("%s", str.str().c_str());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 }
106
Ben Murdoch61f157c2016-09-16 13:49:30 +0100107 i::Handle<i::String> Reify() {
108 auto result = message_;
109 message_ = i::Handle<i::String>();
110 return result;
111 }
112
113 bool error() const { return !message_.is_null(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114
115 private:
116 Isolate* isolate_;
117 const char* context_;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100118 i::Handle<i::String> message_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119};
120} // namespace wasm
121} // namespace internal
122} // namespace v8
123
124#endif