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 "js/HeapAPI.h" 13 #include "js/RootingAPI.h" 14 15 #include "vm/Shape.h" 16 17 namespace js { 18 19 class PropertyResult { 20 enum class Kind : uint8_t { 21 NotFound, 22 NativeProperty, 23 NonNativeProperty, 24 DenseElement, 25 TypedArrayElement, 26 }; 27 union { 28 // Set if kind is NativeProperty. 29 PropertyInfo propInfo_; 30 // Set if kind is DenseElement. 31 uint32_t denseIndex_; 32 // Set if kind is TypedArrayElement. 33 size_t typedArrayIndex_; 34 }; 35 Kind kind_ = Kind::NotFound; 36 bool ignoreProtoChain_ = false; 37 38 public: 39 // Note: because PropertyInfo does not have a default constructor, we can't 40 // use |= default| here. PropertyResult()41 PropertyResult() {} 42 43 // When a property is not found, we may additionally indicate that the 44 // prototype chain should be ignored. This occurs for: 45 // - An out-of-range numeric property on a TypedArrayObject. 46 // - A resolve hook recursively calling itself as it sets the property. isNotFound()47 bool isNotFound() const { return kind_ == Kind::NotFound; } shouldIgnoreProtoChain()48 bool shouldIgnoreProtoChain() const { 49 MOZ_ASSERT(isNotFound()); 50 return ignoreProtoChain_; 51 } 52 isFound()53 bool isFound() const { return kind_ != Kind::NotFound; } isNonNativeProperty()54 bool isNonNativeProperty() const { return kind_ == Kind::NonNativeProperty; } isDenseElement()55 bool isDenseElement() const { return kind_ == Kind::DenseElement; } isTypedArrayElement()56 bool isTypedArrayElement() const { return kind_ == Kind::TypedArrayElement; } isNativeProperty()57 bool isNativeProperty() const { return kind_ == Kind::NativeProperty; } 58 propertyInfo()59 PropertyInfo propertyInfo() const { 60 MOZ_ASSERT(isNativeProperty()); 61 return propInfo_; 62 } 63 denseElementIndex()64 uint32_t denseElementIndex() const { 65 MOZ_ASSERT(isDenseElement()); 66 return denseIndex_; 67 } 68 typedArrayElementIndex()69 size_t typedArrayElementIndex() const { 70 MOZ_ASSERT(isTypedArrayElement()); 71 return typedArrayIndex_; 72 } 73 setNotFound()74 void setNotFound() { kind_ = Kind::NotFound; } 75 setNativeProperty(PropertyInfo prop)76 void setNativeProperty(PropertyInfo prop) { 77 kind_ = Kind::NativeProperty; 78 propInfo_ = prop; 79 } 80 setTypedObjectProperty()81 void setTypedObjectProperty() { kind_ = Kind::NonNativeProperty; } setProxyProperty()82 void setProxyProperty() { kind_ = Kind::NonNativeProperty; } 83 setDenseElement(uint32_t index)84 void setDenseElement(uint32_t index) { 85 kind_ = Kind::DenseElement; 86 denseIndex_ = index; 87 } 88 setTypedArrayElement(size_t index)89 void setTypedArrayElement(size_t index) { 90 kind_ = Kind::TypedArrayElement; 91 typedArrayIndex_ = index; 92 } 93 setTypedArrayOutOfRange()94 void setTypedArrayOutOfRange() { 95 kind_ = Kind::NotFound; 96 ignoreProtoChain_ = true; 97 } setRecursiveResolve()98 void setRecursiveResolve() { 99 kind_ = Kind::NotFound; 100 ignoreProtoChain_ = true; 101 } 102 }; 103 104 } // namespace js 105 106 #endif /* vm_PropertyResult_h */ 107