| Index: src/parser.cc
|
| ===================================================================
|
| --- src/parser.cc (revision 5319)
|
| +++ src/parser.cc (working copy)
|
| @@ -32,6 +32,7 @@
|
| #include "bootstrapper.h"
|
| #include "codegen.h"
|
| #include "compiler.h"
|
| +#include "func-name-inferrer.h"
|
| #include "messages.h"
|
| #include "parser.h"
|
| #include "platform.h"
|
| @@ -154,6 +155,7 @@
|
| bool is_pre_parsing_;
|
| ScriptDataImpl* pre_data_;
|
| bool seen_loop_stmt_; // Used for inner loop detection.
|
| + FuncNameInferrer* fni_;
|
|
|
| bool inside_with() const { return with_nesting_level_ > 0; }
|
| ParserFactory* factory() const { return factory_; }
|
| @@ -1214,7 +1216,8 @@
|
| log_(log),
|
| is_pre_parsing_(is_pre_parsing == PREPARSE),
|
| pre_data_(pre_data),
|
| - seen_loop_stmt_(false) {
|
| + seen_loop_stmt_(false),
|
| + fni_(NULL) {
|
| }
|
|
|
|
|
| @@ -1243,6 +1246,7 @@
|
|
|
| HistogramTimerScope timer(&Counters::parse);
|
| Counters::total_parse_size.Increment(source->length());
|
| + fni_ = new FuncNameInferrer();
|
|
|
| // Initialize parser state.
|
| source->TryFlatten();
|
| @@ -1303,6 +1307,9 @@
|
| HistogramTimerScope timer(&Counters::parse_lazy);
|
| Counters::total_parse_size.Increment(source->length());
|
|
|
| + fni_ = new FuncNameInferrer();
|
| + fni_->PushEnclosingName(name);
|
| +
|
| // Initialize parser state.
|
| source->TryFlatten();
|
| scanner_.Initialize(source, start_position, end_position, JAVASCRIPT);
|
| @@ -2080,9 +2087,12 @@
|
| VariableProxy* last_var = NULL; // the last variable declared
|
| int nvars = 0; // the number of variables declared
|
| do {
|
| + if (fni_ != NULL) fni_->Enter();
|
| +
|
| // Parse variable name.
|
| if (nvars > 0) Consume(Token::COMMA);
|
| Handle<String> name = ParseIdentifier(CHECK_OK);
|
| + if (fni_ != NULL) fni_->PushVariableName(name);
|
|
|
| // Declare variable.
|
| // Note that we *always* must treat the initial value via a separate init
|
| @@ -2134,6 +2144,8 @@
|
| Expect(Token::ASSIGN, CHECK_OK);
|
| position = scanner().location().beg_pos;
|
| value = ParseAssignmentExpression(accept_IN, CHECK_OK);
|
| + // Don't infer if it is "a = function(){...}();"-like expression.
|
| + if (fni_ != NULL && value->AsCall() == NULL) fni_->Infer();
|
| }
|
|
|
| // Make sure that 'const c' actually initializes 'c' to undefined
|
| @@ -2210,6 +2222,8 @@
|
| Assignment* assignment = NEW(Assignment(op, last_var, value, position));
|
| if (block) block->AddStatement(NEW(ExpressionStatement(assignment)));
|
| }
|
| +
|
| + if (fni_ != NULL) fni_->Leave();
|
| } while (peek() == Token::COMMA);
|
|
|
| if (!is_const && nvars == 1) {
|
| @@ -2822,9 +2836,11 @@
|
| // ConditionalExpression
|
| // LeftHandSideExpression AssignmentOperator AssignmentExpression
|
|
|
| + if (fni_ != NULL) fni_->Enter();
|
| Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
|
|
|
| if (!Token::IsAssignmentOp(peek())) {
|
| + if (fni_ != NULL) fni_->Leave();
|
| // Parsed conditional expression only (no assignment).
|
| return expression;
|
| }
|
| @@ -2855,6 +2871,19 @@
|
| temp_scope_->AddProperty();
|
| }
|
|
|
| + if (fni_ != NULL) {
|
| + // Check if the right hand side is a call to avoid inferring a
|
| + // name if we're dealing with "a = function(){...}();"-like
|
| + // expression.
|
| + if ((op == Token::INIT_VAR
|
| + || op == Token::INIT_CONST
|
| + || op == Token::ASSIGN)
|
| + && (right->AsCall() == NULL)) {
|
| + fni_->Infer();
|
| + }
|
| + fni_->Leave();
|
| + }
|
| +
|
| return NEW(Assignment(op, expression, right, pos));
|
| }
|
|
|
| @@ -3125,6 +3154,7 @@
|
| int pos = scanner().location().beg_pos;
|
| Handle<String> name = ParseIdentifierName(CHECK_OK);
|
| result = factory()->NewProperty(result, NEW(Literal(name)), pos);
|
| + if (fni_ != NULL) fni_->PushLiteralName(name);
|
| break;
|
| }
|
|
|
| @@ -3211,6 +3241,7 @@
|
| int pos = scanner().location().beg_pos;
|
| Handle<String> name = ParseIdentifierName(CHECK_OK);
|
| result = factory()->NewProperty(result, NEW(Literal(name)), pos);
|
| + if (fni_ != NULL) fni_->PushLiteralName(name);
|
| break;
|
| }
|
| case Token::LPAREN: {
|
| @@ -3321,6 +3352,7 @@
|
|
|
| case Token::IDENTIFIER: {
|
| Handle<String> name = ParseIdentifier(CHECK_OK);
|
| + if (fni_ != NULL) fni_->PushVariableName(name);
|
| if (is_pre_parsing_) {
|
| result = VariableProxySentinel::identifier_proxy();
|
| } else {
|
| @@ -3343,6 +3375,7 @@
|
| factory()->LookupSymbol(scanner_.literal_string(),
|
| scanner_.literal_length());
|
| result = NEW(Literal(symbol));
|
| + if (fni_ != NULL) fni_->PushLiteralName(symbol);
|
| break;
|
| }
|
|
|
| @@ -3640,6 +3673,8 @@
|
|
|
| Expect(Token::LBRACE, CHECK_OK);
|
| while (peek() != Token::RBRACE) {
|
| + if (fni_ != NULL) fni_->Enter();
|
| +
|
| Literal* key = NULL;
|
| Token::Value next = peek();
|
| switch (next) {
|
| @@ -3648,6 +3683,8 @@
|
| bool is_setter = false;
|
| Handle<String> id =
|
| ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
|
| + if (fni_ != NULL) fni_->PushLiteralName(id);
|
| +
|
| if ((is_getter || is_setter) && peek() != Token::COLON) {
|
| ObjectLiteral::Property* property =
|
| ParseObjectLiteralGetSet(is_getter, CHECK_OK);
|
| @@ -3656,6 +3693,11 @@
|
| }
|
| properties.Add(property);
|
| if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
|
| +
|
| + if (fni_ != NULL) {
|
| + fni_->Infer();
|
| + fni_->Leave();
|
| + }
|
| continue; // restart the while
|
| }
|
| // Failed to parse as get/set property, so it's just a property
|
| @@ -3668,6 +3710,7 @@
|
| Handle<String> string =
|
| factory()->LookupSymbol(scanner_.literal_string(),
|
| scanner_.literal_length());
|
| + if (fni_ != NULL) fni_->PushLiteralName(string);
|
| uint32_t index;
|
| if (!string.is_null() && string->AsArrayIndex(&index)) {
|
| key = NewNumberLiteral(index);
|
| @@ -3711,6 +3754,11 @@
|
|
|
| // TODO(1240767): Consider allowing trailing comma.
|
| if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
|
| +
|
| + if (fni_ != NULL) {
|
| + fni_->Infer();
|
| + fni_->Leave();
|
| + }
|
| }
|
| Expect(Token::RBRACE, CHECK_OK);
|
| // Computation of literal_index must happen before pre parse bailout.
|
| @@ -3922,6 +3970,7 @@
|
| // when peeling or unrolling such a loop.
|
| seen_loop_stmt_ = true;
|
|
|
| + if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
|
| return function_literal;
|
| }
|
| }
|
|
|