summaryrefslogtreecommitdiffstats
path: root/js/src/vm/PropertyResult.h
blob: e9e9b4c1cc58c669cc424486998e26c50e433409 (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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef vm_PropertyResult_h
#define vm_PropertyResult_h

#include "mozilla/Assertions.h"

#include "vm/PropertyInfo.h"

namespace js {

class PropertyResult {
  enum class Kind : uint8_t {
    NotFound,
    NativeProperty,
    NonNativeProperty,
    DenseElement,
    TypedArrayElement,
  };
  union {
    // Set if kind is NativeProperty.
    PropertyInfo propInfo_;
    // Set if kind is DenseElement.
    uint32_t denseIndex_;
    // Set if kind is TypedArrayElement.
    size_t typedArrayIndex_;
  };
  Kind kind_ = Kind::NotFound;
  bool ignoreProtoChain_ = false;

 public:
  // Note: because PropertyInfo does not have a default constructor, we can't
  // use |= default| here.
  PropertyResult() {}

  // When a property is not found, we may additionally indicate that the
  // prototype chain should be ignored. This occurs for:
  //  - An out-of-range numeric property on a TypedArrayObject.
  //  - A resolve hook recursively calling itself as it sets the property.
  bool isNotFound() const { return kind_ == Kind::NotFound; }
  bool shouldIgnoreProtoChain() const {
    MOZ_ASSERT(isNotFound());
    return ignoreProtoChain_;
  }

  bool isFound() const { return kind_ != Kind::NotFound; }
  bool isNonNativeProperty() const { return kind_ == Kind::NonNativeProperty; }
  bool isDenseElement() const { return kind_ == Kind::DenseElement; }
  bool isTypedArrayElement() const { return kind_ == Kind::TypedArrayElement; }
  bool isNativeProperty() const { return kind_ == Kind::NativeProperty; }

  PropertyInfo propertyInfo() const {
    MOZ_ASSERT(isNativeProperty());
    return propInfo_;
  }

  uint32_t denseElementIndex() const {
    MOZ_ASSERT(isDenseElement());
    return denseIndex_;
  }

  size_t typedArrayElementIndex() const {
    MOZ_ASSERT(isTypedArrayElement());
    return typedArrayIndex_;
  }

  void setNotFound() { kind_ = Kind::NotFound; }

  void setNativeProperty(PropertyInfo prop) {
    kind_ = Kind::NativeProperty;
    propInfo_ = prop;
  }

  void setWasmGcProperty() { kind_ = Kind::NonNativeProperty; }
  void setProxyProperty() { kind_ = Kind::NonNativeProperty; }

  void setDenseElement(uint32_t index) {
    kind_ = Kind::DenseElement;
    denseIndex_ = index;
  }

  void setTypedArrayElement(size_t index) {
    kind_ = Kind::TypedArrayElement;
    typedArrayIndex_ = index;
  }

  void setTypedArrayOutOfRange() {
    kind_ = Kind::NotFound;
    ignoreProtoChain_ = true;
  }
  void setRecursiveResolve() {
    kind_ = Kind::NotFound;
    ignoreProtoChain_ = true;
  }
};

}  // namespace js

#endif /* vm_PropertyResult_h */