summaryrefslogtreecommitdiff
path: root/chromium/v8/src/wasm/constant-expression-interface.h
blob: 6dc225e7b7e2017e6eee0c75317ffcccf22fe70f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif  // !V8_ENABLE_WEBASSEMBLY

#ifndef V8_WASM_CONSTANT_EXPRESSION_INTERFACE_H_
#define V8_WASM_CONSTANT_EXPRESSION_INTERFACE_H_

#include "src/wasm/decoder.h"
#include "src/wasm/function-body-decoder-impl.h"
#include "src/wasm/wasm-value.h"

namespace v8 {
namespace internal {

class WasmInstanceObject;
class JSArrayBuffer;

namespace wasm {

// An interface for WasmFullDecoder used to decode constant expressions.
// This interface has two modes: only validation (when {isolate_ == nullptr}),
// and code-generation (when {isolate_ != nullptr}). We merge two distinct
// functionalities in one class to reduce the number of WasmFullDecoder
// instantiations, and thus V8 binary code size.
// In code-generation mode, the result can be retrieved with {computed_value()}
// if {!has_error()}, or with {error()} otherwise.
class V8_EXPORT_PRIVATE ConstantExpressionInterface {
 public:
  static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
  static constexpr DecodingMode decoding_mode = kConstantExpression;

  struct Value : public ValueBase<validate> {
    WasmValue runtime_value;

    template <typename... Args>
    explicit Value(Args&&... args) V8_NOEXCEPT
        : ValueBase(std::forward<Args>(args)...) {}
  };

  using Control = ControlBase<Value, validate>;
  using FullDecoder =
      WasmFullDecoder<validate, ConstantExpressionInterface, decoding_mode>;

  ConstantExpressionInterface(const WasmModule* module, Isolate* isolate,
                              Handle<WasmInstanceObject> instance)
      : module_(module),
        outer_module_(nullptr),
        isolate_(isolate),
        instance_(instance) {
    DCHECK_NOT_NULL(isolate);
  }

  explicit ConstantExpressionInterface(WasmModule* outer_module)
      : module_(nullptr), outer_module_(outer_module), isolate_(nullptr) {}

#define EMPTY_INTERFACE_FUNCTION(name, ...) \
  V8_INLINE void name(FullDecoder* decoder, ##__VA_ARGS__) {}
  INTERFACE_META_FUNCTIONS(EMPTY_INTERFACE_FUNCTION)
#undef EMPTY_INTERFACE_FUNCTION
#define UNREACHABLE_INTERFACE_FUNCTION(name, ...) \
  V8_INLINE void name(FullDecoder* decoder, ##__VA_ARGS__) { UNREACHABLE(); }
  INTERFACE_NON_CONSTANT_FUNCTIONS(UNREACHABLE_INTERFACE_FUNCTION)
#undef UNREACHABLE_INTERFACE_FUNCTION

#define DECLARE_INTERFACE_FUNCTION(name, ...) \
  void name(FullDecoder* decoder, ##__VA_ARGS__);
  INTERFACE_CONSTANT_FUNCTIONS(DECLARE_INTERFACE_FUNCTION)
#undef DECLARE_INTERFACE_FUNCTION

  WasmValue computed_value() const {
    DCHECK(generate_value());
    // The value has to be initialized.
    DCHECK_NE(computed_value_.type(), kWasmVoid);
    return computed_value_;
  }
  bool end_found() const { return end_found_; }
  bool has_error() const { return error_ != MessageTemplate::kNone; }
  MessageTemplate error() const {
    DCHECK(has_error());
    DCHECK_EQ(computed_value_.type(), kWasmVoid);
    return error_;
  }

 private:
  bool generate_value() const { return isolate_ != nullptr && !has_error(); }

  bool end_found_ = false;
  WasmValue computed_value_;
  MessageTemplate error_ = MessageTemplate::kNone;
  const WasmModule* module_;
  WasmModule* outer_module_;
  Isolate* isolate_;
  Handle<WasmInstanceObject> instance_;
};

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_CONSTANT_EXPRESSION_INTERFACE_H_