Skip to content

Commit

Permalink
[JSC] Redeclaring parameter of a generator / async function makes it …
Browse files Browse the repository at this point in the history
…`undefined`

https://bugs.webkit.org/show_bug.cgi?id=223533
<rdar://problem/75899149>

Reviewed by Yusuke Suzuki.

Since under the hood, a generator / async function is implemented using two functions (wrapper and body),
parameter redeclaration with `var` requires special care.

Given the bytecode for a generator / async body function is generated with the result of reparsing,
we can't consult parent scope in parser and detect which declarations shadow parameters of the wrapper
function, hence the only way to pass that information is via bytecode generator, in rare data
of UnlinkedFunctionExecutable.

This patch prevents createVariable() from being called on `var` declarations that would otherwise
erroneously shadow generator / async wrapper function parameters, downgrading them to VarKind::Invalid
and emitting extra get_from_scope / resolve_scope ops as if `var foo;` declarations were missing.

It's sensible and safe as long as Annex B function hoisting [1] is aligned and shadowed generator /
async wrapper function parameters are marked as captured (done conservatively for all parameters).

Fixes long-standing bug that resulted in Safari breaking on minified code produced by UglifyJS
in default configuration [2].

[1]: https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation (step 29.a.ii)
[2]: mishoo/UglifyJS#5032

* JSTests/stress/regress-223533.js: Added.
* Source/JavaScriptCore/builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createExecutable):
* Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h:
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::hoistSloppyModeFunctionIfNecessary):
(JSC::BytecodeGenerator::getParameterNames const):
(JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::makeFunction):
* Source/JavaScriptCore/runtime/CachedTypes.cpp:
(JSC::CachedFunctionExecutableRareData::encode):
(JSC::CachedFunctionExecutableRareData::decode const):
* Source/JavaScriptCore/runtime/CodeCache.cpp:
(JSC::generateUnlinkedCodeBlockImpl):
(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):

Canonical link: https://commits.webkit.org/272666@main
  • Loading branch information
Alexey Shvayka committed Jan 5, 2024
1 parent f4776fc commit 8f6b201
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 24 deletions.
68 changes: 68 additions & 0 deletions JSTests/stress/regress-223533.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error(`Bad value: ${actual}!`);
}

function* test1(foo) {
shouldBe(foo, 1);
var foo;
shouldBe(foo, 1);
}

function* test2(...foo) {
shouldBe(`${foo}`, "2,2,2");
var foo = 2;
shouldBe(foo, 2);
}

async function test3([foo]) {
shouldBe(foo, 3);
var foo;
shouldBe(foo, 3);
}

async function test4(foo) {
shouldBe(foo, 4);
var foo;
shouldBe(foo, 4);
}

async function* test5({foo}) {
shouldBe(foo, 5);
var foo = 5;
shouldBe(foo, 5);
}

function* hoistingTest1(foo) {
shouldBe(foo, 1);
{
function foo() { return "hoisted"; }
}
shouldBe(foo, 1);
}

async function* hoistingTest2([foo]) {
shouldBe(foo, 2);
if (true) {
function foo() { return "hoisted"; }
}
shouldBe(foo, 2);
}

(async function() {
try {
for (let _ of test1(1)) {}
for (let _ of test2(2, 2, 2)) {}
await test3([3]);
await test4(4);
for await (let _ of test5({foo: 5})) {}

for (let _ of hoistingTest1(1)) {}
for await (let _ of hoistingTest2([2])) {}
} catch (error) {
print(`FAIL! ${error}\n${error.stack}`);
$vm.abort();
}
})();

drainMicrotasks();
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S
}
}

UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(vm, source, &metadata, kind, constructAbility, inlineAttribute, JSParserScriptMode::Classic, nullptr, std::nullopt, DerivedContextType::None, needsClassFieldInitializer, privateBrandRequirement, isBuiltinDefaultClassConstructor);
UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(vm, source, &metadata, kind, constructAbility, inlineAttribute, JSParserScriptMode::Classic, nullptr, std::nullopt, std::nullopt, DerivedContextType::None, needsClassFieldInitializer, privateBrandRequirement, isBuiltinDefaultClassConstructor);
return functionExecutable;
}

Expand Down
7 changes: 5 additions & 2 deletions Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,17 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(vm, FunctionCode, ExecutableInfo(kind == CodeForConstruct, executable->privateBrandRequirement(), functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), executable->needsClassFieldInitializer(), false, isClassContext, EvalContextType::FunctionEvalContext), codeGenerationMode);

auto parentScopeTDZVariables = executable->parentScopeTDZVariables();
const FixedVector<Identifier>* generatorOrAsyncWrapperFunctionParameterNames = executable->generatorOrAsyncWrapperFunctionParameterNames();
const PrivateNameEnvironment* parentPrivateNameEnvironment = executable->parentPrivateNameEnvironment();
error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, parentScopeTDZVariables, parentPrivateNameEnvironment);
error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, parentScopeTDZVariables, generatorOrAsyncWrapperFunctionParameterNames, parentPrivateNameEnvironment);

if (error.isValid())
return nullptr;
vm.codeCache()->updateCache(executable, source, kind, result);
return result;
}

UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, InlineAttribute inlineAttribute, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, std::optional<PrivateNameEnvironment> parentPrivateNameEnvironment, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinDefaultClassConstructor)
UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, InlineAttribute inlineAttribute, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, std::optional<Vector<Identifier>>&& generatorOrAsyncWrapperFunctionParameterNames, std::optional<PrivateNameEnvironment> parentPrivateNameEnvironment, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinDefaultClassConstructor)
: Base(vm, structure)
, m_firstLineOffset(node->firstLine() - parentSource.firstLine().oneBasedInt())
, m_isGeneratedFromCache(false)
Expand Down Expand Up @@ -132,6 +133,8 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* struct
setClassSource(node->classSource());
if (parentScopeTDZVariables)
ensureRareData().m_parentScopeTDZVariables = WTFMove(parentScopeTDZVariables);
if (generatorOrAsyncWrapperFunctionParameterNames)
ensureRareData().m_generatorOrAsyncWrapperFunctionParameterNames = FixedVector<Identifier>(WTFMove(generatorOrAsyncWrapperFunctionParameterNames.value()));
if (parentPrivateNameEnvironment)
ensureRareData().m_parentPrivateNameEnvironment = WTFMove(*parentPrivateNameEnvironment);
}
Expand Down
14 changes: 11 additions & 3 deletions Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ class UnlinkedFunctionExecutable final : public JSCell {
return &vm.unlinkedFunctionExecutableSpace();
}

static UnlinkedFunctionExecutable* create(VM& vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, InlineAttribute inlineAttribute, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, std::optional<PrivateNameEnvironment> parentPrivateNameEnvironment, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinDefaultClassConstructor = false)
static UnlinkedFunctionExecutable* create(VM& vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, InlineAttribute inlineAttribute, JSParserScriptMode scriptMode, RefPtr<TDZEnvironmentLink> parentScopeTDZVariables, std::optional<Vector<Identifier>>&& generatorOrAsyncWrapperFunctionParameterNames, std::optional<PrivateNameEnvironment> parentPrivateNameEnvironment, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, PrivateBrandRequirement privateBrandRequirement, bool isBuiltinDefaultClassConstructor = false)
{
UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm))
UnlinkedFunctionExecutable(vm, vm.unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, inlineAttribute, scriptMode, WTFMove(parentScopeTDZVariables), WTFMove(parentPrivateNameEnvironment), derivedContextType, needsClassFieldInitializer, privateBrandRequirement, isBuiltinDefaultClassConstructor);
UnlinkedFunctionExecutable(vm, vm.unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, inlineAttribute, scriptMode, WTFMove(parentScopeTDZVariables), WTFMove(generatorOrAsyncWrapperFunctionParameterNames), WTFMove(parentPrivateNameEnvironment), derivedContextType, needsClassFieldInitializer, privateBrandRequirement, isBuiltinDefaultClassConstructor);
instance->finishCreation(vm);
return instance;
}
Expand Down Expand Up @@ -182,6 +182,13 @@ class UnlinkedFunctionExecutable final : public JSCell {
return m_rareData->m_parentScopeTDZVariables;
}

const FixedVector<Identifier>* generatorOrAsyncWrapperFunctionParameterNames() const
{
if (!m_rareData)
return nullptr;
return &m_rareData->m_generatorOrAsyncWrapperFunctionParameterNames;
}

const PrivateNameEnvironment* parentPrivateNameEnvironment() const
{
if (!m_rareData)
Expand Down Expand Up @@ -225,6 +232,7 @@ class UnlinkedFunctionExecutable final : public JSCell {
String m_sourceURLDirective;
String m_sourceMappingURLDirective;
RefPtr<TDZEnvironmentLink> m_parentScopeTDZVariables;
FixedVector<Identifier> m_generatorOrAsyncWrapperFunctionParameterNames;
FixedVector<JSTextPosition> m_classFieldLocations;
PrivateNameEnvironment m_parentPrivateNameEnvironment;
};
Expand All @@ -246,7 +254,7 @@ class UnlinkedFunctionExecutable final : public JSCell {
}

private:
UnlinkedFunctionExecutable(VM&, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, InlineAttribute, JSParserScriptMode, RefPtr<TDZEnvironmentLink>, std::optional<PrivateNameEnvironment>, JSC::DerivedContextType, JSC::NeedsClassFieldInitializer, PrivateBrandRequirement, bool isBuiltinDefaultClassConstructor);
UnlinkedFunctionExecutable(VM&, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, InlineAttribute, JSParserScriptMode, RefPtr<TDZEnvironmentLink>, std::optional<Vector<Identifier>>&&, std::optional<PrivateNameEnvironment>, JSC::DerivedContextType, JSC::NeedsClassFieldInitializer, PrivateBrandRequirement, bool isBuiltinDefaultClassConstructor);
UnlinkedFunctionExecutable(Decoder&, const CachedFunctionExecutable&);

DECLARE_VISIT_CHILDREN;
Expand Down
41 changes: 32 additions & 9 deletions Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ ParserError BytecodeGenerator::generate(unsigned& size)
return ParserError(ParserError::ErrorNone);
}

BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment*)
BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const FixedVector<Identifier>*, const PrivateNameEnvironment*)
: BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
, m_codeGenerationMode(codeGenerationMode)
, m_scopeNode(programNode)
Expand Down Expand Up @@ -398,7 +398,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP
}
}

BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment* parentPrivateNameEnvironment)
BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const FixedVector<Identifier>* generatorOrAsyncWrapperFunctionParameterNames, const PrivateNameEnvironment* parentPrivateNameEnvironment)
: BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
, m_codeGenerationMode(codeGenerationMode)
, m_scopeNode(functionNode)
Expand Down Expand Up @@ -432,6 +432,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
int symbolTableConstantIndex = 0;

m_cachedParentTDZ = parentScopeTDZVariables;
m_generatorOrAsyncWrapperFunctionParameterNames = generatorOrAsyncWrapperFunctionParameterNames;

FunctionParameters& parameters = *functionNode->parameters();
// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
Expand All @@ -454,9 +455,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
m_needsGeneratorification = true;
// Generator and AsyncFunction never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
m_needsArguments = false;
}

if (isGeneratorOrAsyncFunctionWrapperParseMode(parseMode) && m_needsArguments) {
} else if (isGeneratorOrAsyncFunctionWrapperParseMode(parseMode)) {
// Generator does not provide "arguments". Instead, wrapping GeneratorFunction provides "arguments".
// This is because arguments of a generator should be evaluated before starting it.
// To workaround it, we evaluate these arguments as arguments of a wrapping generator function, and reference it from a generator.
Expand All @@ -471,7 +470,12 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
// }
// }
// }
shouldCaptureSomeOfTheThings = true;
if (m_needsArguments)
shouldCaptureSomeOfTheThings = true;
if (parameters.size()) {
shouldCaptureSomeOfTheThings = true;
shouldCaptureAllOfTheThings = true;
}
}

if (shouldCaptureAllOfTheThings)
Expand Down Expand Up @@ -718,6 +722,8 @@ IGNORE_GCC_WARNINGS_END
continue;
if (shouldCreateArgumentsVariableInParameterScope && entry.key.get() == propertyNames().arguments.impl())
continue;
if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode) && generatorOrAsyncWrapperFunctionParameterNames->contains(entry.key.get()))
continue;
createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), functionSymbolTable, IgnoreExisting);
}

Expand Down Expand Up @@ -896,7 +902,7 @@ IGNORE_GCC_WARNINGS_END
pushLexicalScope(m_scopeNode, ScopeType::LetConstScope, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
}

BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment* parentPrivateNameEnvironment)
BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const FixedVector<Identifier>*, const PrivateNameEnvironment* parentPrivateNameEnvironment)
: BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
, m_codeGenerationMode(codeGenerationMode)
, m_scopeNode(evalNode)
Expand Down Expand Up @@ -960,7 +966,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
pushLexicalScope(m_scopeNode, ScopeType::LetConstScope, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
}

BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const PrivateNameEnvironment*)
BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const RefPtr<TDZEnvironmentLink>& parentScopeTDZVariables, const FixedVector<Identifier>*, const PrivateNameEnvironment*)
: BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
, m_codeGenerationMode(codeGenerationMode)
, m_scopeNode(moduleProgramNode)
Expand Down Expand Up @@ -2195,6 +2201,13 @@ void BytecodeGenerator::hoistSloppyModeFunctionIfNecessary(FunctionMetadataNode*
{
if (metadata->isSloppyModeHoistedFunction()) {
const Identifier& functionName = metadata->ident();

if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode())) {
RELEASE_ASSERT(m_generatorOrAsyncWrapperFunctionParameterNames);
if (m_generatorOrAsyncWrapperFunctionParameterNames->contains(functionName))
return;
}

Variable currentFunctionVariable = variable(functionName);
RefPtr<RegisterID> currentValue;
if (RegisterID* local = currentFunctionVariable.local())
Expand Down Expand Up @@ -3151,6 +3164,16 @@ void BytecodeGenerator::pushTDZVariables(const VariableEnvironment& environment,
m_TDZStack.append(TDZStackEntry { WTFMove(map), nullptr });
}

Vector<Identifier> BytecodeGenerator::getParameterNames() const
{
RELEASE_ASSERT(m_scopeNode->isFunctionNode());
FunctionParameters& parameters = *static_cast<FunctionNode*>(m_scopeNode)->parameters();
Vector<Identifier> parameterNames;
for (unsigned i = 0; i < parameters.size(); i++)
parameters.at(i).first->collectBoundIdentifiers(parameterNames);
return parameterNames;
}

std::optional<PrivateNameEnvironment> BytecodeGenerator::getAvailablePrivateAccessNames()
{
PrivateNameEnvironment result;
Expand Down Expand Up @@ -3417,7 +3440,7 @@ RegisterID* BytecodeGenerator::emitNewClassFieldInitializerFunction(RegisterID*

FunctionMetadataNode metadata(parserArena(), JSTokenLocation(), JSTokenLocation(), 0, 0, 0, 0, 0, ImplementationVisibility::Private, StrictModeLexicalFeature, ConstructorKind::None, superBinding, 0, parseMode, false);
metadata.finishParsing(m_scopeNode->source(), Identifier(), FunctionMode::MethodDefinition);
auto initializer = UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), &metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, InlineAttribute::Always, scriptMode(), WTFMove(variablesUnderTDZ), WTFMove(parentPrivateNameEnvironment), newDerivedContextType, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None);
auto initializer = UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), &metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, InlineAttribute::Always, scriptMode(), WTFMove(variablesUnderTDZ), { }, WTFMove(parentPrivateNameEnvironment), newDerivedContextType, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None);
initializer->setClassFieldLocations(WTFMove(classFieldLocations));

unsigned index = m_codeBlock->addFunctionExpr(initializer);
Expand Down
Loading

0 comments on commit 8f6b201

Please sign in to comment.