Chromium Code Reviews| 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..f85cefb44813a5975f9549f82428c1420f70ae05 100644 |
| --- a/src/builtins/builtins-internal-gen.cc |
| +++ b/src/builtins/builtins-internal-gen.cc |
| @@ -164,5 +164,123 @@ 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(); |
| + StoreFixedArrayElement(properties, key_index, filler); |
|
Igor Sheludko
2017/04/20 09:18:42
TheHoleValue is in IMMORTAL_IMMOVABLE_ROOT_LIST so
Jakob Kummerow
2017/04/20 09:52:34
Done.
|
| + StoreValueByKeyIndex<NameDictionary>(properties, key_index, filler); |
|
Igor Sheludko
2017/04/20 09:18:42
and here.
Jakob Kummerow
2017/04/20 09:52:34
Done.
|
| + 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); |
| + { |
| + GotoIf(SmiEqual(language_mode, SmiConstant(STRICT)), &slow); |
|
Igor Sheludko
2017/04/20 09:18:42
is_strict(lm) is implemented as lm != SLOPPY which
Jakob Kummerow
2017/04/20 09:52:34
Done.
|
| + 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()); } |
|
Igor Sheludko
2017/04/20 09:18:42
I think this line will look nicer without {}.
Jakob Kummerow
2017/04/20 09:52:34
Done.
|
| + |
| + BIND(&slow); |
| + { |
| + TailCallRuntime(Runtime::kDeleteProperty, context, receiver, key, |
| + language_mode); |
| + } |
| +} |
| + |
| } // namespace internal |
| } // namespace v8 |