this repo has no description
at trunk 113 lines 4.1 kB view raw
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */ 2#pragma once 3 4#include "handles.h" 5#include "objects.h" 6 7namespace py { 8 9class Thread; 10 11const int kAttributeBucketNumWords = 2; 12const int kAttributeBucketKeyOffset = 0; 13const int kAttributeBucketValueOffset = 1; 14const RawObject kAttributeDictEmptyKey = SmallInt::fromWord(0); 15const RawObject kAttributeDictTombstoneKey = NoneType::object(); 16 17bool attributeAt(RawAttributeDict attrs, RawObject name, RawObject* result_out); 18 19bool attributeAtWithHash(RawAttributeDict attrs, RawObject name, word hash, 20 RawObject* result_out); 21 22RawObject attributeAtPut(Thread* thread, const AttributeDict& attrs, 23 const Object& name, const Object& value); 24 25void attributeDictInit(Thread* thread, const AttributeDict& attrs); 26 27RawObject attributeKeys(Thread* thread, const AttributeDict& attrs); 28 29word attributeLen(Thread* thread, const AttributeDict& attrs); 30 31// Prepare `name` to be used as an attribute name: Raise a TypeError if it 32// is not a string; reject some string subclasses. Otherwise return an 33// interned string that can be used with attribute accessors. 34RawObject attributeName(Thread* thread, const Object& name); 35 36RawObject attributeNameNoException(Thread* thread, const Object& name); 37 38bool attributeFindForRemoval(const AttributeDict& attrs, const Object& name, 39 Object* value_cell_out, word* index_out); 40 41void attributeRemove(const AttributeDict& attrs, word index); 42 43// Look-up underlying value-cell to a name. 44bool attributeValueCellAt(RawAttributeDict attrs, RawObject name, 45 RawObject* result_out); 46 47// Look-up underlying value-cell to a name. 48bool attributeValueCellAtWithHash(RawAttributeDict attrs, RawObject name, 49 word hash, RawObject* result_out); 50 51// Look-up or insert a value-cell for a given name. 52RawObject attributeValueCellAtPut(Thread* thread, const AttributeDict& attrs, 53 const Object& name); 54 55RawObject attributeValues(Thread* thread, const AttributeDict& attrs); 56 57word internedStrHash(RawObject name); 58 59inline bool attributeValueCellAtWithHash(RawAttributeDict attrs, RawObject name, 60 word hash, RawObject* result_out) { 61 RawMutableTuple data = MutableTuple::cast(attrs.attributes()); 62 word mask = (data.length() - 1) >> 1; 63 for (word bucket = hash & mask, num_probes = 0;; 64 bucket = (bucket + ++num_probes) & mask) { 65 word idx = bucket * kAttributeBucketNumWords; 66 RawObject key = data.at(idx + kAttributeBucketKeyOffset); 67 if (key == name) { 68 *result_out = data.at(idx + kAttributeBucketValueOffset); 69 return true; 70 } 71 if (key == kAttributeDictEmptyKey) { 72 return false; 73 } 74 // Remaining cases are either a key that does not match or tombstone. 75 } 76} 77 78inline RawObject attributeAtPut(Thread* thread, const AttributeDict& attrs, 79 const Object& name, const Object& value) { 80 RawValueCell value_cell = 81 ValueCell::cast(attributeValueCellAtPut(thread, attrs, name)); 82 value_cell.setValue(*value); 83 return value_cell; 84} 85 86inline bool attributeAtWithHash(RawAttributeDict attrs, RawObject name, 87 word hash, RawObject* result_out) { 88 RawObject result = NoneType::object(); 89 if (!attributeValueCellAtWithHash(attrs, name, hash, &result) || 90 ValueCell::cast(result).isPlaceholder()) { 91 return false; 92 } 93 *result_out = ValueCell::cast(result).value(); 94 return true; 95} 96 97inline bool attributeAt(RawAttributeDict attrs, RawObject name, 98 RawObject* result_out) { 99 word hash = internedStrHash(name); 100 return attributeAtWithHash(attrs, name, hash, result_out); 101} 102 103inline word internedStrHash(RawObject name) { 104 if (name.isImmediateObjectNotSmallInt()) { 105 return SmallStr::cast(name).hash(); 106 } 107 word hash = LargeStr::cast(name).header().hashCode(); 108 DCHECK(hash != Header::kUninitializedHash, 109 "hash has not been computed (string not interned?)"); 110 return hash; 111} 112 113} // namespace py