Changeset 272580 in webkit


Ignore:
Timestamp:
Feb 9, 2021 8:30:24 AM (18 months ago)
Author:
Caio Lima
Message:

[ESNext] Implement private methods
https://bugs.webkit.org/show_bug.cgi?id=194434

Reviewed by Filip Pizlo.

JSTests:

  • stress/private-brand-installed-after-super-call-from-arrow-function.js: Added.
  • stress/private-brand-installed-after-super-call-from-eval.js: Added.
  • stress/private-method-brand-check.js: Added.
  • stress/private-method-change-attribute-from-branded-structure.js: Added.
  • stress/private-method-change-prototype-from-branded-structure.js: Added.
  • stress/private-method-check-private-brand-ic.js: Added.
  • stress/private-method-check-structure-miss.js: Added.
  • stress/private-method-comparison.js: Added.
  • stress/private-method-delete-property-from-branded-structure.js: Added.
  • stress/private-method-extends-brand-check.js: Added.
  • stress/private-method-get-and-call.js: Added.
  • stress/private-method-invalid-multiple-brand-installation.js: Added.
  • stress/private-method-invalidate-compiled-with-constant-symbol.js: Added.
  • stress/private-method-nested-class.js: Added.
  • stress/private-method-on-sealed-objects.js: Added.
  • stress/private-method-on-uncacheable-dictionary.js: Added.
  • stress/private-method-polymorphic-with-constant-symbol.js: Added.
  • stress/private-method-set-brand-should-have-write-barrier.js: Added.
  • stress/private-method-untyped-use.js: Added.
  • stress/private-method-with-uncacheable-dictionary-transition.js: Added.
  • stress/private-methods-inline-cache.js: Added.
  • stress/private-methods-megamorphic-ic.js: Added.
  • stress/private-methods-on-proxy.js: Added.
  • stress/private-methods-poly-ic-multiple-classes.js: Added.
  • stress/private-methods-poly-ic-single-class.js: Added.
  • stress/private-names-available-on-direct-eval.js: Added.
  • test262/config.yaml:

Source/JavaScriptCore:

This patch is adding support to private methods following the
specification on https://tc39.es/proposal-private-methods/.
This is introducing a new way to declare private methods on
class syntax. Private methods are only accessible within
classes they were declared, and only can be called from
objects that are instance of these classes.
To guarantee such rules, the proposal presents the concept of
Brand Check. During class evaluation, if a private method is present,
a brand is installed in this class. Every instance of such class
then gets this brand installed during [[Construct]] operation. It
means that an object can have multiple brands (e.g when there is also
private methods declared on super class). Before accessing a private
method, there is a check to validate if the target of the call has the
brand of callee method.
The brand check mechanism is implemented using a @privateBrand
stored on class scope. Here is a representation of how this mechanism
works:

`
class C {

#m() { return 3; }
method() { return this.#m(); }

}

let c = new C();
console.log(c.method()); prints 3
`

Generated bytecode for the following representation:
`
{ class lexical scope

const @privateBrand = @createPrivateSymbol();
const #m = function () { return 3; }
C.prototype.method = function() {

@check_private_brand(this, @privateBrand);
return #m.call(this);

}
C = function() {

@set_private_brand(this, @privateBrand);

}

}

let c = new C();
console.log(c.method()); prints 3
`

# Resolving correct brand to check

In the case of shadowing or nested scope, we need to emit brand
checks to the right private brand. See code below:

`
class C {

#m() { return 3; }
method() { return this.#m();}

A = class {

#m2() { return 3; }
foo(o) { return o.#m(); }

}

}
`

The call of "#m" in foo refers to "C::#m". In such case, we need to
check C's private brand, instead of A's private brand.
To perform the proper check, we first resolve scope of "#m" and then
check the private brand of this scope (the scope where the private
method and brand are stored is the same).
So the bytecode to lookup the right brand is:

`
mov loc9, arg1
resolve_scope loc10, "#m"
get_from_scope loc11, loc10, "@privateBrand"
check_private_brand loc9, loc11
get_from_scope loc11, loc10, "#m"
setup call frame
call loc11, ...
...
`

# Brand check mechanism

We are introducing in this patch 2 new bytecodes to allow brand check
of objects: op_set_brand and op_check_brand.
op_set_brand sets a new brand in an object, so we can perform the brand
check later when accessing private methods. This operations throws when
trying to add the same brand twice in an Object.
op_check_brand checks if the given object contains the brand we are
looking for. It traverses the brand chain to verify if the brand is
present, and throws TypeError otherwise.

We are also introducing a subclass for Structure called BrandedStructure.
It is used to store brands and to allow brand check mechanism. BrandedStructure
stores a brand and a parent pointer to another BrandedStructure that allow
us traverse the brand chain. With BrandedStructure, we can then
infer that a given object has the brand we are looking for just
checking its structureId. This is a very good optimization, since we can
reduce most of brand checks to structure checks.

We created a new kind of transition called SetBrand that happens when
op_set_brand is executed. This allow us to cache such kind of
trasitions on trasition table using the key `<brand->uid, 0,
TransitionKind::SetBrand>`. During this transition, we take previous
structure and apply one of the following rules:

  1. If it's a BrandedStructure, we then set it to m_parentBrand, to allow proper brand chain check.
  1. If it's not a BrandedStructure, we set m_parentBrand to nullptr, meaning that this is the first brand being added to the object with this structure.

For now, we are using the flag isBrandedStructure to identify that a
given Structure is a BrandedStructure. This is done to avoid changes
on places where we are checking for vm.structureStructure().
However, if we ever need space on Structure, this flag is a good
candidate to be deleted and we can move to a solution that uses
vm.brandedStructureStructure();

# JIT Support

This patch also includes initial JIT support for set_private_brand
and check_private_brand. On Baseline JIT, we are using
JITPravateBrandAccessGenerator to support IC for both operands.
On DFGByteCodeParser we are trying to inline brand access whenever
possible, and fallbacking to SetPrivateBrand and
CheckPrivateBrand otherwise. Those nodes are not being optimized at
their full potential, but the code generated by them is also relying on
JITPrivateBrandAccessGenerator to have IC support for both DFG and
FTL. During DFG parsing, we try to reduce those access to CheckIsConstant
and CheckStructure (with PutStructure for set_private_brand cases)
based on available profiled data. This is meant to make brand checks
almost free on DFG/FTL tiers when we have a single evaluation of a
class, since the CheckIsConstant can be eliminated by the constant-folded
scope load, and the CheckStructure is very likely to be redundant
to any other CheckStructure that can be performed on receiver
when we have a finite structure set.
For instance, when we have a brand check on a path-of-no-return to
a GetByOffset sequence on the same receiver, the CheckStructure
for the brand check will enable CSE of the CheckStructure that
would happen for that GetByOffset. Such design is possible because brand
checks supports polymorphic access very similr to what we have for
GetByOffset sequences.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • builtins/BuiltinExecutables.cpp:

(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutable):

  • builtins/BuiltinExecutables.h:

We are adding a new parameter PrivateBrandRequirement to propagate
when a default constructor needs to emit code to setup private brand
on instances.

  • builtins/BuiltinNames.h:

Adding @privateBrand that we use to store private brand on
class's scope.

  • bytecode/AccessCase.cpp:

(JSC::AccessCase::createCheckPrivateBrand):
(JSC::AccessCase::createSetPrivateBrand):
(JSC::AccessCase::requiresIdentifierNameMatch const):
(JSC::AccessCase::requiresInt32PropertyCheck const):
(JSC::AccessCase::needsScratchFPR const):
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):

  • bytecode/AccessCase.h:

(JSC::AccessCase::structure const):
(JSC::AccessCase::newStructure const):

  • bytecode/BytecodeList.rb:
  • bytecode/BytecodeUseDef.cpp:

(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):

  • bytecode/CheckPrivateBrandStatus.cpp: Added.

(JSC::CheckPrivateBrandStatus::appendVariant):
(JSC::CheckPrivateBrandStatus::computeForBaseline):
(JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
(JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::CheckPrivateBrandStatus::computeFor):
(JSC::CheckPrivateBrandStatus::slowVersion const):
(JSC::CheckPrivateBrandStatus::merge):
(JSC::CheckPrivateBrandStatus::filter):
(JSC::CheckPrivateBrandStatus::singleIdentifier const):
(JSC::CheckPrivateBrandStatus::visitAggregate):
(JSC::CheckPrivateBrandStatus::markIfCheap):
(JSC::CheckPrivateBrandStatus::finalize):
(JSC::CheckPrivateBrandStatus::dump const):

  • bytecode/CheckPrivateBrandStatus.h: Added.
  • bytecode/CheckPrivateBrandVariant.cpp: Added.

(JSC::CheckPrivateBrandVariant::CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::~CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::attemptToMerge):
(JSC::CheckPrivateBrandVariant::markIfCheap):
(JSC::CheckPrivateBrandVariant::finalize):
(JSC::CheckPrivateBrandVariant::visitAggregate):
(JSC::CheckPrivateBrandVariant::dump const):
(JSC::CheckPrivateBrandVariant::dumpInContext const):

  • bytecode/CheckPrivateBrandVariant.h: Added.

(JSC::CheckPrivateBrandVariant::structureSet const):
(JSC::CheckPrivateBrandVariant::structureSet):
(JSC::CheckPrivateBrandVariant::identifier const):
(JSC::CheckPrivateBrandVariant::overlaps):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):

  • bytecode/ExecutableInfo.h:

(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::privateBrandRequirement const):

  • bytecode/PolymorphicAccess.cpp:

(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):

  • bytecode/RecordedStatuses.cpp:

(JSC::RecordedStatuses::operator=):
(JSC::RecordedStatuses::addCheckPrivateBrandStatus):
(JSC::RecordedStatuses::addSetPrivateBrandStatus):
(JSC::RecordedStatuses::visitAggregate):
(JSC::RecordedStatuses::markIfCheap):

  • bytecode/RecordedStatuses.h:

(JSC::RecordedStatuses::forEachVector):

  • bytecode/SetPrivateBrandStatus.cpp: Added.

(JSC::SetPrivateBrandStatus::appendVariant):
(JSC::SetPrivateBrandStatus::computeForBaseline):
(JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
(JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::SetPrivateBrandStatus::computeFor):
(JSC::SetPrivateBrandStatus::slowVersion const):
(JSC::SetPrivateBrandStatus::merge):
(JSC::SetPrivateBrandStatus::filter):
(JSC::SetPrivateBrandStatus::singleIdentifier const):
(JSC::SetPrivateBrandStatus::visitAggregate):
(JSC::SetPrivateBrandStatus::markIfCheap):
(JSC::SetPrivateBrandStatus::finalize):
(JSC::SetPrivateBrandStatus::dump const):

  • bytecode/SetPrivateBrandStatus.h: Added.
  • bytecode/SetPrivateBrandVariant.cpp: Added.

(JSC::SetPrivateBrandVariant::SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::~SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::attemptToMerge):
(JSC::SetPrivateBrandVariant::markIfCheap):
(JSC::SetPrivateBrandVariant::finalize):
(JSC::SetPrivateBrandVariant::visitAggregate):
(JSC::SetPrivateBrandVariant::dump const):
(JSC::SetPrivateBrandVariant::dumpInContext const):

  • bytecode/SetPrivateBrandVariant.h: Added.

(JSC::SetPrivateBrandVariant::oldStructure const):
(JSC::SetPrivateBrandVariant::newStructure const):
(JSC::SetPrivateBrandVariant::identifier const):
(JSC::SetPrivateBrandVariant::overlaps):

  • bytecode/StructureStubInfo.cpp:

(JSC::StructureStubInfo::reset):

  • bytecode/StructureStubInfo.h:
  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::privateBrandRequirement const):

  • bytecode/UnlinkedCodeBlockGenerator.h:

(JSC::UnlinkedCodeBlockGenerator::privateBrandRequirement const):

  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • bytecode/UnlinkedFunctionExecutable.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):

We changed BytecodeGenerator for FunctionNode and EvalNode to
propagate parentScope PrivateNameEnvironment. These environments stores
private name entries that are visible into the scope of the
function/eval.
This is required to identify the kind of access a private name is
referring to, since it can be a private field or a private method.

(JSC::BytecodeGenerator::instantiateLexicalVariables):
(JSC::BytecodeGenerator::emitGetPrivateName):
(JSC::BytecodeGenerator::emitCreatePrivateBrand):

The process to create a private brand is as follows:

  1. Create a PrivateSymbol using @createPrivateSymbol.
  2. Store this symbol into a given scope (i.e class lexical scope) on @privateBrand variable.

(JSC::BytecodeGenerator::emitInstallPrivateBrand):
(JSC::BytecodeGenerator::emitGetPrivateBrand):

We added m_privateNamesStack to BytecodeGenerator to represent the
scope chain of available private names while generating bytecode.

(JSC::BytecodeGenerator::emitCheckPrivateBrand):
(JSC::BytecodeGenerator::isPrivateMethod):
(JSC::BytecodeGenerator::pushPrivateAccessNames):
(JSC::BytecodeGenerator::popPrivateAccessNames):
(JSC::BytecodeGenerator::getAvailablePrivateAccessNames):
(JSC::BytecodeGenerator::emitNewDefaultConstructor):
(JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
(JSC::BytecodeGenerator::emitDirectGetByVal): Deleted.

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::privateBrandRequirement const):
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::makeFunction):

This change is required to properly propagate PrivateBrandRequirement
to arrow functions that can potentially call super().

  • bytecompiler/NodesCodegen.cpp:

(JSC::PropertyListNode::emitDeclarePrivateFieldNames):
(JSC::PropertyListNode::emitBytecode):
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BaseDotNode::emitGetPropertyValue):

Adding support to properly access private method. Since we store
private methods on class lexical scope, we need a different set of
instructions to access a private method.

(JSC::BaseDotNode::emitPutProperty):

In the case of we trying to write in a private method, we need to
throw a TypeError according to specification
(https://tc39.es/proposal-private-methods/#sec-privatefieldset).

(JSC::FunctionCallValueNode::emitBytecode):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitDot):
(JSC::ClassExprNode::emitBytecode):

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::evaluateWithScopeExtension):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):

  • dfg/DFGArgumentsEliminationPhase.cpp:
  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGClobbersExitState.cpp:

(JSC::DFG::clobbersExitState):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGGraph.h:
  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::addPrivateBrandAccess):

  • dfg/DFGMayExit.cpp:
  • dfg/DFGNode.h:

(JSC::DFG::Node::hasCheckPrivateBrandStatus):
(JSC::DFG::Node::checkPrivateBrandStatus):
(JSC::DFG::Node::hasSetPrivateBrandStatus):
(JSC::DFG::Node::setPrivateBrandStatus):

  • dfg/DFGNodeType.h:
  • dfg/DFGObjectAllocationSinkingPhase.cpp:
  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand):
(JSC::DFG::SpeculativeJIT::compileSetPrivateBrand):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStoreBarrierInsertionPhase.cpp:
  • dfg/DFGVarargsForwardingPhase.cpp:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckPrivateBrand):
(JSC::FTL::DFG::LowerDFGToB3::compileSetPrivateBrand):

  • interpreter/Interpreter.cpp:

(JSC::eval):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):

  • jit/JIT.h:
  • jit/JITInlineCacheGenerator.cpp:

(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::generateFastPath):
(JSC::JITPrivateBrandAccessGenerator::finalize):

  • jit/JITInlineCacheGenerator.h:

(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::slowPathJump const):

  • jit/JITOperations.cpp:

(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::getPrivateName):

  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):

  • jit/Repatch.cpp:

(JSC::tryCacheCheckPrivateBrand):
(JSC::repatchCheckPrivateBrand):
(JSC::tryCacheSetPrivateBrand):
(JSC::repatchSetPrivateBrand):
(JSC::resetCheckPrivateBrand):
(JSC::resetSetPrivateBrand):

  • jit/Repatch.h:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • parser/Nodes.cpp:

(JSC::FunctionMetadataNode::FunctionMetadataNode):

  • parser/Nodes.h:

(JSC::BaseDotNode::isPrivateMember const):
(JSC::BaseDotNode::isPrivateField const): Deleted.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseMemberExpression):

  • parser/Parser.h:

(JSC::Scope::declarePrivateMethod):
(JSC::Scope::declarePrivateField):
(JSC::Parser<LexerType>::parse):
(JSC::parse):
(JSC::Scope::declarePrivateName): Deleted.

  • parser/ParserModes.h:
  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createDotAccess):

  • parser/VariableEnvironment.cpp:

(JSC::VariableEnvironment::declarePrivateMethod):

  • parser/VariableEnvironment.h:

(JSC::VariableEnvironmentEntry::isPrivateField const):
(JSC::VariableEnvironmentEntry::isPrivateMethod const):
(JSC::VariableEnvironmentEntry::setIsPrivateField):
(JSC::VariableEnvironmentEntry::setIsPrivateMethod):
(JSC::PrivateNameEntry::isMethod const):
(JSC::PrivateNameEntry::isPrivateMethodOrAcessor const):
(JSC::VariableEnvironment::addPrivateName):
(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::declarePrivateMethod):
(JSC::VariableEnvironment::privateNameEnvironment const):
(JSC::VariableEnvironment::hasPrivateMethodOrAccessor const):
(JSC::VariableEnvironment::addPrivateNamesFrom):
(JSC::VariableEnvironmentEntry::isPrivateName const): Deleted.
(JSC::VariableEnvironmentEntry::setIsPrivateName): Deleted.
(JSC::VariableEnvironment::declarePrivateName): Deleted.

  • runtime/CachedTypes.cpp:

(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):
(JSC::CachedFunctionExecutableRareData::encode):
(JSC::CachedFunctionExecutableRareData::decode const):
(JSC::CachedFunctionExecutable::privateBrandRequirement const):
(JSC::CachedCodeBlock::derivedContextType const):
(JSC::CachedFunctionExecutable::encode):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::CachedCodeBlock::needsClassFieldInitializer const): Deleted.

  • runtime/CodeCache.cpp:

(JSC::generateUnlinkedCodeBlockImpl):
(JSC::generateUnlinkedCodeBlock):
(JSC::generateUnlinkedCodeBlockForDirectEval):
(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):

  • runtime/CodeCache.h:
  • runtime/DirectEvalExecutable.cpp:

(JSC::DirectEvalExecutable::create):
(JSC::DirectEvalExecutable::DirectEvalExecutable):

  • runtime/DirectEvalExecutable.h:
  • runtime/EvalExecutable.cpp:

(JSC::EvalExecutable::EvalExecutable):

  • runtime/EvalExecutable.h:

(JSC::EvalExecutable::executableInfo const):
(JSC::EvalExecutable::privateBrandRequirement const):

  • runtime/ExceptionHelpers.cpp:

(JSC::createInvalidPrivateNameError):

  • runtime/IndirectEvalExecutable.cpp:

(JSC::IndirectEvalExecutable::IndirectEvalExecutable):

  • runtime/JSObject.h:
  • runtime/JSObjectInlines.h:

(JSC::JSObject::checkPrivateBrand):
(JSC::JSObject::setPrivateBrand):

  • runtime/JSScope.cpp:

(JSC::JSScope::collectClosureVariablesUnderTDZ):

  • runtime/JSScope.h:
  • runtime/ModuleProgramExecutable.h:
  • runtime/Options.cpp:

(JSC::Options::recomputeDependentOptions):

  • runtime/OptionsList.h:
  • runtime/ProgramExecutable.h:
  • runtime/Structure.cpp:

(JSC::Structure::materializePropertyTable):
(JSC::BrandedStructure::BrandedStructure):
(JSC::BrandedStructure::create):
(JSC::BrandedStructure::checkBrand):
(JSC::Structure::setBrandTransitionFromExistingStructureImpl):
(JSC::Structure::setBrandTransitionFromExistingStructureConcurrently):
(JSC::Structure::setBrandTransition):

  • runtime/Structure.h:

(JSC::Structure::finishCreation):

  • runtime/StructureInlines.h:

(JSC::Structure::create):
(JSC::Structure::forEachPropertyConcurrently):

  • runtime/StructureTransitionTable.h:
  • runtime/SymbolTable.cpp:

(JSC::SymbolTable::cloneScopePart):

  • runtime/SymbolTable.h:
  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:
Location:
trunk
Files:
34 added
102 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r272466 r272580  
     12021-02-09  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [ESNext] Implement private methods
     4        https://bugs.webkit.org/show_bug.cgi?id=194434
     5
     6        Reviewed by Filip Pizlo.
     7
     8        * stress/private-brand-installed-after-super-call-from-arrow-function.js: Added.
     9        * stress/private-brand-installed-after-super-call-from-eval.js: Added.
     10        * stress/private-method-brand-check.js: Added.
     11        * stress/private-method-change-attribute-from-branded-structure.js: Added.
     12        * stress/private-method-change-prototype-from-branded-structure.js: Added.
     13        * stress/private-method-check-private-brand-ic.js: Added.
     14        * stress/private-method-check-structure-miss.js: Added.
     15        * stress/private-method-comparison.js: Added.
     16        * stress/private-method-delete-property-from-branded-structure.js: Added.
     17        * stress/private-method-extends-brand-check.js: Added.
     18        * stress/private-method-get-and-call.js: Added.
     19        * stress/private-method-invalid-multiple-brand-installation.js: Added.
     20        * stress/private-method-invalidate-compiled-with-constant-symbol.js: Added.
     21        * stress/private-method-nested-class.js: Added.
     22        * stress/private-method-on-sealed-objects.js: Added.
     23        * stress/private-method-on-uncacheable-dictionary.js: Added.
     24        * stress/private-method-polymorphic-with-constant-symbol.js: Added.
     25        * stress/private-method-set-brand-should-have-write-barrier.js: Added.
     26        * stress/private-method-untyped-use.js: Added.
     27        * stress/private-method-with-uncacheable-dictionary-transition.js: Added.
     28        * stress/private-methods-inline-cache.js: Added.
     29        * stress/private-methods-megamorphic-ic.js: Added.
     30        * stress/private-methods-on-proxy.js: Added.
     31        * stress/private-methods-poly-ic-multiple-classes.js: Added.
     32        * stress/private-methods-poly-ic-single-class.js: Added.
     33        * stress/private-names-available-on-direct-eval.js: Added.
     34        * test262/config.yaml:
     35
    1362021-02-06  Alexey Shvayka  <shvaikalesh@gmail.com>
    237
  • trunk/JSTests/test262/config.yaml

    r272431 r272580  
    55  FinalizationRegistry: useWeakRefs
    66  class-fields-private: usePrivateClassFields
     7  class-methods-private: usePrivateMethods
    78  class-static-fields-public: usePublicStaticClassFields
    89  class-static-fields-private: usePrivateStaticClassFields
     
    2021    - legacy-regexp
    2122
    22     - class-methods-private
    2323    - class-static-methods-private
    2424    - cleanupSome
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r272170 r272580  
    539539    bytecode/CallMode.h
    540540    bytecode/CallVariant.h
     541    bytecode/CheckPrivateBrandStatus.h
     542    bytecode/CheckPrivateBrandVariant.h
    541543    bytecode/CodeBlock.h
    542544    bytecode/CodeBlockHash.h
     
    574576    bytecode/PropertyCondition.h
    575577    bytecode/PutByIdFlags.h
     578    bytecode/SetPrivateBrandStatus.h
     579    bytecode/SetPrivateBrandVariant.h
    576580    bytecode/SpeculatedType.h
    577581    bytecode/StructureSet.h
     
    829833    runtime/BooleanObject.h
    830834    runtime/BooleanPrototype.h
     835    runtime/BrandedStructure.h
    831836    runtime/Butterfly.h
    832837    runtime/ButterflyInlines.h
  • trunk/Source/JavaScriptCore/ChangeLog

    r272570 r272580  
     12021-02-09  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [ESNext] Implement private methods
     4        https://bugs.webkit.org/show_bug.cgi?id=194434
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch is adding support to private methods following the
     9        specification on https://tc39.es/proposal-private-methods/.
     10        This is introducing a new way to declare private methods on
     11        class syntax. Private methods are only accessible within
     12        classes they were declared, and only can be called from
     13        objects that are instance of these classes.
     14        To guarantee such rules, the proposal presents the concept of
     15        Brand Check. During class evaluation, if a private method is present,
     16        a `brand` is installed in this class. Every instance of such class
     17        then gets this brand installed during `[[Construct]]` operation. It
     18        means that an object can have multiple brands (e.g when there is also
     19        private methods declared on super class). Before accessing a private
     20        method, there is a check to validate if the target of the call has the
     21        brand of callee method.
     22        The brand check mechanism is implemented using a `@privateBrand`
     23        stored on class scope. Here is a representation of how this mechanism
     24        works:
     25
     26        ```
     27        class C {
     28            #m() { return 3; }
     29            method() { return this.#m(); }
     30        }
     31
     32        let c = new C();
     33        console.log(c.method()); // prints 3
     34        ```
     35
     36        Generated bytecode for the following representation:
     37        ```
     38        { // class lexical scope
     39            const @privateBrand = @createPrivateSymbol();
     40            const #m = function () { return 3; }
     41            C.prototype.method = function() {
     42                @check_private_brand(this, @privateBrand);
     43                return #m.call(this);
     44            }
     45            C = function() {
     46                @set_private_brand(this, @privateBrand);
     47            }
     48        }
     49
     50        let c = new C();
     51        console.log(c.method()); // prints 3
     52        ```
     53
     54        # Resolving correct brand to check
     55
     56        In the case of shadowing or nested scope, we need to emit brand
     57        checks to the right private brand. See code below:
     58
     59        ```
     60        class C {
     61            #m() { return 3; }
     62            method() { return this.#m();}
     63
     64            A = class {
     65                #m2() { return 3; }
     66                foo(o) { return o.#m(); }
     67            }
     68        }
     69        ```
     70
     71        The call of "#m" in `foo` refers to "C::#m". In such case, we need to
     72        check C's private brand, instead of A's private brand.
     73        To perform the proper check, we first resolve scope of "#m" and then
     74        check the private brand of this scope (the scope where the private
     75        method and brand are stored is the same).
     76        So the bytecode to lookup the right brand is:
     77
     78        ```
     79        mov loc9, arg1
     80        resolve_scope loc10, "#m"
     81        get_from_scope loc11, loc10, "@privateBrand"
     82        check_private_brand loc9, loc11
     83        get_from_scope loc11, loc10, "#m"
     84        // setup call frame
     85        call loc11, ...
     86        // ...
     87        ```
     88
     89        # Brand check mechanism
     90
     91        We are introducing in this patch 2 new bytecodes to allow brand check
     92        of objects: `op_set_brand` and `op_check_brand`.
     93        `op_set_brand` sets a new brand in an object, so we can perform the brand
     94        check later when accessing private methods. This operations throws when
     95        trying to add the same brand twice in an Object.
     96        `op_check_brand` checks if the given object contains the brand we are
     97        looking for. It traverses the brand chain to verify if the brand is
     98        present, and throws `TypeError` otherwise.
     99
     100        We are also introducing a subclass for Structure called BrandedStructure.
     101        It is used to store brands and to allow brand check mechanism. BrandedStructure
     102        stores a brand and a parent pointer to another BrandedStructure that allow
     103        us traverse the brand chain. With `BrandedStructure`, we can then
     104        infer that a given object has the brand we are looking for just
     105        checking its structureId. This is a very good optimization, since we can
     106        reduce most of brand checks to structure checks.
     107
     108        We created a new kind of transition called `SetBrand` that happens when
     109        `op_set_brand` is executed. This allow us to cache such kind of
     110        trasitions on trasition table using the key `<brand->uid, 0,
     111        TransitionKind::SetBrand>`. During this transition, we take previous
     112        structure and apply one of the following rules:
     113
     114            1. If it's a BrandedStructure, we then set it to `m_parentBrand`,
     115            to allow proper brand chain check.
     116       
     117            2. If it's not a BrandedStructure, we set `m_parentBrand` to `nullptr`,
     118            meaning that this is the first brand being added to the object
     119            with this structure.
     120       
     121        For now, we are using the flag `isBrandedStructure` to identify that a
     122        given Structure is a BrandedStructure. This is done to avoid changes
     123        on places where we are checking for `vm.structureStructure()`.
     124        However, if we ever need space on Structure, this flag is a good
     125        candidate to be deleted and we can move to a solution that uses
     126        `vm.brandedStructureStructure()`;
     127
     128         # JIT Support
     129
     130        This patch also includes initial JIT support for `set_private_brand`
     131        and `check_private_brand`. On Baseline JIT, we are using
     132        `JITPravateBrandAccessGenerator` to support IC for both operands.
     133        On `DFGByteCodeParser` we are trying to inline brand access whenever
     134        possible, and fallbacking to `SetPrivateBrand` and
     135        `CheckPrivateBrand` otherwise. Those nodes are not being optimized at
     136        their full potential, but the code generated by them is also relying on
     137        `JITPrivateBrandAccessGenerator` to have IC support for both DFG and
     138        FTL. During DFG parsing, we try to reduce those access  to `CheckIsConstant`
     139        and `CheckStructure` (with `PutStructure` for `set_private_brand` cases)
     140        based on available profiled data. This is meant to make brand checks
     141        almost free on DFG/FTL tiers when we have a single evaluation of a
     142        class, since the `CheckIsConstant` can be eliminated by the constant-folded
     143        scope load, and the `CheckStructure` is very likely to be redundant
     144        to any other `CheckStructure` that can be performed on receiver
     145        when we have a finite structure set.
     146        For instance, when we have a brand check on a path-of-no-return to
     147        a `GetByOffset` sequence on the same receiver, the `CheckStructure`
     148        for the brand check will enable CSE of the `CheckStructure` that
     149        would happen for that `GetByOffset`. Such design is possible because brand
     150        checks supports polymorphic access very similr to what we have for
     151        `GetByOffset` sequences.
     152
     153        * CMakeLists.txt:
     154        * JavaScriptCore.xcodeproj/project.pbxproj:
     155        * Sources.txt:
     156        * builtins/BuiltinExecutables.cpp:
     157        (JSC::BuiltinExecutables::createDefaultConstructor):
     158        (JSC::BuiltinExecutables::createExecutable):
     159        * builtins/BuiltinExecutables.h:
     160
     161        We are adding a new parameter `PrivateBrandRequirement` to propagate
     162        when a default constructor needs to emit code to setup private brand
     163        on instances.
     164
     165        * builtins/BuiltinNames.h:
     166
     167        Adding `@privateBrand` that  we use to store private brand on
     168        class's scope.
     169
     170        * bytecode/AccessCase.cpp:
     171        (JSC::AccessCase::createCheckPrivateBrand):
     172        (JSC::AccessCase::createSetPrivateBrand):
     173        (JSC::AccessCase::requiresIdentifierNameMatch const):
     174        (JSC::AccessCase::requiresInt32PropertyCheck const):
     175        (JSC::AccessCase::needsScratchFPR const):
     176        (JSC::AccessCase::forEachDependentCell const):
     177        (JSC::AccessCase::doesCalls const):
     178        (JSC::AccessCase::canReplace const):
     179        (JSC::AccessCase::dump const):
     180        (JSC::AccessCase::generateWithGuard):
     181        (JSC::AccessCase::generateImpl):
     182        * bytecode/AccessCase.h:
     183        (JSC::AccessCase::structure const):
     184        (JSC::AccessCase::newStructure const):
     185        * bytecode/BytecodeList.rb:
     186        * bytecode/BytecodeUseDef.cpp:
     187        (JSC::computeUsesForBytecodeIndexImpl):
     188        (JSC::computeDefsForBytecodeIndexImpl):
     189        * bytecode/CheckPrivateBrandStatus.cpp: Added.
     190        (JSC::CheckPrivateBrandStatus::appendVariant):
     191        (JSC::CheckPrivateBrandStatus::computeForBaseline):
     192        (JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
     193        (JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
     194        (JSC::CheckPrivateBrandStatus::computeFor):
     195        (JSC::CheckPrivateBrandStatus::slowVersion const):
     196        (JSC::CheckPrivateBrandStatus::merge):
     197        (JSC::CheckPrivateBrandStatus::filter):
     198        (JSC::CheckPrivateBrandStatus::singleIdentifier const):
     199        (JSC::CheckPrivateBrandStatus::visitAggregate):
     200        (JSC::CheckPrivateBrandStatus::markIfCheap):
     201        (JSC::CheckPrivateBrandStatus::finalize):
     202        (JSC::CheckPrivateBrandStatus::dump const):
     203        * bytecode/CheckPrivateBrandStatus.h: Added.
     204        * bytecode/CheckPrivateBrandVariant.cpp: Added.
     205        (JSC::CheckPrivateBrandVariant::CheckPrivateBrandVariant):
     206        (JSC::CheckPrivateBrandVariant::~CheckPrivateBrandVariant):
     207        (JSC::CheckPrivateBrandVariant::attemptToMerge):
     208        (JSC::CheckPrivateBrandVariant::markIfCheap):
     209        (JSC::CheckPrivateBrandVariant::finalize):
     210        (JSC::CheckPrivateBrandVariant::visitAggregate):
     211        (JSC::CheckPrivateBrandVariant::dump const):
     212        (JSC::CheckPrivateBrandVariant::dumpInContext const):
     213        * bytecode/CheckPrivateBrandVariant.h: Added.
     214        (JSC::CheckPrivateBrandVariant::structureSet const):
     215        (JSC::CheckPrivateBrandVariant::structureSet):
     216        (JSC::CheckPrivateBrandVariant::identifier const):
     217        (JSC::CheckPrivateBrandVariant::overlaps):
     218        * bytecode/CodeBlock.cpp:
     219        (JSC::CodeBlock::finishCreation):
     220        (JSC::CodeBlock::finalizeLLIntInlineCaches):
     221        * bytecode/ExecutableInfo.h:
     222        (JSC::ExecutableInfo::ExecutableInfo):
     223        (JSC::ExecutableInfo::privateBrandRequirement const):
     224        * bytecode/PolymorphicAccess.cpp:
     225        (JSC::PolymorphicAccess::regenerate):
     226        (WTF::printInternal):
     227        * bytecode/RecordedStatuses.cpp:
     228        (JSC::RecordedStatuses::operator=):
     229        (JSC::RecordedStatuses::addCheckPrivateBrandStatus):
     230        (JSC::RecordedStatuses::addSetPrivateBrandStatus):
     231        (JSC::RecordedStatuses::visitAggregate):
     232        (JSC::RecordedStatuses::markIfCheap):
     233        * bytecode/RecordedStatuses.h:
     234        (JSC::RecordedStatuses::forEachVector):
     235        * bytecode/SetPrivateBrandStatus.cpp: Added.
     236        (JSC::SetPrivateBrandStatus::appendVariant):
     237        (JSC::SetPrivateBrandStatus::computeForBaseline):
     238        (JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
     239        (JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
     240        (JSC::SetPrivateBrandStatus::computeFor):
     241        (JSC::SetPrivateBrandStatus::slowVersion const):
     242        (JSC::SetPrivateBrandStatus::merge):
     243        (JSC::SetPrivateBrandStatus::filter):
     244        (JSC::SetPrivateBrandStatus::singleIdentifier const):
     245        (JSC::SetPrivateBrandStatus::visitAggregate):
     246        (JSC::SetPrivateBrandStatus::markIfCheap):
     247        (JSC::SetPrivateBrandStatus::finalize):
     248        (JSC::SetPrivateBrandStatus::dump const):
     249        * bytecode/SetPrivateBrandStatus.h: Added.
     250        * bytecode/SetPrivateBrandVariant.cpp: Added.
     251        (JSC::SetPrivateBrandVariant::SetPrivateBrandVariant):
     252        (JSC::SetPrivateBrandVariant::~SetPrivateBrandVariant):
     253        (JSC::SetPrivateBrandVariant::attemptToMerge):
     254        (JSC::SetPrivateBrandVariant::markIfCheap):
     255        (JSC::SetPrivateBrandVariant::finalize):
     256        (JSC::SetPrivateBrandVariant::visitAggregate):
     257        (JSC::SetPrivateBrandVariant::dump const):
     258        (JSC::SetPrivateBrandVariant::dumpInContext const):
     259        * bytecode/SetPrivateBrandVariant.h: Added.
     260        (JSC::SetPrivateBrandVariant::oldStructure const):
     261        (JSC::SetPrivateBrandVariant::newStructure const):
     262        (JSC::SetPrivateBrandVariant::identifier const):
     263        (JSC::SetPrivateBrandVariant::overlaps):
     264        * bytecode/StructureStubInfo.cpp:
     265        (JSC::StructureStubInfo::reset):
     266        * bytecode/StructureStubInfo.h:
     267        * bytecode/UnlinkedCodeBlock.cpp:
     268        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
     269        * bytecode/UnlinkedCodeBlock.h:
     270        (JSC::UnlinkedCodeBlock::privateBrandRequirement const):
     271        * bytecode/UnlinkedCodeBlockGenerator.h:
     272        (JSC::UnlinkedCodeBlockGenerator::privateBrandRequirement const):
     273        * bytecode/UnlinkedFunctionExecutable.cpp:
     274        (JSC::generateUnlinkedFunctionCodeBlock):
     275        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     276        * bytecode/UnlinkedFunctionExecutable.h:
     277        * bytecompiler/BytecodeGenerator.cpp:
     278        (JSC::BytecodeGenerator::BytecodeGenerator):
     279
     280        We changed BytecodeGenerator for FunctionNode and EvalNode to
     281        propagate parentScope PrivateNameEnvironment. These environments stores
     282        private name entries that are visible into the scope of the
     283        function/eval.
     284        This is required to identify the kind of access a private name is
     285        referring to, since it can be a private field or a private method.
     286
     287        (JSC::BytecodeGenerator::instantiateLexicalVariables):
     288        (JSC::BytecodeGenerator::emitGetPrivateName):
     289        (JSC::BytecodeGenerator::emitCreatePrivateBrand):
     290
     291        The process to create a private brand is as follows:
     292            1. Create a PrivateSymbol using `@createPrivateSymbol`.
     293            2. Store this symbol into a given scope (i.e class lexical scope)
     294               on `@privateBrand` variable.
     295
     296        (JSC::BytecodeGenerator::emitInstallPrivateBrand):
     297        (JSC::BytecodeGenerator::emitGetPrivateBrand):
     298
     299        We added `m_privateNamesStack` to BytecodeGenerator to represent the
     300        scope chain of available private names while generating bytecode.
     301
     302        (JSC::BytecodeGenerator::emitCheckPrivateBrand):
     303        (JSC::BytecodeGenerator::isPrivateMethod):
     304        (JSC::BytecodeGenerator::pushPrivateAccessNames):
     305        (JSC::BytecodeGenerator::popPrivateAccessNames):
     306        (JSC::BytecodeGenerator::getAvailablePrivateAccessNames):
     307        (JSC::BytecodeGenerator::emitNewDefaultConstructor):
     308        (JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
     309        (JSC::BytecodeGenerator::emitDirectGetByVal): Deleted.
     310        * bytecompiler/BytecodeGenerator.h:
     311        (JSC::BytecodeGenerator::privateBrandRequirement const):
     312        (JSC::BytecodeGenerator::generate):
     313        (JSC::BytecodeGenerator::makeFunction):
     314
     315        This change is required to properly propagate PrivateBrandRequirement
     316        to arrow functions that can potentially call `super()`.
     317
     318        * bytecompiler/NodesCodegen.cpp:
     319        (JSC::PropertyListNode::emitDeclarePrivateFieldNames):
     320        (JSC::PropertyListNode::emitBytecode):
     321        (JSC::PropertyListNode::emitPutConstantProperty):
     322        (JSC::BaseDotNode::emitGetPropertyValue):
     323
     324        Adding support to properly access private method. Since we store
     325        private methods on class lexical scope, we need a different set of
     326        instructions to access a private method.
     327
     328        (JSC::BaseDotNode::emitPutProperty):
     329
     330        In the case of we trying to write in a private method, we need to
     331        throw a TypeError according to specification
     332        (https://tc39.es/proposal-private-methods/#sec-privatefieldset).
     333
     334        (JSC::FunctionCallValueNode::emitBytecode):
     335        (JSC::PostfixNode::emitDot):
     336        (JSC::PrefixNode::emitDot):
     337        (JSC::ClassExprNode::emitBytecode):
     338        * debugger/DebuggerCallFrame.cpp:
     339        (JSC::DebuggerCallFrame::evaluateWithScopeExtension):
     340        * dfg/DFGAbstractInterpreterInlines.h:
     341        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     342        (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
     343        * dfg/DFGArgumentsEliminationPhase.cpp:
     344        * dfg/DFGByteCodeParser.cpp:
     345        (JSC::DFG::ByteCodeParser::parseBlock):
     346        * dfg/DFGCapabilities.cpp:
     347        (JSC::DFG::capabilityLevel):
     348        * dfg/DFGClobberize.h:
     349        (JSC::DFG::clobberize):
     350        * dfg/DFGClobbersExitState.cpp:
     351        (JSC::DFG::clobbersExitState):
     352        * dfg/DFGDoesGC.cpp:
     353        (JSC::DFG::doesGC):
     354        * dfg/DFGFixupPhase.cpp:
     355        (JSC::DFG::FixupPhase::fixupNode):
     356        * dfg/DFGGraph.h:
     357        * dfg/DFGJITCompiler.cpp:
     358        (JSC::DFG::JITCompiler::link):
     359        * dfg/DFGJITCompiler.h:
     360        (JSC::DFG::JITCompiler::addPrivateBrandAccess):
     361        * dfg/DFGMayExit.cpp:
     362        * dfg/DFGNode.h:
     363        (JSC::DFG::Node::hasCheckPrivateBrandStatus):
     364        (JSC::DFG::Node::checkPrivateBrandStatus):
     365        (JSC::DFG::Node::hasSetPrivateBrandStatus):
     366        (JSC::DFG::Node::setPrivateBrandStatus):
     367        * dfg/DFGNodeType.h:
     368        * dfg/DFGObjectAllocationSinkingPhase.cpp:
     369        * dfg/DFGPredictionPropagationPhase.cpp:
     370        * dfg/DFGSafeToExecute.h:
     371        (JSC::DFG::safeToExecute):
     372        * dfg/DFGSpeculativeJIT.cpp:
     373        (JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand):
     374        (JSC::DFG::SpeculativeJIT::compileSetPrivateBrand):
     375        * dfg/DFGSpeculativeJIT.h:
     376        * dfg/DFGSpeculativeJIT32_64.cpp:
     377        (JSC::DFG::SpeculativeJIT::compile):
     378        * dfg/DFGSpeculativeJIT64.cpp:
     379        (JSC::DFG::SpeculativeJIT::compile):
     380        * dfg/DFGStoreBarrierInsertionPhase.cpp:
     381        * dfg/DFGVarargsForwardingPhase.cpp:
     382        * ftl/FTLCapabilities.cpp:
     383        (JSC::FTL::canCompile):
     384        * ftl/FTLLowerDFGToB3.cpp:
     385        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     386        (JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess):
     387        (JSC::FTL::DFG::LowerDFGToB3::compileCheckPrivateBrand):
     388        (JSC::FTL::DFG::LowerDFGToB3::compileSetPrivateBrand):
     389        * interpreter/Interpreter.cpp:
     390        (JSC::eval):
     391        * jit/JIT.cpp:
     392        (JSC::JIT::privateCompileMainPass):
     393        (JSC::JIT::privateCompileSlowCases):
     394        (JSC::JIT::link):
     395        * jit/JIT.h:
     396        * jit/JITInlineCacheGenerator.cpp:
     397        (JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
     398        (JSC::JITPrivateBrandAccessGenerator::generateFastPath):
     399        (JSC::JITPrivateBrandAccessGenerator::finalize):
     400        * jit/JITInlineCacheGenerator.h:
     401        (JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
     402        (JSC::JITPrivateBrandAccessGenerator::slowPathJump const):
     403        * jit/JITOperations.cpp:
     404        (JSC::JSC_DEFINE_JIT_OPERATION):
     405        (JSC::getPrivateName):
     406        * jit/JITOperations.h:
     407        * jit/JITPropertyAccess.cpp:
     408        (JSC::JIT::emit_op_set_private_brand):
     409        (JSC::JIT::emitSlow_op_set_private_brand):
     410        (JSC::JIT::emit_op_check_private_brand):
     411        (JSC::JIT::emitSlow_op_check_private_brand):
     412        * jit/JITPropertyAccess32_64.cpp:
     413        (JSC::JIT::emit_op_set_private_brand):
     414        (JSC::JIT::emitSlow_op_set_private_brand):
     415        (JSC::JIT::emit_op_check_private_brand):
     416        (JSC::JIT::emitSlow_op_check_private_brand):
     417        * jit/Repatch.cpp:
     418        (JSC::tryCacheCheckPrivateBrand):
     419        (JSC::repatchCheckPrivateBrand):
     420        (JSC::tryCacheSetPrivateBrand):
     421        (JSC::repatchSetPrivateBrand):
     422        (JSC::resetCheckPrivateBrand):
     423        (JSC::resetSetPrivateBrand):
     424        * jit/Repatch.h:
     425        * llint/LLIntSlowPaths.cpp:
     426        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     427        * llint/LLIntSlowPaths.h:
     428        * llint/LowLevelInterpreter32_64.asm:
     429        * llint/LowLevelInterpreter64.asm:
     430        * parser/Nodes.cpp:
     431        (JSC::FunctionMetadataNode::FunctionMetadataNode):
     432        * parser/Nodes.h:
     433        (JSC::BaseDotNode::isPrivateMember const):
     434        (JSC::BaseDotNode::isPrivateField const): Deleted.
     435        * parser/Parser.cpp:
     436        (JSC::Parser<LexerType>::parseClass):
     437        (JSC::Parser<LexerType>::parseMemberExpression):
     438        * parser/Parser.h:
     439        (JSC::Scope::declarePrivateMethod):
     440        (JSC::Scope::declarePrivateField):
     441        (JSC::Parser<LexerType>::parse):
     442        (JSC::parse):
     443        (JSC::Scope::declarePrivateName): Deleted.
     444        * parser/ParserModes.h:
     445        * parser/SyntaxChecker.h:
     446        (JSC::SyntaxChecker::createDotAccess):
     447        * parser/VariableEnvironment.cpp:
     448        (JSC::VariableEnvironment::declarePrivateMethod):
     449        * parser/VariableEnvironment.h:
     450        (JSC::VariableEnvironmentEntry::isPrivateField const):
     451        (JSC::VariableEnvironmentEntry::isPrivateMethod const):
     452        (JSC::VariableEnvironmentEntry::setIsPrivateField):
     453        (JSC::VariableEnvironmentEntry::setIsPrivateMethod):
     454        (JSC::PrivateNameEntry::isMethod const):
     455        (JSC::PrivateNameEntry::isPrivateMethodOrAcessor const):
     456        (JSC::VariableEnvironment::addPrivateName):
     457        (JSC::VariableEnvironment::declarePrivateField):
     458        (JSC::VariableEnvironment::declarePrivateMethod):
     459        (JSC::VariableEnvironment::privateNameEnvironment const):
     460        (JSC::VariableEnvironment::hasPrivateMethodOrAccessor const):
     461        (JSC::VariableEnvironment::addPrivateNamesFrom):
     462        (JSC::VariableEnvironmentEntry::isPrivateName const): Deleted.
     463        (JSC::VariableEnvironmentEntry::setIsPrivateName): Deleted.
     464        (JSC::VariableEnvironment::declarePrivateName): Deleted.
     465        * runtime/CachedTypes.cpp:
     466        (JSC::CachedCodeBlockRareData::encode):
     467        (JSC::CachedCodeBlockRareData::decode const):
     468        (JSC::CachedFunctionExecutableRareData::encode):
     469        (JSC::CachedFunctionExecutableRareData::decode const):
     470        (JSC::CachedFunctionExecutable::privateBrandRequirement const):
     471        (JSC::CachedCodeBlock::derivedContextType const):
     472        (JSC::CachedFunctionExecutable::encode):
     473        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     474        (JSC::CachedCodeBlock::needsClassFieldInitializer const): Deleted.
     475        * runtime/CodeCache.cpp:
     476        (JSC::generateUnlinkedCodeBlockImpl):
     477        (JSC::generateUnlinkedCodeBlock):
     478        (JSC::generateUnlinkedCodeBlockForDirectEval):
     479        (JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):
     480        * runtime/CodeCache.h:
     481        * runtime/DirectEvalExecutable.cpp:
     482        (JSC::DirectEvalExecutable::create):
     483        (JSC::DirectEvalExecutable::DirectEvalExecutable):
     484        * runtime/DirectEvalExecutable.h:
     485        * runtime/EvalExecutable.cpp:
     486        (JSC::EvalExecutable::EvalExecutable):
     487        * runtime/EvalExecutable.h:
     488        (JSC::EvalExecutable::executableInfo const):
     489        (JSC::EvalExecutable::privateBrandRequirement const):
     490        * runtime/ExceptionHelpers.cpp:
     491        (JSC::createInvalidPrivateNameError):
     492        * runtime/IndirectEvalExecutable.cpp:
     493        (JSC::IndirectEvalExecutable::IndirectEvalExecutable):
     494        * runtime/JSObject.h:
     495        * runtime/JSObjectInlines.h:
     496        (JSC::JSObject::checkPrivateBrand):
     497        (JSC::JSObject::setPrivateBrand):
     498        * runtime/JSScope.cpp:
     499        (JSC::JSScope::collectClosureVariablesUnderTDZ):
     500        * runtime/JSScope.h:
     501        * runtime/ModuleProgramExecutable.h:
     502        * runtime/Options.cpp:
     503        (JSC::Options::recomputeDependentOptions):
     504        * runtime/OptionsList.h:
     505        * runtime/ProgramExecutable.h:
     506        * runtime/Structure.cpp:
     507        (JSC::Structure::materializePropertyTable):
     508        (JSC::BrandedStructure::BrandedStructure):
     509        (JSC::BrandedStructure::create):
     510        (JSC::BrandedStructure::checkBrand):
     511        (JSC::Structure::setBrandTransitionFromExistingStructureImpl):
     512        (JSC::Structure::setBrandTransitionFromExistingStructureConcurrently):
     513        (JSC::Structure::setBrandTransition):
     514        * runtime/Structure.h:
     515        (JSC::Structure::finishCreation):
     516        * runtime/StructureInlines.h:
     517        (JSC::Structure::create):
     518        (JSC::Structure::forEachPropertyConcurrently):
     519        * runtime/StructureTransitionTable.h:
     520        * runtime/SymbolTable.cpp:
     521        (JSC::SymbolTable::cloneScopePart):
     522        * runtime/SymbolTable.h:
     523        * runtime/VM.cpp:
     524        (JSC::VM::VM):
     525        * runtime/VM.h:
     526
    15272021-02-09  Yusuke Suzuki  <ysuzuki@apple.com>
    2528
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r272222 r272580  
    12431243                86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */ = {isa = PBXBuildFile; fileRef = 86158AB2155C8B3F00B45C9C /* PropertyName.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12441244                861816771FB7924200ECC4EC /* BigIntObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 861816761FB7922F00ECC4EC /* BigIntObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1245                861AF60725D18C9D000B63E1 /* BrandedStructure.h in Headers */ = {isa = PBXBuildFile; fileRef = 861AF60625D18C9D000B63E1 /* BrandedStructure.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12451246                862553D216136E1A009F17D0 /* JSProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 862553CF16136AA5009F17D0 /* JSProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1247                86281EF025B6160000367004 /* CheckPrivateBrandVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 86281EEF25B6160000367004 /* CheckPrivateBrandVariant.h */; };
     1248                86281EF425B61AF000367004 /* CheckPrivateBrandStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 86281EF325B61AF000367004 /* CheckPrivateBrandStatus.h */; };
    12461249                863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12471250                863FBC5A25B093B900F6C930 /* WasmValueLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 863FBC5825B093B900F6C930 /* WasmValueLocation.h */; };
    12481251                865A30F1135007E100CDB49E /* JSCJSValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1252                865DA0C525B8957400875772 /* SetPrivateBrandVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 865DA0C425B8957400875772 /* SetPrivateBrandVariant.h */; };
     1253                865DA0C825B8960C00875772 /* SetPrivateBrandStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 865DA0C725B8960C00875772 /* SetPrivateBrandStatus.h */; };
    12491254                866739D213BFDE710023D87C /* BigInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D013BFDE710023D87C /* BigInteger.h */; };
    12501255                866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D113BFDE710023D87C /* Uint16WithFraction.h */; };
     
    41414146                861816761FB7922F00ECC4EC /* BigIntObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BigIntObject.h; sourceTree = "<group>"; };
    41424147                861816781FB7931300ECC4EC /* BigIntObject.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BigIntObject.cpp; sourceTree = "<group>"; };
     4148                861AF60625D18C9D000B63E1 /* BrandedStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BrandedStructure.h; sourceTree = "<group>"; };
    41434149                862553CE16136AA5009F17D0 /* JSProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSProxy.cpp; sourceTree = "<group>"; };
    41444150                862553CF16136AA5009F17D0 /* JSProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSProxy.h; sourceTree = "<group>"; };
     4151                86281EEF25B6160000367004 /* CheckPrivateBrandVariant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CheckPrivateBrandVariant.h; sourceTree = "<group>"; };
     4152                86281EF125B6165E00367004 /* CheckPrivateBrandVariant.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CheckPrivateBrandVariant.cpp; sourceTree = "<group>"; };
     4153                86281EF325B61AF000367004 /* CheckPrivateBrandStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CheckPrivateBrandStatus.h; sourceTree = "<group>"; };
     4154                86281EF525B61B0600367004 /* CheckPrivateBrandStatus.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CheckPrivateBrandStatus.cpp; sourceTree = "<group>"; };
    41454155                863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; };
    41464156                863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrCanonicalizeUCS2.cpp; path = yarr/YarrCanonicalizeUCS2.cpp; sourceTree = "<group>"; };
     
    41534163                8640923C156EED3B00566CB2 /* MacroAssemblerARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARM64.h; sourceTree = "<group>"; };
    41544164                865A30F0135007E100CDB49E /* JSCJSValueInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCJSValueInlines.h; sourceTree = "<group>"; };
     4165                865DA0C425B8957400875772 /* SetPrivateBrandVariant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SetPrivateBrandVariant.h; sourceTree = "<group>"; };
     4166                865DA0C625B8959E00875772 /* SetPrivateBrandVariant.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SetPrivateBrandVariant.cpp; sourceTree = "<group>"; };
     4167                865DA0C725B8960C00875772 /* SetPrivateBrandStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SetPrivateBrandStatus.h; sourceTree = "<group>"; };
     4168                865DA0C925B8962A00875772 /* SetPrivateBrandStatus.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SetPrivateBrandStatus.cpp; sourceTree = "<group>"; };
     4169                8664967A25D1DD1200516B36 /* BrandedStructure.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BrandedStructure.cpp; sourceTree = "<group>"; };
    41554170                866739D013BFDE710023D87C /* BigInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BigInteger.h; sourceTree = "<group>"; };
    41564171                866739D113BFDE710023D87C /* Uint16WithFraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uint16WithFraction.h; sourceTree = "<group>"; };
     
    71577172                                BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */,
    71587173                                BC7952350E15EB5600A898AB /* BooleanPrototype.h */,
     7174                                8664967A25D1DD1200516B36 /* BrandedStructure.cpp */,
     7175                                861AF60625D18C9D000B63E1 /* BrandedStructure.h */,
    71597176                                9E72940A190F0514001A91B5 /* BundlePath.h */,
    71607177                                9E729409190F0306001A91B5 /* BundlePath.mm */,
     
    84178434                                0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */,
    84188435                                0F3B7E2519A11B8000D9BC56 /* CallVariant.h */,
     8436                                86281EF525B61B0600367004 /* CheckPrivateBrandStatus.cpp */,
     8437                                86281EF325B61AF000367004 /* CheckPrivateBrandStatus.h */,
     8438                                86281EF125B6165E00367004 /* CheckPrivateBrandVariant.cpp */,
     8439                                86281EEF25B6160000367004 /* CheckPrivateBrandVariant.h */,
    84198440                                969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
    84208441                                969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
     
    85518572                                0FF60ABF16740F8100029779 /* ReduceWhitespace.cpp */,
    85528573                                0FF60AC016740F8100029779 /* ReduceWhitespace.h */,
     8574                                865DA0C925B8962A00875772 /* SetPrivateBrandStatus.cpp */,
     8575                                865DA0C725B8960C00875772 /* SetPrivateBrandStatus.h */,
     8576                                865DA0C625B8959E00875772 /* SetPrivateBrandVariant.cpp */,
     8577                                865DA0C425B8957400875772 /* SetPrivateBrandVariant.h */,
    85538578                                0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
    85548579                                0FD82E4F141DAEA100179C94 /* SpeculatedType.h */,
     
    92779302                                9B4694391F97439E00CCB3F9 /* BooleanPrototype.h in Headers */,
    92789303                                996B73191BDA068000331B84 /* BooleanPrototype.lut.h in Headers */,
     9304                                861AF60725D18C9D000B63E1 /* BrandedStructure.h in Headers */,
    92799305                                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */,
    92809306                                DE26E9031CB5DD0500D2BE82 /* BuiltinExecutableCreator.h in Headers */,
     
    93429368                                0F1C3DDA1BBCE09E00E523E4 /* CellState.h in Headers */,
    93439369                                5338E2A72396EFFB00C61BAD /* CheckpointOSRExitSideState.h in Headers */,
     9370                                86281EF425B61AF000367004 /* CheckPrivateBrandStatus.h in Headers */,
     9371                                86281EF025B6160000367004 /* CheckPrivateBrandVariant.h in Headers */,
    93449372                                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
    93459373                                0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */,
     
    1039310421                                A7299DA617D12858005F5FF9 /* SetConstructor.h in Headers */,
    1039410422                                A790DD6E182F499700588807 /* SetIteratorPrototype.h in Headers */,
     10423                                865DA0C825B8960C00875772 /* SetPrivateBrandStatus.h in Headers */,
     10424                                865DA0C525B8957400875772 /* SetPrivateBrandVariant.h in Headers */,
    1039510425                                A7299DA217D12848005F5FF9 /* SetPrototype.h in Headers */,
    1039610426                                0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r271993 r272580  
    212212bytecode/CallMode.cpp
    213213bytecode/CallVariant.cpp
     214bytecode/CheckPrivateBrandStatus.cpp
     215bytecode/CheckPrivateBrandVariant.cpp
    214216bytecode/CodeBlock.cpp
    215217bytecode/CodeBlockHash.cpp
     
    272274bytecode/RecordedStatuses.cpp
    273275bytecode/ReduceWhitespace.cpp
     276bytecode/SetPrivateBrandStatus.cpp
     277bytecode/SetPrivateBrandVariant.cpp
    274278bytecode/SpeculatedType.cpp
    275279bytecode/StructureSet.cpp
     
    735739runtime/BooleanObject.cpp
    736740runtime/BooleanPrototype.cpp
     741runtime/BrandedStructure.cpp
    737742runtime/BytecodeCacheError.cpp
    738743runtime/CallData.cpp
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp

    r270870 r272580  
    6060}
    6161
    62 UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name, NeedsClassFieldInitializer needsClassFieldInitializer)
     62UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement)
    6363{
    6464    switch (constructorKind) {
     
    6868    case ConstructorKind::Base:
    6969    case ConstructorKind::Extends:
    70         return createExecutable(m_vm, defaultConstructorSourceCode(constructorKind), name, constructorKind, ConstructAbility::CanConstruct, needsClassFieldInitializer);
     70        return createExecutable(m_vm, defaultConstructorSourceCode(constructorKind), name, constructorKind, ConstructAbility::CanConstruct, needsClassFieldInitializer, privateBrandRequirement);
    7171    }
    7272    ASSERT_NOT_REACHED();
     
    7979}
    8080
    81 UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility, NeedsClassFieldInitializer needsClassFieldInitializer)
     81UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement)
    8282{
    8383    // FIXME: Can we just make MetaData computation be constexpr and have the compiler do this for us?
     
    252252    }
    253253
    254     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(vm, source, &metadata, kind, constructAbility, JSParserScriptMode::Classic, nullptr, DerivedContextType::None, needsClassFieldInitializer, isBuiltinDefaultClassConstructor);
     254    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(vm, source, &metadata, kind, constructAbility, JSParserScriptMode::Classic, nullptr, WTF::nullopt, DerivedContextType::None, needsClassFieldInitializer, privateBrandRequirement, isBuiltinDefaultClassConstructor);
    255255    return functionExecutable;
    256256}
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.h

    r254653 r272580  
    5959
    6060    static SourceCode defaultConstructorSourceCode(ConstructorKind);
    61     UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name, NeedsClassFieldInitializer);
     61    UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name, NeedsClassFieldInitializer, PrivateBrandRequirement);
    6262
    63     static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility, NeedsClassFieldInitializer);
     63    static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility, NeedsClassFieldInitializer, PrivateBrandRequirement = PrivateBrandRequirement::None);
    6464
    6565    void finalizeUnconditionally();
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.h

    r272364 r272580  
    174174    macro(webAssemblyInstantiateStreamingInternal) \
    175175    macro(instanceFieldInitializer) \
     176    macro(privateBrand) \
    176177    macro(hasOwnPropertyFunction) \
    177178    macro(createPrivateSymbol) \
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp

    r272174 r272580  
    134134}
    135135
     136std::unique_ptr<AccessCase> AccessCase::createCheckPrivateBrand(VM& vm, JSCell* owner, CacheableIdentifier identifier, Structure* structure)
     137{
     138    return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, CheckPrivateBrand, identifier, invalidOffset, structure, { }, { }));
     139}
     140
     141std::unique_ptr<AccessCase> AccessCase::createSetPrivateBrand(
     142    VM& vm, JSCell* owner, CacheableIdentifier identifier, Structure* oldStructure, Structure* newStructure)
     143{
     144    RELEASE_ASSERT(oldStructure == newStructure->previousID());
     145    return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, SetPrivateBrand, identifier, invalidOffset, newStructure, { }, { }));
     146}
     147
    136148AccessCase::~AccessCase()
    137149{
     
    293305    case ScopedArgumentsLength:
    294306    case ModuleNamespaceLoad:
     307    case CheckPrivateBrand:
     308    case SetPrivateBrand:
    295309        return true;
    296310    case InstanceOfHit:
     
    346360    case InstanceOfMiss:
    347361    case InstanceOfGeneric:
     362    case CheckPrivateBrand:
     363    case SetPrivateBrand:
    348364        return false;
    349365    case IndexedInt32Load:
     
    388404    case InHit:
    389405    case InMiss:
     406    case CheckPrivateBrand:
     407    case SetPrivateBrand:
    390408    case ArrayLength:
    391409    case StringLength:
     
    475493    case InHit:
    476494    case InMiss:
     495    case CheckPrivateBrand:
     496    case SetPrivateBrand:
    477497    case ArrayLength:
    478498    case StringLength:
     
    524544    case InHit:
    525545    case InMiss:
     546    case CheckPrivateBrand:
     547    case SetPrivateBrand:
    526548    case ArrayLength:
    527549    case StringLength:
     
    675697    case InHit:
    676698    case InMiss:
     699    case CheckPrivateBrand:
     700    case SetPrivateBrand:
    677701        if (other.type() != type())
    678702            return false;
     
    706730        m_polyProtoAccessChain->dump(structure(), out);
    707731    } else {
    708         if (m_type == Transition || m_type == Delete)
     732        if (m_type == Transition || m_type == Delete || m_type == SetPrivateBrand)
    709733            out.print(comma, "structure = ", pointerDump(structure()), " -> ", pointerDump(newStructure()));
    710734        else if (m_structure)
     
    13351359        } else
    13361360            state.failAndIgnore.append(failAndIgnore);
     1361        return;
     1362    }
     1363
     1364    case CheckPrivateBrand: {
     1365        emitDefaultGuard();
     1366        state.succeed();
    13371367        return;
    13381368    }
     
    20392069    }
    20402070
     2071    case SetPrivateBrand: {
     2072        ASSERT(structure()->transitionWatchpointSetHasBeenInvalidated());
     2073        ASSERT(newStructure()->transitionKind() == TransitionKind::SetBrand);
     2074
     2075        uint32_t structureBits = bitwise_cast<uint32_t>(newStructure()->id());
     2076        jit.store32(
     2077            CCallHelpers::TrustedImm32(structureBits),
     2078            CCallHelpers::Address(baseGPR, JSCell::structureIDOffset()));
     2079
     2080        state.succeed();
     2081        return;
     2082    }
     2083
    20412084    case DeleteNonConfigurable: {
    20422085        jit.move(MacroAssembler::TrustedImm32(false), valueRegs.payloadGPR());
     
    21122155    case IndexedTypedArrayFloat64Load:
    21132156    case IndexedStringLoad:
     2157    case CheckPrivateBrand:
    21142158        // These need to be handled by generateWithGuard(), since the guard is part of the
    21152159        // algorithm. We can be sure that nobody will call generate() directly for these since they
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.h

    r259463 r272580  
    109109        InstanceOfMiss,
    110110        InstanceOfGeneric,
     111        CheckPrivateBrand,
     112        SetPrivateBrand,
    111113        IndexedInt32Load,
    112114        IndexedDoubleLoad,
     
    154156    static std::unique_ptr<AccessCase> createDelete(VM&, JSCell* owner, CacheableIdentifier, PropertyOffset, Structure* oldStructure,
    155157        Structure* newStructure);
     158
     159    static std::unique_ptr<AccessCase> createCheckPrivateBrand(VM&, JSCell* owner, CacheableIdentifier, Structure*);
     160    static std::unique_ptr<AccessCase> createSetPrivateBrand(VM&, JSCell* owner, CacheableIdentifier, Structure* oldStructure, Structure* newStructure);
    156161   
    157162    static std::unique_ptr<AccessCase> fromStructureStubInfo(VM&, JSCell* owner, CacheableIdentifier, StructureStubInfo&);
     
    163168    Structure* structure() const
    164169    {
    165         if (m_type == Transition || m_type == Delete)
     170        if (m_type == Transition || m_type == Delete || m_type == SetPrivateBrand)
    166171            return m_structure->previousID();
    167172        return m_structure.get();
     
    171176    Structure* newStructure() const
    172177    {
    173         ASSERT(m_type == Transition || m_type == Delete);
     178        ASSERT(m_type == Transition || m_type == Delete || m_type == SetPrivateBrand);
    174179        return m_structure.get();
    175180    }
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb

    r270948 r272580  
    588588        newStructureID: StructureID,
    589589    }
     590
     591op :set_private_brand,
     592    args: {
     593        base: VirtualRegister,
     594        brand: VirtualRegister,
     595    },
     596    metadata: {
     597        oldStructureID: StructureID,
     598        newStructureID: StructureID,
     599        brand: WriteBarrier[JSCell],
     600    }
     601
     602op :check_private_brand,
     603    args: {
     604        base: VirtualRegister,
     605        brand: VirtualRegister,
     606    },
     607    metadata: {
     608        structureID: StructureID,
     609        brand: WriteBarrier[JSCell],
     610    }
     611   
    590612
    591613op :put_by_val,
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp

    r270874 r272580  
    230230    USES(OpGetPrivateName, base, property)
    231231    USES(OpPutPrivateName, base, property, value)
     232    USES(OpSetPrivateBrand, base, brand)
     233    USES(OpCheckPrivateBrand, base, brand)
    232234    USES(OpInByVal, base, property)
    233235    USES(OpOverridesHasInstance, constructor, hasInstanceValue)
     
    398400    case op_put_by_val_direct:
    399401    case op_put_private_name:
     402    case op_set_private_brand:
     403    case op_check_private_brand:
    400404    case op_put_internal_field:
    401405    case op_define_data_property:
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r270874 r272580  
    545545        LINK(OpPutPrivateName)
    546546
     547        LINK(OpSetPrivateBrand)
     548        LINK(OpCheckPrivateBrand)
     549
    547550        LINK(OpNewArray)
    548551        LINK(OpNewArrayWithSize)
     
    13371340            metadata.m_newStructureID = 0;
    13381341            metadata.m_property.clear();
     1342        });
     1343
     1344        m_metadata->forEach<OpSetPrivateBrand>([&] (auto& metadata) {
     1345            StructureID oldStructureID = metadata.m_oldStructureID;
     1346            StructureID newStructureID = metadata.m_newStructureID;
     1347            JSCell* brand = metadata.m_brand.get();
     1348            if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
     1349                && (!brand || vm.heap.isMarked(brand))
     1350                && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID))))
     1351                return;
     1352
     1353            dataLogLnIf(Options::verboseOSR(), "Clearing LLInt set_private_brand transition.");
     1354            metadata.m_oldStructureID = 0;
     1355            metadata.m_newStructureID = 0;
     1356            metadata.m_brand.clear();
     1357        });
     1358
     1359        m_metadata->forEach<OpCheckPrivateBrand>([&] (auto& metadata) {
     1360            StructureID structureID = metadata.m_structureID;
     1361            JSCell* brand = metadata.m_brand.get();
     1362            if ((!structureID || vm.heap.isMarked(vm.heap.structureIDTable().get(structureID)))
     1363                && (!brand || vm.heap.isMarked(brand)))
     1364                return;
     1365
     1366            dataLogLnIf(Options::verboseOSR(), "Clearing LLInt set_private_brand transition.");
     1367            metadata.m_structureID = 0;
     1368            metadata.m_brand.clear();
    13391369        });
    13401370
  • trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h

    r259676 r272580  
    3737// https://bugs.webkit.org/show_bug.cgi?id=151547
    3838struct ExecutableInfo {
    39     ExecutableInfo(bool usesEval, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, JSParserScriptMode scriptMode, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isArrowFunctionContext, bool isClassContext, EvalContextType evalContextType)
     39    ExecutableInfo(bool usesEval, bool isConstructor, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinFunction, ConstructorKind constructorKind, JSParserScriptMode scriptMode, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isArrowFunctionContext, bool isClassContext, EvalContextType evalContextType)
    4040        : m_usesEval(usesEval)
    4141        , m_isConstructor(isConstructor)
     42        , m_privateBrandRequirement(static_cast<unsigned>(privateBrandRequirement))
    4243        , m_isBuiltinFunction(isBuiltinFunction)
    4344        , m_constructorKind(static_cast<unsigned>(constructorKind))
     
    5859    bool usesEval() const { return m_usesEval; }
    5960    bool isConstructor() const { return m_isConstructor; }
     61    PrivateBrandRequirement privateBrandRequirement() const { return static_cast<PrivateBrandRequirement>(m_privateBrandRequirement); }
    6062    bool isBuiltinFunction() const { return m_isBuiltinFunction; }
    6163    ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
     
    7274    unsigned m_usesEval : 1;
    7375    unsigned m_isConstructor : 1;
     76    unsigned m_privateBrandRequirement : 1;
    7477    unsigned m_isBuiltinFunction : 1;
    7578    unsigned m_constructorKind : 2;
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp

    r265997 r272580  
    470470    if (state.u.thisGPR != InvalidGPRReg)
    471471        allocator.lock(state.u.thisGPR);
    472     allocator.lock(state.valueRegs);
     472    if (state.valueRegs)
     473        allocator.lock(state.valueRegs);
    473474#if USE(JSVALUE32_64)
    474475    allocator.lock(stubInfo.baseTagGPR);
     
    853854        out.print("InMiss");
    854855        return;
     856    case AccessCase::CheckPrivateBrand:
     857        out.print("CheckPrivateBrand");
     858        return;
     859    case AccessCase::SetPrivateBrand:
     860        out.print("SetPrivateBrand");
     861        return;
    855862    case AccessCase::ArrayLength:
    856863        out.print("ArrayLength");
  • trunk/Source/JavaScriptCore/bytecode/RecordedStatuses.cpp

    r259583 r272580  
    3636    ins = WTFMove(other.ins);
    3737    deletes = WTFMove(other.deletes);
     38    checkPrivateBrands = WTFMove(other.checkPrivateBrands);
     39    setPrivateBrands = WTFMove(other.setPrivateBrands);
    3840    shrinkToFit();
    3941    return *this;
     
    8587}
    8688
     89CheckPrivateBrandStatus* RecordedStatuses::addCheckPrivateBrandStatus(const CodeOrigin& codeOrigin, const CheckPrivateBrandStatus& status)
     90{
     91    auto statusPtr = makeUnique<CheckPrivateBrandStatus>(status);
     92    CheckPrivateBrandStatus* result = statusPtr.get();
     93    checkPrivateBrands.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
     94    return result;
     95}
     96
     97SetPrivateBrandStatus* RecordedStatuses::addSetPrivateBrandStatus(const CodeOrigin& codeOrigin, const SetPrivateBrandStatus& status)
     98{
     99    auto statusPtr = makeUnique<SetPrivateBrandStatus>(status);
     100    SetPrivateBrandStatus* result = statusPtr.get();
     101    setPrivateBrands.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
     102    return result;
     103}
     104
    87105void RecordedStatuses::visitAggregate(SlotVisitor& slotVisitor)
    88106{
     
    90108        pair.second->visitAggregate(slotVisitor);
    91109    for (auto& pair : deletes)
     110        pair.second->visitAggregate(slotVisitor);
     111    for (auto& pair : checkPrivateBrands)
     112        pair.second->visitAggregate(slotVisitor);
     113    for (auto& pair : setPrivateBrands)
    92114        pair.second->visitAggregate(slotVisitor);
    93115}
     
    102124        pair.second->markIfCheap(slotVisitor);
    103125    for (auto& pair : deletes)
     126        pair.second->markIfCheap(slotVisitor);
     127    for (auto& pair : checkPrivateBrands)
     128        pair.second->markIfCheap(slotVisitor);
     129    for (auto& pair : setPrivateBrands)
    104130        pair.second->markIfCheap(slotVisitor);
    105131}
  • trunk/Source/JavaScriptCore/bytecode/RecordedStatuses.h

    r259583 r272580  
    2727
    2828#include "CallLinkStatus.h"
     29#include "CheckPrivateBrandStatus.h"
    2930#include "DeleteByStatus.h"
    3031#include "GetByStatus.h"
    3132#include "InByIdStatus.h"
    3233#include "PutByIdStatus.h"
     34#include "SetPrivateBrandStatus.h"
    3335
    3436namespace JSC {
     
    5052    InByIdStatus* addInByIdStatus(const CodeOrigin&, const InByIdStatus&);
    5153    DeleteByStatus* addDeleteByStatus(const CodeOrigin&, const DeleteByStatus&);
     54    CheckPrivateBrandStatus* addCheckPrivateBrandStatus(const CodeOrigin&, const CheckPrivateBrandStatus&);
     55    SetPrivateBrandStatus* addSetPrivateBrandStatus(const CodeOrigin&, const SetPrivateBrandStatus&);
    5256   
    5357    void visitAggregate(SlotVisitor&);
     
    6771        func(ins);
    6872        func(deletes);
     73        func(checkPrivateBrands);
     74        func(setPrivateBrands);
    6975    }
    7076   
     
    7480    Vector<std::pair<CodeOrigin, std::unique_ptr<InByIdStatus>>> ins;
    7581    Vector<std::pair<CodeOrigin, std::unique_ptr<DeleteByStatus>>> deletes;
     82    Vector<std::pair<CodeOrigin, std::unique_ptr<CheckPrivateBrandStatus>>> checkPrivateBrands;
     83    Vector<std::pair<CodeOrigin, std::unique_ptr<SetPrivateBrandStatus>>> setPrivateBrands;
    7684};
    7785
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp

    r266359 r272580  
    285285        resetDelBy(codeBlock, *this, DelByKind::NormalByVal);
    286286        break;
     287    case AccessType::CheckPrivateBrand:
     288        resetCheckPrivateBrand(codeBlock, *this);
     289        break;
     290    case AccessType::SetPrivateBrand:
     291        resetSetPrivateBrand(codeBlock, *this);
     292        break;
    287293    }
    288294   
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h

    r268794 r272580  
    6060    DeleteByVal,
    6161    GetPrivateName,
     62    CheckPrivateBrand,
     63    SetPrivateBrand,
    6264};
    6365
     
    353355        GPRReg prototypeGPR;
    354356        GPRReg propertyGPR;
     357        GPRReg brandGPR;
    355358    } regs;
    356359#if USE(JSVALUE32_64)
     
    362365        GPRReg thisTagGPR;
    363366        GPRReg propertyTagGPR;
     367        GPRReg brandTagGPR;
    364368    } v;
    365369#endif
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp

    r261895 r272580  
    7070        m_rareData->m_needsClassFieldInitializer = static_cast<unsigned>(NeedsClassFieldInitializer::Yes);
    7171    }
     72    if (info.privateBrandRequirement() == PrivateBrandRequirement::Needed) {
     73        createRareDataIfNecessary(holdLock(cellLock()));
     74        m_rareData->m_privateBrandRequirement = static_cast<unsigned>(PrivateBrandRequirement::Needed);
     75    }
    7276}
    7377
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r259676 r272580  
    267267    }
    268268
     269    PrivateBrandRequirement privateBrandRequirement() const
     270    {
     271        if (m_rareData)
     272            return static_cast<PrivateBrandRequirement>(m_rareData->m_privateBrandRequirement);
     273        return PrivateBrandRequirement::None;
     274    }
     275
    269276    void dump(PrintStream&) const;
    270277
     
    408415
    409416        unsigned m_needsClassFieldInitializer : 1;
     417        unsigned m_privateBrandRequirement : 1;
    410418    };
    411419
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlockGenerator.h

    r259676 r272580  
    5151    JSParserScriptMode scriptMode() const { return m_codeBlock->scriptMode(); }
    5252    NeedsClassFieldInitializer needsClassFieldInitializer() const { return m_codeBlock->needsClassFieldInitializer(); }
     53    PrivateBrandRequirement privateBrandRequirement() const { return m_codeBlock->privateBrandRequirement(); }
    5354    bool usesEval() const { return m_codeBlock->usesEval(); }
    5455    SourceParseMode parseMode() const { return m_codeBlock->parseMode(); }
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r271420 r272580  
    7171    bool isClassContext = executable->superBinding() == SuperBinding::Needed || executable->parseMode() == SourceParseMode::ClassFieldInitializerMode;
    7272
    73     UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(vm, FunctionCode, ExecutableInfo(function->usesEval(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), executable->needsClassFieldInitializer(), false, isClassContext, EvalContextType::FunctionEvalContext), codeGenerationMode);
     73    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(vm, FunctionCode, ExecutableInfo(function->usesEval(), kind == CodeForConstruct, executable->privateBrandRequirement(), functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), executable->needsClassFieldInitializer(), false, isClassContext, EvalContextType::FunctionEvalContext), codeGenerationMode);
    7474
    7575    auto parentScopeTDZVariables = executable->parentScopeTDZVariables();
     76    PrivateNameEnvironment parentPrivateNameEnvironment = executable->parentPrivateNameEnvironment();
    7677    ECMAMode ecmaMode = executable->isInStrictContext() ? ECMAMode::strict() : ECMAMode::sloppy();
    77     error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, parentScopeTDZVariables, ecmaMode);
     78    error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, parentScopeTDZVariables, &parentPrivateNameEnvironment, ecmaMode);
    7879
    7980    if (error.isValid())
     
    8384}
    8485
    85 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isBuiltinDefaultClassConstructor)
     86UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, Optional<PrivateNameEnvironment> parentPrivateNameEnvironment, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinDefaultClassConstructor)
    8687    : Base(vm, structure)
    8788    , m_firstLineOffset(node->firstLine() - parentSource.firstLine().oneBasedInt())
     
    104105    , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1)
    105106    , m_parameterCount(node->parameterCount())
     107    , m_privateBrandRequirement(static_cast<unsigned>(privateBrandRequirement))
    106108    , m_features(0)
    107109    , m_sourceParseMode(node->parseMode())
     
    123125    ASSERT(m_superBinding == static_cast<unsigned>(node->superBinding()));
    124126    ASSERT(m_derivedContextType == static_cast<unsigned>(derivedContextType));
     127    ASSERT(m_privateBrandRequirement == static_cast<unsigned>(privateBrandRequirement));
    125128    ASSERT(!(m_isBuiltinDefaultClassConstructor && constructorKind() == ConstructorKind::None));
    126129    ASSERT(!m_needsClassFieldInitializer || (isClassConstructorFunction() || derivedContextType == DerivedContextType::DerivedConstructorContext));
     
    129132    if (parentScopeTDZVariables)
    130133        ensureRareData().m_parentScopeTDZVariables = WTFMove(parentScopeTDZVariables);
     134    if (parentPrivateNameEnvironment)
     135        ensureRareData().m_parentPrivateNameEnvironment = WTFMove(*parentPrivateNameEnvironment);
    131136}
    132137
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r270870 r272580  
    7171    }
    7272
    73     static UnlinkedFunctionExecutable* create(VM& vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isBuiltinDefaultClassConstructor = false)
     73    static UnlinkedFunctionExecutable* create(VM& vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, Optional<PrivateNameEnvironment> parentPrivateNameEnvironment, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinDefaultClassConstructor = false)
    7474    {
    7575        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm.heap))
    76             UnlinkedFunctionExecutable(vm, vm.unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, scriptMode, WTFMove(parentScopeTDZVariables), derivedContextType, needsClassFieldInitializer, isBuiltinDefaultClassConstructor);
     76            UnlinkedFunctionExecutable(vm, vm.unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, scriptMode, WTFMove(parentScopeTDZVariables), WTFMove(parentPrivateNameEnvironment), derivedContextType, needsClassFieldInitializer, privateBrandRequirement, isBuiltinDefaultClassConstructor);
    7777        instance->finishCreation(vm);
    7878        return instance;
     
    144144    bool hasCapturedVariables() const { return m_hasCapturedVariables; }
    145145
     146    PrivateBrandRequirement privateBrandRequirement() const { return static_cast<PrivateBrandRequirement>(m_privateBrandRequirement); }
     147
    146148    static constexpr bool needsDestruction = true;
    147149    static void destroy(JSCell*);
     
    175177        return m_rareData->m_parentScopeTDZVariables;
    176178    }
     179
     180    PrivateNameEnvironment parentPrivateNameEnvironment() const
     181    {
     182        if (!m_rareData)
     183            return PrivateNameEnvironment();
     184        return m_rareData->m_parentPrivateNameEnvironment;
     185    }
    177186   
    178187    bool isArrowFunction() const { return isArrowFunctionParseMode(parseMode()); }
     
    211220        RefPtr<TDZEnvironmentLink> m_parentScopeTDZVariables;
    212221        Vector<JSTextPosition> m_classFieldLocations;
     222        PrivateNameEnvironment m_parentPrivateNameEnvironment;
    213223    };
    214224
     
    230240
    231241private:
    232     UnlinkedFunctionExecutable(VM&, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, RefPtr<TDZEnvironmentLink>,  JSC::DerivedContextType, JSC::NeedsClassFieldInitializer, bool isBuiltinDefaultClassConstructor);
     242    UnlinkedFunctionExecutable(VM&, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, RefPtr<TDZEnvironmentLink>, Optional<PrivateNameEnvironment>, JSC::DerivedContextType, JSC::NeedsClassFieldInitializer, PrivateBrandRequirement, bool isBuiltinDefaultClassConstructor);
    233243    UnlinkedFunctionExecutable(Decoder&, const CachedFunctionExecutable&);
    234244
     
    262272    unsigned m_typeProfilingStartOffset;
    263273    unsigned m_typeProfilingEndOffset;
    264     unsigned m_parameterCount;
     274    unsigned m_parameterCount : 31;
     275    unsigned m_privateBrandRequirement : 1;
    265276    CodeFeatures m_features;
    266277    SourceParseMode m_sourceParseMode;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r270874 r272580  
    290290}
    291291
    292 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, ECMAMode ecmaMode)
     292BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment*, ECMAMode ecmaMode)
    293293    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
    294294    , m_codeGenerationMode(codeGenerationMode)
     
    337337}
    338338
    339 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, ECMAMode ecmaMode)
     339BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment* parentPrivateNameEnvironment, ECMAMode ecmaMode)
    340340    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
    341341    , m_codeGenerationMode(codeGenerationMode)
     
    360360    , m_derivedContextType(codeBlock->derivedContextType())
    361361{
     362    pushPrivateAccessNames(parentPrivateNameEnvironment);
     363
    362364    SymbolTable* functionSymbolTable = SymbolTable::create(m_vm);
    363365    functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
     
    708710                case ConstructorKind::Base:
    709711                    emitCreateThis(&m_thisRegister);
     712                    if (Options::usePrivateMethods() && privateBrandRequirement() == PrivateBrandRequirement::Needed)
     713                        emitInstallPrivateBrand(&m_thisRegister);
     714
    710715                    emitInstanceFieldInitializationIfNeeded(&m_thisRegister, &m_calleeRegister, m_scopeNode->position(), m_scopeNode->position(), m_scopeNode->position());
    711716                    break;
     
    839844}
    840845
    841 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, ECMAMode ecmaMode)
     846BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment* parentPrivateNameEnvironment, ECMAMode ecmaMode)
    842847    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
    843848    , m_codeGenerationMode(codeGenerationMode)
     
    857862    m_codeBlock->setNumParameters(1);
    858863
     864    pushPrivateAccessNames(parentPrivateNameEnvironment);
     865
    859866    m_cachedParentTDZ = parentScopeTDZVariables;
    860867
     
    902909}
    903910
    904 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, ECMAMode ecmaMode)
     911BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment*, ECMAMode ecmaMode)
    905912    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
    906913    , m_codeGenerationMode(codeGenerationMode)
     
    18941901            // FIXME: only do this if there is an eval() within a nested scope --- otherwise it isn't needed.
    18951902            // https://bugs.webkit.org/show_bug.cgi?id=206663
    1896             if (entry.value.isPrivateName())
    1897                 symbolTable->addPrivateName(entry.key.get());
     1903            if (entry.value.isPrivateField())
     1904                symbolTable->addPrivateName(entry.key.get(), PrivateNameEntry(PrivateNameEntry::Traits::IsDeclared));
     1905            else if (entry.value.isPrivateMethod())
     1906                symbolTable->addPrivateName(entry.key.get(), PrivateNameEntry(PrivateNameEntry::Traits::IsDeclared | PrivateNameEntry::Traits::IsMethod));
    18981907        }
    18991908    }
     
    27152724}
    27162725
    2717 RegisterID* BytecodeGenerator::emitDirectGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
     2726RegisterID* BytecodeGenerator::emitGetPrivateName(RegisterID* dst, RegisterID* base, RegisterID* property)
    27182727{
    27192728    OpGetPrivateName::emit(this, dst, base, property);
     
    27512760}
    27522761
     2762void BytecodeGenerator::emitCreatePrivateBrand(RegisterID* scope, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
     2763{
     2764    RefPtr<RegisterID> createPrivateSymbol = moveLinkTimeConstant(nullptr, LinkTimeConstant::createPrivateSymbol);
     2765
     2766    CallArguments arguments(*this, nullptr, 0);
     2767    emitLoad(arguments.thisRegister(), jsUndefined());
     2768    RegisterID* newSymbol = emitCall(finalDestination(nullptr, createPrivateSymbol.get()), createPrivateSymbol.get(), NoExpectedFunction, arguments, divot, divotStart, divotEnd, DebuggableCall::No);
     2769
     2770    Variable privateBrandVar = variable(propertyNames().builtinNames().privateBrandPrivateName());
     2771
     2772    emitPutToScope(scope, privateBrandVar, newSymbol, DoNotThrowIfNotFound, InitializationMode::Initialization);
     2773}
     2774
     2775void BytecodeGenerator::emitInstallPrivateBrand(RegisterID* target)
     2776{
     2777    Variable privateBrandVar = variable(propertyNames().builtinNames().privateBrandPrivateName());
     2778    RefPtr<RegisterID> privateBrandVarScope = emitResolveScope(nullptr, privateBrandVar);
     2779    RegisterID* privateBrandSymbol = emitGetPrivateBrand(newTemporary(), privateBrandVarScope.get());
     2780    OpSetPrivateBrand::emit(this, target, privateBrandSymbol);
     2781}
     2782
     2783RegisterID* BytecodeGenerator::emitGetPrivateBrand(RegisterID* dst, RegisterID* scope)
     2784{
     2785    Variable privateBrandVar = variable(propertyNames().builtinNames().privateBrandPrivateName());
     2786    return emitGetFromScope(dst, scope, privateBrandVar, ThrowIfNotFound);
     2787}
     2788
    27532789RegisterID* BytecodeGenerator::emitPrivateFieldPut(RegisterID* base, RegisterID* property, RegisterID* value)
    27542790{
    27552791    OpPutPrivateName::emit(this, base, property, value, PrivateFieldPutKind::set());
    27562792    return value;
     2793}
     2794
     2795void BytecodeGenerator::emitCheckPrivateBrand(RegisterID* base, RegisterID* brandSymbol)
     2796{
     2797    OpCheckPrivateBrand::emit(this, base, brandSymbol);
    27572798}
    27582799
     
    28892930        }
    28902931    }
     2932}
     2933
     2934bool BytecodeGenerator::isPrivateMethod(const Identifier& ident)
     2935{
     2936    for (unsigned i = m_privateNamesStack.size(); i--; ) {
     2937        auto& map = m_privateNamesStack[i];
     2938        auto it = map.find(ident.impl());
     2939        if (it != map.end())
     2940            return it->value.isMethod();
     2941    }
     2942
     2943    return false;
     2944}
     2945
     2946void BytecodeGenerator::pushPrivateAccessNames(const PrivateNameEnvironment* environment)
     2947{
     2948    if (!environment || !environment->size())
     2949        return;
     2950
     2951    m_privateNamesStack.append(*environment);
     2952}
     2953
     2954void BytecodeGenerator::popPrivateAccessNames()
     2955{
     2956    ASSERT(m_privateNamesStack.size());
     2957    m_privateNamesStack.removeLast();
    28912958}
    28922959
     
    29102977
    29112978    m_TDZStack.append(TDZStackEntry { WTFMove(map), nullptr });
     2979}
     2980
     2981Optional<PrivateNameEnvironment> BytecodeGenerator::getAvailablePrivateAccessNames()
     2982{
     2983    PrivateNameEnvironment result;
     2984    SmallPtrSet<UniquedStringImpl*, 16> excludedNames;
     2985    for (unsigned i = m_privateNamesStack.size(); i--; ) {
     2986        auto& map = m_privateNamesStack[i];
     2987        for (auto& entry : map)  {
     2988            if (entry.value.isPrivateMethodOrAcessor()) {
     2989                if (!excludedNames.contains(entry.key.get())) {
     2990                    result.add(entry.key, entry.value);
     2991                    excludedNames.add(entry.key.get());
     2992                }
     2993            } else
     2994                excludedNames.add(entry.key.get());
     2995        }
     2996    }
     2997
     2998    if (!result.size())
     2999        return WTF::nullopt;
     3000    return result;
    29123001}
    29133002
     
    31213210
    31223211RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name,
    3123     const Identifier& ecmaName, const SourceCode& classSource, NeedsClassFieldInitializer needsClassFieldInitializer)
    3124 {
    3125     UnlinkedFunctionExecutable* executable = m_vm.builtinExecutables()->createDefaultConstructor(constructorKind, name, needsClassFieldInitializer);
     3212    const Identifier& ecmaName, const SourceCode& classSource, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement)
     3213{
     3214    UnlinkedFunctionExecutable* executable = m_vm.builtinExecutables()->createDefaultConstructor(constructorKind, name, needsClassFieldInitializer, privateBrandRequirement);
    31263215    executable->setInvalidTypeProfilingOffsets();
    31273216    executable->setEcmaName(ecmaName);
     
    31473236
    31483237    auto variablesUnderTDZ = getVariablesUnderTDZ();
     3238    Optional<PrivateNameEnvironment> parentPrivateNameEnvironment = getAvailablePrivateAccessNames();
    31493239    SourceParseMode parseMode = SourceParseMode::ClassFieldInitializerMode;
    31503240    ConstructAbility constructAbility = ConstructAbility::CannotConstruct;
     
    31533243    FunctionMetadataNode metadata(parserArena(), JSTokenLocation(), JSTokenLocation(), 0, 0, 0, 0, 0, alwaysStrictInClass, ConstructorKind::None, superBinding, 0, parseMode, false);
    31543244    metadata.finishParsing(m_scopeNode->source(), Identifier(), FunctionMode::MethodDefinition);
    3155     auto initializer = UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), &metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, scriptMode(), WTFMove(variablesUnderTDZ), newDerivedContextType, NeedsClassFieldInitializer::No);
     3245    auto initializer = UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), &metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, scriptMode(), WTFMove(variablesUnderTDZ), WTFMove(parentPrivateNameEnvironment), newDerivedContextType, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None);
    31563246    initializer->setClassFieldLocations(WTFMove(classFieldLocations));
    31573247
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r270874 r272580  
    409409        typedef DeclarationStacks::FunctionStack FunctionStack;
    410410
    411         BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, ECMAMode);
    412         BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, ECMAMode);
    413         BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, ECMAMode);
    414         BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, ECMAMode);
     411        BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, const PrivateNameEnvironment*, ECMAMode);
     412        BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, const PrivateNameEnvironment*, ECMAMode);
     413        BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, const PrivateNameEnvironment*, ECMAMode);
     414        BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, OptionSet<CodeGenerationMode>, const RefPtr<TDZEnvironmentLink>&, const PrivateNameEnvironment*, ECMAMode);
    415415
    416416        ~BytecodeGenerator();
     
    426426        bool usesEval() const { return m_scopeNode->usesEval(); }
    427427        bool usesThis() const { return m_scopeNode->usesThis(); }
     428        PrivateBrandRequirement privateBrandRequirement() const { return m_codeBlock->privateBrandRequirement(); }
    428429        ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
    429430        SuperBinding superBinding() const { return m_codeBlock->superBinding(); }
     
    432433
    433434        template<typename Node, typename UnlinkedCodeBlock>
    434         static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, ECMAMode ecmaMode)
     435        static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment* privateNameEnvironment, ECMAMode ecmaMode)
    435436        {
    436437            MonotonicTime before;
     
    439440
    440441            DeferGC deferGC(vm.heap);
    441             auto bytecodeGenerator = makeUnique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, codeGenerationMode, parentScopeTDZVariables, ecmaMode);
     442            auto bytecodeGenerator = makeUnique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, codeGenerationMode, parentScopeTDZVariables, privateNameEnvironment, ecmaMode);
    442443            auto result = bytecodeGenerator->generate();
    443444
     
    775776        RegisterID* emitNewFunction(RegisterID* dst, FunctionMetadataNode*);
    776777        RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode*);
    777         RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name, const Identifier& ecmaName, const SourceCode& classSource, NeedsClassFieldInitializer);
     778        RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name, const Identifier& ecmaName, const SourceCode& classSource, NeedsClassFieldInitializer, PrivateBrandRequirement);
    778779        RegisterID* emitNewClassFieldInitializerFunction(RegisterID* dst, Vector<JSTextPosition>&& classFieldLocations, bool isDerived);
    779780        RegisterID* emitNewArrowFunctionExpression(RegisterID*, ArrowFuncExprNode*);
     
    816817        RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
    817818        RegisterID* emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value);
    818         RegisterID* emitDirectGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
    819819        RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
    820820        RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
     
    824824        RegisterID* emitDefinePrivateField(RegisterID* base, RegisterID* property, RegisterID* value);
    825825        RegisterID* emitPrivateFieldPut(RegisterID* base, RegisterID* property, RegisterID* value);
     826        RegisterID* emitGetPrivateName(RegisterID* dst, RegisterID* base, RegisterID* property);
     827
     828        void emitCreatePrivateBrand(RegisterID* dst, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
     829        void emitInstallPrivateBrand(RegisterID* target);
     830        RegisterID* emitGetPrivateBrand(RegisterID* dst, RegisterID* scope);
     831        void emitCheckPrivateBrand(RegisterID* base, RegisterID* brand);
    826832
    827833        void emitSuperSamplerBegin();
     
    11771183
    11781184            NeedsClassFieldInitializer needsClassFieldInitializer = metadata->isConstructorAndNeedsClassFieldInitializer() ? NeedsClassFieldInitializer::Yes : NeedsClassFieldInitializer::No;
     1185            PrivateBrandRequirement privateBrandRequirement = metadata->privateBrandRequirement();
    11791186            if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode, SourceParseMode::AsyncArrowFunctionBodyMode).contains(metadata->parseMode())) {
    11801187                if (constructorKind() == ConstructorKind::Extends || isDerivedConstructorContext()) {
    11811188                    newDerivedContextType = DerivedContextType::DerivedConstructorContext;
    11821189                    needsClassFieldInitializer = m_codeBlock->needsClassFieldInitializer();
     1190                    privateBrandRequirement = m_codeBlock->privateBrandRequirement();
    11831191                }
    11841192                else if (m_codeBlock->isClassContext() || isDerivedClassContext())
     
    11871195
    11881196            auto optionalVariablesUnderTDZ = getVariablesUnderTDZ();
     1197            Optional<PrivateNameEnvironment> parentPrivateNameEnvironment = getAvailablePrivateAccessNames();
    11891198
    11901199            // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
     
    11951204                constructAbility = ConstructAbility::CanConstruct;
    11961205
    1197             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, scriptMode(), WTFMove(optionalVariablesUnderTDZ), newDerivedContextType, needsClassFieldInitializer);
     1206            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, scriptMode(), WTFMove(optionalVariablesUnderTDZ), WTFMove(parentPrivateNameEnvironment), newDerivedContextType, needsClassFieldInitializer, privateBrandRequirement);
    11981207        }
    11991208
    12001209        RefPtr<TDZEnvironmentLink> getVariablesUnderTDZ();
     1210        Optional<PrivateNameEnvironment> getAvailablePrivateAccessNames();
    12011211
    12021212        RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
     
    12541264        }
    12551265
     1266        bool isPrivateMethod(const Identifier&);
     1267
     1268        void pushPrivateAccessNames(const PrivateNameEnvironment*);
     1269        void popPrivateAccessNames();
     1270
    12561271    private:
    12571272        OptionSet<CodeGenerationMode> m_codeGenerationMode;
     
    12671282        RefPtr<TDZEnvironmentLink> m_cachedParentTDZ;
    12681283        Vector<TDZStackEntry> m_TDZStack;
     1284        Vector<PrivateNameEnvironment> m_privateNamesStack;
    12691285        Optional<size_t> m_varScopeLexicalScopeStackIndex;
    12701286        void pushTDZVariables(const VariableEnvironment&, TDZCheckOptimization, TDZRequirement);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r272243 r272580  
    564564    for (PropertyListNode* p = this; p; p = p->m_next) {
    565565        const PropertyNode& node = *p->m_node;
    566         if (node.type() & PropertyNode::Private) {
     566        if (node.type() & PropertyNode::PrivateField) {
    567567            if (!createPrivateSymbol)
    568568                createPrivateSymbol = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::createPrivateSymbol);
     
    590590            emitSaveComputedFieldName(generator, *p->m_node);
    591591
    592         if (p->isInstanceClassField()) {
     592        if (p->isInstanceClassField() && !(p->m_node->type() & PropertyNode::PrivateMethod)) {
    593593            ASSERT(instanceFieldLocations);
    594594            instanceFieldLocations->append(p->position());
     
    758758{
    759759    // Private fields are handled in a synthetic classFieldInitializer function, not here.
    760     ASSERT(!(node.type() & PropertyNode::Private));
     760    ASSERT(!(node.type() & PropertyNode::PrivateField));
    761761
    762762    if (PropertyNode::isUnderscoreProtoSetter(generator.vm(), node)) {
     
    783783    if (node.isClassProperty()) {
    784784        ASSERT(node.needsSuperBinding());
     785
     786        if (node.type() & PropertyNode::PrivateMethod) {
     787            Variable var = generator.variable(*node.name());
     788            generator.emitPutToScope(generator.scopeRegister(), var, value.get(), DoNotThrowIfNotFound, InitializationMode::ConstInitialization);
     789            return;
     790        }
     791
     792        RefPtr<RegisterID> propertyNameRegister;
    785793        if (node.name())
    786794            propertyName = generator.emitLoad(nullptr, *node.name());
     
    911919RegisterID* BaseDotNode::emitGetPropertyValue(BytecodeGenerator& generator, RegisterID* dst, RegisterID* base, RefPtr<RegisterID>& thisValue)
    912920{
    913     if (isPrivateField()) {
     921    if (isPrivateMember()) {
     922        if (generator.isPrivateMethod(identifier())) {
     923            Variable var = generator.variable(identifier());
     924            RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     925
     926            RegisterID* privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
     927            generator.emitCheckPrivateBrand(base, privateBrandSymbol);
     928
     929            return generator.emitGetFromScope(dst, scope.get(), var, ThrowIfNotFound);
     930        }
     931
    914932        Variable var = generator.variable(m_ident);
    915933        ASSERT_WITH_MESSAGE(!var.local(), "Private Field names must be stored in captured variables");
     
    918936        RefPtr<RegisterID> privateName = generator.newTemporary();
    919937        generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound);
    920         return generator.emitDirectGetByVal(dst, base, privateName.get());
     938        return generator.emitGetPrivateName(dst, base, privateName.get());
    921939    }
    922940
     
    938956RegisterID* BaseDotNode::emitPutProperty(BytecodeGenerator& generator, RegisterID* base, RegisterID* value, RefPtr<RegisterID>& thisValue)
    939957{
    940     if (isPrivateField()) {
     958    if (isPrivateMember()) {
     959        auto identifierName = identifier();
     960        if (generator.isPrivateMethod(identifierName)) {
     961            Variable var = generator.variable(identifierName);
     962            RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     963
     964            RegisterID* privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());
     965            generator.emitCheckPrivateBrand(base, privateBrandSymbol);
     966
     967            generator.emitThrowTypeError("Trying to access a not defined private setter");
     968        }
     969
    941970        Variable var = generator.variable(m_ident);
    942971        ASSERT_WITH_MESSAGE(!var.local(), "Private Field names must be stored in captured variables");
     
    10961125
    10971126        // Initialize instance fields after super-call.
     1127        if (Options::usePrivateMethods() && generator.privateBrandRequirement() == PrivateBrandRequirement::Needed)
     1128            generator.emitInstallPrivateBrand(generator.thisRegister());
     1129
    10981130        if (generator.needsClassFieldInitializer() == NeedsClassFieldInitializer::Yes) {
    10991131            ASSERT(generator.isConstructor() || generator.isDerivedConstructorContext());
     
    11011133            generator.emitInstanceFieldInitializationIfNeeded(generator.thisRegister(), func.get(), divot(), divotStart(), divotEnd());
    11021134        }
    1103 
    11041135        return ret;
    11051136    }
     
    22552286    generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
    22562287
    2257     if (dotAccessor->isPrivateField()) {
     2288    if (dotAccessor->isPrivateMember()) {
    22582289        ASSERT(!baseIsSuper);
    22592290        Variable var = generator.variable(ident);
     
    22622293        generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound);
    22632294
    2264         RefPtr<RegisterID> value = generator.emitDirectGetByVal(generator.newTemporary(), base.get(), privateName.get());
     2295        RefPtr<RegisterID> value = generator.emitGetPrivateName(generator.newTemporary(), base.get(), privateName.get());
    22652296        RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
    22662297        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     
    24942525    generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
    24952526    RegisterID* value;
    2496     if (dotAccessor->isPrivateField()) {
     2527    if (dotAccessor->isPrivateMember()) {
    24972528        ASSERT(!baseNode->isSuperNode());
    24982529        Variable var = generator.variable(ident);
     
    25012532        generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound);
    25022533
    2503         value = generator.emitDirectGetByVal(propDst.get(), base.get(), privateName.get());
     2534        value = generator.emitGetPrivateName(propDst.get(), base.get(), privateName.get());
    25042535        emitIncOrDec(generator, value, m_operator);
    25052536        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     
    49164947        generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
    49174948
     4949    bool hasPrivateNames = !!m_lexicalVariables.privateNamesSize();
     4950    bool shouldEmitPrivateBrand = m_lexicalVariables.hasPrivateMethodOrAccessor();
     4951    if (hasPrivateNames)
     4952        generator.pushPrivateAccessNames(m_lexicalVariables.privateNameEnvironment());
     4953    if (shouldEmitPrivateBrand)
     4954        generator.emitCreatePrivateBrand(generator.scopeRegister(), m_position, m_position, m_position);
     4955
    49184956    RefPtr<RegisterID> superclass;
    49194957    if (m_classHeritage) {
     
    49264964
    49274965    auto needsClassFieldInitializer = this->hasInstanceFields() ? NeedsClassFieldInitializer::Yes : NeedsClassFieldInitializer::No;
    4928 
     4966    auto privateBrandRequirement = shouldEmitPrivateBrand ? PrivateBrandRequirement::Needed : PrivateBrandRequirement::None;
    49294967    if (m_constructorExpression) {
    49304968        ASSERT(m_constructorExpression->isFuncExprNode());
     
    49334971        metadata->setClassSource(m_classSource);
    49344972        metadata->setNeedsClassFieldInitializer(needsClassFieldInitializer == NeedsClassFieldInitializer::Yes);
     4973        metadata->setPrivateBrandRequirement(privateBrandRequirement);
    49354974        constructor = generator.emitNode(constructor.get(), m_constructorExpression);
    49364975        needsHomeObject = m_classHeritage || metadata->superBinding() == SuperBinding::Needed;
    49374976    } else
    4938         constructor = generator.emitNewDefaultConstructor(constructor.get(), m_classHeritage ? ConstructorKind::Extends : ConstructorKind::Base, m_name, ecmaName(), m_classSource, needsClassFieldInitializer);
     4977        constructor = generator.emitNewDefaultConstructor(constructor.get(), m_classHeritage ? ConstructorKind::Extends : ConstructorKind::Base, m_name, ecmaName(), m_classSource, needsClassFieldInitializer, privateBrandRequirement);
    49394978
    49404979    const auto& propertyNames = generator.propertyNames();
     
    50145053    if (m_needsLexicalScope)
    50155054        generator.popLexicalScope(this);
     5055
     5056    if (hasPrivateNames)
     5057        generator.popPrivateAccessNames();
    50165058
    50175059    return generator.move(generator.finalDestination(dst, constructor.get()), constructor.get());
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r269115 r272580  
    260260
    261261    TDZEnvironment variablesUnderTDZ;
    262     VariableEnvironment privateNames;
    263     JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ, privateNames);
     262    PrivateNameEnvironment privateNameEnvironment;
     263    JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ, privateNameEnvironment);
    264264
    265265    ECMAMode ecmaMode = codeBlock->ownerExecutable()->isInStrictContext() ? ECMAMode::strict() : ECMAMode::sloppy();
    266     auto* eval = DirectEvalExecutable::create(globalObject, makeSource(script, callFrame->callerSourceOrigin(vm)), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->needsClassFieldInitializer(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), codeBlock->ownerExecutable()->isInsideOrdinaryFunction(), evalContextType, &variablesUnderTDZ, &privateNames, ecmaMode);
     266    auto* eval = DirectEvalExecutable::create(globalObject, makeSource(script, callFrame->callerSourceOrigin(vm)), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->needsClassFieldInitializer(), codeBlock->unlinkedCodeBlock()->privateBrandRequirement(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), codeBlock->ownerExecutable()->isInsideOrdinaryFunction(), evalContextType, &variablesUnderTDZ, &privateNameEnvironment, ecmaMode);
    267267    if (UNLIKELY(catchScope.exception())) {
    268268        exception = catchScope.exception();
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r272405 r272580  
    3131#include "ArrayPrototype.h"
    3232#include "CacheableIdentifierInlines.h"
     33#include "CheckPrivateBrandStatus.h"
    3334#include "DFGAbstractInterpreter.h"
    3435#include "DFGAbstractInterpreterClobberState.h"
     
    4849#include "NumberConstructor.h"
    4950#include "PutByIdStatus.h"
     51#include "SetPrivateBrandStatus.h"
    5052#include "StringObject.h"
    5153#include "StructureCache.h"
     
    40804082    }
    40814083
     4084    case CheckPrivateBrand:
     4085    case SetPrivateBrand:
    40824086    case PutPrivateName: {
    40834087        clobberWorld();
     
    44104414    case FilterInByIdStatus:
    44114415    case FilterDeleteByStatus:
     4416    case FilterCheckPrivateBrandStatus:
     4417    case FilterSetPrivateBrandStatus:
    44124418    case ClearCatchLocals:
    44134419        break;
     
    45974603        break;
    45984604    }
     4605
     4606    case FilterCheckPrivateBrandStatus: {
     4607        AbstractValue& value = forNode(node->child1());
     4608        if (value.m_structure.isFinite())
     4609            node->checkPrivateBrandStatus()->filter(value.m_structure.toStructureSet());
     4610        break;
     4611    }
     4612
     4613    case FilterSetPrivateBrandStatus: {
     4614        AbstractValue& value = forNode(node->child1());
     4615        if (value.m_structure.isFinite())
     4616            node->setPrivateBrandStatus()->filter(value.m_structure.toStructureSet());
     4617        break;
     4618    }
     4619
    45994620
    46004621    default:
  • trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp

    r264488 r272580  
    407407                case FilterInByIdStatus:
    408408                case FilterDeleteByStatus:
     409                case FilterCheckPrivateBrandStatus:
     410                case FilterSetPrivateBrandStatus:
    409411                    break;
    410412
     
    12671269                case FilterCallLinkStatus:
    12681270                case FilterInByIdStatus:
    1269                 case FilterDeleteByStatus: {
     1271                case FilterDeleteByStatus:
     1272                case FilterCheckPrivateBrandStatus:
     1273                case FilterSetPrivateBrandStatus: {
    12701274                    if (!isEliminatedAllocation(node->child1().node()))
    12711275                        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r272349 r272580  
    3838#include "CacheableIdentifierInlines.h"
    3939#include "CallLinkStatus.h"
     40#include "CheckPrivateBrandStatus.h"
    4041#include "CodeBlock.h"
    4142#include "CodeBlockWithJITType.h"
     
    7576#include "PutByIdStatus.h"
    7677#include "RegExpPrototype.h"
     78#include "SetPrivateBrandStatus.h"
    7779#include "StackAlignment.h"
    7880#include "StringConstructor.h"
     
    62606262
    62616263            NEXT_OPCODE(op_put_by_val_with_this);
     6264        }
     6265
     6266        case op_check_private_brand: {
     6267            auto bytecode = currentInstruction->as<OpCheckPrivateBrand>();
     6268            Node* base = get(bytecode.m_base);
     6269            Node* brand = get(bytecode.m_brand);
     6270            bool compiledAsCheckStructure = false;
     6271
     6272            CheckPrivateBrandStatus checkStatus = CheckPrivateBrandStatus::computeFor(
     6273                m_inlineStackTop->m_profiledBlock,
     6274                m_inlineStackTop->m_baselineMap, m_icContextStack,
     6275                currentCodeOrigin());
     6276
     6277            if (!m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
     6278                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
     6279                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantValue)) {
     6280
     6281                if (CacheableIdentifier identifier = checkStatus.singleIdentifier()) {
     6282                    m_graph.identifiers().ensure(identifier.uid());
     6283                    ASSERT(identifier.isSymbol());
     6284                    FrozenValue* frozen = m_graph.freezeStrong(identifier.cell());
     6285                    addToGraph(CheckIsConstant, OpInfo(frozen), brand);
     6286
     6287                    if (checkStatus.isSimple() && checkStatus.variants().size() && Options::useAccessInlining()) {
     6288                        ASSERT(checkStatus.variants().size() == 1); // If we have single identifier, we should have only 1 variant.
     6289                        CheckPrivateBrandVariant variant = checkStatus.variants()[0];
     6290
     6291                        addToGraph(FilterCheckPrivateBrandStatus, OpInfo(m_graph.m_plan.recordedStatuses().addCheckPrivateBrandStatus(currentCodeOrigin(), checkStatus)), base);
     6292                        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base);
     6293
     6294                        compiledAsCheckStructure = true;
     6295                    }
     6296                }
     6297            }
     6298
     6299            if (!compiledAsCheckStructure)
     6300                addToGraph(CheckPrivateBrand, base, brand);
     6301
     6302            NEXT_OPCODE(op_check_private_brand);
     6303        }
     6304
     6305        case op_set_private_brand: {
     6306            auto bytecode = currentInstruction->as<OpSetPrivateBrand>();
     6307            Node* base = get(bytecode.m_base);
     6308            Node* brand = get(bytecode.m_brand);
     6309
     6310            bool inlinedSetPrivateBrand = false;
     6311            SetPrivateBrandStatus setStatus = SetPrivateBrandStatus::computeFor(
     6312                m_inlineStackTop->m_profiledBlock,
     6313                m_inlineStackTop->m_baselineMap, m_icContextStack,
     6314                currentCodeOrigin());
     6315
     6316            if (!m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent)
     6317                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
     6318                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantValue)) {
     6319
     6320                if (CacheableIdentifier identifier = setStatus.singleIdentifier()) {
     6321                    ASSERT(identifier.isSymbol());
     6322                    FrozenValue* frozen = m_graph.freezeStrong(identifier.cell());
     6323                    addToGraph(CheckIsConstant, OpInfo(frozen), brand);
     6324
     6325
     6326                    // FIXME: We should include a MultiSetPrivateBrand to handle polymorphic cases
     6327                    // https://bugs.webkit.org/show_bug.cgi?id=221570
     6328                    if (setStatus.isSimple() && setStatus.variants().size() == 1 && Options::useAccessInlining()) {
     6329                        SetPrivateBrandVariant variant = setStatus.variants()[0];
     6330
     6331                        addToGraph(FilterSetPrivateBrandStatus, OpInfo(m_graph.m_plan.recordedStatuses().addSetPrivateBrandStatus(currentCodeOrigin(), setStatus)), base);
     6332                        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
     6333                        ASSERT(variant.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
     6334                        ASSERT(variant.newStructure());
     6335
     6336                        Transition* transition = m_graph.m_transitions.add(
     6337                            m_graph.registerStructure(variant.oldStructure()), m_graph.registerStructure(variant.newStructure()));
     6338
     6339                        addToGraph(PutStructure, OpInfo(transition), base);
     6340
     6341                        inlinedSetPrivateBrand = true;
     6342                    }
     6343                }
     6344            }
     6345
     6346            if (!inlinedSetPrivateBrand)
     6347                addToGraph(SetPrivateBrand, base, brand);
     6348
     6349            NEXT_OPCODE(op_set_private_brand);
    62626350        }
    62636351
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r270874 r272580  
    295295    case op_get_private_name:
    296296    case op_put_private_name:
     297    case op_set_private_brand:
     298    case op_check_private_brand:
    297299        return CanCompileAndInline;
    298300
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r272170 r272580  
    506506    case FilterInByIdStatus:
    507507    case FilterDeleteByStatus:
     508    case FilterCheckPrivateBrandStatus:
     509    case FilterSetPrivateBrandStatus:
    508510        write(SideState);
    509511        return;
     
    678680    case GetPrivateName:
    679681    case GetPrivateNameById:
     682    // FIXME: We should have a better cloberize rule for both CheckPrivateBrand and SetPrivateBrand
     683    // https://bugs.webkit.org/show_bug.cgi?id=221571
     684    case CheckPrivateBrand:
     685    case SetPrivateBrand:
    680686    case DefineDataProperty:
    681687    case DefineAccessorProperty:
  • trunk/Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp

    r266095 r272580  
    8585    case FilterInByIdStatus:
    8686    case FilterDeleteByStatus:
     87    case FilterCheckPrivateBrandStatus:
     88    case FilterSetPrivateBrandStatus:
    8789    case TryGetById:
    8890        // These do clobber memory, but nothing that is observable. It may be nice to separate the
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r270874 r272580  
    251251    case FilterInByIdStatus:
    252252    case FilterDeleteByStatus:
     253    case FilterCheckPrivateBrandStatus:
     254    case FilterSetPrivateBrandStatus:
    253255    case DateGetInt32OrNaN:
    254256    case DateGetTime:
     
    328330    case GetPrivateName:
    329331    case GetPrivateNameById:
     332    case SetPrivateBrand:
     333    case CheckPrivateBrand:
    330334    case PutStack:
    331335    case PutToArguments:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r272405 r272580  
    19741974
    19751975
     1976        case SetPrivateBrand: {
     1977            fixEdge<CellUse>(node->child1());
     1978            fixEdge<SymbolUse>(node->child2());
     1979            break;
     1980        }
     1981
     1982        case CheckPrivateBrand:
    19761983        case PutPrivateName: {
    19771984            fixEdge<SymbolUse>(node->child2());
     
    28702877        case FilterInByIdStatus:
    28712878        case FilterDeleteByStatus:
     2879        case FilterCheckPrivateBrandStatus:
     2880        case FilterSetPrivateBrandStatus:
    28722881        case InvalidationPoint:
    28732882        case CreateArgumentsButterfly:
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r268077 r272580  
    246246    finalizeInlineCaches(m_inByIds, linkBuffer);
    247247    finalizeInlineCaches(m_instanceOfs, linkBuffer);
     248    finalizeInlineCaches(m_privateBrandAccesses, linkBuffer);
    248249
    249250    auto linkCallThunk = FunctionPtr<NoPtrTag>(vm().getCTIStub(linkCallThunkGenerator).retaggedCode<NoPtrTag>());
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r271422 r272580  
    213213    }
    214214
     215    void addPrivateBrandAccess(const JITPrivateBrandAccessGenerator& gen, SlowPathGenerator* slowPath)
     216    {
     217        m_privateBrandAccesses.append(InlineCacheWrapper<JITPrivateBrandAccessGenerator>(gen, slowPath));
     218    }
     219
    215220    void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo* info)
    216221    {
     
    363368    Vector<InlineCacheWrapper<JITInByIdGenerator>, 4> m_inByIds;
    364369    Vector<InlineCacheWrapper<JITInstanceOfGenerator>, 4> m_instanceOfs;
     370    Vector<InlineCacheWrapper<JITPrivateBrandAccessGenerator>, 4> m_privateBrandAccesses;
    365371    Vector<JSCallRecord, 4> m_jsCalls;
    366372    Vector<JSDirectCallRecord, 4> m_jsDirectCalls;
  • trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp

    r266095 r272580  
    109109    case FilterInByIdStatus:
    110110    case FilterDeleteByStatus:
     111    case FilterCheckPrivateBrandStatus:
     112    case FilterSetPrivateBrandStatus:
    111113        break;
    112114
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r270874 r272580  
    3030#include "B3SparseCollection.h"
    3131#include "BasicBlockLocation.h"
     32#include "CheckPrivateBrandVariant.h"
    3233#include "CodeBlock.h"
    3334#include "DFGAdjacencyList.h"
     
    5556#include "PrivateFieldPutKind.h"
    5657#include "PutByIdVariant.h"
     58#include "SetPrivateBrandVariant.h"
    5759#include "SpeculatedType.h"
    5860#include "TypeLocation.h"
     
    31413143    }
    31423144
     3145    bool hasCheckPrivateBrandStatus()
     3146    {
     3147        return op() == FilterCheckPrivateBrandStatus;
     3148    }
     3149
     3150    CheckPrivateBrandStatus* checkPrivateBrandStatus()
     3151    {
     3152        ASSERT(hasCheckPrivateBrandStatus());
     3153        return m_opInfo.as<CheckPrivateBrandStatus*>();
     3154    }
     3155
     3156    bool hasSetPrivateBrandStatus()
     3157    {
     3158        return op() == FilterSetPrivateBrandStatus;
     3159    }
     3160
     3161    SetPrivateBrandStatus* setPrivateBrandStatus()
     3162    {
     3163        ASSERT(hasSetPrivateBrandStatus());
     3164        return m_opInfo.as<SetPrivateBrandStatus*>();
     3165    }
     3166
    31433167    void dumpChildren(PrintStream& out)
    31443168    {
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r270874 r272580  
    213213    macro(PutPrivateName, NodeMustGenerate) \
    214214    macro(PutPrivateNameById, NodeMustGenerate) \
     215    macro(CheckPrivateBrand, NodeMustGenerate) \
     216    macro(SetPrivateBrand, NodeMustGenerate) \
    215217    macro(TryGetById, NodeResultJS) \
    216218    macro(GetById, NodeResultJS | NodeMustGenerate) \
     
    545547    macro(FilterPutByIdStatus, NodeMustGenerate) \
    546548    macro(FilterDeleteByStatus, NodeMustGenerate) \
     549    macro(FilterCheckPrivateBrandStatus, NodeMustGenerate) \
     550    macro(FilterSetPrivateBrandStatus, NodeMustGenerate) \
    547551    /* Data view access */ \
    548552    macro(DataViewGetInt, NodeMustGenerate | NodeResultJS) /* The gets are must generate for now because they do bounds checks */ \
  • trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp

    r267114 r272580  
    12621262        case FilterInByIdStatus:
    12631263        case FilterDeleteByStatus:
     1264        case FilterCheckPrivateBrandStatus:
     1265        case FilterSetPrivateBrandStatus:
    12641266            break;
    12651267
     
    26122614                case FilterInByIdStatus:
    26132615                case FilterDeleteByStatus:
     2616                case FilterCheckPrivateBrandStatus:
     2617                case FilterSetPrivateBrandStatus:
    26142618                    if (node->child1()->isPhantomAllocation())
    26152619                        node->removeWithoutChecks();
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r272170 r272580  
    13891389        case PutPrivateName:
    13901390        case PutPrivateNameById:
     1391        case SetPrivateBrand:
     1392        case CheckPrivateBrand:
    13911393        case PutClosureVar:
    13921394        case PutInternalField:
     
    14551457        case FilterInByIdStatus:
    14561458        case FilterDeleteByStatus:
     1459        case FilterCheckPrivateBrandStatus:
     1460        case FilterSetPrivateBrandStatus:
    14571461        case ClearCatchLocals:
    14581462        case DataViewSet:
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r270874 r272580  
    363363    case FilterInByIdStatus:
    364364    case FilterDeleteByStatus:
     365    case FilterCheckPrivateBrandStatus:
     366    case FilterSetPrivateBrandStatus:
    365367        // We don't want these to be moved anywhere other than where we put them, since we want them
    366368        // to capture "profiling" at the point in control flow here the user put them.
     
    533535    case GetPrivateName:
    534536    case GetPrivateNameById:
     537    case CheckPrivateBrand:
     538    case SetPrivateBrand:
    535539    case DefineDataProperty:
    536540    case DefineAccessorProperty:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r272405 r272580  
    36893689    auto putKind = node->privateFieldPutKind().isDefine() ? PutKind::DirectPrivateFieldDefine : PutKind::DirectPrivateFieldSet;
    36903690    cachedPutById(node->origin.semantic, baseGPR, valueRegs, scratchGPR, node->cacheableIdentifier(), putKind, ECMAMode::strict());
     3691
     3692    noResult(node);
     3693}
     3694
     3695void SpeculativeJIT::compileCheckPrivateBrand(Node* node)
     3696{
     3697    JSValueOperand base(this, node->child1());
     3698    SpeculateCellOperand brandValue(this, node->child2());
     3699
     3700    JSValueRegs baseRegs = base.jsValueRegs();
     3701
     3702    GPRReg brandGPR = brandValue.gpr();
     3703
     3704    speculateSymbol(node->child2(), brandGPR);
     3705
     3706    CodeOrigin codeOrigin = node->origin.semantic;
     3707    CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
     3708    RegisterSet usedRegisters = this->usedRegisters();
     3709
     3710    JITCompiler::JumpList slowCases;
     3711    if (needsTypeCheck(node->child1(), SpecCell))
     3712        slowCases.append(m_jit.branchIfNotCell(baseRegs));
     3713
     3714    JITPrivateBrandAccessGenerator gen(
     3715        m_jit.codeBlock(), codeOrigin, callSite, AccessType::CheckPrivateBrand, usedRegisters,
     3716        baseRegs, JSValueRegs::payloadOnly(brandGPR));
     3717
     3718    gen.stubInfo()->propertyIsSymbol = true;
     3719    gen.generateFastPath(m_jit);
     3720    slowCases.append(gen.slowPathJump());
     3721
     3722    std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall(
     3723        slowCases, this, operationCheckPrivateBrandOptimize, NoResult,
     3724        TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), baseRegs, CCallHelpers::CellValue(brandGPR));
     3725
     3726    m_jit.addPrivateBrandAccess(gen, slowPath.get());
     3727    addSlowPathGenerator(WTFMove(slowPath));
     3728
     3729    noResult(node);
     3730}
     3731
     3732void SpeculativeJIT::compileSetPrivateBrand(Node* node)
     3733{
     3734    ASSERT(node->child1().useKind() == CellUse);
     3735    SpeculateCellOperand base(this, node->child1());
     3736    SpeculateCellOperand brandValue(this, node->child2());
     3737
     3738    GPRReg baseGPR = base.gpr();
     3739    GPRReg brandGPR = brandValue.gpr();
     3740
     3741    speculateSymbol(node->child2(), brandGPR);
     3742
     3743    CodeOrigin codeOrigin = node->origin.semantic;
     3744    CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
     3745    RegisterSet usedRegisters = this->usedRegisters();
     3746
     3747    JITCompiler::JumpList slowCases;
     3748    JITPrivateBrandAccessGenerator gen(
     3749        m_jit.codeBlock(), codeOrigin, callSite, AccessType::SetPrivateBrand, usedRegisters,
     3750        JSValueRegs::payloadOnly(baseGPR), JSValueRegs::payloadOnly(brandGPR));
     3751
     3752    gen.stubInfo()->propertyIsSymbol = true;
     3753    gen.generateFastPath(m_jit);
     3754    slowCases.append(gen.slowPathJump());
     3755
     3756    std::unique_ptr<SlowPathGenerator> slowPath = slowPathCall(
     3757        slowCases, this, operationSetPrivateBrandOptimize, NoResult,
     3758        TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(codeOrigin)), gen.stubInfo(), CCallHelpers::CellValue(baseGPR), CCallHelpers::CellValue(brandGPR));
     3759
     3760    m_jit.addPrivateBrandAccess(gen, slowPath.get());
     3761    addSlowPathGenerator(WTFMove(slowPath));
    36913762
    36923763    noResult(node);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r272405 r272580  
    13741374    void compilePutPrivateName(Node*);
    13751375    void compilePutPrivateNameById(Node*);
     1376    void compileCheckPrivateBrand(Node*);
     1377    void compileSetPrivateBrand(Node*);
    13761378    void compileGetByOffset(Node*);
    13771379    void compilePutByOffset(Node*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r270874 r272580  
    26072607    }
    26082608
     2609    case CheckPrivateBrand: {
     2610        compileCheckPrivateBrand(node);
     2611        break;
     2612    }
     2613
     2614    case SetPrivateBrand: {
     2615        compileSetPrivateBrand(node);
     2616        break;
     2617    }
     2618
    26092619    case PutByValDirect:
    26102620    case PutByVal:
     
    42424252    case FilterInByIdStatus:
    42434253    case FilterDeleteByStatus:
     4254    case FilterCheckPrivateBrandStatus:
     4255    case FilterSetPrivateBrandStatus:
    42444256        m_interpreter.filterICStatus(node);
    42454257        noResult(node);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r272405 r272580  
    29642964    case PutPrivateNameById: {
    29652965        compilePutPrivateNameById(node);
     2966        break;
     2967    }
     2968
     2969    case CheckPrivateBrand: {
     2970        compileCheckPrivateBrand(node);
     2971        break;
     2972    }
     2973
     2974    case SetPrivateBrand: {
     2975        compileSetPrivateBrand(node);
    29662976        break;
    29672977    }
     
    56885698    case FilterInByIdStatus:
    56895699    case FilterDeleteByStatus:
     5700    case FilterCheckPrivateBrandStatus:
     5701    case FilterSetPrivateBrandStatus:
    56905702        m_interpreter.filterICStatus(node);
    56915703        noResult(node);
  • trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp

    r267489 r272580  
    274274            }
    275275
     276            case SetPrivateBrand:
    276277            case PutById:
    277278            case PutByIdFlush:
  • trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp

    r266095 r272580  
    200200            case FilterInByIdStatus:
    201201            case FilterDeleteByStatus:
     202            case FilterCheckPrivateBrandStatus:
     203            case FilterSetPrivateBrandStatus:
    202204                break;
    203205
     
    403405            case FilterInByIdStatus:
    404406            case FilterDeleteByStatus:
     407            case FilterCheckPrivateBrandStatus:
     408            case FilterSetPrivateBrandStatus:
    405409                if (node->child1().node() == candidate)
    406410                    node->remove(m_graph);
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r270874 r272580  
    401401    case GetPrivateName:
    402402    case GetPrivateNameById:
     403    case CheckPrivateBrand:
     404    case SetPrivateBrand:
    403405    case MatchStructure:
    404406    case FilterCallLinkStatus:
     
    407409    case FilterInByIdStatus:
    408410    case FilterDeleteByStatus:
     411    case FilterCheckPrivateBrandStatus:
     412    case FilterSetPrivateBrandStatus:
    409413    case CreateThis:
    410414    case CreatePromise:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r272405 r272580  
    962962            compileInByVal();
    963963            break;
     964        case CheckPrivateBrand:
     965            compileCheckPrivateBrand();
     966            break;
     967        case SetPrivateBrand:
     968            compileSetPrivateBrand();
     969            break;
    964970        case HasOwnProperty:
    965971            compileHasOwnProperty();
     
    16391645        case FilterInByIdStatus:
    16401646        case FilterDeleteByStatus:
     1647        case FilterCheckPrivateBrandStatus:
     1648        case FilterSetPrivateBrandStatus:
    16411649            compileFilterICStatus();
    16421650            break;
     
    40824090            setJSValue(m_out.phi(Int64, cellResult, notCellResult));
    40834091        }
     4092    }
     4093
     4094    void compilePrivateBrandAccess(LValue base, LValue brand, AccessType accessType)
     4095    {
     4096        Node* node = m_node;
     4097        PatchpointValue* patchpoint = m_out.patchpoint(Void);
     4098        patchpoint->appendSomeRegister(base);
     4099        patchpoint->appendSomeRegister(brand);
     4100        patchpoint->append(m_notCellMask, ValueRep::lateReg(GPRInfo::notCellMaskRegister));
     4101        patchpoint->append(m_numberTag, ValueRep::lateReg(GPRInfo::numberTagRegister));
     4102        patchpoint->clobber(RegisterSet::macroScratchRegisters());
     4103
     4104        RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
     4105
     4106        State* state = &m_ftlState;
     4107        bool baseIsCell = abstractValue(m_node->child1()).isType(SpecCell);
     4108        patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     4109            AllowMacroScratchRegisterUsage allowScratch(jit);
     4110
     4111            CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
     4112
     4113            // This is the direct exit target for operation calls.
     4114            Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit);
     4115
     4116            // This is the exit for call IC's created by the IC for getters. We don't have
     4117            // to do anything weird other than call this, since it will associate the exit with
     4118            // the callsite index.
     4119            exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
     4120
     4121            GPRReg baseGPR = params[0].gpr();
     4122            GPRReg brandGPR = params[1].gpr();
     4123
     4124            auto generator = Box<JITPrivateBrandAccessGenerator>::create(
     4125                jit.codeBlock(), node->origin.semantic, callSiteIndex, accessType,
     4126                params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(brandGPR));
     4127
     4128            CCallHelpers::Jump notCell;
     4129            if (!baseIsCell)
     4130                notCell = jit.branchIfNotCell(baseGPR);
     4131
     4132            generator->generateFastPath(jit);
     4133            CCallHelpers::Label done = jit.label();
     4134
     4135            params.addLatePath([=] (CCallHelpers& jit) {
     4136                AllowMacroScratchRegisterUsage allowScratch(jit);
     4137
     4138                auto appropriatePrivateAccessFunction = [=] (AccessType type) -> decltype(&operationCheckPrivateBrandOptimize) {
     4139                    switch (type) {
     4140                    case AccessType::CheckPrivateBrand:
     4141                        return operationCheckPrivateBrandOptimize;
     4142                    case AccessType::SetPrivateBrand:
     4143                        return operationSetPrivateBrandOptimize;
     4144                    default:
     4145                        RELEASE_ASSERT_NOT_REACHED();
     4146                        return nullptr;
     4147                    }
     4148                };
     4149
     4150                if (notCell.isSet())
     4151                    notCell.link(&jit);
     4152                generator->slowPathJump().link(&jit);
     4153                CCallHelpers::Label slowPathBegin = jit.label();
     4154                CCallHelpers::Call slowPathCall = callOperation(
     4155                    *state, params.unavailableRegisters(), jit, node->origin.semantic,
     4156                    exceptions.get(), appropriatePrivateAccessFunction(accessType), InvalidGPRReg,
     4157                    jit.codeBlock()->globalObjectFor(node->origin.semantic),
     4158                    CCallHelpers::TrustedImmPtr(generator->stubInfo()), baseGPR, brandGPR).call();
     4159                jit.jump().linkTo(done, &jit);
     4160
     4161                generator->reportSlowPathCall(slowPathBegin, slowPathCall);
     4162
     4163                jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     4164                    generator->finalize(linkBuffer, linkBuffer);
     4165                });
     4166            });
     4167        });
     4168    }
     4169
     4170    void compileCheckPrivateBrand()
     4171    {
     4172        compilePrivateBrandAccess(lowJSValue(m_node->child1()), lowSymbol(m_node->child2()), AccessType::CheckPrivateBrand);
     4173    }
     4174
     4175    void compileSetPrivateBrand()
     4176    {
     4177        DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == CellUse, m_node->child1().useKind());
     4178        compilePrivateBrandAccess(lowCell(m_node->child1()), lowSymbol(m_node->child2()), AccessType::SetPrivateBrand);
    40844179    }
    40854180
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r269922 r272580  
    145145       
    146146        TDZEnvironment variablesUnderTDZ;
    147         VariableEnvironment privateNames;
    148         JSScope::collectClosureVariablesUnderTDZ(callerScopeChain, variablesUnderTDZ, privateNames);
    149         eval = DirectEvalExecutable::create(globalObject, makeSource(programSource, callerCodeBlock->source().provider()->sourceOrigin()), derivedContextType, callerUnlinkedCodeBlock->needsClassFieldInitializer(), isArrowFunctionContext, callerCodeBlock->ownerExecutable()->isInsideOrdinaryFunction(), evalContextType, &variablesUnderTDZ, &privateNames, ecmaMode);
     147        PrivateNameEnvironment privateNameEnvironment;
     148        JSScope::collectClosureVariablesUnderTDZ(callerScopeChain, variablesUnderTDZ, privateNameEnvironment);
     149        eval = DirectEvalExecutable::create(globalObject, makeSource(programSource, callerCodeBlock->source().provider()->sourceOrigin()), derivedContextType, callerUnlinkedCodeBlock->needsClassFieldInitializer(), callerUnlinkedCodeBlock->privateBrandRequirement(), isArrowFunctionContext, callerCodeBlock->ownerExecutable()->isInsideOrdinaryFunction(), evalContextType, &variablesUnderTDZ, &privateNameEnvironment, ecmaMode);
    150150        EXCEPTION_ASSERT(!!scope.exception() == !eval);
    151151        if (!eval)
  • trunk/Source/JavaScriptCore/jit/ICStats.h

    r268794 r272580  
    7676    macro(OperationGetPrivateNameById) \
    7777    macro(OperationGetPrivateNameByIdOptimize) \
    78     macro(OperationGetPrivateNameByIdGeneric)
     78    macro(OperationGetPrivateNameByIdGeneric) \
     79    macro(CheckPrivateBrandAddAccessCase) \
     80    macro(SetPrivateBrandAddAccessCase) \
     81    macro(CheckPrivateBrandReplaceWithJump) \
     82    macro(SetPrivateBrandReplaceWithJump)
    7983
    8084class ICEvent {
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r271279 r272580  
    359359        DEFINE_OP(op_get_by_val)
    360360        DEFINE_OP(op_get_private_name)
     361        DEFINE_OP(op_set_private_brand)
     362        DEFINE_OP(op_check_private_brand)
    361363        DEFINE_OP(op_get_prototype_of)
    362364        DEFINE_OP(op_overrides_has_instance)
     
    509511    m_delByIdIndex = 0;
    510512    m_instanceOfIndex = 0;
     513    m_privateBrandAccessIndex = 0;
    511514    m_byValInstructionIndex = 0;
    512515    m_callLinkInfoIndex = 0;
     
    565568        DEFINE_SLOWCASE_OP(op_get_by_val)
    566569        DEFINE_SLOWCASE_OP(op_get_private_name)
     570        DEFINE_SLOWCASE_OP(op_set_private_brand)
     571        DEFINE_SLOWCASE_OP(op_check_private_brand)
    567572        DEFINE_SLOWCASE_OP(op_instanceof)
    568573        DEFINE_SLOWCASE_OP(op_instanceof_custom)
     
    655660    RELEASE_ASSERT(m_inByIdIndex == m_inByIds.size());
    656661    RELEASE_ASSERT(m_instanceOfIndex == m_instanceOfs.size());
     662    RELEASE_ASSERT(m_privateBrandAccessIndex == m_privateBrandAccesses.size());
    657663    RELEASE_ASSERT(m_callLinkInfoIndex == m_callCompilationInfo.size());
    658664
     
    903909    finalizeInlineCaches(m_inByIds, patchBuffer);
    904910    finalizeInlineCaches(m_instanceOfs, patchBuffer);
     911    finalizeInlineCaches(m_privateBrandAccesses, patchBuffer);
    905912
    906913    if (m_byValCompilationInfo.size()) {
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r270874 r272580  
    564564        void emit_op_get_by_val(const Instruction*);
    565565        void emit_op_get_private_name(const Instruction*);
     566        void emit_op_set_private_brand(const Instruction*);
     567        void emit_op_check_private_brand(const Instruction*);
    566568        void emit_op_get_argument_by_val(const Instruction*);
    567569        void emit_op_get_prototype_of(const Instruction*);
     
    696698        void emitSlow_op_get_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
    697699        void emitSlow_op_get_private_name(const Instruction*, Vector<SlowCaseEntry>::iterator&);
     700        void emitSlow_op_set_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
     701        void emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator&);
    698702        void emitSlow_op_get_argument_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
    699703        void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
     
    986990        Vector<JITDelByValGenerator> m_delByVals;
    987991        Vector<JITInstanceOfGenerator> m_instanceOfs;
     992        Vector<JITPrivateBrandAccessGenerator> m_privateBrandAccesses;
    988993        Vector<ByValCompilationInfo> m_byValCompilationInfo;
    989994        Vector<CallCompilationInfo> m_callCompilationInfo;
     
    10091014        unsigned m_delByIdIndex { UINT_MAX };
    10101015        unsigned m_instanceOfIndex { UINT_MAX };
     1016        unsigned m_privateBrandAccessIndex { UINT_MAX };
    10111017        unsigned m_byValInstructionIndex { UINT_MAX };
    10121018        unsigned m_callLinkInfoIndex { UINT_MAX };
  • trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp

    r267489 r272580  
    325325}
    326326
     327JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs brand)
     328    : Base(codeBlock, codeOrigin, callSiteIndex, accessType, usedRegisters)
     329{
     330    ASSERT(accessType == AccessType::CheckPrivateBrand || accessType == AccessType::SetPrivateBrand);
     331    m_stubInfo->hasConstantIdentifier = false;
     332
     333    m_stubInfo->baseGPR = base.payloadGPR();
     334    m_stubInfo->regs.brandGPR = brand.payloadGPR();
     335    m_stubInfo->valueGPR = InvalidGPRReg;
     336#if USE(JSVALUE32_64)
     337    m_stubInfo->baseTagGPR = base.tagGPR();
     338    m_stubInfo->v.brandTagGPR = brand.tagGPR();
     339    m_stubInfo->valueTagGPR = InvalidGPRReg;
     340#endif
     341}
     342
     343void JITPrivateBrandAccessGenerator::generateFastPath(MacroAssembler& jit)
     344{
     345    m_start = jit.label();
     346    m_slowPathJump = jit.patchableJump();
     347    m_done = jit.label();
     348}
     349
     350void JITPrivateBrandAccessGenerator::finalize(
     351    LinkBuffer& fastPath, LinkBuffer& slowPath)
     352{
     353    ASSERT(m_start.isSet());
     354    Base::finalize(
     355        fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start));
     356}
     357
    327358} // namespace JSC
    328359
  • trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h

    r267489 r272580  
    247247    JSValueRegs m_base;
    248248    JSValueRegs m_result;
    249     JSValueRegs m_;
    250 
     249
     250    MacroAssembler::Label m_start;
     251    MacroAssembler::PatchableJump m_slowPathJump;
     252};
     253
     254class JITPrivateBrandAccessGenerator : public JITInlineCacheGenerator {
     255    using Base = JITInlineCacheGenerator;
     256public:
     257    JITPrivateBrandAccessGenerator() { }
     258
     259    JITPrivateBrandAccessGenerator(
     260        CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,
     261        JSValueRegs base, JSValueRegs brand);
     262
     263    MacroAssembler::Jump slowPathJump() const
     264    {
     265        ASSERT(m_slowPathJump.m_jump.isSet());
     266        return m_slowPathJump.m_jump;
     267    }
     268
     269    void finalize(
     270        LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer);
     271   
     272    void generateFastPath(MacroAssembler&);
     273
     274private:
    251275    MacroAssembler::Label m_start;
    252276    MacroAssembler::PatchableJump m_slowPathJump;
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r271987 r272580  
    10931093    RELEASE_ASSERT(baseValue.isObject());
    10941094    directPutByVal(globalObject, asObject(baseValue), subscript, value, byValInfo, ecmaMode);
     1095}
     1096
     1097JSC_DEFINE_JIT_OPERATION(operationSetPrivateBrandOptimize, void, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBaseValue, EncodedJSValue encodedBrand))
     1098{
     1099    VM& vm = globalObject->vm();
     1100    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     1101    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     1102    auto scope = DECLARE_THROW_SCOPE(vm);
     1103
     1104    JSValue baseValue = JSValue::decode(encodedBaseValue);
     1105    JSValue brand = JSValue::decode(encodedBrand);
     1106
     1107    ASSERT(baseValue.isObject());
     1108    ASSERT(brand.isSymbol());
     1109
     1110    JSObject* baseObject = asObject(baseValue);
     1111    Structure* oldStructure = baseObject->structure(vm);
     1112    baseObject->setPrivateBrand(globalObject, brand);
     1113    RETURN_IF_EXCEPTION(scope, void());
     1114
     1115    CodeBlock* codeBlock = callFrame->codeBlock();
     1116    if (CacheableIdentifier::isCacheableIdentifierCell(brand)) {
     1117        CacheableIdentifier identifier = CacheableIdentifier::createFromCell(brand.asCell());
     1118        if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
     1119            repatchSetPrivateBrand(globalObject, codeBlock, baseObject, oldStructure, identifier, *stubInfo);
     1120    }
     1121
     1122}
     1123
     1124JSC_DEFINE_JIT_OPERATION(operationSetPrivateBrandGeneric, void, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBaseValue, EncodedJSValue encodedBrand))
     1125{
     1126    VM& vm = globalObject->vm();
     1127    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     1128    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     1129    auto scope = DECLARE_THROW_SCOPE(vm);
     1130
     1131    JSValue baseValue = JSValue::decode(encodedBaseValue);
     1132    JSValue brand = JSValue::decode(encodedBrand);
     1133
     1134    if (stubInfo)
     1135        stubInfo->tookSlowPath = true;
     1136
     1137    ASSERT(baseValue.isObject());
     1138    ASSERT(brand.isSymbol());
     1139
     1140    JSObject* baseObject = asObject(baseValue);
     1141    baseObject->setPrivateBrand(globalObject, brand);
     1142    RETURN_IF_EXCEPTION(scope, void());
     1143}
     1144
     1145JSC_DEFINE_JIT_OPERATION(operationCheckPrivateBrandOptimize, void, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBaseValue, EncodedJSValue encodedBrand))
     1146{
     1147    VM& vm = globalObject->vm();
     1148    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     1149    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     1150    auto scope = DECLARE_THROW_SCOPE(vm);
     1151
     1152    JSValue baseValue = JSValue::decode(encodedBaseValue);
     1153    JSValue brand = JSValue::decode(encodedBrand);
     1154
     1155    JSObject* baseObject = baseValue.toObject(globalObject);
     1156    RETURN_IF_EXCEPTION(scope, void());
     1157
     1158    ASSERT(brand.isSymbol());
     1159
     1160    baseObject->checkPrivateBrand(globalObject, brand);
     1161    RETURN_IF_EXCEPTION(scope, void());
     1162
     1163    CodeBlock* codeBlock = callFrame->codeBlock();
     1164    if (CacheableIdentifier::isCacheableIdentifierCell(brand)) {
     1165        CacheableIdentifier identifier = CacheableIdentifier::createFromCell(brand.asCell());
     1166        if (stubInfo->considerCachingBy(vm, codeBlock, baseObject->structure(vm), identifier))
     1167            repatchCheckPrivateBrand(globalObject, codeBlock, baseObject, identifier, *stubInfo);
     1168    }
     1169}
     1170
     1171JSC_DEFINE_JIT_OPERATION(operationCheckPrivateBrandGeneric, void, (JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBaseValue, EncodedJSValue encodedBrand))
     1172{
     1173    VM& vm = globalObject->vm();
     1174    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     1175    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     1176    auto scope = DECLARE_THROW_SCOPE(vm);
     1177
     1178    JSValue baseValue = JSValue::decode(encodedBaseValue);
     1179    JSValue brand = JSValue::decode(encodedBrand);
     1180
     1181    stubInfo->tookSlowPath = true;
     1182
     1183    JSObject* baseObject = baseValue.toObject(globalObject);
     1184    RETURN_IF_EXCEPTION(scope, void());
     1185
     1186    ASSERT(brand.isSymbol());
     1187
     1188    baseObject->checkPrivateBrand(globalObject, brand);
     1189    RETURN_IF_EXCEPTION(scope, void());
    10951190}
    10961191
     
    22772372
    22782373    JSObject* base = baseValue.toObject(globalObject);
     2374    RETURN_IF_EXCEPTION(scope, JSValue());
     2375
    22792376    PropertySlot slot(base, PropertySlot::InternalMethodType::GetOwnProperty);
    22802377    base->getPrivateField(globalObject, fieldName, slot);
     
    23832480    }
    23842481
    2385     return JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldName));
     2482    RELEASE_AND_RETURN(scope, JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldName)));
    23862483}
    23872484
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r270874 r272580  
    193193JSC_DECLARE_JIT_OPERATION(operationPutByIdSetPrivateFieldStrictOptimize, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, uintptr_t));
    194194
     195JSC_DECLARE_JIT_OPERATION(operationSetPrivateBrandOptimize, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     196JSC_DECLARE_JIT_OPERATION(operationCheckPrivateBrandOptimize, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     197JSC_DECLARE_JIT_OPERATION(operationSetPrivateBrandGeneric, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     198JSC_DECLARE_JIT_OPERATION(operationCheckPrivateBrandGeneric, void, (JSGlobalObject*, StructureStubInfo*, EncodedJSValue, EncodedJSValue));
     199
    195200JSC_DECLARE_JIT_OPERATION(operationPutPrivateNameOptimize, void, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ByValInfo*, PrivateFieldPutKind));
    196201JSC_DECLARE_JIT_OPERATION(operationPutPrivateNameGeneric, void, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ByValInfo*, PrivateFieldPutKind));
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r272170 r272580  
    140140    Label coldPathBegin = label();
    141141    Call call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetPrivateNameOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseGPR, propertyGPR);
     142    gen.reportSlowPathCall(coldPathBegin, call);
     143}
     144
     145void JIT::emit_op_set_private_brand(const Instruction* currentInstruction)
     146{
     147    auto bytecode = currentInstruction->as<OpSetPrivateBrand>();
     148    VirtualRegister base = bytecode.m_base;
     149    VirtualRegister brand = bytecode.m_brand;
     150    GPRReg baseGPR = regT0;
     151    GPRReg brandGPR = regT1;
     152    emitGetVirtualRegister(base, baseGPR);
     153    emitGetVirtualRegister(brand, brandGPR);
     154
     155    emitJumpSlowCaseIfNotJSCell(baseGPR, base);
     156
     157    JITPrivateBrandAccessGenerator gen(
     158        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::SetPrivateBrand, RegisterSet::stubUnavailableRegisters(),
     159        JSValueRegs(baseGPR), JSValueRegs(brandGPR));
     160    gen.generateFastPath(*this);
     161    addSlowCase(gen.slowPathJump());
     162    m_privateBrandAccesses.append(gen);
     163
     164    // We should emit write-barrier at the end of sequence since write-barrier clobbers registers.
     165    // IC can write new Structure without write-barrier if a base is cell.
     166    // FIXME: Use UnconditionalWriteBarrier in Baseline effectively to reduce code size.
     167    // https://bugs.webkit.org/show_bug.cgi?id=209395
     168    emitWriteBarrier(base, ShouldFilterBase);
     169}
     170
     171void JIT::emitSlow_op_set_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator& iter)
     172{
     173    GPRReg baseGPR = regT0;
     174    GPRReg brandGPR = regT1;
     175
     176    linkAllSlowCases(iter);
     177
     178    JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex];
     179    ++m_privateBrandAccessIndex;
     180    Label coldPathBegin = label();
     181    Call call = callOperation(operationSetPrivateBrandOptimize, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseGPR, brandGPR);
     182    gen.reportSlowPathCall(coldPathBegin, call);
     183}
     184
     185void JIT::emit_op_check_private_brand(const Instruction* currentInstruction)
     186{
     187    auto bytecode = currentInstruction->as<OpCheckPrivateBrand>();
     188    VirtualRegister base = bytecode.m_base;
     189    VirtualRegister brand = bytecode.m_brand;
     190
     191    emitGetVirtualRegister(base, regT0);
     192    emitGetVirtualRegister(brand, regT1);
     193
     194    emitJumpSlowCaseIfNotJSCell(regT0, base);
     195
     196    JITPrivateBrandAccessGenerator gen(
     197        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::CheckPrivateBrand, RegisterSet::stubUnavailableRegisters(),
     198        JSValueRegs(regT0), JSValueRegs(regT1));
     199    gen.generateFastPath(*this);
     200    addSlowCase(gen.slowPathJump());
     201    m_privateBrandAccesses.append(gen);
     202}
     203
     204void JIT::emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator& iter)
     205{
     206    GPRReg baseGPR = regT0;
     207    GPRReg brandGPR = regT1;
     208
     209    linkAllSlowCases(iter);
     210
     211    JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex];
     212    ++m_privateBrandAccessIndex;
     213    Label coldPathBegin = label();
     214    Call call = callOperation(operationCheckPrivateBrandOptimize, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseGPR, brandGPR);
    142215    gen.reportSlowPathCall(coldPathBegin, call);
    143216}
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r270711 r272580  
    379379    m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
    380380    m_byValInstructionIndex++;
     381}
     382
     383void JIT::emit_op_set_private_brand(const Instruction* currentInstruction)
     384{
     385    auto bytecode = currentInstruction->as<OpSetPrivateBrand>();
     386    VirtualRegister base = bytecode.m_base;
     387    VirtualRegister brand = bytecode.m_brand;
     388    JSValueRegs baseRegs(regT1, regT0);
     389    JSValueRegs brandRegs(regT3, regT2);
     390    emitLoad(base, baseRegs.tagGPR(), baseRegs.payloadGPR());
     391    emitLoad(brand, brandRegs.tagGPR(), brandRegs.payloadGPR());
     392
     393    emitJumpSlowCaseIfNotJSCell(base, baseRegs.tagGPR());
     394
     395    JITPrivateBrandAccessGenerator gen(
     396        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::SetPrivateBrand, RegisterSet::stubUnavailableRegisters(),
     397        baseRegs, brandRegs);
     398    gen.generateFastPath(*this);
     399    addSlowCase(gen.slowPathJump());
     400    m_privateBrandAccesses.append(gen);
     401
     402    // We should emit write-barrier at the end of sequence since write-barrier clobbers registers.
     403    // IC can write new Structure without write-barrier if a base is cell.
     404    // FIXME: Use UnconditionalWriteBarrier in Baseline effectively to reduce code size.
     405    // https://bugs.webkit.org/show_bug.cgi?id=209395
     406    emitWriteBarrier(base, ShouldFilterBase);
     407}
     408
     409void JIT::emitSlow_op_set_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator& iter)
     410{
     411    JSValueRegs baseRegs(regT1, regT0);
     412    JSValueRegs brandRegs(regT3, regT2);
     413
     414    linkAllSlowCases(iter);
     415
     416    JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex];
     417    ++m_privateBrandAccessIndex;
     418    Label coldPathBegin = label();
     419    Call call = callOperation(operationSetPrivateBrandOptimize, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseRegs, brandRegs);
     420    gen.reportSlowPathCall(coldPathBegin, call);
     421}
     422
     423void JIT::emit_op_check_private_brand(const Instruction* currentInstruction)
     424{
     425    auto bytecode = currentInstruction->as<OpCheckPrivateBrand>();
     426    VirtualRegister base = bytecode.m_base;
     427    VirtualRegister brand = bytecode.m_brand;
     428    JSValueRegs baseRegs(regT1, regT0);
     429    JSValueRegs brandRegs(regT3, regT2);
     430    emitLoad(base, baseRegs.tagGPR(), baseRegs.payloadGPR());
     431    emitLoad(brand, brandRegs.tagGPR(), brandRegs.payloadGPR());
     432
     433    emitJumpSlowCaseIfNotJSCell(base, baseRegs.tagGPR());
     434
     435    JITPrivateBrandAccessGenerator gen(
     436        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::CheckPrivateBrand, RegisterSet::stubUnavailableRegisters(),
     437        baseRegs, brandRegs);
     438    gen.generateFastPath(*this);
     439    addSlowCase(gen.slowPathJump());
     440    m_privateBrandAccesses.append(gen);
     441}
     442
     443void JIT::emitSlow_op_check_private_brand(const Instruction*, Vector<SlowCaseEntry>::iterator& iter)
     444{
     445    JSValueRegs baseRegs(regT1, regT0);
     446    JSValueRegs brandRegs(regT3, regT2);
     447
     448    linkAllSlowCases(iter);
     449
     450    JITPrivateBrandAccessGenerator& gen = m_privateBrandAccesses[m_privateBrandAccessIndex];
     451    ++m_privateBrandAccessIndex;
     452    Label coldPathBegin = label();
     453    Call call = callOperation(operationCheckPrivateBrandOptimize, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseRegs, brandRegs);
     454    gen.reportSlowPathCall(coldPathBegin, call);
    381455}
    382456
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r272170 r272580  
    10111011}
    10121012
     1013static InlineCacheAction tryCacheCheckPrivateBrand(
     1014    JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, CacheableIdentifier brandID,
     1015    StructureStubInfo& stubInfo)
     1016{
     1017    VM& vm = globalObject->vm();
     1018    AccessGenerationResult result;
     1019    Identifier ident = Identifier::fromUid(vm, brandID.uid());
     1020
     1021    {
     1022        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
     1023        if (forceICFailure(globalObject))
     1024            return GiveUpOnCache;
     1025
     1026        Structure* structure = base->structure(vm);
     1027
     1028        InlineCacheAction action = actionForCell(vm, base);
     1029        if (action != AttemptToCache)
     1030            return action;
     1031
     1032        bool isBaseProperty = true;
     1033        LOG_IC((ICEvent::CheckPrivateBrandAddAccessCase, structure->classInfo(), ident, isBaseProperty));
     1034
     1035        std::unique_ptr<AccessCase> newCase = AccessCase::createCheckPrivateBrand(vm, codeBlock, brandID, structure);
     1036
     1037        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, ECMAMode::strict(), brandID, WTFMove(newCase));
     1038
     1039        if (result.generatedSomeCode()) {
     1040            LOG_IC((ICEvent::CheckPrivateBrandReplaceWithJump, structure->classInfo(), ident, isBaseProperty));
     1041
     1042            RELEASE_ASSERT(result.code());
     1043            InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
     1044        }
     1045    }
     1046
     1047    fireWatchpointsAndClearStubIfNeeded(vm, stubInfo, codeBlock, result);
     1048
     1049    return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater;
     1050}
     1051
     1052void repatchCheckPrivateBrand(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* baseObject, CacheableIdentifier brandID, StructureStubInfo& stubInfo)
     1053{
     1054    SuperSamplerScope superSamplerScope(false);
     1055
     1056    if (tryCacheCheckPrivateBrand(globalObject, codeBlock, baseObject, brandID, stubInfo) == GiveUpOnCache)
     1057        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationCheckPrivateBrandGeneric);
     1058}
     1059
     1060static InlineCacheAction tryCacheSetPrivateBrand(
     1061    JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* base, Structure* oldStructure, CacheableIdentifier brandID,
     1062    StructureStubInfo& stubInfo)
     1063{
     1064    VM& vm = globalObject->vm();
     1065    AccessGenerationResult result;
     1066    Identifier ident = Identifier::fromUid(vm, brandID.uid());
     1067
     1068    {
     1069        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
     1070        if (forceICFailure(globalObject))
     1071            return GiveUpOnCache;
     1072       
     1073        ASSERT(oldStructure);
     1074
     1075        if (oldStructure->isDictionary())
     1076            return RetryCacheLater;
     1077
     1078        InlineCacheAction action = actionForCell(vm, base);
     1079        if (action != AttemptToCache)
     1080            return action;
     1081       
     1082        Structure* newStructure = Structure::setBrandTransitionFromExistingStructureConcurrently(oldStructure, brandID.uid());
     1083        if (!newStructure)
     1084            return RetryCacheLater;
     1085        if (newStructure->isDictionary())
     1086            return GiveUpOnCache;
     1087        ASSERT(newStructure->previousID() == oldStructure);
     1088        ASSERT(newStructure->transitionKind() == TransitionKind::SetBrand);
     1089        ASSERT(newStructure->isObject());
     1090       
     1091        bool isBaseProperty = true;
     1092        LOG_IC((ICEvent::SetPrivateBrandAddAccessCase, oldStructure->classInfo(), ident, isBaseProperty));
     1093
     1094        std::unique_ptr<AccessCase> newCase = AccessCase::createSetPrivateBrand(vm, codeBlock, brandID, oldStructure, newStructure);
     1095
     1096        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, ECMAMode::strict(), brandID, WTFMove(newCase));
     1097
     1098        if (result.generatedSomeCode()) {
     1099            LOG_IC((ICEvent::SetPrivateBrandReplaceWithJump, oldStructure->classInfo(), ident, isBaseProperty));
     1100           
     1101            RELEASE_ASSERT(result.code());
     1102            InlineAccess::rewireStubAsJump(stubInfo, CodeLocationLabel<JITStubRoutinePtrTag>(result.code()));
     1103        }
     1104    }
     1105
     1106    fireWatchpointsAndClearStubIfNeeded(vm, stubInfo, codeBlock, result);
     1107   
     1108    return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater;
     1109}
     1110
     1111void repatchSetPrivateBrand(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSObject* baseObject, Structure* oldStructure, CacheableIdentifier brandID, StructureStubInfo& stubInfo)
     1112{
     1113    SuperSamplerScope superSamplerScope(false);
     1114
     1115    if (tryCacheSetPrivateBrand(globalObject, codeBlock, baseObject, oldStructure,  brandID, stubInfo) == GiveUpOnCache)
     1116        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationSetPrivateBrandGeneric);
     1117}
     1118
    10131119static InlineCacheAction tryCacheInstanceOf(
    10141120    JSGlobalObject* globalObject, CodeBlock* codeBlock, JSValue valueValue, JSValue prototypeValue, StructureStubInfo& stubInfo,
     
    15861692}
    15871693
     1694void resetCheckPrivateBrand(CodeBlock* codeBlock, StructureStubInfo& stubInfo)
     1695{
     1696    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationCheckPrivateBrandOptimize);
     1697    InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);
     1698}
     1699
     1700void resetSetPrivateBrand(CodeBlock* codeBlock, StructureStubInfo& stubInfo)
     1701{
     1702    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, operationSetPrivateBrandOptimize);
     1703    InlineAccess::rewireStubAsJump(stubInfo, stubInfo.slowPathStartLocation);
     1704}
     1705
    15881706MacroAssemblerCodePtr<JSEntryPtrTag> jsToWasmICCodePtr(VM& vm, CodeSpecializationKind kind, JSObject* callee)
    15891707{
  • trunk/Source/JavaScriptCore/jit/Repatch.h

    r268794 r272580  
    5454void repatchDeleteBy(JSGlobalObject*, CodeBlock*, DeletePropertySlot&, JSValue, Structure*, CacheableIdentifier, StructureStubInfo&, DelByKind, ECMAMode);
    5555void repatchInByID(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, bool wasFound, const PropertySlot&, StructureStubInfo&);
     56void repatchCheckPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, CacheableIdentifier, StructureStubInfo&);
     57void repatchSetPrivateBrand(JSGlobalObject*, CodeBlock*, JSObject*, Structure*, CacheableIdentifier, StructureStubInfo&);
    5658void repatchInstanceOf(JSGlobalObject*, CodeBlock*, JSValue value, JSValue prototype, StructureStubInfo&, bool wasFound);
    5759void linkFor(VM&, CallFrame*, CallLinkInfo&, CodeBlock*, JSObject* callee, MacroAssemblerCodePtr<JSEntryPtrTag>);
     
    6567void resetInByID(CodeBlock*, StructureStubInfo&);
    6668void resetInstanceOf(StructureStubInfo&);
     69void resetCheckPrivateBrand(CodeBlock*, StructureStubInfo&);
     70void resetSetPrivateBrand(CodeBlock*, StructureStubInfo&);
    6771void ftlThunkAwareRepatchCall(CodeBlock*, CodeLocationCall<JSInternalPtrTag>, FunctionPtr<CFunctionPtrTag> newCalleeFunction);
    6872MacroAssemblerCodePtr<JSEntryPtrTag> jsToWasmICCodePtr(VM&, CodeSpecializationKind, JSObject* callee);
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r271987 r272580  
    13021302}
    13031303
     1304LLINT_SLOW_PATH_DECL(slow_path_set_private_brand)
     1305{
     1306    LLINT_BEGIN();
     1307
     1308    auto bytecode = pc->as<OpSetPrivateBrand>();
     1309    JSValue baseValue = getOperand(callFrame, bytecode.m_base);
     1310    JSValue brand = getOperand(callFrame, bytecode.m_brand);
     1311    auto& metadata = bytecode.metadata(codeBlock);
     1312    ASSERT(baseValue.isObject());
     1313    ASSERT(brand.isSymbol());
     1314
     1315    JSObject* baseObject = asObject(baseValue);
     1316    Structure* oldStructure = baseObject->structure(vm);
     1317
     1318    baseObject->setPrivateBrand(globalObject, brand);
     1319    LLINT_CHECK_EXCEPTION();
     1320
     1321    if (!LLINT_ALWAYS_ACCESS_SLOW && !oldStructure->isDictionary()) {
     1322        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
     1323        Structure* newStructure = baseObject->structure(vm);
     1324
     1325        ASSERT(oldStructure == newStructure->previousID());
     1326        ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated());
     1327
     1328        // Start out by clearing out the old cache.
     1329        metadata.m_oldStructureID = 0;
     1330        metadata.m_newStructureID = 0;
     1331        metadata.m_brand.clear();
     1332
     1333        if (!newStructure->isDictionary()) {
     1334            metadata.m_oldStructureID = oldStructure->id();
     1335            metadata.m_newStructureID = newStructure->id();
     1336            metadata.m_brand.set(vm, codeBlock, brand.asCell());
     1337        }
     1338        vm.heap.writeBarrier(codeBlock);
     1339    }
     1340
     1341    LLINT_END();   
     1342}
     1343
     1344LLINT_SLOW_PATH_DECL(slow_path_check_private_brand)
     1345{
     1346    LLINT_BEGIN();
     1347
     1348    auto bytecode = pc->as<OpCheckPrivateBrand>();
     1349    auto& metadata = bytecode.metadata(codeBlock);
     1350    JSValue baseValue = getOperand(callFrame, bytecode.m_base);
     1351    JSValue brand = getOperand(callFrame, bytecode.m_brand);
     1352
     1353    JSObject* baseObject = baseValue.toObject(globalObject);
     1354    LLINT_CHECK_EXCEPTION();
     1355
     1356    ASSERT(brand.isSymbol());
     1357
     1358    baseObject->checkPrivateBrand(globalObject, brand);
     1359    LLINT_CHECK_EXCEPTION();
     1360
     1361    // Since a brand can't ever be removed from an object, it's safe to
     1362    // rely on StructureID even if it's an uncacheable dictionary.
     1363    Structure* structure = baseObject->structure(vm);
     1364    if (!LLINT_ALWAYS_ACCESS_SLOW) {
     1365        GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
     1366
     1367        metadata.m_structureID = structure->id();
     1368        metadata.m_brand.set(vm, codeBlock, brand.asCell());
     1369        vm.heap.writeBarrier(codeBlock);
     1370    }
     1371
     1372    LLINT_END();   
     1373}
     1374
    13041375LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
    13051376{
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r267808 r272580  
    7878LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_val_direct);
    7979LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_private_name);
     80LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_check_private_brand);
     81LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_set_private_brand);
    8082LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val);
    8183LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_getter_by_id);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r271120 r272580  
    29922992    notSupported()
    29932993end)
     2994
     2995
     2996llintOpWithMetadata(op_check_private_brand, OpCheckPrivateBrand, macro (size, get, dispatch, metadata, return)
     2997    metadata(t5, t2)
     2998    get(m_base, t3)
     2999    loadConstantOrVariablePayload(size, t3, CellTag, t0, .opCheckPrivateBrandSlow)
     3000    get(m_brand, t3)
     3001    loadConstantOrVariablePayload(size, t3, CellTag, t1, .opCheckPrivateBrandSlow)
     3002
     3003    loadi OpCheckPrivateBrand::Metadata::m_structureID[t5], t3
     3004    bineq JSCell::m_structureID[t0], t3, .opCheckPrivateBrandSlow
     3005
     3006    loadp OpCheckPrivateBrand::Metadata::m_brand[t5], t3
     3007    bpneq t3, t1, .opCheckPrivateBrandSlow
     3008    dispatch()
     3009
     3010.opCheckPrivateBrandSlow:
     3011    callSlowPath(_llint_slow_path_check_private_brand)
     3012    dispatch()
     3013end)
     3014
     3015
     3016llintOpWithMetadata(op_set_private_brand, OpSetPrivateBrand, macro (size, get, dispatch, metadata, return)
     3017    metadata(t5, t2)
     3018    get(m_base, t3)
     3019    loadConstantOrVariablePayload(size, t3, CellTag, t0, .opSetPrivateBrandSlow)
     3020    get(m_brand, t3)
     3021    loadConstantOrVariablePayload(size, t3, CellTag, t1, .opSetPrivateBrandSlow)
     3022
     3023    loadi OpSetPrivateBrand::Metadata::m_oldStructureID[t5], t2
     3024    bineq t2, JSCell::m_structureID[t0], .opSetPrivateBrandSlow
     3025
     3026    loadp OpSetPrivateBrand::Metadata::m_brand[t5], t3
     3027    bpneq t3, t1, .opSetPrivateBrandSlow
     3028
     3029    loadi OpSetPrivateBrand::Metadata::m_newStructureID[t5], t1
     3030    storei t1, JSCell::m_structureID[t0]
     3031    writeBarrierOnOperand(size, get, m_base)
     3032    dispatch()
     3033
     3034.opSetPrivateBrandSlow:
     3035    callSlowPath(_llint_slow_path_set_private_brand)
     3036    dispatch()
     3037end)
     3038
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r271120 r272580  
    18131813.opPutPrivateNameSlow:
    18141814    callSlowPath(_llint_slow_path_put_private_name)
     1815    dispatch()
     1816end)
     1817
     1818llintOpWithMetadata(op_set_private_brand, OpSetPrivateBrand, macro (size, get, dispatch, metadata, return)
     1819    get(m_base, t3)
     1820    loadConstantOrVariableCell(size, t3, t0, .opSetPrivateBrandSlow)
     1821    get(m_brand, t3)
     1822    loadConstantOrVariableCell(size, t3, t1, .opSetPrivateBrandSlow)
     1823    metadata(t5, t2)
     1824    loadi OpSetPrivateBrand::Metadata::m_oldStructureID[t5], t2
     1825    bineq t2, JSCell::m_structureID[t0], .opSetPrivateBrandSlow
     1826
     1827    loadp OpSetPrivateBrand::Metadata::m_brand[t5], t3
     1828    bpneq t3, t1, .opSetPrivateBrandSlow
     1829
     1830    loadi OpSetPrivateBrand::Metadata::m_newStructureID[t5], t1
     1831    storei t1, JSCell::m_structureID[t0]
     1832    writeBarrierOnOperand(size, get, m_base)
     1833    dispatch()
     1834
     1835.opSetPrivateBrandSlow:
     1836    callSlowPath(_llint_slow_path_set_private_brand)
     1837    dispatch()
     1838end)
     1839
     1840llintOpWithMetadata(op_check_private_brand, OpCheckPrivateBrand, macro (size, get, dispatch, metadata, return)
     1841    metadata(t5, t2)
     1842    get(m_base, t3)
     1843    loadConstantOrVariableCell(size, t3, t0, .opCheckPrivateBrandSlow)
     1844    get(m_brand, t3)
     1845    loadConstantOrVariableCell(size, t3, t1, .opCheckPrivateBrandSlow)
     1846
     1847    loadp OpCheckPrivateBrand::Metadata::m_brand[t5], t3
     1848    bqneq t3, t1, .opCheckPrivateBrandSlow
     1849
     1850    loadi OpCheckPrivateBrand::Metadata::m_structureID[t5], t2
     1851    bineq t2, JSCell::m_structureID[t0], .opCheckPrivateBrandSlow
     1852    dispatch()
     1853
     1854.opCheckPrivateBrandSlow:
     1855    callSlowPath(_llint_slow_path_check_private_brand)
    18151856    dispatch()
    18161857end)
  • trunk/Source/JavaScriptCore/parser/Nodes.cpp

    r262613 r272580  
    203203        , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
    204204        , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
     205        , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
    205206        , m_parseMode(mode)
    206207        , m_startColumn(startColumn)
     
    227228        , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
    228229        , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
     230        , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
    229231        , m_parseMode(mode)
    230232        , m_startColumn(startColumn)
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r271265 r272580  
    722722    class PropertyNode final : public ParserArenaFreeable {
    723723    public:
    724         enum Type : uint8_t { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16, Spread = 32, Private = 64 };
     724        enum Type : uint8_t { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16, Spread = 32, PrivateField = 64, PrivateMethod = 128 };
    725725
    726726        PropertyNode(const Identifier&, ExpressionNode*, Type, SuperBinding, ClassElementTag);
     
    741741        bool isStaticClassField() const { return isStaticClassProperty() && !needsSuperBinding(); }
    742742        bool isOverriddenByDuplicate() const { return m_isOverriddenByDuplicate; }
    743         bool isPrivate() const { return m_type & Private; }
     743        bool isPrivate() const { return m_type & (PrivateField | PrivateMethod); }
    744744        bool hasComputedName() const { return m_expression; }
    745745        bool isComputedClassField() const { return isClassField() && hasComputedName(); }
     
    761761        ExpressionNode* m_expression;
    762762        ExpressionNode* m_assign;
    763         unsigned m_type : 7;
     763        unsigned m_type;
    764764        unsigned m_needsSuperBinding : 1;
    765765        static_assert(1 << 2 > static_cast<unsigned>(ClassElementTag::LastTag), "ClassElementTag shouldn't use more than two bits");
     
    839839    };
    840840
    841     enum class DotType { Name, PrivateField };
     841    enum class DotType { Name, PrivateMember };
    842842    class BaseDotNode : public ExpressionNode {
    843843    public:
     
    847847        const Identifier& identifier() const { return m_ident; }
    848848        DotType type() const { return m_type; }
    849         bool isPrivateField() const { return m_type == DotType::PrivateField; }
     849        bool isPrivateMember() const { return m_type == DotType::PrivateMember; }
    850850
    851851        RegisterID* emitGetPropertyValue(BytecodeGenerator&, RegisterID* dst, RegisterID* base, RefPtr<RegisterID>& thisValue);
     
    871871
    872872        bool isLocation() const final { return true; }
    873         bool isPrivateLocation() const override { return m_type == DotType::PrivateField; }
     873        bool isPrivateLocation() const override { return m_type == DotType::PrivateMember; }
    874874        bool isDotAccessorNode() const final { return true; }
    875875    };
     
    21622162        const Identifier& ecmaName() { return m_ident.isEmpty() ? m_ecmaName : m_ident; }
    21632163
     2164        void setPrivateBrandRequirement(PrivateBrandRequirement privateBrandRequirement) { m_privateBrandRequirement = static_cast<unsigned>(privateBrandRequirement); }
     2165        PrivateBrandRequirement privateBrandRequirement() { return static_cast<PrivateBrandRequirement>(m_privateBrandRequirement); }
     2166
    21642167        FunctionMode functionMode() { return m_functionMode; }
    21652168
     
    22102213        unsigned m_needsClassFieldInitializer : 1;
    22112214        unsigned m_isArrowFunctionBodyExpression : 1;
     2215        unsigned m_privateBrandRequirement : 1;
    22122216        SourceParseMode m_parseMode;
    22132217        FunctionMode m_functionMode;
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r272086 r272580  
    28712871    classScope->preventVarDeclarations();
    28722872    classScope->setStrictMode();
     2873    bool declaresPrivateMethod = false;
    28732874    next();
    28742875
     
    29902991        case PRIVATENAME: {
    29912992            ASSERT(Options::usePrivateClassFields());
    2992             JSToken token = m_token;
    29932993            ident = m_token.m_data.ident;
    29942994            if (!Options::usePrivateStaticClassFields())
     
    29972997            ASSERT(ident);
    29982998            next();
    2999             failIfTrue(matchAndUpdate(OPENPAREN, token), "Cannot parse class method with private name");
    3000             semanticFailIfTrue(classScope->declarePrivateName(*ident) & DeclarationResult::InvalidDuplicateDeclaration, "Cannot declare private field twice");
    3001             type = static_cast<PropertyNode::Type>(type | PropertyNode::Private);
     2999            if (Options::usePrivateMethods() && match(OPENPAREN)) {
     3000                semanticFailIfTrue(classScope->declarePrivateMethod(*ident) & DeclarationResult::InvalidDuplicateDeclaration, "Cannot declare private method twice");
     3001                declaresPrivateMethod = true;
     3002                type = static_cast<PropertyNode::Type>(type | PropertyNode::PrivateMethod);
     3003                break;
     3004            }
     3005
     3006            failIfTrue(match(OPENPAREN), "Cannot parse class method with private name");
     3007            semanticFailIfTrue(classScope->declarePrivateField(*ident) & DeclarationResult::InvalidDuplicateDeclaration, "Cannot declare private field twice");
     3008            type = static_cast<PropertyNode::Type>(type | PropertyNode::PrivateField);
    30023009            break;
    30033010        }
     
    30853092    consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
    30863093
     3094    if (declaresPrivateMethod) {
     3095        Identifier privateBrandIdentifier = m_vm.propertyNames->builtinNames().privateBrandPrivateName();
     3096        DeclarationResultMask declarationResult = classScope->declareLexicalVariable(&privateBrandIdentifier, true);
     3097        ASSERT_UNUSED(declarationResult, declarationResult == DeclarationResult::Valid);
     3098        classScope->useVariable(&privateBrandIdentifier, false);
     3099        classScope->addClosedVariableCandidateUnconditionally(privateBrandIdentifier.impl());
     3100    }
     3101
    30873102    if (Options::usePrivateClassFields()) {
    30883103        // Fail if there are no parent private name scopes and any used-but-undeclared private names.
    30893104        semanticFailIfFalse(copyUndeclaredPrivateNamesToOuterScope(), "Cannot reference undeclared private names");
    30903105    }
     3106
    30913107    auto classExpression = context.createClassExpr(location, info, classScope->finalizeLexicalEnvironment(), constructor, parentClass, classElements);
    30923108    popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
     
    51665182                    m_parserState.lastPrivateName = ident;
    51675183                    currentScope()->useVariable(ident, false);
    5168                     type = DotType::PrivateField;
     5184                    type = DotType::PrivateMember;
    51695185                    m_token.m_type = IDENT;
    51705186                }
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r272086 r272580  
    501501    }
    502502
    503     DeclarationResultMask declarePrivateName(const Identifier& ident)
     503    DeclarationResultMask declarePrivateMethod(const Identifier& ident)
    504504    {
    505505        ASSERT(m_allowsLexicalDeclarations);
    506506        DeclarationResultMask result = DeclarationResult::Valid;
    507         auto addResult = m_lexicalVariables.declarePrivateName(ident);
     507        bool addResult = m_lexicalVariables.declarePrivateMethod(ident);
     508
     509        if (!addResult) {
     510            result |= DeclarationResult::InvalidDuplicateDeclaration;
     511            return result;
     512        }
     513
     514        useVariable(&ident, false);
     515        addClosedVariableCandidateUnconditionally(ident.impl());
     516
     517        return result;
     518    }
     519
     520    DeclarationResultMask declarePrivateField(const Identifier& ident)
     521    {
     522        ASSERT(m_allowsLexicalDeclarations);
     523        DeclarationResultMask result = DeclarationResult::Valid;
     524        auto addResult = m_lexicalVariables.declarePrivateField(ident);
    508525        if (!addResult.isNewEntry)
    509526            result |= DeclarationResult::InvalidDuplicateDeclaration;
     
    945962
    946963    template <class ParsedNode>
    947     std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, ParsingContext, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt, const VariableEnvironment* = nullptr, const Vector<JSTextPosition>* = nullptr);
     964    std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, ParsingContext, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt, const PrivateNameEnvironment* = nullptr, const Vector<JSTextPosition>* = nullptr);
    948965
    949966    JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
     
    20812098template <typename LexerType>
    20822099template <class ParsedNode>
    2083 std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, ParsingContext parsingContext, Optional<int> functionConstructorParametersEndPosition, const VariableEnvironment* parentScopePrivateNames, const Vector<JSTextPosition>* classFieldLocations)
     2100std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, ParsingContext parsingContext, Optional<int> functionConstructorParametersEndPosition, const PrivateNameEnvironment* parentScopePrivateNames, const Vector<JSTextPosition>* classFieldLocations)
    20842101{
    20852102    int errLine;
     
    20972114    unsigned startColumn = m_source->startColumn().zeroBasedInt();
    20982115
    2099     if (isEvalNode<ParsedNode>() && parentScopePrivateNames && parentScopePrivateNames->privateNamesSize()) {
     2116    if (isEvalNode<ParsedNode>() && parentScopePrivateNames && parentScopePrivateNames->size()) {
    21002117        currentScope()->setIsPrivateNameScope();
    2101         parentScopePrivateNames->copyPrivateNamesTo(currentScope()->lexicalVariables());
     2118        currentScope()->lexicalVariables().addPrivateNamesFrom(parentScopePrivateNames);
    21022119    }
    21032120
     
    21862203    EvalContextType evalContextType = EvalContextType::None,
    21872204    DebuggerParseData* debuggerParseData = nullptr,
    2188     const VariableEnvironment* parentScopePrivateNames = nullptr,
     2205    const PrivateNameEnvironment* parentScopePrivateNames = nullptr,
    21892206    const Vector<JSTextPosition>* classFieldLocations = nullptr,
    21902207    bool isInsideOrdinaryFunction = false)
  • trunk/Source/JavaScriptCore/parser/ParserModes.h

    r269922 r272580  
    3838enum class SuperBinding { Needed, NotNeeded };
    3939
     40enum class PrivateBrandRequirement { None, Needed };
     41
    4042enum class CodeGenerationMode : uint8_t {
    4143    Debugger = 1 << 0,
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r271265 r272580  
    180180    ExpressionType createNull(const JSTokenLocation&) { return NullExpr; }
    181181    ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
    182     ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, DotType type, int, int, int) { return type == DotType::PrivateField ? PrivateDotExpr : DotExpr; }
     182    ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, DotType type, int, int, int) { return type == DotType::PrivateMember ? PrivateDotExpr : DotExpr; }
    183183    ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags, int) { return Yarr::hasError(Yarr::checkSyntax(pattern.string(), flags.string())) ? 0 : RegExpExpr; }
    184184    ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int) { return NewExpr; }
  • trunk/Source/JavaScriptCore/parser/VariableEnvironment.cpp

    r269115 r272580  
    105105}
    106106
     107bool VariableEnvironment::declarePrivateMethod(const RefPtr<UniquedStringImpl>& identifier)
     108{
     109    if (!m_rareData)
     110        m_rareData = makeUnique<VariableEnvironment::RareData>();
     111
     112    auto findResult = m_rareData->m_privateNames.find(identifier);
     113
     114    if (findResult == m_rareData->m_privateNames.end()) {
     115        PrivateNameEntry meta(PrivateNameEntry::Traits::IsDeclared | PrivateNameEntry::Traits::IsMethod);
     116
     117        auto entry = VariableEnvironmentEntry();
     118        entry.setIsPrivateMethod();
     119        entry.setIsConst();
     120        entry.setIsCaptured();
     121        m_map.add(identifier, entry);
     122
     123        auto addResult = m_rareData->m_privateNames.add(identifier, meta);
     124        return addResult.isNewEntry;
     125    }
     126
     127    if (findResult->value.isDeclared())
     128        return false; // Error: declaring a duplicate private name.
     129
     130    auto entry = VariableEnvironmentEntry();
     131    entry.setIsPrivateMethod();
     132    entry.setIsConst();
     133    entry.setIsCaptured();
     134    m_map.add(identifier, entry);
     135
     136    // it was previously used, mark it as declared.
     137    PrivateNameEntry meta(PrivateNameEntry::Traits::IsDeclared | PrivateNameEntry::Traits::IsUsed | PrivateNameEntry::Traits::IsMethod);
     138    auto addResult = m_rareData->m_privateNames.set(identifier, meta);
     139    return !addResult.isNewEntry;
     140}
    107141
    108142void CompactTDZEnvironment::sortCompact(Compact& compact)
  • trunk/Source/JavaScriptCore/parser/VariableEnvironment.h

    r270870 r272580  
    4646    ALWAYS_INLINE bool isParameter() const { return m_bits & IsParameter; }
    4747    ALWAYS_INLINE bool isSloppyModeHoistingCandidate() const { return m_bits & IsSloppyModeHoistingCandidate; }
    48     ALWAYS_INLINE bool isPrivateName() const { return m_bits & IsPrivateName; }
     48    ALWAYS_INLINE bool isPrivateField() const { return m_bits & IsPrivateField; }
     49    ALWAYS_INLINE bool isPrivateMethod() const { return m_bits & IsPrivateMethod; }
    4950
    5051    ALWAYS_INLINE void setIsCaptured() { m_bits |= IsCaptured; }
     
    5859    ALWAYS_INLINE void setIsParameter() { m_bits |= IsParameter; }
    5960    ALWAYS_INLINE void setIsSloppyModeHoistingCandidate() { m_bits |= IsSloppyModeHoistingCandidate; }
    60     ALWAYS_INLINE void setIsPrivateName() { m_bits |= IsPrivateName; }
     61    ALWAYS_INLINE void setIsPrivateField() { m_bits |= IsPrivateField; }
     62    ALWAYS_INLINE void setIsPrivateMethod() { m_bits |= IsPrivateMethod; }
    6163
    6264    ALWAYS_INLINE void clearIsVar() { m_bits &= ~IsVar; }
     
    8183        IsParameter = 1 << 8,
    8284        IsSloppyModeHoistingCandidate = 1 << 9,
    83         IsPrivateName = 1 << 10,
     85        IsPrivateField = 1 << 10,
     86        IsPrivateMethod = 1 << 11,
    8487    };
    8588    uint16_t m_bits { 0 };
     
    9194
    9295struct PrivateNameEntry {
     96    friend class CachedPrivateNameEntry;
     97
    9398public:
    9499    PrivateNameEntry(uint16_t traits = 0) { m_bits = traits; }
     
    96101    ALWAYS_INLINE bool isUsed() const { return m_bits & IsUsed; }
    97102    ALWAYS_INLINE bool isDeclared() const { return m_bits & IsDeclared; }
     103    ALWAYS_INLINE bool isMethod() const { return m_bits & IsMethod; }
     104
     105    bool isPrivateMethodOrAcessor() const { return isMethod(); }
    98106
    99107    ALWAYS_INLINE void setIsUsed() { m_bits |= IsUsed; }
     
    108116
    109117    enum Traits : uint16_t {
     118        None = 0,
    110119        IsUsed = 1 << 0,
    111120        IsDeclared = 1 << 1,
     121        IsMethod = 1 << 2,
    112122    };
    113123
     
    117127
    118128struct PrivateNameEntryHashTraits : HashTraits<PrivateNameEntry> {
    119     static const bool needsDestruction = false;
    120 };
     129    static constexpr bool needsDestruction = false;
     130};
     131
     132typedef HashMap<PackedRefPtr<UniquedStringImpl>, PrivateNameEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, PrivateNameEntryHashTraits> PrivateNameEnvironment;
    121133
    122134class VariableEnvironment {
     
    124136private:
    125137    typedef HashMap<PackedRefPtr<UniquedStringImpl>, VariableEnvironmentEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, VariableEnvironmentEntryHashTraits> Map;
    126     typedef HashMap<PackedRefPtr<UniquedStringImpl>, PrivateNameEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, PrivateNameEntryHashTraits> PrivateNames;
     138
    127139public:
     140
    128141    VariableEnvironment() { }
    129142    VariableEnvironment(VariableEnvironment&& other)
     
    147160    ALWAYS_INLINE Map::AddResult add(const RefPtr<UniquedStringImpl>& identifier) { return m_map.add(identifier, VariableEnvironmentEntry()); }
    148161    ALWAYS_INLINE Map::AddResult add(const Identifier& identifier) { return add(identifier.impl()); }
     162
     163    ALWAYS_INLINE PrivateNameEnvironment::AddResult addPrivateName(const Identifier& identifier) { return addPrivateName(identifier.impl()); }
     164    ALWAYS_INLINE PrivateNameEnvironment::AddResult addPrivateName(const RefPtr<UniquedStringImpl>& identifier)
     165    {
     166        if (!m_rareData)
     167            m_rareData = makeUnique<VariableEnvironment::RareData>();
     168
     169        return m_rareData->m_privateNames.add(identifier, PrivateNameEntry());
     170    }
     171
    149172    ALWAYS_INLINE unsigned size() const { return m_map.size() + privateNamesSize(); }
    150173    ALWAYS_INLINE unsigned mapSize() const { return m_map.size(); }
     
    165188    bool isEmpty() const { return !m_map.size(); }
    166189
    167     using PrivateNamesRange = WTF::IteratorRange<PrivateNames::iterator>;
    168 
    169     ALWAYS_INLINE Map::AddResult declarePrivateName(const Identifier& identifier) { return declarePrivateName(identifier.impl()); }
     190    using PrivateNamesRange = WTF::IteratorRange<PrivateNameEnvironment::iterator>;
     191
     192    ALWAYS_INLINE Map::AddResult declarePrivateField(const Identifier& identifier) { return declarePrivateField(identifier.impl()); }
    170193    ALWAYS_INLINE void usePrivateName(const Identifier& identifier) { usePrivateName(identifier.impl()); }
    171194
    172     Map::AddResult declarePrivateName(const RefPtr<UniquedStringImpl>& identifier)
     195    bool declarePrivateMethod(const Identifier& identifier) { return declarePrivateMethod(identifier.impl()); }
     196    bool declarePrivateMethod(const RefPtr<UniquedStringImpl>& identifier);
     197
     198    Map::AddResult declarePrivateField(const RefPtr<UniquedStringImpl>& identifier)
    173199    {
    174200        auto& meta = getOrAddPrivateName(identifier.get());
    175201        meta.setIsDeclared();
    176202        auto entry = VariableEnvironmentEntry();
    177         entry.setIsPrivateName();
     203        entry.setIsPrivateField();
    178204        entry.setIsConst();
    179205        entry.setIsCaptured();
     
    200226            return 0;
    201227        return m_rareData->m_privateNames.size();
     228    }
     229
     230    ALWAYS_INLINE const PrivateNameEnvironment* privateNameEnvironment() const
     231    {
     232        if (!m_rareData)
     233            return nullptr;
     234        return &m_rareData->m_privateNames;
     235    }
     236
     237    ALWAYS_INLINE bool hasPrivateMethodOrAccessor() const
     238    {
     239        if (!m_rareData)
     240            return false;
     241
     242        for (auto entry : privateNames()) {
     243            if (entry.value.isPrivateMethodOrAcessor())
     244                return true;
     245        }
     246
     247        return false;
    202248    }
    203249
     
    220266                    other.m_rareData->m_privateNames.add(entry.key, entry.value);
    221267            }
     268        }
     269    }
     270
     271    ALWAYS_INLINE void addPrivateNamesFrom(const PrivateNameEnvironment* privateNameEnvironment)
     272    {
     273        if (!privateNameEnvironment)
     274            return;
     275
     276        if (!m_rareData)
     277            m_rareData = makeUnique<VariableEnvironment::RareData>();
     278
     279        for (auto entry : *privateNameEnvironment) {
     280            ASSERT(entry.value.isDeclared());
     281            m_rareData->m_privateNames.add(entry.key, entry.value);
    222282        }
    223283    }
     
    245305        RareData(const RareData&) = default;
    246306        RareData& operator=(const RareData&) = default;
    247         PrivateNames m_privateNames;
     307        PrivateNameEnvironment m_privateNames;
    248308    };
    249309
  • trunk/Source/JavaScriptCore/runtime/BrandedStructure.cpp

    r272579 r272580  
    11/*
    2  * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
     3 * Copyright (C) 2021 Igalia S.A. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2425 */
    2526
    26 #pragma once
     27#include "config.h"
     28#include "BrandedStructure.h"
    2729
    28 #include "EvalExecutable.h"
     30#include "JSCInlines.h"
    2931
    3032namespace JSC {
    3133
    32 class DirectEvalExecutable final : public EvalExecutable {
    33 public:
    34     static DirectEvalExecutable* create(JSGlobalObject*, const SourceCode&, DerivedContextType, NeedsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType, const TDZEnvironment* parentScopeTDZVariables, const VariableEnvironment* privateNames, ECMAMode);
    35 private:
    36     DirectEvalExecutable(JSGlobalObject*, const SourceCode&, bool inStrictContext, DerivedContextType, NeedsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType);
    37 };
     34BrandedStructure::BrandedStructure(VM& vm, Structure* previous, UniquedStringImpl* brandUid, DeferredStructureTransitionWatchpointFire* deferred)
     35    : Structure(vm, previous, deferred)
     36    , m_brand(brandUid)
     37{
     38    if (previous->isBrandedStructure())
     39        m_parentBrand.set(vm, this, jsCast<BrandedStructure*>(previous));
     40    this->setIsBrandedStructure(true);
     41}
    3842
    39 static_assert(sizeof(DirectEvalExecutable) == sizeof(EvalExecutable), "");
     43BrandedStructure::BrandedStructure(VM& vm, BrandedStructure* previous, DeferredStructureTransitionWatchpointFire* deferred)
     44    : Structure(vm, previous, deferred)
     45    , m_brand(previous->m_brand)
     46    , m_parentBrand(vm, this, previous->m_parentBrand.get(), WriteBarrier<BrandedStructure>::MayBeNull)
     47{
     48    this->setIsBrandedStructure(true);
     49}
     50
     51Structure* BrandedStructure::create(VM& vm, Structure* previous, UniquedStringImpl* brandUid, DeferredStructureTransitionWatchpointFire* deferred)
     52{
     53    ASSERT(vm.structureStructure);
     54    BrandedStructure* newStructure = new (NotNull, allocateCell<BrandedStructure>(vm.heap)) BrandedStructure(vm, previous, brandUid, deferred);
     55    newStructure->finishCreation(vm, previous);
     56    return newStructure;
     57}
    4058
    4159} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/BrandedStructure.h

    r272579 r272580  
    11/*
    2  * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
     3 * Copyright (C) 2021 Igalia S.A. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2627#pragma once
    2728
    28 #include "EvalExecutable.h"
     29#include "Structure.h"
     30#include "Symbol.h"
     31#include "Watchpoint.h"
     32#include "WriteBarrierInlines.h"
     33
     34namespace WTF {
     35
     36class UniquedStringImpl;
     37
     38} // namespace WTF
    2939
    3040namespace JSC {
    3141
    32 class DirectEvalExecutable final : public EvalExecutable {
     42class BrandedStructure final : public Structure {
     43    typedef Structure Base;
     44
    3345public:
    34     static DirectEvalExecutable* create(JSGlobalObject*, const SourceCode&, DerivedContextType, NeedsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType, const TDZEnvironment* parentScopeTDZVariables, const VariableEnvironment* privateNames, ECMAMode);
    35 private:
    36     DirectEvalExecutable(JSGlobalObject*, const SourceCode&, bool inStrictContext, DerivedContextType, NeedsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType);
     46
     47    template<typename CellType, SubspaceAccess>
     48    static IsoSubspace* subspaceFor(VM& vm)
     49    {
     50        return &vm.brandedStructureSpace;
     51    }
     52
     53    ALWAYS_INLINE bool checkBrand(Symbol* brand)
     54    {
     55        UniquedStringImpl* brandUid = &brand->uid();
     56        for (BrandedStructure* currentStructure = this; currentStructure; currentStructure = currentStructure->m_parentBrand.get()) {
     57            if (brandUid == currentStructure->m_brand)
     58                return true;
     59        }
     60        return false;
     61    }
     62
     63private:
     64    BrandedStructure(VM&, Structure*, UniquedStringImpl* brand, DeferredStructureTransitionWatchpointFire*);
     65    BrandedStructure(VM&, BrandedStructure*, DeferredStructureTransitionWatchpointFire*);
     66
     67    static Structure* create(VM&, Structure*, UniquedStringImpl* brand, DeferredStructureTransitionWatchpointFire* = nullptr);
     68
     69    UniquedStringImpl* m_brand;
     70    WriteBarrier<BrandedStructure> m_parentBrand;
     71
     72    friend class Structure;
    3773};
    3874
    39 static_assert(sizeof(DirectEvalExecutable) == sizeof(EvalExecutable), "");
    40 
    4175} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp

    r270991 r272580  
    995995        m_constantIdentifierSets.encode(encoder, rareData.m_constantIdentifierSets);
    996996        m_needsClassFieldInitializer = rareData.m_needsClassFieldInitializer;
     997        m_privateBrandRequirement = rareData.m_privateBrandRequirement;
    997998    }
    998999
     
    10091010        m_constantIdentifierSets.decode(decoder, rareData->m_constantIdentifierSets);
    10101011        rareData->m_needsClassFieldInitializer = m_needsClassFieldInitializer;
     1012        rareData->m_privateBrandRequirement = m_privateBrandRequirement;
    10111013        return rareData;
    10121014    }
     
    10221024    CachedVector<CachedConstantIdentifierSetEntry> m_constantIdentifierSets;
    10231025    unsigned m_needsClassFieldInitializer : 1;
    1024 };
     1026    unsigned m_privateBrandRequirement : 1;
     1027};
     1028
     1029typedef CachedHashMap<CachedRefPtr<CachedUniquedStringImpl, UniquedStringImpl, WTF::PackedPtrTraits<UniquedStringImpl>>, PrivateNameEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, PrivateNameEntryHashTraits> CachedPrivateNameEnvironment;
    10251030
    10261031class CachedVariableEnvironmentRareData : public CachedObject<VariableEnvironment::RareData> {
     
    10371042
    10381043private:
    1039     CachedHashMap<CachedRefPtr<CachedUniquedStringImpl, UniquedStringImpl, WTF::PackedPtrTraits<UniquedStringImpl>>, PrivateNameEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, PrivateNameEntryHashTraits> m_privateNames;
     1044    CachedPrivateNameEnvironment m_privateNames;
    10401045};
    10411046
     
    12141219
    12151220private:
    1216     CachedHashSet<CachedRefPtr<CachedUniquedStringImpl>, IdentifierRepHash> m_privateNames;
     1221    CachedPrivateNameEnvironment m_privateNames;
    12171222};
    12181223
     
    17911796        m_classSource.encode(encoder, rareData.m_classSource);
    17921797        m_parentScopeTDZVariables.encode(encoder, rareData.m_parentScopeTDZVariables);
     1798        m_parentPrivateNameEnvironment.encode(encoder, rareData.m_parentPrivateNameEnvironment);
    17931799    }
    17941800
     
    17981804        m_classSource.decode(decoder, rareData->m_classSource);
    17991805        m_parentScopeTDZVariables.decode(decoder, rareData->m_parentScopeTDZVariables);
     1806        m_parentPrivateNameEnvironment.decode(decoder, rareData->m_parentPrivateNameEnvironment);
    18001807        return rareData;
    18011808    }
     
    18041811    CachedSourceCodeWithoutProvider m_classSource;
    18051812    CachedRefPtr<CachedTDZEnvironmentLink> m_parentScopeTDZVariables;
     1813    CachedPrivateNameEnvironment m_parentPrivateNameEnvironment;
    18061814};
    18071815
     
    18391847    unsigned derivedContextType() const { return m_derivedContextType; }
    18401848    unsigned needsClassFieldInitializer() const { return m_needsClassFieldInitializer; }
     1849    unsigned privateBrandRequirement() const { return m_privateBrandRequirement; }
    18411850
    18421851    Identifier name(Decoder& decoder) const { return m_name.decode(decoder); }
     
    18671876    unsigned m_typeProfilingStartOffset;
    18681877    unsigned m_typeProfilingEndOffset;
    1869     unsigned m_parameterCount;
     1878    unsigned m_parameterCount:31;
     1879    unsigned m_privateBrandRequirement : 1;
    18701880    SourceParseMode m_sourceParseMode;
    18711881    unsigned m_constructorKind : 2;
     
    19241934    unsigned constructorKind() const { return m_constructorKind; }
    19251935    unsigned derivedContextType() const { return m_derivedContextType; }
    1926     unsigned needsClassFieldInitializer() const { return m_needsClassFieldInitializer; }
    19271936    unsigned evalContextType() const { return m_evalContextType; }
    19281937    unsigned hasTailCalls() const { return m_hasTailCalls; }
     
    19561965    unsigned m_constructorKind : 2;
    19571966    unsigned m_derivedContextType : 2;
    1958     unsigned m_needsClassFieldInitializer : 1;
    19591967    unsigned m_evalContextType : 2;
    19601968    unsigned m_hasTailCalls : 1;
     
    22372245    m_derivedContextType = executable.m_derivedContextType;
    22382246    m_needsClassFieldInitializer = executable.m_needsClassFieldInitializer;
     2247    m_privateBrandRequirement = executable.m_privateBrandRequirement;
    22392248
    22402249    m_rareData.encode(encoder, executable.m_rareData.get());
     
    22782287    , m_typeProfilingEndOffset(cachedExecutable.typeProfilingEndOffset())
    22792288    , m_parameterCount(cachedExecutable.parameterCount())
     2289    , m_privateBrandRequirement(cachedExecutable.privateBrandRequirement())
    22802290    , m_features(cachedExecutable.features())
    22812291    , m_sourceParseMode(cachedExecutable.sourceParseMode())
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r270870 r272580  
    7272
    7373template <class UnlinkedCodeBlockType, class ExecutableType = ScriptExecutable>
    74 UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, DerivedContextType derivedContextType, bool isArrowFunctionContext, const TDZEnvironment* variablesUnderTDZ = nullptr, const VariableEnvironment* parentScopePrivateNames = nullptr, ExecutableType* executable = nullptr)
     74UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, DerivedContextType derivedContextType, bool isArrowFunctionContext, const TDZEnvironment* variablesUnderTDZ = nullptr, const PrivateNameEnvironment* privateNameEnvironment = nullptr, ExecutableType* executable = nullptr)
    7575{
    7676    typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
     
    7878
    7979    std::unique_ptr<RootNode> rootNode = parse<RootNode>(
    80         vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, strictMode, scriptMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType, nullptr, parentScopePrivateNames, nullptr, isInsideOrdinaryFunction);
     80        vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, strictMode, scriptMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType, nullptr, privateNameEnvironment, nullptr, isInsideOrdinaryFunction);
    8181
    8282    if (!rootNode)
     
    9595    ECMAMode ecmaMode = rootNode->features() & StrictModeFeature ? ECMAMode::strict() : ECMAMode::sloppy();
    9696    NeedsClassFieldInitializer needsClassFieldInitializer = NeedsClassFieldInitializer::No;
    97     if constexpr (std::is_same_v<ExecutableType, DirectEvalExecutable>)
     97    PrivateBrandRequirement privateBrandRequirement = PrivateBrandRequirement::None;
     98    if constexpr (std::is_same_v<ExecutableType, DirectEvalExecutable>) {
    9899        needsClassFieldInitializer = executable->needsClassFieldInitializer();
    99     ExecutableInfo executableInfo(usesEval, false, false, ConstructorKind::None, scriptMode, SuperBinding::NotNeeded, CacheTypes<UnlinkedCodeBlockType>::parseMode, derivedContextType, needsClassFieldInitializer, isArrowFunctionContext, false, evalContextType);
     100        privateBrandRequirement = executable->privateBrandRequirement();
     101    }
     102    ExecutableInfo executableInfo(usesEval, false, privateBrandRequirement, false, ConstructorKind::None, scriptMode, SuperBinding::NotNeeded, CacheTypes<UnlinkedCodeBlockType>::parseMode, derivedContextType, needsClassFieldInitializer, isArrowFunctionContext, false, evalContextType);
    100103
    101104    UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(vm, executableInfo, codeGenerationMode);
     
    109112    if (variablesUnderTDZ)
    110113        parentVariablesUnderTDZ = TDZEnvironmentLink::create(vm.m_compactVariableMap->get(*variablesUnderTDZ), nullptr);
    111     error = BytecodeGenerator::generate(vm, rootNode.get(), source, unlinkedCodeBlock, codeGenerationMode, parentVariablesUnderTDZ, ecmaMode);
     114    error = BytecodeGenerator::generate(vm, rootNode.get(), source, unlinkedCodeBlock, codeGenerationMode, parentVariablesUnderTDZ, privateNameEnvironment, ecmaMode);
    112115
    113116    if (error.isValid())
     
    118121
    119122template <class UnlinkedCodeBlockType, class ExecutableType>
    120 UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ = nullptr, const VariableEnvironment* parentScopePrivateNames = nullptr)
    121 {
    122     return generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType, ExecutableType>(vm, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, parentScopePrivateNames, executable);
    123 }
    124 
    125 UnlinkedEvalCodeBlock* generateUnlinkedCodeBlockForDirectEval(VM& vm, DirectEvalExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ, const VariableEnvironment* parentScopePrivateNames)
    126 {
    127     return generateUnlinkedCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, variablesUnderTDZ, parentScopePrivateNames);
     123UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ = nullptr, const PrivateNameEnvironment* privateNameEnvironment = nullptr)
     124{
     125    return generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType, ExecutableType>(vm, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, privateNameEnvironment, executable);
     126}
     127
     128UnlinkedEvalCodeBlock* generateUnlinkedCodeBlockForDirectEval(VM& vm, DirectEvalExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ, const PrivateNameEnvironment* privateNameEnvironment)
     129{
     130    return generateUnlinkedCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, variablesUnderTDZ, privateNameEnvironment);
    128131}
    129132
     
    249252    // in the global lexical environment, which we always TDZ check accesses from.
    250253    ConstructAbility constructAbility = constructAbilityForParseMode(metadata->parseMode());
    251     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(vm, source, metadata, UnlinkedNormalFunction, constructAbility, JSParserScriptMode::Classic, nullptr, DerivedContextType::None, NeedsClassFieldInitializer::No);
     254    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(vm, source, metadata, UnlinkedNormalFunction, constructAbility, JSParserScriptMode::Classic, nullptr, WTF::nullopt, DerivedContextType::None, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None);
    252255
    253256    if (!source.provider()->sourceURLDirective().isNull())
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r269115 r272580  
    255255};
    256256
    257 UnlinkedEvalCodeBlock* generateUnlinkedCodeBlockForDirectEval(VM&, DirectEvalExecutable*, const SourceCode&, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>, ParserError&, EvalContextType, const TDZEnvironment* variablesUnderTDZ, const VariableEnvironment* parentScopePrivateNames);
     257UnlinkedEvalCodeBlock* generateUnlinkedCodeBlockForDirectEval(VM&, DirectEvalExecutable*, const SourceCode&, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>, ParserError&, EvalContextType, const TDZEnvironment* variablesUnderTDZ, const PrivateNameEnvironment*);
    258258UnlinkedProgramCodeBlock* recursivelyGenerateUnlinkedCodeBlockForProgram(VM&, const SourceCode&, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>, ParserError&, EvalContextType);
    259259UnlinkedModuleProgramCodeBlock* recursivelyGenerateUnlinkedCodeBlockForModuleProgram(VM&, const SourceCode&, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>, ParserError&, EvalContextType);
  • trunk/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp

    r269115 r272580  
    3535namespace JSC {
    3636
    37 DirectEvalExecutable* DirectEvalExecutable::create(JSGlobalObject* globalObject, const SourceCode& source, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ, const VariableEnvironment* privateNames, ECMAMode ecmaMode)
     37DirectEvalExecutable* DirectEvalExecutable::create(JSGlobalObject* globalObject, const SourceCode& source, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ, const PrivateNameEnvironment* privateNameEnvironment, ECMAMode ecmaMode)
    3838{
    3939    VM& vm = globalObject->vm();
     
    4545    }
    4646
    47     auto* executable = new (NotNull, allocateCell<DirectEvalExecutable>(vm.heap)) DirectEvalExecutable(globalObject, source, ecmaMode.isStrict(), derivedContextType, needsClassFieldInitializer, isArrowFunctionContext, isInsideOrdinaryFunction, evalContextType);
     47    auto* executable = new (NotNull, allocateCell<DirectEvalExecutable>(vm.heap)) DirectEvalExecutable(globalObject, source, ecmaMode.isStrict(), derivedContextType, needsClassFieldInitializer, privateBrandRequirement, isArrowFunctionContext, isInsideOrdinaryFunction, evalContextType);
    4848    executable->finishCreation(vm);
    4949
     
    5353
    5454    // We don't bother with CodeCache here because direct eval uses a specialized DirectEvalCodeCache.
    55     UnlinkedEvalCodeBlock* unlinkedEvalCode = generateUnlinkedCodeBlockForDirectEval(vm, executable, executable->source(), strictMode, JSParserScriptMode::Classic, codeGenerationMode, error, evalContextType, variablesUnderTDZ, privateNames);
     55    UnlinkedEvalCodeBlock* unlinkedEvalCode = generateUnlinkedCodeBlockForDirectEval(vm, executable, executable->source(), strictMode, JSParserScriptMode::Classic, codeGenerationMode, error, evalContextType, variablesUnderTDZ, privateNameEnvironment);
    5656
    5757    if (globalObject->hasDebugger())
     
    6868}
    6969
    70 DirectEvalExecutable::DirectEvalExecutable(JSGlobalObject* globalObject, const SourceCode& source, bool inStrictContext, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType evalContextType)
    71     : EvalExecutable(globalObject, source, inStrictContext, derivedContextType, isArrowFunctionContext, isInsideOrdinaryFunction, evalContextType, needsClassFieldInitializer)
     70DirectEvalExecutable::DirectEvalExecutable(JSGlobalObject* globalObject, const SourceCode& source, bool inStrictContext, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType evalContextType)
     71    : EvalExecutable(globalObject, source, inStrictContext, derivedContextType, isArrowFunctionContext, isInsideOrdinaryFunction, evalContextType, needsClassFieldInitializer, privateBrandRequirement)
    7272{
    73     ASSERT(needsClassFieldInitializer == NeedsClassFieldInitializer::No || derivedContextType == DerivedContextType::DerivedConstructorContext);
     73    ASSERT((needsClassFieldInitializer == NeedsClassFieldInitializer::No && privateBrandRequirement == PrivateBrandRequirement::None) || derivedContextType == DerivedContextType::DerivedConstructorContext);
    7474}
    7575
  • trunk/Source/JavaScriptCore/runtime/DirectEvalExecutable.h

    r269115 r272580  
    3232class DirectEvalExecutable final : public EvalExecutable {
    3333public:
    34     static DirectEvalExecutable* create(JSGlobalObject*, const SourceCode&, DerivedContextType, NeedsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType, const TDZEnvironment* parentScopeTDZVariables, const VariableEnvironment* privateNames, ECMAMode);
     34    static DirectEvalExecutable* create(JSGlobalObject*, const SourceCode&, DerivedContextType, NeedsClassFieldInitializer, PrivateBrandRequirement, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType, const TDZEnvironment* parentScopeTDZVariables, const PrivateNameEnvironment*, ECMAMode);
    3535private:
    36     DirectEvalExecutable(JSGlobalObject*, const SourceCode&, bool inStrictContext, DerivedContextType, NeedsClassFieldInitializer, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType);
     36    DirectEvalExecutable(JSGlobalObject*, const SourceCode&, bool inStrictContext, DerivedContextType, NeedsClassFieldInitializer, PrivateBrandRequirement, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType);
    3737};
    3838
  • trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp

    r261895 r272580  
    3333const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(EvalExecutable) };
    3434
    35 EvalExecutable::EvalExecutable(JSGlobalObject* globalObject, const SourceCode& source, bool inStrictContext, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType evalContextType, NeedsClassFieldInitializer needsClassFieldInitializer)
     35EvalExecutable::EvalExecutable(JSGlobalObject* globalObject, const SourceCode& source, bool inStrictContext, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType evalContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement)
    3636    : Base(globalObject->vm().evalExecutableStructure.get(), globalObject->vm(), source, inStrictContext, derivedContextType, isArrowFunctionContext, isInsideOrdinaryFunction, evalContextType, NoIntrinsic)
    3737    , m_needsClassFieldInitializer(static_cast<unsigned>(needsClassFieldInitializer))
     38    , m_privateBrandRequirement(static_cast<unsigned>(privateBrandRequirement))
    3839{
    3940    ASSERT(source.provider()->sourceType() == SourceProviderSourceType::Program);
  • trunk/Source/JavaScriptCore/runtime/EvalExecutable.h

    r259676 r272580  
    6363    DECLARE_INFO;
    6464
    65     ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), needsClassFieldInitializer(), isArrowFunctionContext(), false, evalContextType()); }
     65    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, PrivateBrandRequirement::None, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), needsClassFieldInitializer(), isArrowFunctionContext(), false, evalContextType()); }
    6666
    6767    unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
     
    7070    bool allowDirectEvalCache() const { return m_unlinkedEvalCodeBlock->allowDirectEvalCache(); }
    7171    NeedsClassFieldInitializer needsClassFieldInitializer() const { return static_cast<NeedsClassFieldInitializer>(m_needsClassFieldInitializer); }
     72    PrivateBrandRequirement privateBrandRequirement() const { return static_cast<PrivateBrandRequirement>(m_privateBrandRequirement); }
    7273    TemplateObjectMap& ensureTemplateObjectMap(VM&);
    7374
     
    7778
    7879    using Base::finishCreation;
    79     EvalExecutable(JSGlobalObject*, const SourceCode&, bool inStrictContext, DerivedContextType, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType, NeedsClassFieldInitializer);
     80    EvalExecutable(JSGlobalObject*, const SourceCode&, bool inStrictContext, DerivedContextType, bool isArrowFunctionContext, bool isInsideOrdinaryFunction, EvalContextType, NeedsClassFieldInitializer, PrivateBrandRequirement);
    8081
    8182    static void visitChildren(JSCell*, SlotVisitor&);
    8283
    8384    unsigned m_needsClassFieldInitializer : 1;
     85    unsigned m_privateBrandRequirement : 1;
    8486
    8587    WriteBarrier<ExecutableToCodeBlockEdge> m_evalCodeBlock;
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r262613 r272580  
    335335}
    336336
     337JSObject* createPrivateMethodAccessError(JSGlobalObject* globalObject)
     338{
     339    return createTypeError(globalObject, makeString("Cannot access private method"_s), defaultSourceAppender, TypeNothing);
     340}
     341
     342JSObject* createReinstallPrivateMethodError(JSGlobalObject* globalObject)
     343{
     344    return createTypeError(globalObject, makeString("Cannot install same private methods on object more than once"_s), defaultSourceAppender, TypeNothing);
     345}
     346
    337347Exception* throwOutOfMemoryError(JSGlobalObject* globalObject, ThrowScope& scope)
    338348{
  • trunk/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp

    r261755 r272580  
    7070constexpr bool insideOrdinaryFunction = false;
    7171IndirectEvalExecutable::IndirectEvalExecutable(JSGlobalObject* globalObject, const SourceCode& source, DerivedContextType derivedContextType, bool isArrowFunctionContext, EvalContextType evalContextType)
    72     : EvalExecutable(globalObject, source, inStrictContext, derivedContextType, isArrowFunctionContext, insideOrdinaryFunction, evalContextType, NeedsClassFieldInitializer::No)
     72    : EvalExecutable(globalObject, source, inStrictContext, derivedContextType, isArrowFunctionContext, insideOrdinaryFunction, evalContextType, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None)
    7373{
    7474}
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r271269 r272580  
    185185    inline void setPrivateField(JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
    186186    inline void definePrivateField(JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
     187    inline bool checkPrivateBrand(JSGlobalObject*, JSValue brand);
     188    inline void setPrivateBrand(JSGlobalObject*, JSValue brand);
    187189
    188190    unsigned getArrayLength() const
  • trunk/Source/JavaScriptCore/runtime/JSObjectInlines.h

    r271599 r272580  
    2525
    2626#include "AuxiliaryBarrierInlines.h"
     27#include "BrandedStructure.h"
    2728#include "ButterflyInlines.h"
    2829#include "Error.h"
     
    579580JSObject* createInvalidPrivateNameError(JSGlobalObject*);
    580581JSObject* createRedefinedPrivateNameError(JSGlobalObject*);
     582JSObject* createReinstallPrivateMethodError(JSGlobalObject*);
     583JSObject* createPrivateMethodAccessError(JSGlobalObject*);
    581584
    582585ALWAYS_INLINE bool JSObject::getPrivateFieldSlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
     
    670673}
    671674
     675inline bool JSObject::checkPrivateBrand(JSGlobalObject* globalObject, JSValue brand)
     676{
     677    ASSERT(brand.isSymbol());
     678    VM& vm = getVM(globalObject);
     679    auto scope = DECLARE_THROW_SCOPE(vm);
     680
     681    Structure* structure = this->structure(vm);
     682    if (!structure->isBrandedStructure() || !jsCast<BrandedStructure*>(structure)->checkBrand(asSymbol(brand))) {
     683        throwException(globalObject, scope, createPrivateMethodAccessError(globalObject));
     684        RELEASE_AND_RETURN(scope, false);
     685    }
     686    EXCEPTION_ASSERT(!scope.exception());
     687
     688    return true;
     689}
     690
     691inline void JSObject::setPrivateBrand(JSGlobalObject* globalObject, JSValue brand)
     692{
     693    ASSERT(brand.isSymbol());
     694    VM& vm = getVM(globalObject);
     695    auto scope = DECLARE_THROW_SCOPE(vm);
     696
     697    Structure* structure = this->structure(vm);
     698    if (structure->isBrandedStructure() && jsCast<BrandedStructure*>(structure)->checkBrand(asSymbol(brand))) {
     699        throwException(globalObject, scope, createReinstallPrivateMethodError(globalObject));
     700        RELEASE_AND_RETURN(scope, void());
     701    }
     702    EXCEPTION_ASSERT(!scope.exception());
     703
     704    scope.release();
     705
     706    DeferredStructureTransitionWatchpointFire deferredWatchpointFire(vm, structure);
     707
     708    Structure* newStructure = Structure::setBrandTransition(vm, structure, asSymbol(brand), &deferredWatchpointFire);
     709    ASSERT(newStructure->isBrandedStructure());
     710    ASSERT(newStructure->outOfLineCapacity() || !this->structure(vm)->outOfLineCapacity());
     711    this->setStructure(vm, newStructure);
     712}
     713
    672714} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSScope.cpp

    r269115 r272580  
    322322}
    323323
    324 void JSScope::collectClosureVariablesUnderTDZ(JSScope* scope, TDZEnvironment& result, VariableEnvironment& privateNames)
     324void JSScope::collectClosureVariablesUnderTDZ(JSScope* scope, TDZEnvironment& result, PrivateNameEnvironment& privateNameEnvironment)
    325325{
    326326    for (; scope; scope = scope->next()) {
     
    341341
    342342        if (symbolTable->hasPrivateNames()) {
    343             for (auto name : symbolTable->privateNames())
    344                 privateNames.usePrivateName(name);   
     343            auto privateNames = symbolTable->privateNames();
     344            for (auto end = privateNames.end(), iter = privateNames.begin(); iter != end; ++iter)
     345                privateNameEnvironment.add(iter->key, iter->value);
    345346        }
    346347    }
  • trunk/Source/JavaScriptCore/runtime/JSScope.h

    r269115 r272580  
    2828#include "GetPutInfo.h"
    2929#include "JSObject.h"
     30#include "VariableEnvironment.h"
    3031
    3132namespace JSC {
     
    3334class ScopeChainIterator;
    3435class SymbolTable;
    35 class VariableEnvironment;
    3636class WatchpointSet;
    3737
     
    6363    static JSScope* constantScopeForCodeBlock(ResolveType, CodeBlock*);
    6464
    65     static void collectClosureVariablesUnderTDZ(JSScope*, TDZEnvironment& result, VariableEnvironment& privateNames);
     65    static void collectClosureVariablesUnderTDZ(JSScope*, TDZEnvironment& result, PrivateNameEnvironment&);
    6666
    6767    static void visitChildren(JSCell*, SlotVisitor&);
  • trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h

    r259676 r272580  
    6464    DECLARE_INFO;
    6565
    66     ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, false, ConstructorKind::None, JSParserScriptMode::Module, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), NeedsClassFieldInitializer::No, isArrowFunctionContext(), false, EvalContextType::None); }
     66    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, PrivateBrandRequirement::None, false, ConstructorKind::None, JSParserScriptMode::Module, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), NeedsClassFieldInitializer::No, isArrowFunctionContext(), false, EvalContextType::None); }
    6767
    6868    UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r272085 r272580  
    540540    else if (Options::randomIntegrityAuditRate() > 1.0)
    541541        Options::randomIntegrityAuditRate() = 1.0;
     542   
     543    if (Options::usePrivateMethods())
     544        Options::usePrivateClassFields() = true;
    542545
    543546    if (!Options::allowUnsupportedTiers()) {
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r272074 r272580  
    513513    v(Bool, allowUnsupportedTiers, false, Normal, "If true, we will not disable DFG or FTL when an experimental feature is enabled.") \
    514514    v(Bool, usePrivateClassFields, true, Normal, "If true, the parser will understand private data fields inside classes.") \
     515    v(Bool, usePrivateMethods, false, Normal, "If true, the parser will understand private methods inside classes.") \
    515516    v(Bool, returnEarlyFromInfiniteLoopsForFuzzing, false, Normal, nullptr) \
    516517    v(Size, earlyReturnFromInfiniteLoopsLimit, 1300000000, Normal, "When returnEarlyFromInfiniteLoopsForFuzzing is true, this determines the number of executions a loop can run for before just returning. This is helpful for the fuzzer so it doesn't get stuck in infinite loops.") \
     
    569570
    570571#define FOR_EACH_JSC_EXPERIMENTAL_OPTION(v) \
    571     v(usePrivateClassFields, (SupportsFTL | SupportsDFG), "https://bugs.webkit.org/show_bug.cgi?id=212781", "https://bugs.webkit.org/show_bug.cgi?id=212784")
     572    v(usePrivateClassFields, (SupportsFTL | SupportsDFG), "https://bugs.webkit.org/show_bug.cgi?id=212781", "https://bugs.webkit.org/show_bug.cgi?id=212784") \
     573    v(usePrivateMethods, (SupportsFTL | SupportsDFG), "https://bugs.webkit.org/show_bug.cgi?id=194434", "https://bugs.webkit.org/show_bug.cgi?id=194434")
    572574
    573575constexpr size_t countNumberOfJSCOptions()
  • trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h

    r259676 r272580  
    7272    DECLARE_INFO;
    7373
    74     ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), NeedsClassFieldInitializer::No, isArrowFunctionContext(), false, EvalContextType::None); }
     74    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, PrivateBrandRequirement::None, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), NeedsClassFieldInitializer::No, isArrowFunctionContext(), false, EvalContextType::None); }
    7575
    7676    TemplateObjectMap& ensureTemplateObjectMap(VM&);
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r271269 r272580  
    2828#include "Structure.h"
    2929
     30#include "BrandedStructure.h"
    3031#include "BuiltinNames.h"
    3132#include "DumpContext.h"
     
    425426    for (size_t i = structures.size(); i--;) {
    426427        structure = structures[i];
    427         if (!structure->m_transitionPropertyName)
     428        if (!structure->m_transitionPropertyName || structure->transitionKind() == TransitionKind::SetBrand)
    428429            continue;
    429430        switch (structure->transitionKind()) {
     
    14971498}
    14981499
     1500Structure* Structure::setBrandTransitionFromExistingStructureImpl(Structure* structure, UniquedStringImpl* brandID)
     1501{
     1502    ASSERT(structure->isObject());
     1503
     1504    if (structure->hasBeenDictionary())
     1505        return nullptr;
     1506
     1507    if (Structure* existingTransition = structure->m_transitionTable.get(brandID, 0, TransitionKind::SetBrand))
     1508        return existingTransition;
     1509
     1510    return nullptr;
     1511}
     1512
     1513Structure* Structure::setBrandTransitionFromExistingStructureConcurrently(Structure* structure, UniquedStringImpl* brandID)
     1514{
     1515    ConcurrentJSLocker locker(structure->m_lock);
     1516    return setBrandTransitionFromExistingStructureImpl(structure, brandID);
     1517}
     1518
     1519Structure* Structure::setBrandTransition(VM& vm, Structure* structure, Symbol* brand, DeferredStructureTransitionWatchpointFire* deferred)
     1520{
     1521    Structure* existingTransition = setBrandTransitionFromExistingStructureImpl(structure, &brand->uid());
     1522    if (existingTransition)
     1523        return existingTransition;
     1524
     1525    Structure* transition = BrandedStructure::create(vm, structure, &brand->uid(), deferred);
     1526    transition->setTransitionKind(TransitionKind::SetBrand);
     1527
     1528    transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
     1529    transition->m_blob.setIndexingModeIncludingHistory(structure->indexingModeIncludingHistory());
     1530    transition->m_transitionPropertyName = &brand->uid();
     1531    transition->setTransitionPropertyAttributes(0);
     1532    transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm));
     1533    transition->setMaxOffset(vm, structure->maxOffset());
     1534    checkOffset(transition->maxOffset(), transition->inlineCapacity());
     1535
     1536    if (structure->isDictionary()) {
     1537        PropertyTable* table = transition->ensurePropertyTable(vm);
     1538        transition->pin(holdLock(transition->m_lock), vm, table);
     1539    } else {
     1540        auto locker = holdLock(structure->m_lock);
     1541        structure->m_transitionTable.add(vm, transition);
     1542    }
     1543
     1544    transition->checkOffsetConsistency();
     1545    return transition;
     1546}
     1547
    14991548} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r271269 r272580  
    124124};
    125125
    126 class Structure final : public JSCell {
     126class Structure : public JSCell {
    127127    static constexpr uint16_t shortInvalidOffset = std::numeric_limits<uint16_t>::max() - 1;
    128128    static constexpr uint16_t useRareDataFlag = std::numeric_limits<uint16_t>::max();
     
    147147    JS_EXPORT_PRIVATE static bool isValidPrototype(JSValue);
    148148
    149 private:
    150     void finishCreation(VM& vm)
    151     {
    152         Base::finishCreation(vm);
    153         ASSERT(m_prototype.get().isEmpty() || isValidPrototype(m_prototype.get()));
    154     }
    155 
     149protected:
    156150    void finishCreation(VM& vm, const Structure* previous)
    157151    {
     
    164158            }
    165159        }
     160    }
     161
     162private:
     163    void finishCreation(VM& vm)
     164    {
     165        Base::finishCreation(vm);
     166        ASSERT(m_prototype.get().isEmpty() || isValidPrototype(m_prototype.get()));
    166167    }
    167168
     
    207208    static Structure* nonPropertyTransition(VM&, Structure*, TransitionKind);
    208209    JS_EXPORT_PRIVATE static Structure* nonPropertyTransitionSlow(VM&, Structure*, TransitionKind);
     210    static Structure* setBrandTransitionFromExistingStructureConcurrently(Structure*, UniquedStringImpl*);
     211    static Structure* setBrandTransition(VM&, Structure*, Symbol* brand, DeferredStructureTransitionWatchpointFire* = nullptr);
    209212
    210213    JS_EXPORT_PRIVATE bool isSealed(VM&);
     
    716719    DEFINE_BITFIELD(bool, protectPropertyTableWhileTransitioning, ProtectPropertyTableWhileTransitioning, 1, 28);
    717720    DEFINE_BITFIELD(bool, hasUnderscoreProtoPropertyExcludingOriginalProto, HasUnderscoreProtoPropertyExcludingOriginalProto, 1, 29);
     721    DEFINE_BITFIELD(bool, isBrandedStructure, IsBrandedStructure, 1, 30);
    718722
    719723    static_assert(s_bitWidthOfTransitionPropertyAttributes <= sizeof(TransitionPropertyAttributes) * 8);
    720724    static_assert(s_bitWidthOfTransitionKind <= sizeof(TransitionKind) * 8);
    721725
     726protected:
     727    Structure(VM&, Structure*, DeferredStructureTransitionWatchpointFire*);
     728
    722729private:
    723730    friend class LLIntOffsetsExtractor;
     
    725732    JS_EXPORT_PRIVATE Structure(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
    726733    Structure(VM&);
    727     Structure(VM&, Structure*, DeferredStructureTransitionWatchpointFire*);
    728734
    729735    static Structure* create(VM&, Structure*, DeferredStructureTransitionWatchpointFire* = nullptr);
     
    731737    static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, UniquedStringImpl* uid, unsigned attributes, PropertyOffset&);
    732738    static Structure* removePropertyTransitionFromExistingStructureImpl(Structure*, PropertyName, unsigned attributes, PropertyOffset&);
     739    static Structure* setBrandTransitionFromExistingStructureImpl(Structure*, UniquedStringImpl*);
    733740
    734741    // This will return the structure that has a usable property table, that property table,
  • trunk/Source/JavaScriptCore/runtime/StructureInlines.h

    r272430 r272580  
    2626#pragma once
    2727
     28#include "BrandedStructure.h"
    2829#include "JSArrayBufferView.h"
    2930#include "JSCJSValueInlines.h"
     
    6263{
    6364    ASSERT(vm.structureStructure);
    64     Structure* newStructure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm, previous, deferred);
     65    Structure* newStructure;
     66    if (previous->isBrandedStructure())
     67        newStructure = new (NotNull, allocateCell<BrandedStructure>(vm.heap)) BrandedStructure(vm, jsCast<BrandedStructure*>(previous), deferred);
     68    else
     69        newStructure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm, previous, deferred);
     70
    6571    newStructure->finishCreation(vm, previous);
    6672    return newStructure;
     
    182188            break;
    183189        case TransitionKind::PropertyDeletion:
     190        case TransitionKind::SetBrand:
    184191            continue;
    185192        default:
  • trunk/Source/JavaScriptCore/runtime/StructureTransitionTable.h

    r265640 r272580  
    5656    PreventExtensions,
    5757    Seal,
    58     Freeze
     58    Freeze,
     59
     60    // Support for transitions related with private brand
     61    SetBrand
    5962};
    6063
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp

    r262613 r272580  
    185185        {
    186186            for (auto name : m_rareData->m_privateNames)
    187                 result->m_rareData->m_privateNames.add(name);
     187                result->m_rareData->m_privateNames.add(name.key, name.value);
    188188        }
    189189    }
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r263117 r272580  
    3636#include "TypeLocation.h"
    3737#include "VarOffset.h"
     38#include "VariableEnvironment.h"
    3839#include "Watchpoint.h"
    3940#include <memory>
     
    451452    typedef HashMap<VarOffset, RefPtr<UniquedStringImpl>> OffsetToVariableMap;
    452453    typedef Vector<SymbolTableEntry*> LocalToEntryVec;
    453     typedef HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> PrivateNameSet;
    454     typedef WTF::IteratorRange<typename PrivateNameSet::iterator> PrivateNameIteratorRange;
     454    typedef WTF::IteratorRange<typename PrivateNameEnvironment::iterator> PrivateNameIteratorRange;
    455455
    456456    template<typename CellType, SubspaceAccess>
     
    606606    }
    607607
    608     void addPrivateName(UniquedStringImpl* key)
     608    void addPrivateName(const RefPtr<UniquedStringImpl>& key, PrivateNameEntry value)
    609609    {
    610610        ASSERT(key && !key->isSymbol());
     
    612612            m_rareData = WTF::makeUnique<SymbolTableRareData>();
    613613
    614         ASSERT(!m_rareData->m_privateNames.contains(key));
    615         m_rareData->m_privateNames.add(key);
     614        ASSERT(m_rareData->m_privateNames.find(key) == m_rareData->m_privateNames.end());
     615        m_rareData->m_privateNames.add(key, value);
    616616    }
    617617
     
    757757        UniqueTypeSetMap m_uniqueTypeSetMap;
    758758        WriteBarrier<CodeBlock> m_codeBlock;
    759         PrivateNameSet m_privateNames;
     759        PrivateNameEnvironment m_privateNames;
    760760    };
    761761
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r272170 r272580  
    3434#include "BigIntObject.h"
    3535#include "BooleanObject.h"
     36#include "BrandedStructure.h"
    3637#include "BuiltinExecutables.h"
    3738#include "BytecodeIntrinsicRegistry.h"
     
    370371    , structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData) // Hash:0xaca4e62d
    371372    , structureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), Structure) // Hash:0x1f1bcdca
     373    , brandedStructureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), BrandedStructure)
    372374    , symbolTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), SymbolTable) // Hash:0xc5215afd
    373375    , executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace)
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r272170 r272580  
    466466    IsoSubspace structureRareDataSpace;
    467467    IsoSubspace structureSpace;
     468    IsoSubspace brandedStructureSpace;
    468469    IsoSubspace symbolTableSpace;
    469470
Note: See TracChangeset for help on using the changeset viewer.