Changeset 163960 in webkit for trunk/Source/JavaScriptCore/parser
- Timestamp:
- Feb 12, 2014, 9:14:23 AM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore/parser
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r163225 r163960 889 889 DotAccessorNode* dot = static_cast<DotAccessorNode*>(func); 890 890 FunctionCallDotNode* node; 891 if (dot->identifier() == m_vm->propertyNames->call )891 if (dot->identifier() == m_vm->propertyNames->call || dot->identifier() == m_vm->propertyNames->callPrivateName) 892 892 node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd); 893 else if (dot->identifier() == m_vm->propertyNames->apply )893 else if (dot->identifier() == m_vm->propertyNames->apply || dot->identifier() == m_vm->propertyNames->applyPrivateName) 894 894 node = new (m_vm) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd); 895 895 else -
trunk/Source/JavaScriptCore/parser/Lexer.cpp
r163844 r163960 92 92 // Other types (only one so far) 93 93 CharacterWhiteSpace, 94 CharacterPrivateIdentifierStart 94 95 }; 95 96 … … 160 161 /* 62 - > */ CharacterGreater, 161 162 /* 63 - ? */ CharacterQuestion, 162 /* 64 - @ */ Character Invalid,163 /* 64 - @ */ CharacterPrivateIdentifierStart, 163 164 /* 65 - A */ CharacterIdentifierStart, 164 165 /* 66 - B */ CharacterIdentifierStart, … … 488 489 489 490 template <typename T> 490 Lexer<T>::Lexer(VM* vm )491 Lexer<T>::Lexer(VM* vm, JSParserStrictness strictness) 491 492 : m_isReparsing(false) 492 493 , m_vm(vm) 494 , m_parsingBuiltinFunction(strictness == JSParseBuiltin) 493 495 { 494 496 } … … 755 757 m_buffer16.append(static_cast<UChar>(c)); 756 758 } 757 759 760 #if !ASSERT_DISABLED 761 bool isSafeBuiltinIdentifier(VM& vm, const Identifier* ident) 762 { 763 if (!ident) 764 return true; 765 /* Just block any use of suspicious identifiers. This is intended to 766 * be used as a safety net while implementing builtins. 767 */ 768 if (*ident == vm.propertyNames->call) 769 return false; 770 if (*ident == vm.propertyNames->apply) 771 return false; 772 if (*ident == vm.propertyNames->eval) 773 return false; 774 if (*ident == vm.propertyNames->Function) 775 return false; 776 return true; 777 } 778 #endif 779 758 780 template <> 759 781 template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::parseIdentifier(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode) … … 767 789 } 768 790 } 769 791 792 bool isPrivateName = m_current == '@' && m_parsingBuiltinFunction; 793 if (isPrivateName) 794 shift(); 795 770 796 const LChar* identifierStart = currentSourcePtr(); 771 797 unsigned identifierLineStart = currentLineStartOffset(); … … 781 807 const Identifier* ident = 0; 782 808 783 if (shouldCreateIdentifier ) {809 if (shouldCreateIdentifier || m_parsingBuiltinFunction) { 784 810 int identifierLength = currentSourcePtr() - identifierStart; 785 811 ident = makeIdentifier(identifierStart, identifierLength); 786 812 if (m_parsingBuiltinFunction) { 813 if (!isSafeBuiltinIdentifier(*m_vm, ident) && !isPrivateName) { 814 m_lexErrorMessage = makeString("The use of '", ident->string(), "' is disallowed in builtin functions."); 815 return ERRORTOK; 816 } 817 if (isPrivateName) 818 ident = m_vm->propertyNames->getPrivateName(*ident); 819 else if (*ident == m_vm->propertyNames->undefinedKeyword) 820 tokenData->ident = &m_vm->propertyNames->undefinedPrivateName; 821 if (!ident) 822 return INVALID_PRIVATE_NAME_ERRORTOK; 823 } 787 824 tokenData->ident = ident; 788 825 } else 789 826 tokenData->ident = 0; 790 827 791 if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) ) {828 if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) && !isPrivateName) { 792 829 ASSERT(shouldCreateIdentifier); 793 830 if (remaining < maxTokenLength) { … … 816 853 } 817 854 } 855 856 bool isPrivateName = m_current == '@' && m_parsingBuiltinFunction; 857 if (isPrivateName) 858 shift(); 818 859 819 860 const UChar* identifierStart = currentSourcePtr(); … … 828 869 829 870 if (UNLIKELY(m_current == '\\')) { 871 ASSERT(!isPrivateName); 830 872 setOffsetFromSourcePtr(identifierStart, identifierLineStart); 831 873 return parseIdentifierSlowCase<shouldCreateIdentifier>(tokenData, lexerFlags, strictMode); … … 839 881 const Identifier* ident = 0; 840 882 841 if (shouldCreateIdentifier ) {883 if (shouldCreateIdentifier || m_parsingBuiltinFunction) { 842 884 int identifierLength = currentSourcePtr() - identifierStart; 843 885 if (isAll8Bit) … … 845 887 else 846 888 ident = makeIdentifier(identifierStart, identifierLength); 847 889 if (m_parsingBuiltinFunction) { 890 if (!isSafeBuiltinIdentifier(*m_vm, ident) && !isPrivateName) { 891 m_lexErrorMessage = makeString("The use of '", ident->string(), "' is disallowed in builtin functions."); 892 return ERRORTOK; 893 } 894 if (isPrivateName) 895 ident = m_vm->propertyNames->getPrivateName(*ident); 896 else if (*ident == m_vm->propertyNames->undefinedKeyword) 897 tokenData->ident = &m_vm->propertyNames->undefinedPrivateName; 898 if (!ident) 899 return INVALID_PRIVATE_NAME_ERRORTOK; 900 } 848 901 tokenData->ident = ident; 849 902 } else 850 903 tokenData->ident = 0; 851 904 852 if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) ) {905 if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) && !isPrivateName) { 853 906 ASSERT(shouldCreateIdentifier); 854 907 if (remaining < maxTokenLength) { … … 1660 1713 FALLTHROUGH; 1661 1714 case CharacterBackSlash: 1715 parseIdent: 1662 1716 if (lexerFlags & LexexFlagsDontBuildKeywords) 1663 1717 token = parseIdentifier<false>(tokenData, lexerFlags, strictMode); … … 1672 1726 m_lineStart = m_code; 1673 1727 goto start; 1728 case CharacterPrivateIdentifierStart: 1729 if (m_parsingBuiltinFunction) 1730 goto parseIdent; 1731 1732 FALLTHROUGH; 1674 1733 case CharacterInvalid: 1675 1734 m_lexErrorMessage = invalidCharacterMessage(); -
trunk/Source/JavaScriptCore/parser/Lexer.h
r163325 r163960 72 72 73 73 public: 74 Lexer(VM* );74 Lexer(VM*, JSParserStrictness); 75 75 ~Lexer(); 76 76 … … 238 238 239 239 VM* m_vm; 240 bool m_parsingBuiltinFunction; 240 241 }; 241 242 … … 335 336 return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length); 336 337 } 338 339 #if ASSERT_DISABLED 340 ALWAYS_INLINE bool isSafeBuiltinIdentifier(VM&, const Identifier*) { return true; } 341 #else 342 bool isSafeBuiltinIdentifier(VM&, const Identifier*); 343 #endif 337 344 338 345 template <typename T> … … 371 378 372 379 // Create the identifier if needed 373 if (lexerFlags & LexexFlagsDontBuildKeywords) 380 if (lexerFlags & LexexFlagsDontBuildKeywords 381 #if !ASSERT_DISABLED 382 && !m_parsingBuiltinFunction 383 #endif 384 ) 374 385 tokenData->ident = 0; 375 386 else 376 387 tokenData->ident = makeLCharIdentifier(start, ptr - start); 388 377 389 tokenLocation->line = m_lineNumber; 378 390 tokenLocation->lineStartOffset = currentLineStartOffset(); … … 382 394 tokenRecord->m_startPosition = startPosition; 383 395 tokenRecord->m_endPosition = currentPosition(); 396 #if !ASSERT_DISABLED 397 if (m_parsingBuiltinFunction) { 398 if (!isSafeBuiltinIdentifier(*m_vm, tokenData->ident)) 399 return ERRORTOK; 400 } 401 #endif 402 384 403 m_lastToken = IDENT; 385 404 return IDENT; -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r163844 r163960 133 133 } 134 134 135 136 void ProgramNode::setClosedVariables(const Vector<RefPtr<StringImpl>>&& closedVariables) 137 { 138 m_closedVariables = std::move(closedVariables); 139 } 140 135 141 // ------------------------------ EvalNode ----------------------------- 136 142 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r163321 r163960 1432 1432 bool hasCapturedVariables() const { return !!m_capturedVariables.size(); } 1433 1433 size_t capturedVariableCount() const { return m_capturedVariables.size(); } 1434 const IdentifierSet& capturedVariables() const { return m_capturedVariables; } 1434 1435 bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); } 1435 1436 … … 1447 1448 1448 1449 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination); 1450 1451 void setClosedVariables(const Vector<RefPtr<StringImpl>>&&) { } 1449 1452 1450 1453 protected: … … 1476 1479 static const bool scopeIsFunction = false; 1477 1480 1481 void setClosedVariables(const Vector<RefPtr<StringImpl>>&&); 1482 const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; } 1478 1483 private: 1479 1484 ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1480 1485 1481 1486 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1482 1487 Vector<RefPtr<StringImpl>> m_closedVariables; 1483 1488 unsigned m_startColumn; 1484 1489 unsigned m_endColumn; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r163959 r163960 206 206 , m_lastFunctionName(nullptr) 207 207 , m_sourceElements(0) 208 { 209 m_lexer = adoptPtr(new LexerType(vm)); 208 , m_parsingBuiltin(strictness == JSParseBuiltin) 209 { 210 m_lexer = adoptPtr(new LexerType(vm, strictness)); 210 211 m_arena = m_vm->parserArena.get(); 211 212 m_lexer->setCode(source, m_arena); … … 272 273 bool modifiedParameter = false; 273 274 scope->getCapturedVariables(capturedVariables, modifiedParameter); 275 274 276 CodeFeatures features = context.features(); 275 277 if (scope->strictMode()) … … 279 281 if (modifiedParameter) 280 282 features |= ModifiedParameterFeature; 281 283 284 Vector<RefPtr<StringImpl>> closedVariables; 285 if (m_parsingBuiltin) { 286 RELEASE_ASSERT(!capturedVariables.size()); 287 IdentifierSet usedVariables; 288 scope->getUsedVariables(usedVariables); 289 for (const auto& variable : usedVariables) { 290 if (scope->hasDeclaredVariable(Identifier(m_vm, variable.get()))) 291 continue; 292 293 if (scope->hasDeclaredParameter(Identifier(m_vm, variable.get()))) 294 continue; 295 closedVariables.append(variable); 296 } 297 } 282 298 didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features, 283 context.numConstants(), capturedVariables );299 context.numConstants(), capturedVariables, std::move(closedVariables)); 284 300 285 301 return parseError; … … 288 304 template <typename LexerType> 289 305 void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, 290 ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars )306 ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars, const Vector<RefPtr<StringImpl>>&& closedVariables) 291 307 { 292 308 m_sourceElements = sourceElements; … … 294 310 m_funcDeclarations = funcStack; 295 311 m_capturedVariables.swap(capturedVars); 312 m_closedVariables = closedVariables; 296 313 m_features = features; 297 314 m_numConstants = numConstants; … … 2363 2380 out.print("Unexpected use of reserved word '", getToken(), "'"); 2364 2381 return; 2382 2383 case INVALID_PRIVATE_NAME_ERRORTOK: 2384 out.print("Invalid private name '", getToken(), "'"); 2385 return; 2365 2386 2366 2387 case IDENT: -
trunk/Source/JavaScriptCore/parser/Parser.h
r163225 r163960 260 260 } 261 261 262 void getUsedVariables(IdentifierSet& usedVariables) 263 { 264 usedVariables.swap(m_usedVariables); 265 } 262 266 263 267 void useVariable(const Identifier* ident, bool isEval) … … 415 419 416 420 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); } 421 const Vector<RefPtr<StringImpl>>&& closedVariables() { return std::move(m_closedVariables); } 417 422 418 423 private: … … 541 546 542 547 void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 543 ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet& );548 ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<StringImpl>>&&); 544 549 545 550 // Used to determine type of error to report. … … 841 846 RefPtr<SourceProviderCache> m_functionCache; 842 847 SourceElements* m_sourceElements; 848 bool m_parsingBuiltin; 843 849 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; 844 850 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 845 851 IdentifierSet m_capturedVariables; 852 Vector<RefPtr<StringImpl>> m_closedVariables; 846 853 CodeFeatures m_features; 847 854 int m_numConstants; … … 958 965 if (positionBeforeLastNewline) 959 966 *positionBeforeLastNewline = parser.positionBeforeLastNewline(); 967 if (strictness == JSParseBuiltin) { 968 if (!result) 969 WTF::dataLog("Error compiling builtin: ", error.m_message, "\n"); 970 RELEASE_ASSERT(result); 971 result->setClosedVariables(std::move(parser.closedVariables())); 972 } 960 973 return result.release(); 961 974 } -
trunk/Source/JavaScriptCore/parser/ParserModes.h
r163321 r163960 32 32 namespace JSC { 33 33 34 enum JSParserStrictness { JSParseNormal, JSParse Strict };34 enum JSParserStrictness { JSParseNormal, JSParseBuiltin, JSParseStrict }; 35 35 enum JSParserMode { JSParseProgramCode, JSParseFunctionCode }; 36 36 -
trunk/Source/JavaScriptCore/parser/ParserTokens.h
r163225 r163960 150 150 UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag, 151 151 INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag, 152 INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag 152 153 }; 153 154
Note:
See TracChangeset
for help on using the changeset viewer.