[webkit-reviews] review granted: [Bug 194435] [ESNext] Implement private accessors : [Attachment 420127] Patch
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Sun Feb 14 01:45:40 PST 2021
Yusuke Suzuki <ysuzuki at apple.com> has granted Caio Lima
<ticaiolima at gmail.com>'s request for review:
Bug 194435: [ESNext] Implement private accessors
https://bugs.webkit.org/show_bug.cgi?id=194435
Attachment 420127: Patch
https://bugs.webkit.org/attachment.cgi?id=420127&action=review
--- Comment #15 from Yusuke Suzuki <ysuzuki at apple.com> ---
Comment on attachment 420127
--> https://bugs.webkit.org/attachment.cgi?id=420127
Patch
View in context: https://bugs.webkit.org/attachment.cgi?id=420127&action=review
r=me with comments.
> Source/JavaScriptCore/ChangeLog:37
> + new_object dst:loc12, inlineCapacity:2 // this is the object
to store getter and setter pair
Can we have a FIXME about using GetterSetter instead?
> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:3000
> + if (!excludedNames.contains(entry.key.get())) {
> + result.add(entry.key, entry.value);
> excludedNames.add(entry.key.get());
> + }
contains & add is duplicate cost. Let's do,
auto addResult = excludedNames.add(entry.key.get());
if (addResult.isNewEntry)
result.add(entry.key, entry.value);
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:583
> + typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
> + typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash>
GetterSetterMap;
Use `using` instead for new code.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:588
> + for (; p; p = p->m_next) {
Let's not use p variable here. This is used for the latter iteration. So, let's
move
PropertyListNode* p = this;
RegisterID* dst = nullptr;
just before // Fast case: this loop just handles regular value properties.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:601
> + if (!(p->m_node->type() & (PropertyNode::PrivateGetter |
PropertyNode::PrivateSetter)))
> + continue;
> +
> + // We group private getters and setters to store them in a object
> + GetterSetterPair pair(p->m_node,
static_cast<PropertyNode*>(nullptr));
> + GetterSetterMap::AddResult result =
privateAccessorMap.add(p->m_node->name()->impl(), pair);
> + auto& resultPair = result.iterator->value;
> + // If the map already contains an element with node->name(),
> + // we need to store this node in the second part.
> + if (!result.isNewEntry)
> + resultPair.second = p->m_node;
> + continue;
> + }
Can we collect this information into PropertyListNode when parsing?
private getter / setter is not so frequently seen. We should not iterate every
time.
Like,
if (hasPrivateGettersOrSetters()) {
GetterSetterMap privateAccessorMap;
for (; p; p = p->m_next) {
...
}
...
for (auto& it : privateAccessorMap) {
...
}
}
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:603
> + // Then we declare private accessos
accessos => accessors.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:609
> + dst = pair.first->isInstanceClassProperty() ? prototype :
dstOrConstructor;
Let's use block local variable instead of dst.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:628
> + generator.emitDirectPutById(getterSetterObj.get(),
setterOrGetterIdent, value.get());
> + }
>
> + if (pair.second) {
> + dst = pair.second->isInstanceClassProperty() ? prototype :
dstOrConstructor;
> + RefPtr<RegisterID> value =
generator.emitNode(pair.second->m_assign);
> + if (pair.second->needsSuperBinding())
> + emitPutHomeObject(generator, value.get(), dst);
> + auto setterOrGetterIdent = pair.second->m_type &
PropertyNode::PrivateGetter
> + ? generator.propertyNames().builtinNames().getPrivateName()
> + : generator.propertyNames().builtinNames().setPrivateName();
> + generator.emitDirectPutById(getterSetterObj.get(),
setterOrGetterIdent, value.get());
> + }
They are largely duplicate. Please add lambda to dedupe code.
if (pair.first)
xxxxx(pair.first);
if (pair.second)
xxxxx(pair.second);
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:983
> RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Use RefPtr<RegisterID>.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:993
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Use `RefPtr<RegisterID> privateBrandSymbol`.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1008
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1010
> + generator.emitThrowTypeError("Trying to access a not defined
private getter");
"Trying to access an undefined private getter"
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1048
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:1068
> generator.emitThrowTypeError("Trying to access a not defined
private setter");
"Trying to access an undefined private setter"
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2413
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Ditto. Please check the same things too.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2424
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2435
> + generator.emitThrowTypeError("Trying to access a not defined
private getter");
"Trying to access an undefined private getter"
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2453
> + generator.emitThrowTypeError("Trying to access a not defined private
getter");
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2702
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2706
> + generator.emitThrowTypeError("Trying to access a not defined
private setter");
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2713
> + RegisterID* privateBrandSymbol =
generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2723
> + generator.emitThrowTypeError("Trying to access a not defined
private getter");
Ditto.
> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2741
> + generator.emitThrowTypeError("Trying to access a not defined private
getter");
Ditto.
> Source/JavaScriptCore/parser/VariableEnvironment.cpp:129
> + if (currentEntry.isSetter() || currentEntry.isMethod() ||
!currentEntry.isGetter())
Is `currentEntry.isSetter() || currentEntry.isMethod()` necessary?
> Source/JavaScriptCore/parser/VariableEnvironment.cpp:173
> +bool VariableEnvironment::declarePrivateGetter(const
RefPtr<UniquedStringImpl>& identifier)
> +{
> + if (!m_rareData)
> + m_rareData = WTF::makeUnique<VariableEnvironment::RareData>();
> +
> + auto findResult = m_rareData->m_privateNames.find(identifier);
> +
> + if (findResult == m_rareData->m_privateNames.end()) {
> + PrivateNameEntry meta(PrivateNameEntry::Traits::IsDeclared |
PrivateNameEntry::Traits::IsGetter);
> +
> + auto entry = VariableEnvironmentEntry();
> + entry.setIsPrivateGetter();
> + entry.setIsConst();
> + entry.setIsCaptured();
> + m_map.add(identifier, entry);
> +
> + auto addResult = m_rareData->m_privateNames.add(identifier, meta);
> + return addResult.isNewEntry;
> + }
Looks like declarePrivateGetter is largely duplicate to declarePrivateSetter.
Could you dedupe the code?
> Source/JavaScriptCore/parser/VariableEnvironment.cpp:177
> + if (currentEntry.isGetter() || currentEntry.isMethod() ||
!currentEntry.isSetter())
Is `currentEntry.isGetter() || currentEntry.isMethod()` necessary?
More information about the webkit-reviews
mailing list