| 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 |