Index: src/builtins/builtins-internal-gen.cc |
diff --git a/src/builtins/builtins-internal-gen.cc b/src/builtins/builtins-internal-gen.cc |
index d1d000ce9efbd8689eff613dcc47d765a116d633..b152d63bbd68d9c3820149ed4f350256740f2a0c 100644 |
--- a/src/builtins/builtins-internal-gen.cc |
+++ b/src/builtins/builtins-internal-gen.cc |
@@ -164,5 +164,126 @@ TF_BUILTIN(ReturnReceiver, CodeStubAssembler) { |
Return(Parameter(Descriptor::kReceiver)); |
} |
+class DeletePropertyBaseAssembler : public CodeStubAssembler { |
+ public: |
+ explicit DeletePropertyBaseAssembler(compiler::CodeAssemblerState* state) |
+ : CodeStubAssembler(state) {} |
+ |
+ void DeleteDictionaryProperty(Node* receiver, Node* properties, Node* name, |
+ Node* context, Label* dont_delete, |
+ Label* notfound) { |
+ VARIABLE(var_name_index, MachineType::PointerRepresentation()); |
+ Label dictionary_found(this, &var_name_index); |
+ NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found, |
+ &var_name_index, notfound); |
+ |
+ BIND(&dictionary_found); |
+ Node* key_index = var_name_index.value(); |
+ Node* details = |
+ LoadDetailsByKeyIndex<NameDictionary>(properties, key_index); |
+ GotoIf(IsSetWord32(details, PropertyDetails::kAttributesDontDeleteMask), |
+ dont_delete); |
+ // Overwrite the entry itself (see NameDictionary::SetEntry). |
+ Node* filler = TheHoleConstant(); |
+ DCHECK(Heap::RootIsImmortalImmovable(Heap::kTheHoleValueRootIndex)); |
+ StoreFixedArrayElement(properties, key_index, filler, SKIP_WRITE_BARRIER); |
+ StoreValueByKeyIndex<NameDictionary>(properties, key_index, filler, |
+ SKIP_WRITE_BARRIER); |
+ StoreDetailsByKeyIndex<NameDictionary>(properties, key_index, |
+ SmiConstant(Smi::kZero)); |
+ |
+ // Update bookkeeping information (see NameDictionary::ElementRemoved). |
+ Node* nof = GetNumberOfElements<NameDictionary>(properties); |
+ Node* new_nof = SmiSub(nof, SmiConstant(1)); |
+ SetNumberOfElements<NameDictionary>(properties, new_nof); |
+ Node* num_deleted = GetNumberOfDeletedElements<NameDictionary>(properties); |
+ Node* new_deleted = SmiAdd(num_deleted, SmiConstant(1)); |
+ SetNumberOfDeletedElements<NameDictionary>(properties, new_deleted); |
+ |
+ // Shrink the dictionary if necessary (see NameDictionary::Shrink). |
+ Label shrinking_done(this); |
+ Node* capacity = GetCapacity<NameDictionary>(properties); |
+ GotoIf(SmiGreaterThan(new_nof, SmiShr(capacity, 2)), &shrinking_done); |
+ GotoIf(SmiLessThan(new_nof, SmiConstant(16)), &shrinking_done); |
+ CallRuntime(Runtime::kShrinkPropertyDictionary, context, receiver, name); |
+ Goto(&shrinking_done); |
+ BIND(&shrinking_done); |
+ |
+ Return(TrueConstant()); |
+ } |
+}; |
+ |
+TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { |
+ Node* receiver = Parameter(Descriptor::kObject); |
+ Node* key = Parameter(Descriptor::kKey); |
+ Node* language_mode = Parameter(Descriptor::kLanguageMode); |
+ Node* context = Parameter(Descriptor::kContext); |
+ |
+ VARIABLE(var_index, MachineType::PointerRepresentation()); |
+ VARIABLE(var_unique, MachineRepresentation::kTagged, key); |
+ Label if_index(this), if_unique_name(this), if_notunique(this), |
+ if_notfound(this), slow(this); |
+ |
+ GotoIf(TaggedIsSmi(receiver), &slow); |
+ Node* receiver_map = LoadMap(receiver); |
+ Node* instance_type = LoadMapInstanceType(receiver_map); |
+ GotoIf(Int32LessThanOrEqual(instance_type, |
+ Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
+ &slow); |
+ TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique, &slow, |
+ &if_notunique); |
+ |
+ BIND(&if_index); |
+ { |
+ Comment("integer index"); |
+ Goto(&slow); // TODO(jkummerow): Implement more smarts here. |
+ } |
+ |
+ BIND(&if_unique_name); |
+ { |
+ Comment("key is unique name"); |
+ Node* unique = var_unique.value(); |
+ CheckForAssociatedProtector(unique, &slow); |
+ |
+ Label dictionary(this), dont_delete(this); |
+ Node* properties = LoadProperties(receiver); |
+ Node* properties_map = LoadMap(properties); |
+ GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
+ &dictionary); |
+ // TODO(jkummerow): Implement support for fast properties? |
+ Goto(&slow); |
+ |
+ BIND(&dictionary); |
+ { |
+ DeleteDictionaryProperty(receiver, properties, unique, context, |
+ &dont_delete, &if_notfound); |
+ } |
+ |
+ BIND(&dont_delete); |
+ { |
+ STATIC_ASSERT(LANGUAGE_END == 2); |
+ GotoIf(SmiNotEqual(language_mode, SmiConstant(SLOPPY)), &slow); |
+ Return(FalseConstant()); |
+ } |
+ } |
+ |
+ BIND(&if_notunique); |
+ { |
+ // If the string was not found in the string table, then no object can |
+ // have a property with that name. |
+ TryInternalizeString(key, &if_index, &var_index, &if_unique_name, |
+ &var_unique, &if_notfound, &slow); |
+ } |
+ |
+ BIND(&if_notfound); |
+ Return(TrueConstant()); |
+ |
+ BIND(&slow); |
+ { |
+ TailCallRuntime(Runtime::kDeleteProperty, context, receiver, key, |
+ language_mode); |
+ } |
+} |
+ |
} // namespace internal |
} // namespace v8 |