1// Copyright 2021 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#if !V8_ENABLE_WEBASSEMBLY
6#error This header should only be included if WebAssembly is enabled.
7#endif  // !V8_ENABLE_WEBASSEMBLY
8
9#ifndef V8_WASM_INIT_EXPR_INTERFACE_H_
10#define V8_WASM_INIT_EXPR_INTERFACE_H_
11
12#include "src/wasm/decoder.h"
13#include "src/wasm/function-body-decoder-impl.h"
14#include "src/wasm/wasm-value.h"
15
16namespace v8 {
17namespace internal {
18
19class WasmInstanceObject;
20class JSArrayBuffer;
21
22namespace wasm {
23
24// An interface for WasmFullDecoder used to decode initializer expressions. This
25// interface has two modes: only validation (when {isolate_ == nullptr}), which
26// is used in module-decoder, and code-generation (when {isolate_ != nullptr}),
27// which is used in module-instantiate. We merge two distinct functionalities
28// in one class to reduce the number of WasmFullDecoder instantiations, and thus
29// V8 binary code size.
30class InitExprInterface {
31 public:
32  static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
33  static constexpr DecodingMode decoding_mode = kInitExpression;
34
35  struct Value : public ValueBase<validate> {
36    WasmValue runtime_value;
37
38    template <typename... Args>
39    explicit Value(Args&&... args) V8_NOEXCEPT
40        : ValueBase(std::forward<Args>(args)...) {}
41  };
42
43  using Control = ControlBase<Value, validate>;
44  using FullDecoder =
45      WasmFullDecoder<validate, InitExprInterface, decoding_mode>;
46
47  InitExprInterface(const WasmModule* module, Isolate* isolate,
48                    Handle<WasmInstanceObject> instance)
49      : module_(module),
50        outer_module_(nullptr),
51        isolate_(isolate),
52        instance_(instance) {
53    DCHECK_NOT_NULL(isolate);
54  }
55
56  explicit InitExprInterface(WasmModule* outer_module)
57      : module_(nullptr), outer_module_(outer_module), isolate_(nullptr) {}
58
59#define EMPTY_INTERFACE_FUNCTION(name, ...) \
60  V8_INLINE void name(FullDecoder* decoder, ##__VA_ARGS__) {}
61  INTERFACE_META_FUNCTIONS(EMPTY_INTERFACE_FUNCTION)
62#undef EMPTY_INTERFACE_FUNCTION
63#define UNREACHABLE_INTERFACE_FUNCTION(name, ...) \
64  V8_INLINE void name(FullDecoder* decoder, ##__VA_ARGS__) { UNREACHABLE(); }
65  INTERFACE_NON_CONSTANT_FUNCTIONS(UNREACHABLE_INTERFACE_FUNCTION)
66#undef UNREACHABLE_INTERFACE_FUNCTION
67
68#define DECLARE_INTERFACE_FUNCTION(name, ...) \
69  void name(FullDecoder* decoder, ##__VA_ARGS__);
70  INTERFACE_CONSTANT_FUNCTIONS(DECLARE_INTERFACE_FUNCTION)
71#undef DECLARE_INTERFACE_FUNCTION
72
73  WasmValue result() {
74    DCHECK_NOT_NULL(isolate_);
75    return result_;
76  }
77  bool end_found() { return end_found_; }
78  bool runtime_error() { return error_ != nullptr; }
79  const char* runtime_error_msg() { return error_; }
80
81 private:
82  bool generate_result() { return isolate_ != nullptr && !runtime_error(); }
83  bool end_found_ = false;
84  const char* error_ = nullptr;
85  WasmValue result_;
86  const WasmModule* module_;
87  WasmModule* outer_module_;
88  Isolate* isolate_;
89  Handle<WasmInstanceObject> instance_;
90};
91
92}  // namespace wasm
93}  // namespace internal
94}  // namespace v8
95
96#endif  // V8_WASM_INIT_EXPR_INTERFACE_H_
97