X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/runtime/LiteralParser.cpp diff --git a/runtime/LiteralParser.cpp b/runtime/LiteralParser.cpp index f594518..9d9fe2f 100644 --- a/runtime/LiteralParser.cpp +++ b/runtime/LiteralParser.cpp @@ -33,7 +33,7 @@ #include "JSString.h" #include "Lexer.h" #include "ObjectConstructor.h" -#include "Operations.h" +#include "JSCInlines.h" #include "StrongInlines.h" #include #include @@ -57,17 +57,17 @@ bool LiteralParser::tryJSONPParse(Vector& results, bool nee do { Vector path; // Unguarded next to start off the lexer - Identifier name = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + Identifier name = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); JSONPPathEntry entry; if (name == m_exec->vm().propertyNames->varKeyword) { if (m_lexer.next() != TokIdentifier) return false; entry.m_type = JSONPPathEntryTypeDeclare; - entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); path.append(entry); } else { entry.m_type = JSONPPathEntryTypeDot; - entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); path.append(entry); } if (m_exec->vm().keywords->isKeyword(entry.m_pathEntryName)) @@ -94,7 +94,7 @@ bool LiteralParser::tryJSONPParse(Vector& results, bool nee entry.m_type = JSONPPathEntryTypeDot; if (m_lexer.next() != TokIdentifier) return false; - entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); break; } case TokLParen: { @@ -135,17 +135,17 @@ ALWAYS_INLINE const Identifier LiteralParser::makeIdentifier(const LCh if (!length) return m_exec->vm().propertyNames->emptyIdentifier; if (characters[0] >= MaximumCachableCharacter) - return Identifier(&m_exec->vm(), characters, length); + return Identifier::fromString(&m_exec->vm(), characters, length); if (length == 1) { if (!m_shortIdentifiers[characters[0]].isNull()) return m_shortIdentifiers[characters[0]]; - m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_shortIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_shortIdentifiers[characters[0]]; } if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length)) return m_recentIdentifiers[characters[0]]; - m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_recentIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_recentIdentifiers[characters[0]]; } @@ -155,17 +155,17 @@ ALWAYS_INLINE const Identifier LiteralParser::makeIdentifier(const UCh if (!length) return m_exec->vm().propertyNames->emptyIdentifier; if (characters[0] >= MaximumCachableCharacter) - return Identifier(&m_exec->vm(), characters, length); + return Identifier::fromString(&m_exec->vm(), characters, length); if (length == 1) { if (!m_shortIdentifiers[characters[0]].isNull()) return m_shortIdentifiers[characters[0]]; - m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_shortIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_shortIdentifiers[characters[0]]; } if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length)) return m_recentIdentifiers[characters[0]]; - m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_recentIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_recentIdentifiers[characters[0]]; } @@ -281,7 +281,7 @@ template TokenType LiteralParser::Lexer::lex(Literal return lexString(token); } } - m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr).impl(); + m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr); return TokError; } @@ -406,7 +406,7 @@ template ALWAYS_INLINE TokenType LiteralParse } // uNNNN == 5 characters for (int i = 1; i < 5; i++) { if (!isASCIIHexDigit(m_ptr[i])) { - m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data()).impl(); + m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data()); return TokError; } } @@ -420,7 +420,7 @@ template ALWAYS_INLINE TokenType LiteralParse m_ptr++; break; } - m_lexErrorMessage = String::format("Invalid escape character %c", *m_ptr).impl(); + m_lexErrorMessage = String::format("Invalid escape character %c", *m_ptr); return TokError; } } @@ -548,15 +548,16 @@ JSValue LiteralParser::parse(ParserState initialState) JSValue lastValue; Vector stateStack; Vector identifierStack; + HashSet visitedUnderscoreProto; while (1) { switch(state) { startParseArray: case StartParseArray: { JSArray* array = constructEmptyArray(m_exec, 0); objectStack.append(array); - // fallthrough } doParseArrayStartExpression: + FALLTHROUGH; case DoParseArrayStartExpression: { TokenType lastToken = m_lexer.currentToken().type; if (m_lexer.next() == TokRBracket) { @@ -649,11 +650,20 @@ JSValue LiteralParser::parse(ParserState initialState) { JSObject* object = asObject(objectStack.last()); PropertyName ident = identifierStack.last(); - unsigned i = ident.asIndex(); - if (i != PropertyName::NotAnIndex) - object->putDirectIndex(m_exec, i, lastValue); - else - object->putDirect(m_exec->vm(), ident, lastValue); + if (m_mode != StrictJSON && ident == m_exec->vm().propertyNames->underscoreProto) { + if (!visitedUnderscoreProto.add(object).isNewEntry) { + m_parseErrorMessage = ASCIILiteral("Attempted to redefine __proto__ property"); + return JSValue(); + } + CodeBlock* codeBlock = m_exec->codeBlock(); + PutPropertySlot slot(object, codeBlock ? codeBlock->isStrictMode() : false); + objectStack.last().put(m_exec, ident, lastValue, slot); + } else { + if (Optional index = parseIndex(ident)) + object->putDirectIndex(m_exec, index.value(), lastValue); + else + object->putDirect(m_exec->vm(), ident, lastValue); + } identifierStack.removeLast(); if (m_lexer.currentToken().type == TokComma) goto doParseObjectStartExpression; @@ -711,9 +721,9 @@ JSValue LiteralParser::parse(ParserState initialState) case TokIdentifier: { const LiteralParserToken& token = m_lexer.currentToken(); if (token.stringIs8Bit) - m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()).impl(); + m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()); else - m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()).impl(); + m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()); return JSValue(); } case TokColon: