OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 14 matching lines...) Expand all Loading... |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "api.h" | 30 #include "api.h" |
31 #include "ast.h" | 31 #include "ast.h" |
32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
33 #include "codegen.h" | 33 #include "codegen.h" |
34 #include "compiler.h" | 34 #include "compiler.h" |
| 35 #include "func-name-inferrer.h" |
35 #include "messages.h" | 36 #include "messages.h" |
36 #include "parser.h" | 37 #include "parser.h" |
37 #include "platform.h" | 38 #include "platform.h" |
38 #include "runtime.h" | 39 #include "runtime.h" |
39 #include "scopeinfo.h" | 40 #include "scopeinfo.h" |
40 #include "scopes.h" | 41 #include "scopes.h" |
41 #include "string-stream.h" | 42 #include "string-stream.h" |
42 | 43 |
43 #include "ast-inl.h" | 44 #include "ast-inl.h" |
44 #include "jump-target-inl.h" | 45 #include "jump-target-inl.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 Mode mode_; | 148 Mode mode_; |
148 | 149 |
149 Target* target_stack_; // for break, continue statements | 150 Target* target_stack_; // for break, continue statements |
150 bool allow_natives_syntax_; | 151 bool allow_natives_syntax_; |
151 v8::Extension* extension_; | 152 v8::Extension* extension_; |
152 ParserFactory* factory_; | 153 ParserFactory* factory_; |
153 ParserLog* log_; | 154 ParserLog* log_; |
154 bool is_pre_parsing_; | 155 bool is_pre_parsing_; |
155 ScriptDataImpl* pre_data_; | 156 ScriptDataImpl* pre_data_; |
156 bool seen_loop_stmt_; // Used for inner loop detection. | 157 bool seen_loop_stmt_; // Used for inner loop detection. |
| 158 FuncNameInferrer* fni_; |
157 | 159 |
158 bool inside_with() const { return with_nesting_level_ > 0; } | 160 bool inside_with() const { return with_nesting_level_ > 0; } |
159 ParserFactory* factory() const { return factory_; } | 161 ParserFactory* factory() const { return factory_; } |
160 ParserLog* log() const { return log_; } | 162 ParserLog* log() const { return log_; } |
161 Scanner& scanner() { return scanner_; } | 163 Scanner& scanner() { return scanner_; } |
162 Mode mode() const { return mode_; } | 164 Mode mode() const { return mode_; } |
163 ScriptDataImpl* pre_data() const { return pre_data_; } | 165 ScriptDataImpl* pre_data() const { return pre_data_; } |
164 | 166 |
165 // All ParseXXX functions take as the last argument an *ok parameter | 167 // All ParseXXX functions take as the last argument an *ok parameter |
166 // which is set to false if parsing failed; it is unchanged otherwise. | 168 // which is set to false if parsing failed; it is unchanged otherwise. |
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 top_scope_(NULL), | 1209 top_scope_(NULL), |
1208 with_nesting_level_(0), | 1210 with_nesting_level_(0), |
1209 temp_scope_(NULL), | 1211 temp_scope_(NULL), |
1210 target_stack_(NULL), | 1212 target_stack_(NULL), |
1211 allow_natives_syntax_(allow_natives_syntax), | 1213 allow_natives_syntax_(allow_natives_syntax), |
1212 extension_(extension), | 1214 extension_(extension), |
1213 factory_(factory), | 1215 factory_(factory), |
1214 log_(log), | 1216 log_(log), |
1215 is_pre_parsing_(is_pre_parsing == PREPARSE), | 1217 is_pre_parsing_(is_pre_parsing == PREPARSE), |
1216 pre_data_(pre_data), | 1218 pre_data_(pre_data), |
1217 seen_loop_stmt_(false) { | 1219 seen_loop_stmt_(false), |
| 1220 fni_(NULL) { |
1218 } | 1221 } |
1219 | 1222 |
1220 | 1223 |
1221 bool Parser::PreParseProgram(Handle<String> source, | 1224 bool Parser::PreParseProgram(Handle<String> source, |
1222 unibrow::CharacterStream* stream) { | 1225 unibrow::CharacterStream* stream) { |
1223 HistogramTimerScope timer(&Counters::pre_parse); | 1226 HistogramTimerScope timer(&Counters::pre_parse); |
1224 AssertNoZoneAllocation assert_no_zone_allocation; | 1227 AssertNoZoneAllocation assert_no_zone_allocation; |
1225 AssertNoAllocation assert_no_allocation; | 1228 AssertNoAllocation assert_no_allocation; |
1226 NoHandleAllocation no_handle_allocation; | 1229 NoHandleAllocation no_handle_allocation; |
1227 scanner_.Initialize(source, stream, JAVASCRIPT); | 1230 scanner_.Initialize(source, stream, JAVASCRIPT); |
1228 ASSERT(target_stack_ == NULL); | 1231 ASSERT(target_stack_ == NULL); |
1229 mode_ = PARSE_EAGERLY; | 1232 mode_ = PARSE_EAGERLY; |
1230 DummyScope top_scope; | 1233 DummyScope top_scope; |
1231 LexicalScope scope(this, &top_scope); | 1234 LexicalScope scope(this, &top_scope); |
1232 TemporaryScope temp_scope(this); | 1235 TemporaryScope temp_scope(this); |
1233 ZoneListWrapper<Statement> processor; | 1236 ZoneListWrapper<Statement> processor; |
1234 bool ok = true; | 1237 bool ok = true; |
1235 ParseSourceElements(&processor, Token::EOS, &ok); | 1238 ParseSourceElements(&processor, Token::EOS, &ok); |
1236 return !scanner().stack_overflow(); | 1239 return !scanner().stack_overflow(); |
1237 } | 1240 } |
1238 | 1241 |
1239 | 1242 |
1240 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 1243 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
1241 bool in_global_context) { | 1244 bool in_global_context) { |
1242 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 1245 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
1243 | 1246 |
1244 HistogramTimerScope timer(&Counters::parse); | 1247 HistogramTimerScope timer(&Counters::parse); |
1245 Counters::total_parse_size.Increment(source->length()); | 1248 Counters::total_parse_size.Increment(source->length()); |
| 1249 fni_ = new FuncNameInferrer(); |
1246 | 1250 |
1247 // Initialize parser state. | 1251 // Initialize parser state. |
1248 source->TryFlatten(); | 1252 source->TryFlatten(); |
1249 scanner_.Initialize(source, JAVASCRIPT); | 1253 scanner_.Initialize(source, JAVASCRIPT); |
1250 ASSERT(target_stack_ == NULL); | 1254 ASSERT(target_stack_ == NULL); |
1251 | 1255 |
1252 // Compute the parsing mode. | 1256 // Compute the parsing mode. |
1253 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 1257 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
1254 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 1258 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
1255 | 1259 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 | 1300 |
1297 FunctionLiteral* Parser::ParseLazy(Handle<String> source, | 1301 FunctionLiteral* Parser::ParseLazy(Handle<String> source, |
1298 Handle<String> name, | 1302 Handle<String> name, |
1299 int start_position, | 1303 int start_position, |
1300 int end_position, | 1304 int end_position, |
1301 bool is_expression) { | 1305 bool is_expression) { |
1302 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 1306 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
1303 HistogramTimerScope timer(&Counters::parse_lazy); | 1307 HistogramTimerScope timer(&Counters::parse_lazy); |
1304 Counters::total_parse_size.Increment(source->length()); | 1308 Counters::total_parse_size.Increment(source->length()); |
1305 | 1309 |
| 1310 fni_ = new FuncNameInferrer(); |
| 1311 fni_->PushEnclosingName(name); |
| 1312 |
1306 // Initialize parser state. | 1313 // Initialize parser state. |
1307 source->TryFlatten(); | 1314 source->TryFlatten(); |
1308 scanner_.Initialize(source, start_position, end_position, JAVASCRIPT); | 1315 scanner_.Initialize(source, start_position, end_position, JAVASCRIPT); |
1309 ASSERT(target_stack_ == NULL); | 1316 ASSERT(target_stack_ == NULL); |
1310 mode_ = PARSE_EAGERLY; | 1317 mode_ = PARSE_EAGERLY; |
1311 | 1318 |
1312 // Place holder for the result. | 1319 // Place holder for the result. |
1313 FunctionLiteral* result = NULL; | 1320 FunctionLiteral* result = NULL; |
1314 | 1321 |
1315 { | 1322 { |
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2073 // rewriter to add a '.result' assignment to such a block (to get compliant | 2080 // rewriter to add a '.result' assignment to such a block (to get compliant |
2074 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2081 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
2075 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2082 // reasons when pretty-printing. Also, unless an assignment (initialization) |
2076 // is inside an initializer block, it is ignored. | 2083 // is inside an initializer block, it is ignored. |
2077 // | 2084 // |
2078 // Create new block with one expected declaration. | 2085 // Create new block with one expected declaration. |
2079 Block* block = NEW(Block(NULL, 1, true)); | 2086 Block* block = NEW(Block(NULL, 1, true)); |
2080 VariableProxy* last_var = NULL; // the last variable declared | 2087 VariableProxy* last_var = NULL; // the last variable declared |
2081 int nvars = 0; // the number of variables declared | 2088 int nvars = 0; // the number of variables declared |
2082 do { | 2089 do { |
| 2090 if (fni_ != NULL) fni_->Enter(); |
| 2091 |
2083 // Parse variable name. | 2092 // Parse variable name. |
2084 if (nvars > 0) Consume(Token::COMMA); | 2093 if (nvars > 0) Consume(Token::COMMA); |
2085 Handle<String> name = ParseIdentifier(CHECK_OK); | 2094 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2095 if (fni_ != NULL) fni_->PushVariableName(name); |
2086 | 2096 |
2087 // Declare variable. | 2097 // Declare variable. |
2088 // Note that we *always* must treat the initial value via a separate init | 2098 // Note that we *always* must treat the initial value via a separate init |
2089 // assignment for variables and constants because the value must be assigned | 2099 // assignment for variables and constants because the value must be assigned |
2090 // when the variable is encountered in the source. But the variable/constant | 2100 // when the variable is encountered in the source. But the variable/constant |
2091 // is declared (and set to 'undefined') upon entering the function within | 2101 // is declared (and set to 'undefined') upon entering the function within |
2092 // which the variable or constant is declared. Only function variables have | 2102 // which the variable or constant is declared. Only function variables have |
2093 // an initial value in the declaration (because they are initialized upon | 2103 // an initial value in the declaration (because they are initialized upon |
2094 // entering the function). | 2104 // entering the function). |
2095 // | 2105 // |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2127 // The "variable" c initialized to x is the same as the declared | 2137 // The "variable" c initialized to x is the same as the declared |
2128 // one - there is no re-lookup (see the last parameter of the | 2138 // one - there is no re-lookup (see the last parameter of the |
2129 // Declare() call above). | 2139 // Declare() call above). |
2130 | 2140 |
2131 Expression* value = NULL; | 2141 Expression* value = NULL; |
2132 int position = -1; | 2142 int position = -1; |
2133 if (peek() == Token::ASSIGN) { | 2143 if (peek() == Token::ASSIGN) { |
2134 Expect(Token::ASSIGN, CHECK_OK); | 2144 Expect(Token::ASSIGN, CHECK_OK); |
2135 position = scanner().location().beg_pos; | 2145 position = scanner().location().beg_pos; |
2136 value = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2146 value = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2147 // Don't infer if it is "a = function(){...}();"-like expression. |
| 2148 if (fni_ != NULL && value->AsCall() == NULL) fni_->Infer(); |
2137 } | 2149 } |
2138 | 2150 |
2139 // Make sure that 'const c' actually initializes 'c' to undefined | 2151 // Make sure that 'const c' actually initializes 'c' to undefined |
2140 // even though it seems like a stupid thing to do. | 2152 // even though it seems like a stupid thing to do. |
2141 if (value == NULL && is_const) { | 2153 if (value == NULL && is_const) { |
2142 value = GetLiteralUndefined(); | 2154 value = GetLiteralUndefined(); |
2143 } | 2155 } |
2144 | 2156 |
2145 // Global variable declarations must be compiled in a specific | 2157 // Global variable declarations must be compiled in a specific |
2146 // way. When the script containing the global variable declaration | 2158 // way. When the script containing the global variable declaration |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2203 // initializations always assign to the declared constant which is | 2215 // initializations always assign to the declared constant which is |
2204 // always at the function scope level. This is only relevant for | 2216 // always at the function scope level. This is only relevant for |
2205 // dynamically looked-up variables and constants (the start context | 2217 // dynamically looked-up variables and constants (the start context |
2206 // for constant lookups is always the function context, while it is | 2218 // for constant lookups is always the function context, while it is |
2207 // the top context for variables). Sigh... | 2219 // the top context for variables). Sigh... |
2208 if (value != NULL) { | 2220 if (value != NULL) { |
2209 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); | 2221 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); |
2210 Assignment* assignment = NEW(Assignment(op, last_var, value, position)); | 2222 Assignment* assignment = NEW(Assignment(op, last_var, value, position)); |
2211 if (block) block->AddStatement(NEW(ExpressionStatement(assignment))); | 2223 if (block) block->AddStatement(NEW(ExpressionStatement(assignment))); |
2212 } | 2224 } |
| 2225 |
| 2226 if (fni_ != NULL) fni_->Leave(); |
2213 } while (peek() == Token::COMMA); | 2227 } while (peek() == Token::COMMA); |
2214 | 2228 |
2215 if (!is_const && nvars == 1) { | 2229 if (!is_const && nvars == 1) { |
2216 // We have a single, non-const variable. | 2230 // We have a single, non-const variable. |
2217 if (is_pre_parsing_) { | 2231 if (is_pre_parsing_) { |
2218 // If we're preparsing then we need to set the var to something | 2232 // If we're preparsing then we need to set the var to something |
2219 // in order for for-in loops to parse correctly. | 2233 // in order for for-in loops to parse correctly. |
2220 *var = ValidLeftHandSideSentinel::instance(); | 2234 *var = ValidLeftHandSideSentinel::instance(); |
2221 } else { | 2235 } else { |
2222 ASSERT(last_var != NULL); | 2236 ASSERT(last_var != NULL); |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2815 return result; | 2829 return result; |
2816 } | 2830 } |
2817 | 2831 |
2818 | 2832 |
2819 // Precedence = 2 | 2833 // Precedence = 2 |
2820 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2834 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2821 // AssignmentExpression :: | 2835 // AssignmentExpression :: |
2822 // ConditionalExpression | 2836 // ConditionalExpression |
2823 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2837 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2824 | 2838 |
| 2839 if (fni_ != NULL) fni_->Enter(); |
2825 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 2840 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
2826 | 2841 |
2827 if (!Token::IsAssignmentOp(peek())) { | 2842 if (!Token::IsAssignmentOp(peek())) { |
| 2843 if (fni_ != NULL) fni_->Leave(); |
2828 // Parsed conditional expression only (no assignment). | 2844 // Parsed conditional expression only (no assignment). |
2829 return expression; | 2845 return expression; |
2830 } | 2846 } |
2831 | 2847 |
2832 // Signal a reference error if the expression is an invalid left-hand | 2848 // Signal a reference error if the expression is an invalid left-hand |
2833 // side expression. We could report this as a syntax error here but | 2849 // side expression. We could report this as a syntax error here but |
2834 // for compatibility with JSC we choose to report the error at | 2850 // for compatibility with JSC we choose to report the error at |
2835 // runtime. | 2851 // runtime. |
2836 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2852 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2837 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); | 2853 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); |
(...skipping 10 matching lines...) Expand all Loading... |
2848 // properties if we haven't seen them before. Otherwise we'll | 2864 // properties if we haven't seen them before. Otherwise we'll |
2849 // probably overestimate the number of properties. | 2865 // probably overestimate the number of properties. |
2850 Property* property = expression ? expression->AsProperty() : NULL; | 2866 Property* property = expression ? expression->AsProperty() : NULL; |
2851 if (op == Token::ASSIGN && | 2867 if (op == Token::ASSIGN && |
2852 property != NULL && | 2868 property != NULL && |
2853 property->obj()->AsVariableProxy() != NULL && | 2869 property->obj()->AsVariableProxy() != NULL && |
2854 property->obj()->AsVariableProxy()->is_this()) { | 2870 property->obj()->AsVariableProxy()->is_this()) { |
2855 temp_scope_->AddProperty(); | 2871 temp_scope_->AddProperty(); |
2856 } | 2872 } |
2857 | 2873 |
| 2874 if (fni_ != NULL) { |
| 2875 // Check if the right hand side is a call to avoid inferring a |
| 2876 // name if we're dealing with "a = function(){...}();"-like |
| 2877 // expression. |
| 2878 if ((op == Token::INIT_VAR |
| 2879 || op == Token::INIT_CONST |
| 2880 || op == Token::ASSIGN) |
| 2881 && (right->AsCall() == NULL)) { |
| 2882 fni_->Infer(); |
| 2883 } |
| 2884 fni_->Leave(); |
| 2885 } |
| 2886 |
2858 return NEW(Assignment(op, expression, right, pos)); | 2887 return NEW(Assignment(op, expression, right, pos)); |
2859 } | 2888 } |
2860 | 2889 |
2861 | 2890 |
2862 // Precedence = 3 | 2891 // Precedence = 3 |
2863 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2892 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
2864 // ConditionalExpression :: | 2893 // ConditionalExpression :: |
2865 // LogicalOrExpression | 2894 // LogicalOrExpression |
2866 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2895 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2867 | 2896 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3118 } | 3147 } |
3119 result = factory()->NewCall(result, args, pos); | 3148 result = factory()->NewCall(result, args, pos); |
3120 break; | 3149 break; |
3121 } | 3150 } |
3122 | 3151 |
3123 case Token::PERIOD: { | 3152 case Token::PERIOD: { |
3124 Consume(Token::PERIOD); | 3153 Consume(Token::PERIOD); |
3125 int pos = scanner().location().beg_pos; | 3154 int pos = scanner().location().beg_pos; |
3126 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3155 Handle<String> name = ParseIdentifierName(CHECK_OK); |
3127 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 3156 result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
| 3157 if (fni_ != NULL) fni_->PushLiteralName(name); |
3128 break; | 3158 break; |
3129 } | 3159 } |
3130 | 3160 |
3131 default: | 3161 default: |
3132 return result; | 3162 return result; |
3133 } | 3163 } |
3134 } | 3164 } |
3135 } | 3165 } |
3136 | 3166 |
3137 | 3167 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3204 Expression* index = ParseExpression(true, CHECK_OK); | 3234 Expression* index = ParseExpression(true, CHECK_OK); |
3205 result = factory()->NewProperty(result, index, pos); | 3235 result = factory()->NewProperty(result, index, pos); |
3206 Expect(Token::RBRACK, CHECK_OK); | 3236 Expect(Token::RBRACK, CHECK_OK); |
3207 break; | 3237 break; |
3208 } | 3238 } |
3209 case Token::PERIOD: { | 3239 case Token::PERIOD: { |
3210 Consume(Token::PERIOD); | 3240 Consume(Token::PERIOD); |
3211 int pos = scanner().location().beg_pos; | 3241 int pos = scanner().location().beg_pos; |
3212 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3242 Handle<String> name = ParseIdentifierName(CHECK_OK); |
3213 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 3243 result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
| 3244 if (fni_ != NULL) fni_->PushLiteralName(name); |
3214 break; | 3245 break; |
3215 } | 3246 } |
3216 case Token::LPAREN: { | 3247 case Token::LPAREN: { |
3217 if ((stack == NULL) || stack->is_empty()) return result; | 3248 if ((stack == NULL) || stack->is_empty()) return result; |
3218 // Consume one of the new prefixes (already parsed). | 3249 // Consume one of the new prefixes (already parsed). |
3219 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3250 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
3220 int last = stack->pop(); | 3251 int last = stack->pop(); |
3221 result = NEW(CallNew(result, args, last)); | 3252 result = NEW(CallNew(result, args, last)); |
3222 break; | 3253 break; |
3223 } | 3254 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3314 result = NEW(Literal(Factory::true_value())); | 3345 result = NEW(Literal(Factory::true_value())); |
3315 break; | 3346 break; |
3316 | 3347 |
3317 case Token::FALSE_LITERAL: | 3348 case Token::FALSE_LITERAL: |
3318 Consume(Token::FALSE_LITERAL); | 3349 Consume(Token::FALSE_LITERAL); |
3319 result = NEW(Literal(Factory::false_value())); | 3350 result = NEW(Literal(Factory::false_value())); |
3320 break; | 3351 break; |
3321 | 3352 |
3322 case Token::IDENTIFIER: { | 3353 case Token::IDENTIFIER: { |
3323 Handle<String> name = ParseIdentifier(CHECK_OK); | 3354 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 3355 if (fni_ != NULL) fni_->PushVariableName(name); |
3324 if (is_pre_parsing_) { | 3356 if (is_pre_parsing_) { |
3325 result = VariableProxySentinel::identifier_proxy(); | 3357 result = VariableProxySentinel::identifier_proxy(); |
3326 } else { | 3358 } else { |
3327 result = top_scope_->NewUnresolved(name, inside_with()); | 3359 result = top_scope_->NewUnresolved(name, inside_with()); |
3328 } | 3360 } |
3329 break; | 3361 break; |
3330 } | 3362 } |
3331 | 3363 |
3332 case Token::NUMBER: { | 3364 case Token::NUMBER: { |
3333 Consume(Token::NUMBER); | 3365 Consume(Token::NUMBER); |
3334 double value = | 3366 double value = |
3335 StringToDouble(scanner_.literal_string(), ALLOW_HEX | ALLOW_OCTALS); | 3367 StringToDouble(scanner_.literal_string(), ALLOW_HEX | ALLOW_OCTALS); |
3336 result = NewNumberLiteral(value); | 3368 result = NewNumberLiteral(value); |
3337 break; | 3369 break; |
3338 } | 3370 } |
3339 | 3371 |
3340 case Token::STRING: { | 3372 case Token::STRING: { |
3341 Consume(Token::STRING); | 3373 Consume(Token::STRING); |
3342 Handle<String> symbol = | 3374 Handle<String> symbol = |
3343 factory()->LookupSymbol(scanner_.literal_string(), | 3375 factory()->LookupSymbol(scanner_.literal_string(), |
3344 scanner_.literal_length()); | 3376 scanner_.literal_length()); |
3345 result = NEW(Literal(symbol)); | 3377 result = NEW(Literal(symbol)); |
| 3378 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
3346 break; | 3379 break; |
3347 } | 3380 } |
3348 | 3381 |
3349 case Token::ASSIGN_DIV: | 3382 case Token::ASSIGN_DIV: |
3350 result = ParseRegExpLiteral(true, CHECK_OK); | 3383 result = ParseRegExpLiteral(true, CHECK_OK); |
3351 break; | 3384 break; |
3352 | 3385 |
3353 case Token::DIV: | 3386 case Token::DIV: |
3354 result = ParseRegExpLiteral(false, CHECK_OK); | 3387 result = ParseRegExpLiteral(false, CHECK_OK); |
3355 break; | 3388 break; |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3633 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3666 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
3634 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3667 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
3635 // )*[','] '}' | 3668 // )*[','] '}' |
3636 | 3669 |
3637 ZoneListWrapper<ObjectLiteral::Property> properties = | 3670 ZoneListWrapper<ObjectLiteral::Property> properties = |
3638 factory()->NewList<ObjectLiteral::Property>(4); | 3671 factory()->NewList<ObjectLiteral::Property>(4); |
3639 int number_of_boilerplate_properties = 0; | 3672 int number_of_boilerplate_properties = 0; |
3640 | 3673 |
3641 Expect(Token::LBRACE, CHECK_OK); | 3674 Expect(Token::LBRACE, CHECK_OK); |
3642 while (peek() != Token::RBRACE) { | 3675 while (peek() != Token::RBRACE) { |
| 3676 if (fni_ != NULL) fni_->Enter(); |
| 3677 |
3643 Literal* key = NULL; | 3678 Literal* key = NULL; |
3644 Token::Value next = peek(); | 3679 Token::Value next = peek(); |
3645 switch (next) { | 3680 switch (next) { |
3646 case Token::IDENTIFIER: { | 3681 case Token::IDENTIFIER: { |
3647 bool is_getter = false; | 3682 bool is_getter = false; |
3648 bool is_setter = false; | 3683 bool is_setter = false; |
3649 Handle<String> id = | 3684 Handle<String> id = |
3650 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3685 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 3686 if (fni_ != NULL) fni_->PushLiteralName(id); |
| 3687 |
3651 if ((is_getter || is_setter) && peek() != Token::COLON) { | 3688 if ((is_getter || is_setter) && peek() != Token::COLON) { |
3652 ObjectLiteral::Property* property = | 3689 ObjectLiteral::Property* property = |
3653 ParseObjectLiteralGetSet(is_getter, CHECK_OK); | 3690 ParseObjectLiteralGetSet(is_getter, CHECK_OK); |
3654 if (IsBoilerplateProperty(property)) { | 3691 if (IsBoilerplateProperty(property)) { |
3655 number_of_boilerplate_properties++; | 3692 number_of_boilerplate_properties++; |
3656 } | 3693 } |
3657 properties.Add(property); | 3694 properties.Add(property); |
3658 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3695 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3696 |
| 3697 if (fni_ != NULL) { |
| 3698 fni_->Infer(); |
| 3699 fni_->Leave(); |
| 3700 } |
3659 continue; // restart the while | 3701 continue; // restart the while |
3660 } | 3702 } |
3661 // Failed to parse as get/set property, so it's just a property | 3703 // Failed to parse as get/set property, so it's just a property |
3662 // called "get" or "set". | 3704 // called "get" or "set". |
3663 key = NEW(Literal(id)); | 3705 key = NEW(Literal(id)); |
3664 break; | 3706 break; |
3665 } | 3707 } |
3666 case Token::STRING: { | 3708 case Token::STRING: { |
3667 Consume(Token::STRING); | 3709 Consume(Token::STRING); |
3668 Handle<String> string = | 3710 Handle<String> string = |
3669 factory()->LookupSymbol(scanner_.literal_string(), | 3711 factory()->LookupSymbol(scanner_.literal_string(), |
3670 scanner_.literal_length()); | 3712 scanner_.literal_length()); |
| 3713 if (fni_ != NULL) fni_->PushLiteralName(string); |
3671 uint32_t index; | 3714 uint32_t index; |
3672 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3715 if (!string.is_null() && string->AsArrayIndex(&index)) { |
3673 key = NewNumberLiteral(index); | 3716 key = NewNumberLiteral(index); |
3674 break; | 3717 break; |
3675 } | 3718 } |
3676 key = NEW(Literal(string)); | 3719 key = NEW(Literal(string)); |
3677 break; | 3720 break; |
3678 } | 3721 } |
3679 case Token::NUMBER: { | 3722 case Token::NUMBER: { |
3680 Consume(Token::NUMBER); | 3723 Consume(Token::NUMBER); |
(...skipping 23 matching lines...) Expand all Loading... |
3704 | 3747 |
3705 ObjectLiteral::Property* property = | 3748 ObjectLiteral::Property* property = |
3706 NEW(ObjectLiteral::Property(key, value)); | 3749 NEW(ObjectLiteral::Property(key, value)); |
3707 | 3750 |
3708 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3751 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
3709 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; | 3752 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; |
3710 properties.Add(property); | 3753 properties.Add(property); |
3711 | 3754 |
3712 // TODO(1240767): Consider allowing trailing comma. | 3755 // TODO(1240767): Consider allowing trailing comma. |
3713 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3756 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3757 |
| 3758 if (fni_ != NULL) { |
| 3759 fni_->Infer(); |
| 3760 fni_->Leave(); |
| 3761 } |
3714 } | 3762 } |
3715 Expect(Token::RBRACE, CHECK_OK); | 3763 Expect(Token::RBRACE, CHECK_OK); |
3716 // Computation of literal_index must happen before pre parse bailout. | 3764 // Computation of literal_index must happen before pre parse bailout. |
3717 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3765 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
3718 if (is_pre_parsing_) return NULL; | 3766 if (is_pre_parsing_) return NULL; |
3719 | 3767 |
3720 Handle<FixedArray> constant_properties = | 3768 Handle<FixedArray> constant_properties = |
3721 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); | 3769 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); |
3722 | 3770 |
3723 bool is_simple = true; | 3771 bool is_simple = true; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3915 function_name->length() > 0)); | 3963 function_name->length() > 0)); |
3916 if (!is_pre_parsing_) { | 3964 if (!is_pre_parsing_) { |
3917 function_literal->set_function_token_position(function_token_position); | 3965 function_literal->set_function_token_position(function_token_position); |
3918 } | 3966 } |
3919 | 3967 |
3920 // Set flag for inner loop detection. We treat loops that contain a function | 3968 // Set flag for inner loop detection. We treat loops that contain a function |
3921 // literal not as inner loops because we avoid duplicating function literals | 3969 // literal not as inner loops because we avoid duplicating function literals |
3922 // when peeling or unrolling such a loop. | 3970 // when peeling or unrolling such a loop. |
3923 seen_loop_stmt_ = true; | 3971 seen_loop_stmt_ = true; |
3924 | 3972 |
| 3973 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
3925 return function_literal; | 3974 return function_literal; |
3926 } | 3975 } |
3927 } | 3976 } |
3928 | 3977 |
3929 | 3978 |
3930 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3979 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
3931 // CallRuntime :: | 3980 // CallRuntime :: |
3932 // '%' Identifier Arguments | 3981 // '%' Identifier Arguments |
3933 | 3982 |
3934 Expect(Token::MOD, CHECK_OK); | 3983 Expect(Token::MOD, CHECK_OK); |
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5257 parser.ParseLazy(script_source, name, | 5306 parser.ParseLazy(script_source, name, |
5258 start_position, end_position, is_expression); | 5307 start_position, end_position, is_expression); |
5259 return result; | 5308 return result; |
5260 } | 5309 } |
5261 | 5310 |
5262 | 5311 |
5263 #undef NEW | 5312 #undef NEW |
5264 | 5313 |
5265 | 5314 |
5266 } } // namespace v8::internal | 5315 } } // namespace v8::internal |
OLD | NEW |