Index: src/key-accumulator.cc |
diff --git a/src/key-accumulator.cc b/src/key-accumulator.cc |
index e7a9c3ccebccd3ba56b7a87b6cc7c1f9148deae7..c259edffe9da4b10a608d113b26d3ac74094a854 100644 |
--- a/src/key-accumulator.cc |
+++ b/src/key-accumulator.cc |
@@ -138,10 +138,11 @@ bool KeyAccumulator::AddKey(uint32_t key) { return AddIntegerKey(key); } |
bool KeyAccumulator::AddIntegerKey(uint32_t key) { |
+ if (IsKeyHidden(key)) return false; |
// Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). |
// We mark proxy-levels with a negative length |
DCHECK_LE(0, level_string_length_); |
- // Binary search over all but the last level. The last one might not be |
+ // Binary search over all but the last level. The last level might not be |
// sorted yet. |
for (size_t i = 1; i < elements_.size(); i++) { |
if (AccumulatorHasKey(elements_[i - 1], key)) return false; |
@@ -154,11 +155,10 @@ bool KeyAccumulator::AddIntegerKey(uint32_t key) { |
bool KeyAccumulator::AddStringKey(Handle<Object> key, |
AddKeyConversion convert) { |
+ if (IsKeyHidden(key)) return false; |
if (string_properties_.is_null()) { |
string_properties_ = OrderedHashSet::Allocate(isolate_, 16); |
} |
- // TODO(cbruni): remove this conversion once we throw the correct TypeError |
- // for non-string/symbol elements returned by proxies |
if (convert == PROXY_MAGIC && key->IsNumber()) { |
key = isolate_->factory()->NumberToString(key); |
} |
@@ -175,6 +175,7 @@ bool KeyAccumulator::AddStringKey(Handle<Object> key, |
bool KeyAccumulator::AddSymbolKey(Handle<Object> key) { |
+ if (IsKeyHidden(key)) return false; |
if (symbol_properties_.is_null()) { |
symbol_properties_ = OrderedHashSet::Allocate(isolate_, 16); |
} |
@@ -299,6 +300,9 @@ void KeyAccumulator::SortCurrentElementsList() { |
} |
+void KeyAccumulator::Prepare() { NextPrototype(); } |
+ |
+ |
void KeyAccumulator::NextPrototype() { |
// Store the protoLength on the first call of this method. |
if (!elements_.empty()) { |
@@ -311,5 +315,32 @@ void KeyAccumulator::NextPrototype() { |
} |
+void KeyAccumulator::HideKey(uint32_t key) { hidden_element_keys_.insert(key); } |
+ |
+ |
+void KeyAccumulator::HideKey(Object* key) { |
+ HideKey(Handle<Object>(key, isolate_)); |
+} |
+ |
+ |
+void KeyAccumulator::HideKey(Handle<Object> key) { |
+ if (hidden_keys_.is_null()) { |
+ hidden_keys_ = OrderedHashSet::Allocate(isolate_, 8); |
+ } |
+ hidden_keys_ = OrderedHashSet::Add(hidden_keys_, key); |
+} |
+ |
+ |
+bool KeyAccumulator::IsKeyHidden(uint32_t key) { |
+ return hidden_element_keys_.count(key); |
+} |
+ |
+ |
+bool KeyAccumulator::IsKeyHidden(Handle<Object> key) { |
+ if (hidden_keys_.is_null()) return false; |
+ return OrderedHashSet::HasKey(hidden_keys_, key); |
+} |
+ |
+ |
} // namespace internal |
} // namespace v8 |