PropertyResult.h (3198B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef vm_PropertyResult_h 8 #define vm_PropertyResult_h 9 10 #include "mozilla/Assertions.h" 11 12 #include "vm/PropertyInfo.h" 13 14 namespace js { 15 16 class PropertyResult { 17 enum class Kind : uint8_t { 18 NotFound, 19 NativeProperty, 20 NonNativeProperty, 21 DenseElement, 22 TypedArrayElement, 23 }; 24 enum class IgnoreProtoChain : uint8_t { 25 No, 26 RecursiveResolve, 27 TypedArrayOutOfRange, 28 }; 29 union { 30 // Set if kind is NativeProperty. 31 PropertyInfo propInfo_; 32 // Set if kind is DenseElement. 33 uint32_t denseIndex_; 34 // Set if kind is TypedArrayElement. 35 size_t typedArrayIndex_; 36 }; 37 Kind kind_ = Kind::NotFound; 38 IgnoreProtoChain ignoreProtoChain_ = IgnoreProtoChain::No; 39 40 public: 41 // Note: because PropertyInfo does not have a default constructor, we can't 42 // use |= default| here. 43 PropertyResult() {} 44 45 // When a property is not found, we may additionally indicate that the 46 // prototype chain should be ignored. This occurs for: 47 // - An out-of-range numeric property on a TypedArrayObject. 48 // - A resolve hook recursively calling itself as it sets the property. 49 bool isNotFound() const { return kind_ == Kind::NotFound; } 50 bool shouldIgnoreProtoChain() const { 51 MOZ_ASSERT(isNotFound()); 52 return ignoreProtoChain_ != IgnoreProtoChain::No; 53 } 54 bool isTypedArrayOutOfRange() const { 55 MOZ_ASSERT(isNotFound()); 56 return ignoreProtoChain_ == IgnoreProtoChain::TypedArrayOutOfRange; 57 } 58 59 bool isFound() const { return kind_ != Kind::NotFound; } 60 bool isNonNativeProperty() const { return kind_ == Kind::NonNativeProperty; } 61 bool isDenseElement() const { return kind_ == Kind::DenseElement; } 62 bool isTypedArrayElement() const { return kind_ == Kind::TypedArrayElement; } 63 bool isNativeProperty() const { return kind_ == Kind::NativeProperty; } 64 65 PropertyInfo propertyInfo() const { 66 MOZ_ASSERT(isNativeProperty()); 67 return propInfo_; 68 } 69 70 uint32_t denseElementIndex() const { 71 MOZ_ASSERT(isDenseElement()); 72 return denseIndex_; 73 } 74 75 size_t typedArrayElementIndex() const { 76 MOZ_ASSERT(isTypedArrayElement()); 77 return typedArrayIndex_; 78 } 79 80 void setNotFound() { kind_ = Kind::NotFound; } 81 82 void setNativeProperty(PropertyInfo prop) { 83 kind_ = Kind::NativeProperty; 84 propInfo_ = prop; 85 } 86 87 void setProxyProperty() { kind_ = Kind::NonNativeProperty; } 88 89 void setDenseElement(uint32_t index) { 90 kind_ = Kind::DenseElement; 91 denseIndex_ = index; 92 } 93 94 void setTypedArrayElement(size_t index) { 95 kind_ = Kind::TypedArrayElement; 96 typedArrayIndex_ = index; 97 } 98 99 void setTypedArrayOutOfRange() { 100 kind_ = Kind::NotFound; 101 ignoreProtoChain_ = IgnoreProtoChain::TypedArrayOutOfRange; 102 } 103 void setRecursiveResolve() { 104 kind_ = Kind::NotFound; 105 ignoreProtoChain_ = IgnoreProtoChain::RecursiveResolve; 106 } 107 }; 108 109 } // namespace js 110 111 #endif /* vm_PropertyResult_h */