]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/LiteralParser.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / LiteralParser.cpp
index 9b01951894eedf90f7fedf3683b0f5009b6a80da..9d9fe2f312f5ecc3fc24771a8801ff2b489527d4 100644 (file)
@@ -57,17 +57,17 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
     do {
         Vector<JSONPPathEntry> path;
         // Unguarded next to start off the lexer
     do {
         Vector<JSONPPathEntry> 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;
         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;
             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))
             path.append(entry);
         }
         if (m_exec->vm().keywords->isKeyword(entry.m_pathEntryName))
@@ -94,7 +94,7 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
                 entry.m_type = JSONPPathEntryTypeDot;
                 if (m_lexer.next() != TokIdentifier)
                     return false;
                 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: {
                 break;
             }
             case TokLParen: {
@@ -135,17 +135,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const LCh
     if (!length)
         return m_exec->vm().propertyNames->emptyIdentifier;
     if (characters[0] >= MaximumCachableCharacter)
     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]];
 
     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]];
         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]];
 }
 
     return m_recentIdentifiers[characters[0]];
 }
 
@@ -155,17 +155,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const UCh
     if (!length)
         return m_exec->vm().propertyNames->emptyIdentifier;
     if (characters[0] >= MaximumCachableCharacter)
     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]];
 
     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]];
         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]];
 }
 
     return m_recentIdentifiers[characters[0]];
 }
 
@@ -281,7 +281,7 @@ template <ParserMode mode> TokenType LiteralParser<CharType>::Lexer::lex(Literal
             return lexString<mode, '\''>(token);
         }
     }
             return lexString<mode, '\''>(token);
         }
     }
-    m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr).impl();
+    m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr);
     return TokError;
 }
 
     return TokError;
 }
 
@@ -406,7 +406,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse
                     } // uNNNN == 5 characters
                     for (int i = 1; i < 5; i++) {
                         if (!isASCIIHexDigit(m_ptr[i])) {
                     } // 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;
                         }
                     }
                             return TokError;
                         }
                     }
@@ -420,7 +420,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse
                         m_ptr++;
                         break;
                     }
                         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;
             }
         }
                     return TokError;
             }
         }
@@ -548,6 +548,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
     JSValue lastValue;
     Vector<ParserState, 16, UnsafeVectorOverflow> stateStack;
     Vector<Identifier, 16, UnsafeVectorOverflow> identifierStack;
     JSValue lastValue;
     Vector<ParserState, 16, UnsafeVectorOverflow> stateStack;
     Vector<Identifier, 16, UnsafeVectorOverflow> identifierStack;
+    HashSet<JSObject*> visitedUnderscoreProto;
     while (1) {
         switch(state) {
             startParseArray:
     while (1) {
         switch(state) {
             startParseArray:
@@ -649,11 +650,20 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
             {
                 JSObject* object = asObject(objectStack.last());
                 PropertyName ident = identifierStack.last();
             {
                 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<uint32_t> 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;
                 identifierStack.removeLast();
                 if (m_lexer.currentToken().type == TokComma)
                     goto doParseObjectStartExpression;
@@ -711,9 +721,9 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
                     case TokIdentifier: {
                         const LiteralParserToken<CharType>& token = m_lexer.currentToken();
                         if (token.stringIs8Bit)
                     case TokIdentifier: {
                         const LiteralParserToken<CharType>& 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
                         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:
                         return JSValue();
                     }
                     case TokColon: