Commit f59ac1cb authored by marja@chromium.org's avatar marja@chromium.org

Move ParseRegexpLiteral to ParserBase.

R=ulan@chromium.org
BUG=v8:3126
LOG=N

Review URL: https://codereview.chromium.org/156423005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19273 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 08707024
......@@ -551,6 +551,11 @@ bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
}
int ParserTraits::NextMaterializedLiteralIndex() {
return parser_->current_function_state_->NextMaterializedLiteralIndex();
}
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
const char* message,
Vector<const char*> args) {
......@@ -601,6 +606,27 @@ Handle<String> ParserTraits::GetSymbol() {
return parser_->LookupSymbol(symbol_id);
}
Handle<String> ParserTraits::NextLiteralString(PretenureFlag tenured) {
Scanner& scanner = parser_->scanner();
if (scanner.is_next_literal_ascii()) {
return parser_->isolate_->factory()->NewStringFromAscii(
scanner.next_literal_ascii_string(), tenured);
} else {
return parser_->isolate_->factory()->NewStringFromTwoByte(
scanner.next_literal_utf16_string(), tenured);
}
}
Expression* ParserTraits::NewRegExpLiteral(Handle<String> js_pattern,
Handle<String> js_flags,
int literal_index,
int pos) {
return parser_->factory()->NewRegExpLiteral(
js_pattern, js_flags, literal_index, pos);
}
Parser::Parser(CompilationInfo* info)
: ParserBase<ParserTraits>(&scanner_,
info->isolate()->stack_guard()->real_climit(),
......@@ -3834,26 +3860,6 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
}
Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
int pos = peek_position();
if (!scanner().ScanRegExpPattern(seen_equal)) {
Next();
ReportMessage("unterminated_regexp", Vector<const char*>::empty());
*ok = false;
return NULL;
}
int literal_index = current_function_state_->NextMaterializedLiteralIndex();
Handle<String> js_pattern = NextLiteralString(TENURED);
scanner().ScanRegExpFlags();
Handle<String> js_flags = NextLiteralString(TENURED);
Next();
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
}
ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
// Arguments ::
// '(' (AssignmentExpression)*[','] ')'
......
......@@ -412,6 +412,7 @@ class ParserTraits {
typedef Parser* ParserType;
// Return types for traversing functions.
typedef Handle<String> IdentifierType;
typedef Expression* ExpressionType;
explicit ParserTraits(Parser* parser) : parser_(parser) {}
......@@ -419,6 +420,7 @@ class ParserTraits {
bool is_classic_mode() const;
bool is_generator() const;
bool IsEvalOrArguments(Handle<String> identifier) const;
int NextMaterializedLiteralIndex();
// Reporting errors.
void ReportMessageAt(Scanner::Location source_location,
......@@ -429,12 +431,21 @@ class ParserTraits {
const char* message,
Vector<Handle<String> > args);
// Identifiers:
// "null" return type creators.
static IdentifierType EmptyIdentifier() {
return Handle<String>();
}
static ExpressionType EmptyExpression() {
return NULL;
}
// Producing data during the recursive descent.
IdentifierType GetSymbol();
IdentifierType NextLiteralString(PretenureFlag tenured);
ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
IdentifierType js_flags,
int literal_index,
int pos);
private:
Parser* parser_;
......@@ -657,7 +668,6 @@ class Parser : public ParserBase<ParserTraits> {
Expression* ParsePrimaryExpression(bool* ok);
Expression* ParseArrayLiteral(bool* ok);
Expression* ParseObjectLiteral(bool* ok);
Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
// Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt,
......@@ -690,16 +700,6 @@ class Parser : public ParserBase<ParserTraits> {
}
}
Handle<String> NextLiteralString(PretenureFlag tenured) {
if (scanner().is_next_literal_ascii()) {
return isolate_->factory()->NewStringFromAscii(
scanner().next_literal_ascii_string(), tenured);
} else {
return isolate_->factory()->NewStringFromTwoByte(
scanner().next_literal_utf16_string(), tenured);
}
}
// Get odd-ball literals.
Literal* GetLiteralUndefined(int position);
Literal* GetLiteralTheHole(int position);
......
......@@ -65,6 +65,11 @@ bool PreParserTraits::is_generator() const {
}
int PreParserTraits::NextMaterializedLiteralIndex() {
return pre_parser_->scope_->NextMaterializedLiteralIndex();
}
void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* message,
Vector<const char*> args) {
......@@ -1301,28 +1306,6 @@ PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
}
PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
bool* ok) {
if (!scanner()->ScanRegExpPattern(seen_equal)) {
Next();
ReportMessageAt(scanner()->location(), "unterminated_regexp");
*ok = false;
return Expression::Default();
}
scope_->NextMaterializedLiteralIndex();
if (!scanner()->ScanRegExpFlags()) {
Next();
ReportMessageAt(scanner()->location(), "invalid_regexp_flags");
*ok = false;
return Expression::Default();
}
Next();
return Expression::Default();
}
PreParser::Arguments PreParser::ParseArguments(bool* ok) {
// Arguments ::
// '(' (AssignmentExpression)*[','] ')'
......
......@@ -225,6 +225,8 @@ class ParserBase : public Traits {
bool* is_set,
bool* ok);
typename Traits::ExpressionType ParseRegExpLiteral(bool seen_equal, bool* ok);
// Used to detect duplicates in object literals. Each of the values
// kGetterProperty, kSetterProperty and kValueProperty represents
// a type of object literal property. When parsing a property, its
......@@ -427,6 +429,7 @@ class PreParserTraits {
typedef PreParser* ParserType;
// Return types for traversing functions.
typedef PreParserIdentifier IdentifierType;
typedef PreParserExpression ExpressionType;
explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
......@@ -436,6 +439,7 @@ class PreParserTraits {
static bool IsEvalOrArguments(IdentifierType identifier) {
return identifier.IsEvalOrArguments();
}
int NextMaterializedLiteralIndex();
// Reporting errors.
void ReportMessageAt(Scanner::Location location,
......@@ -449,12 +453,25 @@ class PreParserTraits {
const char* type,
const char* name_opt);
// Identifiers:
// "null" return type creators.
static IdentifierType EmptyIdentifier() {
return PreParserIdentifier::Default();
}
static ExpressionType EmptyExpression() {
return PreParserExpression::Default();
}
// Producing data during the recursive descent.
IdentifierType GetSymbol();
static IdentifierType NextLiteralString(PretenureFlag tenured) {
return PreParserIdentifier::Default();
}
ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
IdentifierType js_flags,
int literal_index,
int pos) {
return PreParserExpression::Default();
}
private:
PreParser* pre_parser_;
......@@ -616,7 +633,7 @@ class PreParser : public ParserBase<PreParserTraits> {
*variable = this;
}
~Scope() { *variable_ = prev_; }
void NextMaterializedLiteralIndex() { materialized_literal_count_++; }
int NextMaterializedLiteralIndex() { return materialized_literal_count_++; }
void AddProperty() { expected_properties_++; }
ScopeType type() { return type_; }
int expected_properties() { return expected_properties_; }
......@@ -701,7 +718,6 @@ class PreParser : public ParserBase<PreParserTraits> {
Expression ParsePrimaryExpression(bool* ok);
Expression ParseArrayLiteral(bool* ok);
Expression ParseObjectLiteral(bool* ok);
Expression ParseRegExpLiteral(bool seen_equal, bool* ok);
Expression ParseV8Intrinsic(bool* ok);
Arguments ParseArguments(bool* ok);
......@@ -848,6 +864,32 @@ ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
}
template <class Traits>
typename Traits::ExpressionType
ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) {
int pos = peek_position();
if (!scanner()->ScanRegExpPattern(seen_equal)) {
Next();
ReportMessage("unterminated_regexp", Vector<const char*>::empty());
*ok = false;
return Traits::EmptyExpression();
}
int literal_index = this->NextMaterializedLiteralIndex();
typename Traits::IdentifierType js_pattern = this->NextLiteralString(TENURED);
if (!scanner()->ScanRegExpFlags()) {
Next();
ReportMessageAt(scanner()->location(), "invalid_regexp_flags");
*ok = false;
return Traits::EmptyExpression();
}
typename Traits::IdentifierType js_flags = this->NextLiteralString(TENURED);
Next();
return this->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
}
template <typename Traits>
void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
Token::Value property,
......
......@@ -2014,3 +2014,35 @@ TEST(NoErrorsTryCatchFinally) {
RunParserSyncTest(context_data, statement_data, kSuccess);
}
TEST(ErrorsRegexpLiteral) {
const char* context_data[][2] = {
{"var r = ", ""},
{ NULL, NULL }
};
const char* statement_data[] = {
"/unterminated",
NULL
};
RunParserSyncTest(context_data, statement_data, kError);
}
TEST(NoErrorsRegexpLiteral) {
const char* context_data[][2] = {
{"var r = ", ""},
{ NULL, NULL }
};
const char* statement_data[] = {
"/foo/",
"/foo/g",
"/foo/whatever", // This is an error but not detected by the parser.
NULL
};
RunParserSyncTest(context_data, statement_data, kSuccess);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment