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
This commit is contained in:
parent
0870702436
commit
f59ac1cba5
@ -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)*[','] ')'
|
||||
|
24
src/parser.h
24
src/parser.h
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user