summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/LiteralParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/LiteralParser.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/LiteralParser.cpp59
1 files changed, 35 insertions, 24 deletions
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp
index f594518b6..f55498381 100644
--- a/Source/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp
@@ -28,12 +28,13 @@
#include "LiteralParser.h"
#include "ButterflyInlines.h"
+#include "CodeBlock.h"
#include "CopiedSpaceInlines.h"
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "StrongInlines.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
@@ -57,20 +58,20 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
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;
- 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))
+ if (isLexerKeyword(entry.m_pathEntryName))
return false;
TokenType tokenType = m_lexer.next();
if (entry.m_type == JSONPPathEntryTypeDeclare && tokenType != TokAssign)
@@ -94,7 +95,7 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& 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 +136,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::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 +156,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::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 +282,7 @@ template <ParserMode mode> TokenType LiteralParser<CharType>::Lexer::lex(Literal
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;
}
@@ -406,7 +407,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])) {
- 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 +421,7 @@ template <ParserMode mode, char terminator> 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;
}
}
@@ -497,7 +498,7 @@ TokenType LiteralParser<CharType>::Lexer::lexNumber(LiteralParserToken<CharType>
while (m_ptr < m_end && isASCIIDigit(*m_ptr))
++m_ptr;
} else if (m_ptr < m_end && (*m_ptr != 'e' && *m_ptr != 'E') && (m_ptr - token.start) < 10) {
- int result = 0;
+ double result = 0;
token.type = TokNumber;
token.end = m_ptr;
const CharType* digit = token.start;
@@ -548,15 +549,16 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
JSValue lastValue;
Vector<ParserState, 16, UnsafeVectorOverflow> stateStack;
Vector<Identifier, 16, UnsafeVectorOverflow> identifierStack;
+ HashSet<JSObject*> 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 +651,20 @@ JSValue LiteralParser<CharType>::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<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;
@@ -711,9 +722,9 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
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
- 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: