Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
[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. 2. 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: Canonical link: https://commits.webkit.org/233852@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information