Reviewers: marja (ooo until 18th of Aug), rossberg,
Message:
The C++ error (not caught by GCC?) was that you couldn't "friend class Foo"
where Foo was a typedef. A strange restriction! Anyway, this patch does
the
simple thing and inlines the Checkpoint class definition into the
ParserTraits /
PreParserTraits. PTAL.
Description:
Rewind additional parser state when reinterpreting arrow arguments
The new ParserCheckpoint mechanism resets some state, notably the
bailout ID counter but also some statement counters (only applicable
once we get "do" expressions) when we decide to reinterpret a comma
expression as arrow function arguments.
[email protected], [email protected]
BUG=v8:3475
LOG=N
Please review this at https://codereview.chromium.org/443903003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+61, -0 lines):
M src/parser.h
M src/preparser.h
Index: src/parser.h
diff --git a/src/parser.h b/src/parser.h
index
fd24e8d4e952b4d33408f3fc03c0fcb83ec3bf43..5b5466dc8aa408ac532bcd47d4fb632daba7e501
100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -339,6 +339,7 @@ class RegExpParser BASE_EMBEDDED {
//
----------------------------------------------------------------------------
// JAVASCRIPT PARSING
+
class Parser;
class SingletonLogger;
@@ -355,6 +356,21 @@ class ParserTraits {
typedef Variable GeneratorVariable;
typedef v8::internal::Zone Zone;
+ class Checkpoint BASE_EMBEDDED {
+ public:
+ template <typename Parser>
+ explicit Checkpoint(Parser* parser) {
+ isolate_ = parser->zone()->isolate();
+ saved_ast_node_id_ = isolate_->ast_node_id();
+ }
+
+ void Restore() { isolate_->set_ast_node_id(saved_ast_node_id_); }
+
+ private:
+ Isolate* isolate_;
+ int saved_ast_node_id_;
+ };
+
typedef v8::internal::AstProperties AstProperties;
typedef Vector<VariableProxy*> ParameterIdentifierVector;
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index
517403d34733eba81ea86c7bedd38162feded389..b00cbbbd477cf2ea175fc4e62f3f180e23de5122
100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -114,6 +114,8 @@ class ParserBase : public Traits {
}
protected:
+ friend class Traits::Type::Checkpoint;
+
enum AllowEvalOrArgumentsAsIdentifier {
kAllowEvalOrArguments,
kDontAllowEvalOrArguments
@@ -124,6 +126,8 @@ class ParserBase : public Traits {
PARSE_EAGERLY
};
+ class ParserCheckpoint;
+
//
---------------------------------------------------------------------------
// FunctionState and BlockState together implement the parser's scope
stack.
// The parser's current scope is in scope_. BlockState and FunctionState
@@ -219,6 +223,38 @@ class ParserBase : public Traits {
typename Traits::Type::Factory factory_;
friend class ParserTraits;
+ friend class ParserCheckpoint;
+ };
+
+ // Annoyingly, arrow functions first parse as comma expressions, then
when we
+ // see the => we have to go back and reinterpret the arguments as being
formal
+ // parameters. To do so we need to reset some of the parser state back
to
+ // what it was before the arguments were first seen.
+ class ParserCheckpoint : public Traits::Type::Checkpoint {
+ public:
+ template <typename Parser>
+ explicit ParserCheckpoint(Parser* parser)
+ : Traits::Type::Checkpoint(parser) {
+ function_state_ = parser->function_state_;
+ next_materialized_literal_index_ =
+ function_state_->next_materialized_literal_index_;
+ next_handler_index_ = function_state_->next_handler_index_;
+ expected_property_count_ = function_state_->expected_property_count_;
+ }
+
+ void Restore() {
+ Traits::Type::Checkpoint::Restore();
+ function_state_->next_materialized_literal_index_ =
+ next_materialized_literal_index_;
+ function_state_->next_handler_index_ = next_handler_index_;
+ function_state_->expected_property_count_ = expected_property_count_;
+ }
+
+ private:
+ FunctionState* function_state_;
+ int next_materialized_literal_index_;
+ int next_handler_index_;
+ int expected_property_count_;
};
class ParsingModeScope BASE_EMBEDDED {
@@ -1034,6 +1070,13 @@ class PreParserTraits {
typedef PreParserScope Scope;
typedef PreParserScope ScopePtr;
+ class Checkpoint BASE_EMBEDDED {
+ public:
+ template <typename Parser>
+ explicit Checkpoint(Parser* parser) {}
+ void Restore() {}
+ };
+
// PreParser doesn't need to store generator variables.
typedef void GeneratorVariable;
// No interaction with Zones.
@@ -2006,10 +2049,12 @@ ParserBase<Traits>::ParseAssignmentExpression(bool
accept_IN, bool* ok) {
}
if (fni_ != NULL) fni_->Enter();
+ ParserCheckpoint checkpoint(this);
ExpressionT expression =
this->ParseConditionalExpression(accept_IN, CHECK_OK);
if (allow_arrow_functions() && peek() == Token::ARROW) {
+ checkpoint.Restore();
expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
expression, CHECK_OK);
return expression;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.