source: webkit/trunk/Source/JavaScriptCore/parser/Nodes.cpp

Last change on this file was 279447, checked in by [email protected], 4 years ago

[JSC] Private names should be handled by usedVariables mechanism
https://bugs.webkit.org/show_bug.cgi?id=227476
rdar://76049469

Reviewed by Saam Barati.
Source/JavaScriptCore:

Private name handling in the current parser has many problems.

  1. The parser backtracks when it sees destructuring assignment, arrow function etc. In that case, the discarded code must not have any effect on the outside of that code. However, private name handling is annotating "used" of the upper scopes, which is wrong.
  2. In class expression, private name lookup intentionally skips the class-scope when parsing class heritage. But this is not correct since CodeBlock will perform lookup on the normal scope chain and this will look into the class-scope inconsistently. This means that we could encounter different private name at runtime. (it is tested in the added test).
  3. We skip inner function parsing when it is parsed previously. At that case, we must preserve private name annotation, but restored function information does not preserve that.

This patch changes how private name is handled.

  1. We were anyway defining #XXX variables which holds private symbols. So we track "use" information by the mechanism used for usual variables. We remove Used / Declared bits from PrivateNameEntry since they are not necessary at runtime, and these information is handled / tracked in Parser's Scope. For backtracking, we already have a mechanism to roll-back m_usedVariables, so using variable mechanism automatically fixes the problem.
  2. We define class-head-scope separately from class-scope. class-heritage expression can see class name, but it cannot use private names. Previously, our implementation attempted to achieve that by hacky way: skipping this class-scope for private names only while parsing class-heritage. But this was wrong since it does not consider CodeBlock's linking phase as described in the problem (2). Instead, we just define class-head-scope which holds class constructor name.
  3. We clean up popScopeInternal to populate lexical-variables and function-stack. Previously, we are stealing them before popping the scope when necessary, but this is a hack and a bit wrong since scope's popping operation needs to access these information in some cases. Instead, popScopeInternal populates them after popping the scope.
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::pushClassHeadLexicalScope):
(JSC::BytecodeGenerator::popClassHeadLexicalScope):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ClassExprNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createClassExpr):
(JSC::ASTBuilder::createBlockStatement):
(JSC::ASTBuilder::createForLoop):
(JSC::ASTBuilder::createForInLoop):
(JSC::ASTBuilder::createForOfLoop):
(JSC::ASTBuilder::createTryStatement):
(JSC::ASTBuilder::createSwitchStatement):

  • parser/NodeConstructors.h:

(JSC::ForNode::ForNode):
(JSC::TryNode::TryNode):
(JSC::ClassExprNode::ClassExprNode):
(JSC::SwitchNode::SwitchNode):
(JSC::BlockNode::BlockNode):
(JSC::EnumerationNode::EnumerationNode):
(JSC::ForInNode::ForInNode):
(JSC::ForOfNode::ForOfNode):

  • parser/Nodes.cpp:

(JSC::ScopeNode::ScopeNode):
(JSC::ProgramNode::ProgramNode):
(JSC::ModuleProgramNode::ModuleProgramNode):
(JSC::EvalNode::EvalNode):
(JSC::FunctionNode::FunctionNode):
(JSC::VariableEnvironmentNode::VariableEnvironmentNode):

  • parser/Nodes.h:

(JSC::VariableEnvironmentNode::VariableEnvironmentNode): Deleted.

  • parser/Parser.cpp:

(JSC::isPrivateFieldName):
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::parseForStatement):
(JSC::Parser<LexerType>::parseSwitchStatement):
(JSC::Parser<LexerType>::parseTryStatement):
(JSC::Parser<LexerType>::parseBlockStatement):
(JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseBinaryExpression):
(JSC::Parser<LexerType>::parseMemberExpression):
(JSC::Parser<LexerType>::usePrivateName): Deleted.

  • parser/Parser.h:

(JSC::Scope::finalizeLexicalEnvironment):
(JSC::Scope::takeLexicalEnvironment):
(JSC::Scope::takeDeclaredVariables):
(JSC::Scope::takeFunctionDeclarations):
(JSC::Scope::forEachUsedVariable):
(JSC::Scope::usePrivateName):
(JSC::Scope::currentUsedVariablesSize):
(JSC::Parser::popScopeInternal):
(JSC::Parser::popScope):
(JSC::Parser<LexerType>::parse):
(JSC::Scope::copyUndeclaredPrivateNamesTo): Deleted.
(JSC::Scope::hasUsedButUndeclaredPrivateNames const): Deleted.
(JSC::Parser::privateNameScope): Deleted.
(JSC::Parser::copyUndeclaredPrivateNamesToOuterScope): Deleted.

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createClassExpr):
(JSC::SyntaxChecker::createBlockStatement):
(JSC::SyntaxChecker::createForLoop):
(JSC::SyntaxChecker::createForInLoop):
(JSC::SyntaxChecker::createForOfLoop):
(JSC::SyntaxChecker::createTryStatement):
(JSC::SyntaxChecker::createSwitchStatement):

  • parser/VariableEnvironment.cpp:

(JSC::VariableEnvironmentEntry::dump const):
(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::declarePrivateAccessor):
(JSC::VariableEnvironment::declarePrivateMethod):
(JSC::VariableEnvironment::dump const):

  • parser/VariableEnvironment.h:

(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::privateNameEnvironment):
(JSC::VariableEnvironment::addPrivateNamesFrom):
(JSC::PrivateNameEntry::isUsed const): Deleted.
(JSC::PrivateNameEntry::isDeclared const): Deleted.
(JSC::PrivateNameEntry::setIsUsed): Deleted.
(JSC::PrivateNameEntry::setIsDeclared): Deleted.
(JSC::VariableEnvironment::usePrivateName): Deleted.
(JSC::VariableEnvironment::copyPrivateNamesTo const): Deleted.
(JSC::VariableEnvironment::copyUndeclaredPrivateNamesTo const): Deleted.

  • Property svn:eol-style set to native
File size: 16.6 KB
Line 
1/*
2* Copyright (C) 1999-2002 Harri Porten ([email protected])
3* Copyright (C) 2001 Peter Kelly ([email protected])
4* Copyright (C) 2003-2009, 2013, 2016 Apple Inc. All rights reserved.
5* Copyright (C) 2007 Cameron Zwarich ([email protected])
6* Copyright (C) 2007 Maks Orlovich
7* Copyright (C) 2007 Eric Seidel <[email protected]>
8*
9* This library is free software; you can redistribute it and/or
10* modify it under the terms of the GNU Library General Public
11* License as published by the Free Software Foundation; either
12* version 2 of the License, or (at your option) any later version.
13*
14* This library is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17* Library General Public License for more details.
18*
19* You should have received a copy of the GNU Library General Public License
20* along with this library; see the file COPYING.LIB. If not, write to
21* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22* Boston, MA 02110-1301, USA.
23*
24*/
25
26#include "config.h"
27#include "Nodes.h"
28#include "NodeConstructors.h"
29
30#include "ExecutableInfo.h"
31#include "ModuleScopeData.h"
32#include <wtf/Assertions.h>
33
34namespace JSC {
35
36DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArenaRoot);
37
38// ------------------------------ StatementNode --------------------------------
39
40void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
41{
42 m_lastLine = lastLine;
43 m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
44 ASSERT(m_position.offset >= m_position.lineStartOffset);
45}
46
47// ------------------------------ SourceElements --------------------------------
48
49void SourceElements::append(StatementNode* statement)
50{
51 if (statement->isEmptyStatement())
52 return;
53
54 if (!m_head) {
55 m_head = statement;
56 m_tail = statement;
57 return;
58 }
59
60 m_tail->setNext(statement);
61 m_tail = statement;
62}
63
64StatementNode* SourceElements::singleStatement() const
65{
66 return m_head == m_tail ? m_head : nullptr;
67}
68
69StatementNode* SourceElements::lastStatement() const
70{
71 return m_tail;
72}
73
74bool SourceElements::hasCompletionValue() const
75{
76 for (StatementNode* statement = m_head; statement; statement = statement->next()) {
77 if (statement->hasCompletionValue())
78 return true;
79 }
80
81 return false;
82}
83
84bool SourceElements::hasEarlyBreakOrContinue() const
85{
86 for (StatementNode* statement = m_head; statement; statement = statement->next()) {
87 if (statement->isBreak() || statement->isContinue())
88 return true;
89 if (statement->hasCompletionValue())
90 return false;
91 }
92
93 return false;
94}
95
96// ------------------------------ BlockNode ------------------------------------
97
98StatementNode* BlockNode::lastStatement() const
99{
100 return m_statements ? m_statements->lastStatement() : nullptr;
101}
102
103StatementNode* BlockNode::singleStatement() const
104{
105 return m_statements ? m_statements->singleStatement() : nullptr;
106}
107
108bool BlockNode::hasCompletionValue() const
109{
110 return m_statements ? m_statements->hasCompletionValue() : false;
111}
112
113bool BlockNode::hasEarlyBreakOrContinue() const
114{
115 return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
116}
117
118// ------------------------------ ScopeNode -----------------------------
119
120ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, LexicalScopeFeatures lexicalScopeFeatures)
121 : StatementNode(endLocation)
122 , ParserArenaRoot(parserArena)
123 , m_startLineNumber(startLocation.line)
124 , m_startStartOffset(startLocation.startOffset)
125 , m_startLineStartOffset(startLocation.lineStartOffset)
126 , m_features(NoFeatures)
127 , m_lexicalScopeFeatures(lexicalScopeFeatures)
128 , m_innerArrowFunctionCodeFeatures(NoInnerArrowFunctionFeatures)
129 , m_numConstants(0)
130 , m_statements(nullptr)
131{
132}
133
134ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
135 : StatementNode(endLocation)
136 , ParserArenaRoot(parserArena)
137 , VariableEnvironmentNode(WTFMove(lexicalVariables), WTFMove(funcStack))
138 , m_startLineNumber(startLocation.line)
139 , m_startStartOffset(startLocation.startOffset)
140 , m_startLineStartOffset(startLocation.lineStartOffset)
141 , m_features(features)
142 , m_lexicalScopeFeatures(lexicalScopeFeatures)
143 , m_innerArrowFunctionCodeFeatures(innerArrowFunctionCodeFeatures)
144 , m_source(source)
145 , m_varDeclarations(WTFMove(varEnvironment))
146 , m_sloppyModeHoistedFunctions(WTFMove(sloppyModeHoistedFunctions))
147 , m_numConstants(numConstants)
148 , m_statements(children)
149{
150}
151
152StatementNode* ScopeNode::singleStatement() const
153{
154 return m_statements ? m_statements->singleStatement() : nullptr;
155}
156
157bool ScopeNode::hasCompletionValue() const
158{
159 return m_statements ? m_statements->hasCompletionValue() : false;
160}
161
162bool ScopeNode::hasEarlyBreakOrContinue() const
163{
164 return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
165}
166
167// ------------------------------ ProgramNode -----------------------------
168
169ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
170 : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
171 , m_startColumn(startColumn)
172 , m_endColumn(endColumn)
173{
174}
175
176// ------------------------------ ModuleProgramNode -----------------------------
177
178ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
179 : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
180 , m_startColumn(startColumn)
181 , m_endColumn(endColumn)
182 , m_usesAwait(features & AwaitFeature)
183 , m_moduleScopeData(*WTFMove(moduleScopeData))
184{
185}
186
187// ------------------------------ EvalNode -----------------------------
188
189EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
190 : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
191 , m_endColumn(endColumn)
192{
193}
194
195// ------------------------------ FunctionMetadataNode -----------------------------
196
197FunctionMetadataNode::FunctionMetadataNode(
198 ParserArena&, const JSTokenLocation& startLocation,
199 const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
200 int functionKeywordStart, int functionNameStart, int parametersStart, LexicalScopeFeatures lexicalScopeFeatures,
201 ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
202 : Node(endLocation)
203 , m_lexicalScopeFeatures(lexicalScopeFeatures)
204 , m_superBinding(static_cast<unsigned>(superBinding))
205 , m_constructorKind(static_cast<unsigned>(constructorKind))
206 , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
207 , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
208 , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
209 , m_parseMode(mode)
210 , m_startColumn(startColumn)
211 , m_endColumn(endColumn)
212 , m_functionKeywordStart(functionKeywordStart)
213 , m_functionNameStart(functionNameStart)
214 , m_parametersStart(parametersStart)
215 , m_startStartOffset(startLocation.startOffset)
216 , m_parameterCount(parameterCount)
217{
218 ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
219 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
220}
221
222FunctionMetadataNode::FunctionMetadataNode(
223 const JSTokenLocation& startLocation,
224 const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
225 int functionKeywordStart, int functionNameStart, int parametersStart, LexicalScopeFeatures lexicalScopeFeatures,
226 ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
227 : Node(endLocation)
228 , m_lexicalScopeFeatures(lexicalScopeFeatures)
229 , m_superBinding(static_cast<unsigned>(superBinding))
230 , m_constructorKind(static_cast<unsigned>(constructorKind))
231 , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
232 , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
233 , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
234 , m_parseMode(mode)
235 , m_startColumn(startColumn)
236 , m_endColumn(endColumn)
237 , m_functionKeywordStart(functionKeywordStart)
238 , m_functionNameStart(functionNameStart)
239 , m_parametersStart(parametersStart)
240 , m_startStartOffset(startLocation.startOffset)
241 , m_parameterCount(parameterCount)
242{
243 ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
244 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
245}
246
247void FunctionMetadataNode::finishParsing(const SourceCode& source, const Identifier& ident, FunctionMode functionMode)
248{
249 m_source = source;
250 m_ident = ident;
251 m_functionMode = functionMode;
252}
253
254void FunctionMetadataNode::setEndPosition(JSTextPosition position)
255{
256 m_lastLine = position.line;
257 m_endColumn = position.offset - position.lineStartOffset;
258}
259
260bool FunctionMetadataNode::operator==(const FunctionMetadataNode& other) const
261{
262 return m_parseMode == other.m_parseMode
263 && m_lexicalScopeFeatures == other.m_lexicalScopeFeatures
264 && m_superBinding == other.m_superBinding
265 && m_constructorKind == other.m_constructorKind
266 && m_isArrowFunctionBodyExpression == other.m_isArrowFunctionBodyExpression
267 && m_ident == other.m_ident
268 && m_ecmaName == other.m_ecmaName
269 && m_functionMode == other.m_functionMode
270 && m_startColumn == other.m_startColumn
271 && m_endColumn == other.m_endColumn
272 && m_functionKeywordStart == other.m_functionKeywordStart
273 && m_functionNameStart == other.m_functionNameStart
274 && m_parametersStart == other.m_parametersStart
275 && m_source == other.m_source
276 && m_classSource == other.m_classSource
277 && m_startStartOffset == other.m_startStartOffset
278 && m_parameterCount == other.m_parameterCount
279 && m_lastLine == other.m_lastLine
280 && m_position == other.m_position;
281}
282
283void FunctionMetadataNode::dump(PrintStream& stream) const
284{
285 stream.println("m_parseMode ", static_cast<uint32_t>(m_parseMode));
286 stream.println("m_lexicalScopeFeatures ", m_lexicalScopeFeatures);
287 stream.println("m_superBinding ", m_superBinding);
288 stream.println("m_constructorKind ", m_constructorKind);
289 stream.println("m_isArrowFunctionBodyExpression ", m_isArrowFunctionBodyExpression);
290 stream.println("m_ident ", m_ident);
291 stream.println("m_ecmaName ", m_ecmaName);
292 stream.println("m_functionMode ", static_cast<uint32_t>(m_functionMode));
293 stream.println("m_startColumn ", m_startColumn);
294 stream.println("m_endColumn ", m_endColumn);
295 stream.println("m_functionKeywordStart ", m_functionKeywordStart);
296 stream.println("m_functionNameStart ", m_functionNameStart);
297 stream.println("m_parametersStart ", m_parametersStart);
298 stream.println("m_classSource.isNull() ", m_classSource.isNull());
299 stream.println("m_startStartOffset ", m_startStartOffset);
300 stream.println("m_parameterCount ", m_parameterCount);
301 stream.println("m_lastLine ", m_lastLine);
302 stream.println("position().line ", position().line);
303 stream.println("position().offset ", position().offset);
304 stream.println("position().lineStartOffset ", position().lineStartOffset);
305}
306
307// ------------------------------ FunctionNode -----------------------------
308
309FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
310 : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
311 , m_parameters(parameters)
312 , m_startColumn(startColumn)
313 , m_endColumn(endColumn)
314{
315}
316
317void FunctionNode::finishParsing(const Identifier& ident, FunctionMode functionMode)
318{
319 ASSERT(!source().isNull());
320 m_ident = ident;
321 m_functionMode = functionMode;
322}
323
324bool PropertyListNode::hasStaticallyNamedProperty(const Identifier& propName)
325{
326 PropertyListNode* list = this;
327 while (list) {
328 if (list->m_node->isStaticClassProperty()) {
329 const Identifier* currentNodeName = list->m_node->name();
330 if (currentNodeName && *currentNodeName == propName)
331 return true;
332 }
333 list = list->m_next;
334 }
335 return false;
336}
337
338// FIXME: calculate this feature once when parsing the property list.
339// https://bugs.webkit.org/show_bug.cgi?id=206174
340bool PropertyListNode::shouldCreateLexicalScopeForClass(PropertyListNode* list)
341{
342 while (list) {
343 if (list->m_node->isComputedClassField() || list->m_node->isPrivate())
344 return true;
345 list = list->m_next;
346 }
347 return false;
348}
349
350// ------------------------------ ClassExprNode -----------------------------
351
352// FIXME: calculate this feature once when parsing the property list.
353// https://bugs.webkit.org/show_bug.cgi?id=206174
354bool PropertyListNode::hasInstanceFields() const
355{
356 for (auto list = this; list; list = list->m_next) {
357 if (list->m_node->isInstanceClassField())
358 return true;
359 }
360 return false;
361}
362
363VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables)
364 : m_lexicalVariables(WTFMove(lexicalVariables))
365{
366}
367
368VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables, FunctionStack&& functionStack)
369 : m_lexicalVariables(WTFMove(lexicalVariables))
370 , m_functionStack(WTFMove(functionStack))
371{
372}
373
374} // namespace JSC
Note: See TracBrowser for help on using the repository browser.