| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 namespace std { | 46 namespace std { |
| 47 | 47 |
| 48 // Usually defined in math.h, but not in MSVC until VS2013+. | 48 // Usually defined in math.h, but not in MSVC until VS2013+. |
| 49 // Abstracted to work | 49 // Abstracted to work |
| 50 int isfinite(double value); | 50 int isfinite(double value); |
| 51 | 51 |
| 52 } // namespace std | 52 } // namespace std |
| 53 #endif | 53 #endif |
| 54 | 54 |
| 55 namespace v8 { | 55 namespace v8 { |
| 56 | 56 namespace internal { |
| 57 namespace preparser { | |
| 58 | 57 |
| 59 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 58 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| 60 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { | 59 LanguageMode mode, bool is_generator, ParserRecorder* log) { |
| 61 log_ = log; | 60 log_ = log; |
| 62 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 61 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
| 63 Scope top_scope(&scope_, kTopLevelScope); | 62 Scope top_scope(&scope_, kTopLevelScope); |
| 64 set_language_mode(mode); | 63 set_language_mode(mode); |
| 65 Scope function_scope(&scope_, kFunctionScope); | 64 Scope function_scope(&scope_, kFunctionScope); |
| 66 function_scope.set_is_generator(is_generator); | 65 function_scope.set_is_generator(is_generator); |
| 67 ASSERT_EQ(i::Token::LBRACE, scanner_->current_token()); | 66 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); |
| 68 bool ok = true; | 67 bool ok = true; |
| 69 int start_position = scanner_->peek_location().beg_pos; | 68 int start_position = peek_position(); |
| 70 ParseLazyFunctionLiteralBody(&ok); | 69 ParseLazyFunctionLiteralBody(&ok); |
| 71 if (stack_overflow_) return kPreParseStackOverflow; | 70 if (stack_overflow()) return kPreParseStackOverflow; |
| 72 if (!ok) { | 71 if (!ok) { |
| 73 ReportUnexpectedToken(scanner_->current_token()); | 72 ReportUnexpectedToken(scanner()->current_token()); |
| 74 } else { | 73 } else { |
| 75 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); | 74 ASSERT_EQ(Token::RBRACE, scanner()->peek()); |
| 76 if (!is_classic_mode()) { | 75 if (!is_classic_mode()) { |
| 77 int end_pos = scanner_->location().end_pos; | 76 int end_pos = scanner()->location().end_pos; |
| 78 CheckOctalLiteral(start_position, end_pos, &ok); | 77 CheckOctalLiteral(start_position, end_pos, &ok); |
| 79 if (ok) { | 78 if (ok) { |
| 80 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); | 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); |
| 81 } | 80 } |
| 82 } | 81 } |
| 83 } | 82 } |
| 84 return kPreParseSuccess; | 83 return kPreParseSuccess; |
| 85 } | 84 } |
| 86 | 85 |
| 87 | 86 |
| 88 // Preparsing checks a JavaScript program and emits preparse-data that helps | 87 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 89 // a later parsing to be faster. | 88 // a later parsing to be faster. |
| 90 // See preparser-data.h for the data. | 89 // See preparser-data.h for the data. |
| 91 | 90 |
| 92 // The PreParser checks that the syntax follows the grammar for JavaScript, | 91 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| 93 // and collects some information about the program along the way. | 92 // and collects some information about the program along the way. |
| 94 // The grammar check is only performed in order to understand the program | 93 // The grammar check is only performed in order to understand the program |
| 95 // sufficiently to deduce some information about it, that can be used | 94 // sufficiently to deduce some information about it, that can be used |
| 96 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 97 // rather it is to speed up properly written and correct programs. | 96 // rather it is to speed up properly written and correct programs. |
| 98 // That means that contextual checks (like a label being declared where | 97 // That means that contextual checks (like a label being declared where |
| 99 // it is used) are generally omitted. | 98 // it is used) are generally omitted. |
| 100 | 99 |
| 101 void PreParser::ReportUnexpectedToken(i::Token::Value token) { | 100 void PreParser::ReportUnexpectedToken(Token::Value token) { |
| 102 // We don't report stack overflows here, to avoid increasing the | 101 // We don't report stack overflows here, to avoid increasing the |
| 103 // stack depth even further. Instead we report it after parsing is | 102 // stack depth even further. Instead we report it after parsing is |
| 104 // over, in ParseProgram. | 103 // over, in ParseProgram. |
| 105 if (token == i::Token::ILLEGAL && stack_overflow_) { | 104 if (token == Token::ILLEGAL && stack_overflow()) { |
| 106 return; | 105 return; |
| 107 } | 106 } |
| 108 i::Scanner::Location source_location = scanner_->location(); | 107 Scanner::Location source_location = scanner()->location(); |
| 109 | 108 |
| 110 // Four of the tokens are treated specially | 109 // Four of the tokens are treated specially |
| 111 switch (token) { | 110 switch (token) { |
| 112 case i::Token::EOS: | 111 case Token::EOS: |
| 113 return ReportMessageAt(source_location, "unexpected_eos", NULL); | 112 return ReportMessageAt(source_location, "unexpected_eos", NULL); |
| 114 case i::Token::NUMBER: | 113 case Token::NUMBER: |
| 115 return ReportMessageAt(source_location, "unexpected_token_number", NULL); | 114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); |
| 116 case i::Token::STRING: | 115 case Token::STRING: |
| 117 return ReportMessageAt(source_location, "unexpected_token_string", NULL); | 116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); |
| 118 case i::Token::IDENTIFIER: | 117 case Token::IDENTIFIER: |
| 119 return ReportMessageAt(source_location, | 118 return ReportMessageAt(source_location, |
| 120 "unexpected_token_identifier", NULL); | 119 "unexpected_token_identifier", NULL); |
| 121 case i::Token::FUTURE_RESERVED_WORD: | 120 case Token::FUTURE_RESERVED_WORD: |
| 122 return ReportMessageAt(source_location, "unexpected_reserved", NULL); | 121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); |
| 123 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 122 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 124 return ReportMessageAt(source_location, | 123 return ReportMessageAt(source_location, |
| 125 "unexpected_strict_reserved", NULL); | 124 "unexpected_strict_reserved", NULL); |
| 126 default: | 125 default: |
| 127 const char* name = i::Token::String(token); | 126 const char* name = Token::String(token); |
| 128 ReportMessageAt(source_location, "unexpected_token", name); | 127 ReportMessageAt(source_location, "unexpected_token", name); |
| 129 } | 128 } |
| 130 } | 129 } |
| 131 | 130 |
| 132 | 131 |
| 133 // Checks whether octal literal last seen is between beg_pos and end_pos. | |
| 134 // If so, reports an error. | |
| 135 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | |
| 136 i::Scanner::Location octal = scanner_->octal_position(); | |
| 137 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | |
| 138 ReportMessageAt(octal, "strict_octal_literal", NULL); | |
| 139 scanner_->clear_octal_position(); | |
| 140 *ok = false; | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 | |
| 145 #define CHECK_OK ok); \ | 132 #define CHECK_OK ok); \ |
| 146 if (!*ok) return kUnknownSourceElements; \ | 133 if (!*ok) return kUnknownSourceElements; \ |
| 147 ((void)0 | 134 ((void)0 |
| 148 #define DUMMY ) // to make indentation work | 135 #define DUMMY ) // to make indentation work |
| 149 #undef DUMMY | 136 #undef DUMMY |
| 150 | 137 |
| 151 | 138 |
| 152 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { | 139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { |
| 153 // (Ecma 262 5th Edition, clause 14): | 140 // (Ecma 262 5th Edition, clause 14): |
| 154 // SourceElement: | 141 // SourceElement: |
| 155 // Statement | 142 // Statement |
| 156 // FunctionDeclaration | 143 // FunctionDeclaration |
| 157 // | 144 // |
| 158 // In harmony mode we allow additionally the following productions | 145 // In harmony mode we allow additionally the following productions |
| 159 // SourceElement: | 146 // SourceElement: |
| 160 // LetDeclaration | 147 // LetDeclaration |
| 161 // ConstDeclaration | 148 // ConstDeclaration |
| 162 // GeneratorDeclaration | 149 // GeneratorDeclaration |
| 163 | 150 |
| 164 switch (peek()) { | 151 switch (peek()) { |
| 165 case i::Token::FUNCTION: | 152 case Token::FUNCTION: |
| 166 return ParseFunctionDeclaration(ok); | 153 return ParseFunctionDeclaration(ok); |
| 167 case i::Token::LET: | 154 case Token::LET: |
| 168 case i::Token::CONST: | 155 case Token::CONST: |
| 169 return ParseVariableStatement(kSourceElement, ok); | 156 return ParseVariableStatement(kSourceElement, ok); |
| 170 default: | 157 default: |
| 171 return ParseStatement(ok); | 158 return ParseStatement(ok); |
| 172 } | 159 } |
| 173 } | 160 } |
| 174 | 161 |
| 175 | 162 |
| 176 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, | 163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
| 177 bool* ok) { | 164 bool* ok) { |
| 178 // SourceElements :: | 165 // SourceElements :: |
| 179 // (Statement)* <end_token> | 166 // (Statement)* <end_token> |
| 180 | 167 |
| 181 bool allow_directive_prologue = true; | 168 bool allow_directive_prologue = true; |
| 182 while (peek() != end_token) { | 169 while (peek() != end_token) { |
| 183 Statement statement = ParseSourceElement(CHECK_OK); | 170 Statement statement = ParseSourceElement(CHECK_OK); |
| 184 if (allow_directive_prologue) { | 171 if (allow_directive_prologue) { |
| 185 if (statement.IsUseStrictLiteral()) { | 172 if (statement.IsUseStrictLiteral()) { |
| 186 set_language_mode(allow_harmony_scoping() ? | 173 set_language_mode(allow_harmony_scoping() ? |
| 187 i::EXTENDED_MODE : i::STRICT_MODE); | 174 EXTENDED_MODE : STRICT_MODE); |
| 188 } else if (!statement.IsStringLiteral()) { | 175 } else if (!statement.IsStringLiteral()) { |
| 189 allow_directive_prologue = false; | 176 allow_directive_prologue = false; |
| 190 } | 177 } |
| 191 } | 178 } |
| 192 } | 179 } |
| 193 return kUnknownSourceElements; | 180 return kUnknownSourceElements; |
| 194 } | 181 } |
| 195 | 182 |
| 196 | 183 |
| 197 #undef CHECK_OK | 184 #undef CHECK_OK |
| (...skipping 24 matching lines...) Expand all Loading... |
| 222 | 209 |
| 223 // Note: Since labels can only be used by 'break' and 'continue' | 210 // Note: Since labels can only be used by 'break' and 'continue' |
| 224 // statements, which themselves are only valid within blocks, | 211 // statements, which themselves are only valid within blocks, |
| 225 // iterations or 'switch' statements (i.e., BreakableStatements), | 212 // iterations or 'switch' statements (i.e., BreakableStatements), |
| 226 // labels can be simply ignored in all other cases; except for | 213 // labels can be simply ignored in all other cases; except for |
| 227 // trivial labeled break statements 'label: break label' which is | 214 // trivial labeled break statements 'label: break label' which is |
| 228 // parsed into an empty statement. | 215 // parsed into an empty statement. |
| 229 | 216 |
| 230 // Keep the source position of the statement | 217 // Keep the source position of the statement |
| 231 switch (peek()) { | 218 switch (peek()) { |
| 232 case i::Token::LBRACE: | 219 case Token::LBRACE: |
| 233 return ParseBlock(ok); | 220 return ParseBlock(ok); |
| 234 | 221 |
| 235 case i::Token::CONST: | 222 case Token::CONST: |
| 236 case i::Token::LET: | 223 case Token::LET: |
| 237 case i::Token::VAR: | 224 case Token::VAR: |
| 238 return ParseVariableStatement(kStatement, ok); | 225 return ParseVariableStatement(kStatement, ok); |
| 239 | 226 |
| 240 case i::Token::SEMICOLON: | 227 case Token::SEMICOLON: |
| 241 Next(); | 228 Next(); |
| 242 return Statement::Default(); | 229 return Statement::Default(); |
| 243 | 230 |
| 244 case i::Token::IF: | 231 case Token::IF: |
| 245 return ParseIfStatement(ok); | 232 return ParseIfStatement(ok); |
| 246 | 233 |
| 247 case i::Token::DO: | 234 case Token::DO: |
| 248 return ParseDoWhileStatement(ok); | 235 return ParseDoWhileStatement(ok); |
| 249 | 236 |
| 250 case i::Token::WHILE: | 237 case Token::WHILE: |
| 251 return ParseWhileStatement(ok); | 238 return ParseWhileStatement(ok); |
| 252 | 239 |
| 253 case i::Token::FOR: | 240 case Token::FOR: |
| 254 return ParseForStatement(ok); | 241 return ParseForStatement(ok); |
| 255 | 242 |
| 256 case i::Token::CONTINUE: | 243 case Token::CONTINUE: |
| 257 return ParseContinueStatement(ok); | 244 return ParseContinueStatement(ok); |
| 258 | 245 |
| 259 case i::Token::BREAK: | 246 case Token::BREAK: |
| 260 return ParseBreakStatement(ok); | 247 return ParseBreakStatement(ok); |
| 261 | 248 |
| 262 case i::Token::RETURN: | 249 case Token::RETURN: |
| 263 return ParseReturnStatement(ok); | 250 return ParseReturnStatement(ok); |
| 264 | 251 |
| 265 case i::Token::WITH: | 252 case Token::WITH: |
| 266 return ParseWithStatement(ok); | 253 return ParseWithStatement(ok); |
| 267 | 254 |
| 268 case i::Token::SWITCH: | 255 case Token::SWITCH: |
| 269 return ParseSwitchStatement(ok); | 256 return ParseSwitchStatement(ok); |
| 270 | 257 |
| 271 case i::Token::THROW: | 258 case Token::THROW: |
| 272 return ParseThrowStatement(ok); | 259 return ParseThrowStatement(ok); |
| 273 | 260 |
| 274 case i::Token::TRY: | 261 case Token::TRY: |
| 275 return ParseTryStatement(ok); | 262 return ParseTryStatement(ok); |
| 276 | 263 |
| 277 case i::Token::FUNCTION: { | 264 case Token::FUNCTION: { |
| 278 i::Scanner::Location start_location = scanner_->peek_location(); | 265 Scanner::Location start_location = scanner()->peek_location(); |
| 279 Statement statement = ParseFunctionDeclaration(CHECK_OK); | 266 Statement statement = ParseFunctionDeclaration(CHECK_OK); |
| 280 i::Scanner::Location end_location = scanner_->location(); | 267 Scanner::Location end_location = scanner()->location(); |
| 281 if (!is_classic_mode()) { | 268 if (!is_classic_mode()) { |
| 282 ReportMessageAt(start_location.beg_pos, end_location.end_pos, | 269 ReportMessageAt(start_location.beg_pos, end_location.end_pos, |
| 283 "strict_function", NULL); | 270 "strict_function", NULL); |
| 284 *ok = false; | 271 *ok = false; |
| 285 return Statement::Default(); | 272 return Statement::Default(); |
| 286 } else { | 273 } else { |
| 287 return statement; | 274 return statement; |
| 288 } | 275 } |
| 289 } | 276 } |
| 290 | 277 |
| 291 case i::Token::DEBUGGER: | 278 case Token::DEBUGGER: |
| 292 return ParseDebuggerStatement(ok); | 279 return ParseDebuggerStatement(ok); |
| 293 | 280 |
| 294 default: | 281 default: |
| 295 return ParseExpressionOrLabelledStatement(ok); | 282 return ParseExpressionOrLabelledStatement(ok); |
| 296 } | 283 } |
| 297 } | 284 } |
| 298 | 285 |
| 299 | 286 |
| 300 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
| 301 // FunctionDeclaration :: | 288 // FunctionDeclaration :: |
| 302 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 289 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 303 // GeneratorDeclaration :: | 290 // GeneratorDeclaration :: |
| 304 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 291 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 305 // '{' FunctionBody '}' | 292 // '{' FunctionBody '}' |
| 306 Expect(i::Token::FUNCTION, CHECK_OK); | 293 Expect(Token::FUNCTION, CHECK_OK); |
| 307 | 294 |
| 308 bool is_generator = allow_generators_ && Check(i::Token::MUL); | 295 bool is_generator = allow_generators() && Check(Token::MUL); |
| 309 Identifier identifier = ParseIdentifier(CHECK_OK); | 296 Identifier identifier = ParseIdentifier(CHECK_OK); |
| 310 i::Scanner::Location location = scanner_->location(); | 297 Scanner::Location location = scanner()->location(); |
| 311 | 298 |
| 312 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); | 299 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); |
| 313 | 300 |
| 314 if (function_value.IsStrictFunction() && | 301 if (function_value.IsStrictFunction() && |
| 315 !identifier.IsValidStrictVariable()) { | 302 !identifier.IsValidStrictVariable()) { |
| 316 // Strict mode violation, using either reserved word or eval/arguments | 303 // Strict mode violation, using either reserved word or eval/arguments |
| 317 // as name of strict function. | 304 // as name of strict function. |
| 318 const char* type = "strict_function_name"; | 305 const char* type = "strict_function_name"; |
| 319 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { | 306 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { |
| 320 type = "strict_reserved_word"; | 307 type = "strict_reserved_word"; |
| 321 } | 308 } |
| 322 ReportMessageAt(location, type, NULL); | 309 ReportMessageAt(location, type, NULL); |
| 323 *ok = false; | 310 *ok = false; |
| 324 } | 311 } |
| 325 return Statement::FunctionDeclaration(); | 312 return Statement::FunctionDeclaration(); |
| 326 } | 313 } |
| 327 | 314 |
| 328 | 315 |
| 329 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 316 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
| 330 // Block :: | 317 // Block :: |
| 331 // '{' Statement* '}' | 318 // '{' Statement* '}' |
| 332 | 319 |
| 333 // Note that a Block does not introduce a new execution scope! | 320 // Note that a Block does not introduce a new execution scope! |
| 334 // (ECMA-262, 3rd, 12.2) | 321 // (ECMA-262, 3rd, 12.2) |
| 335 // | 322 // |
| 336 Expect(i::Token::LBRACE, CHECK_OK); | 323 Expect(Token::LBRACE, CHECK_OK); |
| 337 while (peek() != i::Token::RBRACE) { | 324 while (peek() != Token::RBRACE) { |
| 338 if (is_extended_mode()) { | 325 if (is_extended_mode()) { |
| 339 ParseSourceElement(CHECK_OK); | 326 ParseSourceElement(CHECK_OK); |
| 340 } else { | 327 } else { |
| 341 ParseStatement(CHECK_OK); | 328 ParseStatement(CHECK_OK); |
| 342 } | 329 } |
| 343 } | 330 } |
| 344 Expect(i::Token::RBRACE, ok); | 331 Expect(Token::RBRACE, ok); |
| 345 return Statement::Default(); | 332 return Statement::Default(); |
| 346 } | 333 } |
| 347 | 334 |
| 348 | 335 |
| 349 PreParser::Statement PreParser::ParseVariableStatement( | 336 PreParser::Statement PreParser::ParseVariableStatement( |
| 350 VariableDeclarationContext var_context, | 337 VariableDeclarationContext var_context, |
| 351 bool* ok) { | 338 bool* ok) { |
| 352 // VariableStatement :: | 339 // VariableStatement :: |
| 353 // VariableDeclarations ';' | 340 // VariableDeclarations ';' |
| 354 | 341 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 378 // | 365 // |
| 379 // ConstDeclaration :: | 366 // ConstDeclaration :: |
| 380 // const ConstBinding (',' ConstBinding)* ';' | 367 // const ConstBinding (',' ConstBinding)* ';' |
| 381 // ConstBinding :: | 368 // ConstBinding :: |
| 382 // Identifier '=' AssignmentExpression | 369 // Identifier '=' AssignmentExpression |
| 383 // | 370 // |
| 384 // TODO(ES6): | 371 // TODO(ES6): |
| 385 // ConstBinding :: | 372 // ConstBinding :: |
| 386 // BindingPattern '=' AssignmentExpression | 373 // BindingPattern '=' AssignmentExpression |
| 387 bool require_initializer = false; | 374 bool require_initializer = false; |
| 388 if (peek() == i::Token::VAR) { | 375 if (peek() == Token::VAR) { |
| 389 Consume(i::Token::VAR); | 376 Consume(Token::VAR); |
| 390 } else if (peek() == i::Token::CONST) { | 377 } else if (peek() == Token::CONST) { |
| 391 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: | 378 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: |
| 392 // | 379 // |
| 393 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 380 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 394 // | 381 // |
| 395 // * It is a Syntax Error if the code that matches this production is not | 382 // * It is a Syntax Error if the code that matches this production is not |
| 396 // contained in extended code. | 383 // contained in extended code. |
| 397 // | 384 // |
| 398 // However disallowing const in classic mode will break compatibility with | 385 // However disallowing const in classic mode will break compatibility with |
| 399 // existing pages. Therefore we keep allowing const with the old | 386 // existing pages. Therefore we keep allowing const with the old |
| 400 // non-harmony semantics in classic mode. | 387 // non-harmony semantics in classic mode. |
| 401 Consume(i::Token::CONST); | 388 Consume(Token::CONST); |
| 402 switch (language_mode()) { | 389 switch (language_mode()) { |
| 403 case i::CLASSIC_MODE: | 390 case CLASSIC_MODE: |
| 404 break; | 391 break; |
| 405 case i::STRICT_MODE: { | 392 case STRICT_MODE: { |
| 406 i::Scanner::Location location = scanner_->peek_location(); | 393 Scanner::Location location = scanner()->peek_location(); |
| 407 ReportMessageAt(location, "strict_const", NULL); | 394 ReportMessageAt(location, "strict_const", NULL); |
| 408 *ok = false; | 395 *ok = false; |
| 409 return Statement::Default(); | 396 return Statement::Default(); |
| 410 } | 397 } |
| 411 case i::EXTENDED_MODE: | 398 case EXTENDED_MODE: |
| 412 if (var_context != kSourceElement && | 399 if (var_context != kSourceElement && |
| 413 var_context != kForStatement) { | 400 var_context != kForStatement) { |
| 414 i::Scanner::Location location = scanner_->peek_location(); | 401 Scanner::Location location = scanner()->peek_location(); |
| 415 ReportMessageAt(location.beg_pos, location.end_pos, | 402 ReportMessageAt(location.beg_pos, location.end_pos, |
| 416 "unprotected_const", NULL); | 403 "unprotected_const", NULL); |
| 417 *ok = false; | 404 *ok = false; |
| 418 return Statement::Default(); | 405 return Statement::Default(); |
| 419 } | 406 } |
| 420 require_initializer = true; | 407 require_initializer = true; |
| 421 break; | 408 break; |
| 422 } | 409 } |
| 423 } else if (peek() == i::Token::LET) { | 410 } else if (peek() == Token::LET) { |
| 424 // ES6 Draft Rev4 section 12.2.1: | 411 // ES6 Draft Rev4 section 12.2.1: |
| 425 // | 412 // |
| 426 // LetDeclaration : let LetBindingList ; | 413 // LetDeclaration : let LetBindingList ; |
| 427 // | 414 // |
| 428 // * It is a Syntax Error if the code that matches this production is not | 415 // * It is a Syntax Error if the code that matches this production is not |
| 429 // contained in extended code. | 416 // contained in extended code. |
| 430 if (!is_extended_mode()) { | 417 if (!is_extended_mode()) { |
| 431 i::Scanner::Location location = scanner_->peek_location(); | 418 Scanner::Location location = scanner()->peek_location(); |
| 432 ReportMessageAt(location.beg_pos, location.end_pos, | 419 ReportMessageAt(location.beg_pos, location.end_pos, |
| 433 "illegal_let", NULL); | 420 "illegal_let", NULL); |
| 434 *ok = false; | 421 *ok = false; |
| 435 return Statement::Default(); | 422 return Statement::Default(); |
| 436 } | 423 } |
| 437 Consume(i::Token::LET); | 424 Consume(Token::LET); |
| 438 if (var_context != kSourceElement && | 425 if (var_context != kSourceElement && |
| 439 var_context != kForStatement) { | 426 var_context != kForStatement) { |
| 440 i::Scanner::Location location = scanner_->peek_location(); | 427 Scanner::Location location = scanner()->peek_location(); |
| 441 ReportMessageAt(location.beg_pos, location.end_pos, | 428 ReportMessageAt(location.beg_pos, location.end_pos, |
| 442 "unprotected_let", NULL); | 429 "unprotected_let", NULL); |
| 443 *ok = false; | 430 *ok = false; |
| 444 return Statement::Default(); | 431 return Statement::Default(); |
| 445 } | 432 } |
| 446 } else { | 433 } else { |
| 447 *ok = false; | 434 *ok = false; |
| 448 return Statement::Default(); | 435 return Statement::Default(); |
| 449 } | 436 } |
| 450 | 437 |
| 451 // The scope of a var/const declared variable anywhere inside a function | 438 // The scope of a var/const declared variable anywhere inside a function |
| 452 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 439 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| 453 // of a let declared variable is the scope of the immediately enclosing | 440 // of a let declared variable is the scope of the immediately enclosing |
| 454 // block. | 441 // block. |
| 455 int nvars = 0; // the number of variables declared | 442 int nvars = 0; // the number of variables declared |
| 456 do { | 443 do { |
| 457 // Parse variable name. | 444 // Parse variable name. |
| 458 if (nvars > 0) Consume(i::Token::COMMA); | 445 if (nvars > 0) Consume(Token::COMMA); |
| 459 Identifier identifier = ParseIdentifier(CHECK_OK); | 446 Identifier identifier = ParseIdentifier(CHECK_OK); |
| 460 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { | 447 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { |
| 461 StrictModeIdentifierViolation(scanner_->location(), | 448 StrictModeIdentifierViolation(scanner()->location(), |
| 462 "strict_var_name", | 449 "strict_var_name", |
| 463 identifier, | 450 identifier, |
| 464 ok); | 451 ok); |
| 465 return Statement::Default(); | 452 return Statement::Default(); |
| 466 } | 453 } |
| 467 nvars++; | 454 nvars++; |
| 468 if (peek() == i::Token::ASSIGN || require_initializer) { | 455 if (peek() == Token::ASSIGN || require_initializer) { |
| 469 Expect(i::Token::ASSIGN, CHECK_OK); | 456 Expect(Token::ASSIGN, CHECK_OK); |
| 470 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 457 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 471 if (decl_props != NULL) *decl_props = kHasInitializers; | 458 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 472 } | 459 } |
| 473 } while (peek() == i::Token::COMMA); | 460 } while (peek() == Token::COMMA); |
| 474 | 461 |
| 475 if (num_decl != NULL) *num_decl = nvars; | 462 if (num_decl != NULL) *num_decl = nvars; |
| 476 return Statement::Default(); | 463 return Statement::Default(); |
| 477 } | 464 } |
| 478 | 465 |
| 479 | 466 |
| 480 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
| 481 // ExpressionStatement | LabelledStatement :: | 468 // ExpressionStatement | LabelledStatement :: |
| 482 // Expression ';' | 469 // Expression ';' |
| 483 // Identifier ':' Statement | 470 // Identifier ':' Statement |
| 484 | 471 |
| 485 Expression expr = ParseExpression(true, CHECK_OK); | 472 Expression expr = ParseExpression(true, CHECK_OK); |
| 486 if (expr.IsRawIdentifier()) { | 473 if (expr.IsRawIdentifier()) { |
| 487 ASSERT(!expr.AsIdentifier().IsFutureReserved()); | 474 ASSERT(!expr.AsIdentifier().IsFutureReserved()); |
| 488 ASSERT(is_classic_mode() || | 475 ASSERT(is_classic_mode() || |
| 489 (!expr.AsIdentifier().IsFutureStrictReserved() && | 476 (!expr.AsIdentifier().IsFutureStrictReserved() && |
| 490 !expr.AsIdentifier().IsYield())); | 477 !expr.AsIdentifier().IsYield())); |
| 491 if (peek() == i::Token::COLON) { | 478 if (peek() == Token::COLON) { |
| 492 Consume(i::Token::COLON); | 479 Consume(Token::COLON); |
| 493 return ParseStatement(ok); | 480 return ParseStatement(ok); |
| 494 } | 481 } |
| 495 // Preparsing is disabled for extensions (because the extension details | 482 // Preparsing is disabled for extensions (because the extension details |
| 496 // aren't passed to lazily compiled functions), so we don't | 483 // aren't passed to lazily compiled functions), so we don't |
| 497 // accept "native function" in the preparser. | 484 // accept "native function" in the preparser. |
| 498 } | 485 } |
| 499 // Parsed expression statement. | 486 // Parsed expression statement. |
| 500 ExpectSemicolon(CHECK_OK); | 487 ExpectSemicolon(CHECK_OK); |
| 501 return Statement::ExpressionStatement(expr); | 488 return Statement::ExpressionStatement(expr); |
| 502 } | 489 } |
| 503 | 490 |
| 504 | 491 |
| 505 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 492 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
| 506 // IfStatement :: | 493 // IfStatement :: |
| 507 // 'if' '(' Expression ')' Statement ('else' Statement)? | 494 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 508 | 495 |
| 509 Expect(i::Token::IF, CHECK_OK); | 496 Expect(Token::IF, CHECK_OK); |
| 510 Expect(i::Token::LPAREN, CHECK_OK); | 497 Expect(Token::LPAREN, CHECK_OK); |
| 511 ParseExpression(true, CHECK_OK); | 498 ParseExpression(true, CHECK_OK); |
| 512 Expect(i::Token::RPAREN, CHECK_OK); | 499 Expect(Token::RPAREN, CHECK_OK); |
| 513 ParseStatement(CHECK_OK); | 500 ParseStatement(CHECK_OK); |
| 514 if (peek() == i::Token::ELSE) { | 501 if (peek() == Token::ELSE) { |
| 515 Next(); | 502 Next(); |
| 516 ParseStatement(CHECK_OK); | 503 ParseStatement(CHECK_OK); |
| 517 } | 504 } |
| 518 return Statement::Default(); | 505 return Statement::Default(); |
| 519 } | 506 } |
| 520 | 507 |
| 521 | 508 |
| 522 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
| 523 // ContinueStatement :: | 510 // ContinueStatement :: |
| 524 // 'continue' [no line terminator] Identifier? ';' | 511 // 'continue' [no line terminator] Identifier? ';' |
| 525 | 512 |
| 526 Expect(i::Token::CONTINUE, CHECK_OK); | 513 Expect(Token::CONTINUE, CHECK_OK); |
| 527 i::Token::Value tok = peek(); | 514 Token::Value tok = peek(); |
| 528 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 515 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 529 tok != i::Token::SEMICOLON && | 516 tok != Token::SEMICOLON && |
| 530 tok != i::Token::RBRACE && | 517 tok != Token::RBRACE && |
| 531 tok != i::Token::EOS) { | 518 tok != Token::EOS) { |
| 532 ParseIdentifier(CHECK_OK); | 519 ParseIdentifier(CHECK_OK); |
| 533 } | 520 } |
| 534 ExpectSemicolon(CHECK_OK); | 521 ExpectSemicolon(CHECK_OK); |
| 535 return Statement::Default(); | 522 return Statement::Default(); |
| 536 } | 523 } |
| 537 | 524 |
| 538 | 525 |
| 539 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
| 540 // BreakStatement :: | 527 // BreakStatement :: |
| 541 // 'break' [no line terminator] Identifier? ';' | 528 // 'break' [no line terminator] Identifier? ';' |
| 542 | 529 |
| 543 Expect(i::Token::BREAK, CHECK_OK); | 530 Expect(Token::BREAK, CHECK_OK); |
| 544 i::Token::Value tok = peek(); | 531 Token::Value tok = peek(); |
| 545 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 532 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 546 tok != i::Token::SEMICOLON && | 533 tok != Token::SEMICOLON && |
| 547 tok != i::Token::RBRACE && | 534 tok != Token::RBRACE && |
| 548 tok != i::Token::EOS) { | 535 tok != Token::EOS) { |
| 549 ParseIdentifier(CHECK_OK); | 536 ParseIdentifier(CHECK_OK); |
| 550 } | 537 } |
| 551 ExpectSemicolon(CHECK_OK); | 538 ExpectSemicolon(CHECK_OK); |
| 552 return Statement::Default(); | 539 return Statement::Default(); |
| 553 } | 540 } |
| 554 | 541 |
| 555 | 542 |
| 556 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
| 557 // ReturnStatement :: | 544 // ReturnStatement :: |
| 558 // 'return' [no line terminator] Expression? ';' | 545 // 'return' [no line terminator] Expression? ';' |
| 559 | 546 |
| 560 // Consume the return token. It is necessary to do the before | 547 // Consume the return token. It is necessary to do the before |
| 561 // reporting any errors on it, because of the way errors are | 548 // reporting any errors on it, because of the way errors are |
| 562 // reported (underlining). | 549 // reported (underlining). |
| 563 Expect(i::Token::RETURN, CHECK_OK); | 550 Expect(Token::RETURN, CHECK_OK); |
| 564 | 551 |
| 565 // An ECMAScript program is considered syntactically incorrect if it | 552 // An ECMAScript program is considered syntactically incorrect if it |
| 566 // contains a return statement that is not within the body of a | 553 // contains a return statement that is not within the body of a |
| 567 // function. See ECMA-262, section 12.9, page 67. | 554 // function. See ECMA-262, section 12.9, page 67. |
| 568 // This is not handled during preparsing. | 555 // This is not handled during preparsing. |
| 569 | 556 |
| 570 i::Token::Value tok = peek(); | 557 Token::Value tok = peek(); |
| 571 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 558 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 572 tok != i::Token::SEMICOLON && | 559 tok != Token::SEMICOLON && |
| 573 tok != i::Token::RBRACE && | 560 tok != Token::RBRACE && |
| 574 tok != i::Token::EOS) { | 561 tok != Token::EOS) { |
| 575 ParseExpression(true, CHECK_OK); | 562 ParseExpression(true, CHECK_OK); |
| 576 } | 563 } |
| 577 ExpectSemicolon(CHECK_OK); | 564 ExpectSemicolon(CHECK_OK); |
| 578 return Statement::Default(); | 565 return Statement::Default(); |
| 579 } | 566 } |
| 580 | 567 |
| 581 | 568 |
| 582 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
| 583 // WithStatement :: | 570 // WithStatement :: |
| 584 // 'with' '(' Expression ')' Statement | 571 // 'with' '(' Expression ')' Statement |
| 585 Expect(i::Token::WITH, CHECK_OK); | 572 Expect(Token::WITH, CHECK_OK); |
| 586 if (!is_classic_mode()) { | 573 if (!is_classic_mode()) { |
| 587 i::Scanner::Location location = scanner_->location(); | 574 Scanner::Location location = scanner()->location(); |
| 588 ReportMessageAt(location, "strict_mode_with", NULL); | 575 ReportMessageAt(location, "strict_mode_with", NULL); |
| 589 *ok = false; | 576 *ok = false; |
| 590 return Statement::Default(); | 577 return Statement::Default(); |
| 591 } | 578 } |
| 592 Expect(i::Token::LPAREN, CHECK_OK); | 579 Expect(Token::LPAREN, CHECK_OK); |
| 593 ParseExpression(true, CHECK_OK); | 580 ParseExpression(true, CHECK_OK); |
| 594 Expect(i::Token::RPAREN, CHECK_OK); | 581 Expect(Token::RPAREN, CHECK_OK); |
| 595 | 582 |
| 596 Scope::InsideWith iw(scope_); | 583 Scope::InsideWith iw(scope_); |
| 597 ParseStatement(CHECK_OK); | 584 ParseStatement(CHECK_OK); |
| 598 return Statement::Default(); | 585 return Statement::Default(); |
| 599 } | 586 } |
| 600 | 587 |
| 601 | 588 |
| 602 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { | 589 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { |
| 603 // SwitchStatement :: | 590 // SwitchStatement :: |
| 604 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 591 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 605 | 592 |
| 606 Expect(i::Token::SWITCH, CHECK_OK); | 593 Expect(Token::SWITCH, CHECK_OK); |
| 607 Expect(i::Token::LPAREN, CHECK_OK); | 594 Expect(Token::LPAREN, CHECK_OK); |
| 608 ParseExpression(true, CHECK_OK); | 595 ParseExpression(true, CHECK_OK); |
| 609 Expect(i::Token::RPAREN, CHECK_OK); | 596 Expect(Token::RPAREN, CHECK_OK); |
| 610 | 597 |
| 611 Expect(i::Token::LBRACE, CHECK_OK); | 598 Expect(Token::LBRACE, CHECK_OK); |
| 612 i::Token::Value token = peek(); | 599 Token::Value token = peek(); |
| 613 while (token != i::Token::RBRACE) { | 600 while (token != Token::RBRACE) { |
| 614 if (token == i::Token::CASE) { | 601 if (token == Token::CASE) { |
| 615 Expect(i::Token::CASE, CHECK_OK); | 602 Expect(Token::CASE, CHECK_OK); |
| 616 ParseExpression(true, CHECK_OK); | 603 ParseExpression(true, CHECK_OK); |
| 617 } else { | 604 } else { |
| 618 Expect(i::Token::DEFAULT, CHECK_OK); | 605 Expect(Token::DEFAULT, CHECK_OK); |
| 619 } | 606 } |
| 620 Expect(i::Token::COLON, CHECK_OK); | 607 Expect(Token::COLON, CHECK_OK); |
| 621 token = peek(); | 608 token = peek(); |
| 622 while (token != i::Token::CASE && | 609 while (token != Token::CASE && |
| 623 token != i::Token::DEFAULT && | 610 token != Token::DEFAULT && |
| 624 token != i::Token::RBRACE) { | 611 token != Token::RBRACE) { |
| 625 ParseStatement(CHECK_OK); | 612 ParseStatement(CHECK_OK); |
| 626 token = peek(); | 613 token = peek(); |
| 627 } | 614 } |
| 628 } | 615 } |
| 629 Expect(i::Token::RBRACE, ok); | 616 Expect(Token::RBRACE, ok); |
| 630 return Statement::Default(); | 617 return Statement::Default(); |
| 631 } | 618 } |
| 632 | 619 |
| 633 | 620 |
| 634 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { | 621 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
| 635 // DoStatement :: | 622 // DoStatement :: |
| 636 // 'do' Statement 'while' '(' Expression ')' ';' | 623 // 'do' Statement 'while' '(' Expression ')' ';' |
| 637 | 624 |
| 638 Expect(i::Token::DO, CHECK_OK); | 625 Expect(Token::DO, CHECK_OK); |
| 639 ParseStatement(CHECK_OK); | 626 ParseStatement(CHECK_OK); |
| 640 Expect(i::Token::WHILE, CHECK_OK); | 627 Expect(Token::WHILE, CHECK_OK); |
| 641 Expect(i::Token::LPAREN, CHECK_OK); | 628 Expect(Token::LPAREN, CHECK_OK); |
| 642 ParseExpression(true, CHECK_OK); | 629 ParseExpression(true, CHECK_OK); |
| 643 Expect(i::Token::RPAREN, ok); | 630 Expect(Token::RPAREN, ok); |
| 644 if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON); | 631 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 645 return Statement::Default(); | 632 return Statement::Default(); |
| 646 } | 633 } |
| 647 | 634 |
| 648 | 635 |
| 649 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { | 636 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { |
| 650 // WhileStatement :: | 637 // WhileStatement :: |
| 651 // 'while' '(' Expression ')' Statement | 638 // 'while' '(' Expression ')' Statement |
| 652 | 639 |
| 653 Expect(i::Token::WHILE, CHECK_OK); | 640 Expect(Token::WHILE, CHECK_OK); |
| 654 Expect(i::Token::LPAREN, CHECK_OK); | 641 Expect(Token::LPAREN, CHECK_OK); |
| 655 ParseExpression(true, CHECK_OK); | 642 ParseExpression(true, CHECK_OK); |
| 656 Expect(i::Token::RPAREN, CHECK_OK); | 643 Expect(Token::RPAREN, CHECK_OK); |
| 657 ParseStatement(ok); | 644 ParseStatement(ok); |
| 658 return Statement::Default(); | 645 return Statement::Default(); |
| 659 } | 646 } |
| 660 | 647 |
| 661 | 648 |
| 662 bool PreParser::CheckInOrOf(bool accept_OF) { | 649 bool PreParser::CheckInOrOf(bool accept_OF) { |
| 663 if (peek() == i::Token::IN || | 650 if (Check(Token::IN) || |
| 664 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && | 651 (allow_for_of() && accept_OF && |
| 665 scanner_->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { | 652 CheckContextualKeyword(CStrVector("of")))) { |
| 666 Next(); | |
| 667 return true; | 653 return true; |
| 668 } | 654 } |
| 669 return false; | 655 return false; |
| 670 } | 656 } |
| 671 | 657 |
| 672 | 658 |
| 673 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 659 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| 674 // ForStatement :: | 660 // ForStatement :: |
| 675 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 661 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 676 | 662 |
| 677 Expect(i::Token::FOR, CHECK_OK); | 663 Expect(Token::FOR, CHECK_OK); |
| 678 Expect(i::Token::LPAREN, CHECK_OK); | 664 Expect(Token::LPAREN, CHECK_OK); |
| 679 if (peek() != i::Token::SEMICOLON) { | 665 if (peek() != Token::SEMICOLON) { |
| 680 if (peek() == i::Token::VAR || peek() == i::Token::CONST || | 666 if (peek() == Token::VAR || peek() == Token::CONST || |
| 681 peek() == i::Token::LET) { | 667 peek() == Token::LET) { |
| 682 bool is_let = peek() == i::Token::LET; | 668 bool is_let = peek() == Token::LET; |
| 683 int decl_count; | 669 int decl_count; |
| 684 VariableDeclarationProperties decl_props = kHasNoInitializers; | 670 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 685 ParseVariableDeclarations( | 671 ParseVariableDeclarations( |
| 686 kForStatement, &decl_props, &decl_count, CHECK_OK); | 672 kForStatement, &decl_props, &decl_count, CHECK_OK); |
| 687 bool has_initializers = decl_props == kHasInitializers; | 673 bool has_initializers = decl_props == kHasInitializers; |
| 688 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); | 674 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); |
| 689 bool accept_OF = !has_initializers; | 675 bool accept_OF = !has_initializers; |
| 690 if (accept_IN && CheckInOrOf(accept_OF)) { | 676 if (accept_IN && CheckInOrOf(accept_OF)) { |
| 691 ParseExpression(true, CHECK_OK); | 677 ParseExpression(true, CHECK_OK); |
| 692 Expect(i::Token::RPAREN, CHECK_OK); | 678 Expect(Token::RPAREN, CHECK_OK); |
| 693 | 679 |
| 694 ParseStatement(CHECK_OK); | 680 ParseStatement(CHECK_OK); |
| 695 return Statement::Default(); | 681 return Statement::Default(); |
| 696 } | 682 } |
| 697 } else { | 683 } else { |
| 698 Expression lhs = ParseExpression(false, CHECK_OK); | 684 Expression lhs = ParseExpression(false, CHECK_OK); |
| 699 if (CheckInOrOf(lhs.IsIdentifier())) { | 685 if (CheckInOrOf(lhs.IsIdentifier())) { |
| 700 ParseExpression(true, CHECK_OK); | 686 ParseExpression(true, CHECK_OK); |
| 701 Expect(i::Token::RPAREN, CHECK_OK); | 687 Expect(Token::RPAREN, CHECK_OK); |
| 702 | 688 |
| 703 ParseStatement(CHECK_OK); | 689 ParseStatement(CHECK_OK); |
| 704 return Statement::Default(); | 690 return Statement::Default(); |
| 705 } | 691 } |
| 706 } | 692 } |
| 707 } | 693 } |
| 708 | 694 |
| 709 // Parsed initializer at this point. | 695 // Parsed initializer at this point. |
| 710 Expect(i::Token::SEMICOLON, CHECK_OK); | 696 Expect(Token::SEMICOLON, CHECK_OK); |
| 711 | 697 |
| 712 if (peek() != i::Token::SEMICOLON) { | 698 if (peek() != Token::SEMICOLON) { |
| 713 ParseExpression(true, CHECK_OK); | 699 ParseExpression(true, CHECK_OK); |
| 714 } | 700 } |
| 715 Expect(i::Token::SEMICOLON, CHECK_OK); | 701 Expect(Token::SEMICOLON, CHECK_OK); |
| 716 | 702 |
| 717 if (peek() != i::Token::RPAREN) { | 703 if (peek() != Token::RPAREN) { |
| 718 ParseExpression(true, CHECK_OK); | 704 ParseExpression(true, CHECK_OK); |
| 719 } | 705 } |
| 720 Expect(i::Token::RPAREN, CHECK_OK); | 706 Expect(Token::RPAREN, CHECK_OK); |
| 721 | 707 |
| 722 ParseStatement(ok); | 708 ParseStatement(ok); |
| 723 return Statement::Default(); | 709 return Statement::Default(); |
| 724 } | 710 } |
| 725 | 711 |
| 726 | 712 |
| 727 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { | 713 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { |
| 728 // ThrowStatement :: | 714 // ThrowStatement :: |
| 729 // 'throw' [no line terminator] Expression ';' | 715 // 'throw' [no line terminator] Expression ';' |
| 730 | 716 |
| 731 Expect(i::Token::THROW, CHECK_OK); | 717 Expect(Token::THROW, CHECK_OK); |
| 732 if (scanner_->HasAnyLineTerminatorBeforeNext()) { | 718 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 733 i::Scanner::Location pos = scanner_->location(); | 719 Scanner::Location pos = scanner()->location(); |
| 734 ReportMessageAt(pos, "newline_after_throw", NULL); | 720 ReportMessageAt(pos, "newline_after_throw", NULL); |
| 735 *ok = false; | 721 *ok = false; |
| 736 return Statement::Default(); | 722 return Statement::Default(); |
| 737 } | 723 } |
| 738 ParseExpression(true, CHECK_OK); | 724 ParseExpression(true, CHECK_OK); |
| 739 ExpectSemicolon(ok); | 725 ExpectSemicolon(ok); |
| 740 return Statement::Default(); | 726 return Statement::Default(); |
| 741 } | 727 } |
| 742 | 728 |
| 743 | 729 |
| 744 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { | 730 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { |
| 745 // TryStatement :: | 731 // TryStatement :: |
| 746 // 'try' Block Catch | 732 // 'try' Block Catch |
| 747 // 'try' Block Finally | 733 // 'try' Block Finally |
| 748 // 'try' Block Catch Finally | 734 // 'try' Block Catch Finally |
| 749 // | 735 // |
| 750 // Catch :: | 736 // Catch :: |
| 751 // 'catch' '(' Identifier ')' Block | 737 // 'catch' '(' Identifier ')' Block |
| 752 // | 738 // |
| 753 // Finally :: | 739 // Finally :: |
| 754 // 'finally' Block | 740 // 'finally' Block |
| 755 | 741 |
| 756 // In preparsing, allow any number of catch/finally blocks, including zero | 742 // In preparsing, allow any number of catch/finally blocks, including zero |
| 757 // of both. | 743 // of both. |
| 758 | 744 |
| 759 Expect(i::Token::TRY, CHECK_OK); | 745 Expect(Token::TRY, CHECK_OK); |
| 760 | 746 |
| 761 ParseBlock(CHECK_OK); | 747 ParseBlock(CHECK_OK); |
| 762 | 748 |
| 763 bool catch_or_finally_seen = false; | 749 bool catch_or_finally_seen = false; |
| 764 if (peek() == i::Token::CATCH) { | 750 if (peek() == Token::CATCH) { |
| 765 Consume(i::Token::CATCH); | 751 Consume(Token::CATCH); |
| 766 Expect(i::Token::LPAREN, CHECK_OK); | 752 Expect(Token::LPAREN, CHECK_OK); |
| 767 Identifier id = ParseIdentifier(CHECK_OK); | 753 Identifier id = ParseIdentifier(CHECK_OK); |
| 768 if (!is_classic_mode() && !id.IsValidStrictVariable()) { | 754 if (!is_classic_mode() && !id.IsValidStrictVariable()) { |
| 769 StrictModeIdentifierViolation(scanner_->location(), | 755 StrictModeIdentifierViolation(scanner()->location(), |
| 770 "strict_catch_variable", | 756 "strict_catch_variable", |
| 771 id, | 757 id, |
| 772 ok); | 758 ok); |
| 773 return Statement::Default(); | 759 return Statement::Default(); |
| 774 } | 760 } |
| 775 Expect(i::Token::RPAREN, CHECK_OK); | 761 Expect(Token::RPAREN, CHECK_OK); |
| 776 { Scope::InsideWith iw(scope_); | 762 { Scope::InsideWith iw(scope_); |
| 777 ParseBlock(CHECK_OK); | 763 ParseBlock(CHECK_OK); |
| 778 } | 764 } |
| 779 catch_or_finally_seen = true; | 765 catch_or_finally_seen = true; |
| 780 } | 766 } |
| 781 if (peek() == i::Token::FINALLY) { | 767 if (peek() == Token::FINALLY) { |
| 782 Consume(i::Token::FINALLY); | 768 Consume(Token::FINALLY); |
| 783 ParseBlock(CHECK_OK); | 769 ParseBlock(CHECK_OK); |
| 784 catch_or_finally_seen = true; | 770 catch_or_finally_seen = true; |
| 785 } | 771 } |
| 786 if (!catch_or_finally_seen) { | 772 if (!catch_or_finally_seen) { |
| 787 *ok = false; | 773 *ok = false; |
| 788 } | 774 } |
| 789 return Statement::Default(); | 775 return Statement::Default(); |
| 790 } | 776 } |
| 791 | 777 |
| 792 | 778 |
| 793 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { | 779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { |
| 794 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 780 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 795 // contexts this is used as a statement which invokes the debugger as if a | 781 // contexts this is used as a statement which invokes the debugger as if a |
| 796 // break point is present. | 782 // break point is present. |
| 797 // DebuggerStatement :: | 783 // DebuggerStatement :: |
| 798 // 'debugger' ';' | 784 // 'debugger' ';' |
| 799 | 785 |
| 800 Expect(i::Token::DEBUGGER, CHECK_OK); | 786 Expect(Token::DEBUGGER, CHECK_OK); |
| 801 ExpectSemicolon(ok); | 787 ExpectSemicolon(ok); |
| 802 return Statement::Default(); | 788 return Statement::Default(); |
| 803 } | 789 } |
| 804 | 790 |
| 805 | 791 |
| 806 #undef CHECK_OK | 792 #undef CHECK_OK |
| 807 #define CHECK_OK ok); \ | 793 #define CHECK_OK ok); \ |
| 808 if (!*ok) return Expression::Default(); \ | 794 if (!*ok) return Expression::Default(); \ |
| 809 ((void)0 | 795 ((void)0 |
| 810 #define DUMMY ) // to make indentation work | 796 #define DUMMY ) // to make indentation work |
| 811 #undef DUMMY | 797 #undef DUMMY |
| 812 | 798 |
| 813 | 799 |
| 814 // Precedence = 1 | 800 // Precedence = 1 |
| 815 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { | 801 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { |
| 816 // Expression :: | 802 // Expression :: |
| 817 // AssignmentExpression | 803 // AssignmentExpression |
| 818 // Expression ',' AssignmentExpression | 804 // Expression ',' AssignmentExpression |
| 819 | 805 |
| 820 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 806 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 821 while (peek() == i::Token::COMMA) { | 807 while (peek() == Token::COMMA) { |
| 822 Expect(i::Token::COMMA, CHECK_OK); | 808 Expect(Token::COMMA, CHECK_OK); |
| 823 ParseAssignmentExpression(accept_IN, CHECK_OK); | 809 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 824 result = Expression::Default(); | 810 result = Expression::Default(); |
| 825 } | 811 } |
| 826 return result; | 812 return result; |
| 827 } | 813 } |
| 828 | 814 |
| 829 | 815 |
| 830 // Precedence = 2 | 816 // Precedence = 2 |
| 831 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, | 817 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, |
| 832 bool* ok) { | 818 bool* ok) { |
| 833 // AssignmentExpression :: | 819 // AssignmentExpression :: |
| 834 // ConditionalExpression | 820 // ConditionalExpression |
| 835 // YieldExpression | 821 // YieldExpression |
| 836 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 822 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 837 | 823 |
| 838 if (scope_->is_generator() && peek() == i::Token::YIELD) { | 824 if (scope_->is_generator() && peek() == Token::YIELD) { |
| 839 return ParseYieldExpression(ok); | 825 return ParseYieldExpression(ok); |
| 840 } | 826 } |
| 841 | 827 |
| 842 i::Scanner::Location before = scanner_->peek_location(); | 828 Scanner::Location before = scanner()->peek_location(); |
| 843 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 829 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
| 844 | 830 |
| 845 if (!i::Token::IsAssignmentOp(peek())) { | 831 if (!Token::IsAssignmentOp(peek())) { |
| 846 // Parsed conditional expression only (no assignment). | 832 // Parsed conditional expression only (no assignment). |
| 847 return expression; | 833 return expression; |
| 848 } | 834 } |
| 849 | 835 |
| 850 if (!is_classic_mode() && | 836 if (!is_classic_mode() && |
| 851 expression.IsIdentifier() && | 837 expression.IsIdentifier() && |
| 852 expression.AsIdentifier().IsEvalOrArguments()) { | 838 expression.AsIdentifier().IsEvalOrArguments()) { |
| 853 i::Scanner::Location after = scanner_->location(); | 839 Scanner::Location after = scanner()->location(); |
| 854 ReportMessageAt(before.beg_pos, after.end_pos, | 840 ReportMessageAt(before.beg_pos, after.end_pos, |
| 855 "strict_lhs_assignment", NULL); | 841 "strict_lhs_assignment", NULL); |
| 856 *ok = false; | 842 *ok = false; |
| 857 return Expression::Default(); | 843 return Expression::Default(); |
| 858 } | 844 } |
| 859 | 845 |
| 860 i::Token::Value op = Next(); // Get assignment operator. | 846 Token::Value op = Next(); // Get assignment operator. |
| 861 ParseAssignmentExpression(accept_IN, CHECK_OK); | 847 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 862 | 848 |
| 863 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { | 849 if ((op == Token::ASSIGN) && expression.IsThisProperty()) { |
| 864 scope_->AddProperty(); | 850 scope_->AddProperty(); |
| 865 } | 851 } |
| 866 | 852 |
| 867 return Expression::Default(); | 853 return Expression::Default(); |
| 868 } | 854 } |
| 869 | 855 |
| 870 | 856 |
| 871 // Precedence = 3 | 857 // Precedence = 3 |
| 872 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) { | 858 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) { |
| 873 // YieldExpression :: | 859 // YieldExpression :: |
| 874 // 'yield' '*'? AssignmentExpression | 860 // 'yield' '*'? AssignmentExpression |
| 875 Consume(i::Token::YIELD); | 861 Consume(Token::YIELD); |
| 876 Check(i::Token::MUL); | 862 Check(Token::MUL); |
| 877 | 863 |
| 878 ParseAssignmentExpression(false, CHECK_OK); | 864 ParseAssignmentExpression(false, CHECK_OK); |
| 879 | 865 |
| 880 return Expression::Default(); | 866 return Expression::Default(); |
| 881 } | 867 } |
| 882 | 868 |
| 883 | 869 |
| 884 // Precedence = 3 | 870 // Precedence = 3 |
| 885 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, | 871 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, |
| 886 bool* ok) { | 872 bool* ok) { |
| 887 // ConditionalExpression :: | 873 // ConditionalExpression :: |
| 888 // LogicalOrExpression | 874 // LogicalOrExpression |
| 889 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 875 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 890 | 876 |
| 891 // We start using the binary expression parser for prec >= 4 only! | 877 // We start using the binary expression parser for prec >= 4 only! |
| 892 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 878 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 893 if (peek() != i::Token::CONDITIONAL) return expression; | 879 if (peek() != Token::CONDITIONAL) return expression; |
| 894 Consume(i::Token::CONDITIONAL); | 880 Consume(Token::CONDITIONAL); |
| 895 // In parsing the first assignment expression in conditional | 881 // In parsing the first assignment expression in conditional |
| 896 // expressions we always accept the 'in' keyword; see ECMA-262, | 882 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 897 // section 11.12, page 58. | 883 // section 11.12, page 58. |
| 898 ParseAssignmentExpression(true, CHECK_OK); | 884 ParseAssignmentExpression(true, CHECK_OK); |
| 899 Expect(i::Token::COLON, CHECK_OK); | 885 Expect(Token::COLON, CHECK_OK); |
| 900 ParseAssignmentExpression(accept_IN, CHECK_OK); | 886 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 901 return Expression::Default(); | 887 return Expression::Default(); |
| 902 } | 888 } |
| 903 | 889 |
| 904 | 890 |
| 905 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { | |
| 906 if (tok == i::Token::IN && !accept_IN) | |
| 907 return 0; // 0 precedence will terminate binary expression parsing | |
| 908 | |
| 909 return i::Token::Precedence(tok); | |
| 910 } | |
| 911 | |
| 912 | |
| 913 // Precedence >= 4 | 891 // Precedence >= 4 |
| 914 PreParser::Expression PreParser::ParseBinaryExpression(int prec, | 892 PreParser::Expression PreParser::ParseBinaryExpression(int prec, |
| 915 bool accept_IN, | 893 bool accept_IN, |
| 916 bool* ok) { | 894 bool* ok) { |
| 917 Expression result = ParseUnaryExpression(CHECK_OK); | 895 Expression result = ParseUnaryExpression(CHECK_OK); |
| 918 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 896 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 919 // prec1 >= 4 | 897 // prec1 >= 4 |
| 920 while (Precedence(peek(), accept_IN) == prec1) { | 898 while (Precedence(peek(), accept_IN) == prec1) { |
| 921 Next(); | 899 Next(); |
| 922 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 900 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 933 // 'delete' UnaryExpression | 911 // 'delete' UnaryExpression |
| 934 // 'void' UnaryExpression | 912 // 'void' UnaryExpression |
| 935 // 'typeof' UnaryExpression | 913 // 'typeof' UnaryExpression |
| 936 // '++' UnaryExpression | 914 // '++' UnaryExpression |
| 937 // '--' UnaryExpression | 915 // '--' UnaryExpression |
| 938 // '+' UnaryExpression | 916 // '+' UnaryExpression |
| 939 // '-' UnaryExpression | 917 // '-' UnaryExpression |
| 940 // '~' UnaryExpression | 918 // '~' UnaryExpression |
| 941 // '!' UnaryExpression | 919 // '!' UnaryExpression |
| 942 | 920 |
| 943 i::Token::Value op = peek(); | 921 Token::Value op = peek(); |
| 944 if (i::Token::IsUnaryOp(op)) { | 922 if (Token::IsUnaryOp(op)) { |
| 945 op = Next(); | 923 op = Next(); |
| 946 ParseUnaryExpression(ok); | 924 ParseUnaryExpression(ok); |
| 947 return Expression::Default(); | 925 return Expression::Default(); |
| 948 } else if (i::Token::IsCountOp(op)) { | 926 } else if (Token::IsCountOp(op)) { |
| 949 op = Next(); | 927 op = Next(); |
| 950 i::Scanner::Location before = scanner_->peek_location(); | 928 Scanner::Location before = scanner()->peek_location(); |
| 951 Expression expression = ParseUnaryExpression(CHECK_OK); | 929 Expression expression = ParseUnaryExpression(CHECK_OK); |
| 952 if (!is_classic_mode() && | 930 if (!is_classic_mode() && |
| 953 expression.IsIdentifier() && | 931 expression.IsIdentifier() && |
| 954 expression.AsIdentifier().IsEvalOrArguments()) { | 932 expression.AsIdentifier().IsEvalOrArguments()) { |
| 955 i::Scanner::Location after = scanner_->location(); | 933 Scanner::Location after = scanner()->location(); |
| 956 ReportMessageAt(before.beg_pos, after.end_pos, | 934 ReportMessageAt(before.beg_pos, after.end_pos, |
| 957 "strict_lhs_prefix", NULL); | 935 "strict_lhs_prefix", NULL); |
| 958 *ok = false; | 936 *ok = false; |
| 959 } | 937 } |
| 960 return Expression::Default(); | 938 return Expression::Default(); |
| 961 } else { | 939 } else { |
| 962 return ParsePostfixExpression(ok); | 940 return ParsePostfixExpression(ok); |
| 963 } | 941 } |
| 964 } | 942 } |
| 965 | 943 |
| 966 | 944 |
| 967 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { | 945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { |
| 968 // PostfixExpression :: | 946 // PostfixExpression :: |
| 969 // LeftHandSideExpression ('++' | '--')? | 947 // LeftHandSideExpression ('++' | '--')? |
| 970 | 948 |
| 971 i::Scanner::Location before = scanner_->peek_location(); | 949 Scanner::Location before = scanner()->peek_location(); |
| 972 Expression expression = ParseLeftHandSideExpression(CHECK_OK); | 950 Expression expression = ParseLeftHandSideExpression(CHECK_OK); |
| 973 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 951 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 974 i::Token::IsCountOp(peek())) { | 952 Token::IsCountOp(peek())) { |
| 975 if (!is_classic_mode() && | 953 if (!is_classic_mode() && |
| 976 expression.IsIdentifier() && | 954 expression.IsIdentifier() && |
| 977 expression.AsIdentifier().IsEvalOrArguments()) { | 955 expression.AsIdentifier().IsEvalOrArguments()) { |
| 978 i::Scanner::Location after = scanner_->location(); | 956 Scanner::Location after = scanner()->location(); |
| 979 ReportMessageAt(before.beg_pos, after.end_pos, | 957 ReportMessageAt(before.beg_pos, after.end_pos, |
| 980 "strict_lhs_postfix", NULL); | 958 "strict_lhs_postfix", NULL); |
| 981 *ok = false; | 959 *ok = false; |
| 982 return Expression::Default(); | 960 return Expression::Default(); |
| 983 } | 961 } |
| 984 Next(); | 962 Next(); |
| 985 return Expression::Default(); | 963 return Expression::Default(); |
| 986 } | 964 } |
| 987 return expression; | 965 return expression; |
| 988 } | 966 } |
| 989 | 967 |
| 990 | 968 |
| 991 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { | 969 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
| 992 // LeftHandSideExpression :: | 970 // LeftHandSideExpression :: |
| 993 // (NewExpression | MemberExpression) ... | 971 // (NewExpression | MemberExpression) ... |
| 994 | 972 |
| 995 Expression result = Expression::Default(); | 973 Expression result = Expression::Default(); |
| 996 if (peek() == i::Token::NEW) { | 974 if (peek() == Token::NEW) { |
| 997 result = ParseNewExpression(CHECK_OK); | 975 result = ParseNewExpression(CHECK_OK); |
| 998 } else { | 976 } else { |
| 999 result = ParseMemberExpression(CHECK_OK); | 977 result = ParseMemberExpression(CHECK_OK); |
| 1000 } | 978 } |
| 1001 | 979 |
| 1002 while (true) { | 980 while (true) { |
| 1003 switch (peek()) { | 981 switch (peek()) { |
| 1004 case i::Token::LBRACK: { | 982 case Token::LBRACK: { |
| 1005 Consume(i::Token::LBRACK); | 983 Consume(Token::LBRACK); |
| 1006 ParseExpression(true, CHECK_OK); | 984 ParseExpression(true, CHECK_OK); |
| 1007 Expect(i::Token::RBRACK, CHECK_OK); | 985 Expect(Token::RBRACK, CHECK_OK); |
| 1008 if (result.IsThis()) { | 986 if (result.IsThis()) { |
| 1009 result = Expression::ThisProperty(); | 987 result = Expression::ThisProperty(); |
| 1010 } else { | 988 } else { |
| 1011 result = Expression::Default(); | 989 result = Expression::Default(); |
| 1012 } | 990 } |
| 1013 break; | 991 break; |
| 1014 } | 992 } |
| 1015 | 993 |
| 1016 case i::Token::LPAREN: { | 994 case Token::LPAREN: { |
| 1017 ParseArguments(CHECK_OK); | 995 ParseArguments(CHECK_OK); |
| 1018 result = Expression::Default(); | 996 result = Expression::Default(); |
| 1019 break; | 997 break; |
| 1020 } | 998 } |
| 1021 | 999 |
| 1022 case i::Token::PERIOD: { | 1000 case Token::PERIOD: { |
| 1023 Consume(i::Token::PERIOD); | 1001 Consume(Token::PERIOD); |
| 1024 ParseIdentifierName(CHECK_OK); | 1002 ParseIdentifierName(CHECK_OK); |
| 1025 if (result.IsThis()) { | 1003 if (result.IsThis()) { |
| 1026 result = Expression::ThisProperty(); | 1004 result = Expression::ThisProperty(); |
| 1027 } else { | 1005 } else { |
| 1028 result = Expression::Default(); | 1006 result = Expression::Default(); |
| 1029 } | 1007 } |
| 1030 break; | 1008 break; |
| 1031 } | 1009 } |
| 1032 | 1010 |
| 1033 default: | 1011 default: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1044 // The grammar for new expressions is pretty warped. The keyword | 1022 // The grammar for new expressions is pretty warped. The keyword |
| 1045 // 'new' can either be a part of the new expression (where it isn't | 1023 // 'new' can either be a part of the new expression (where it isn't |
| 1046 // followed by an argument list) or a part of the member expression, | 1024 // followed by an argument list) or a part of the member expression, |
| 1047 // where it must be followed by an argument list. To accommodate | 1025 // where it must be followed by an argument list. To accommodate |
| 1048 // this, we parse the 'new' keywords greedily and keep track of how | 1026 // this, we parse the 'new' keywords greedily and keep track of how |
| 1049 // many we have parsed. This information is then passed on to the | 1027 // many we have parsed. This information is then passed on to the |
| 1050 // member expression parser, which is only allowed to match argument | 1028 // member expression parser, which is only allowed to match argument |
| 1051 // lists as long as it has 'new' prefixes left | 1029 // lists as long as it has 'new' prefixes left |
| 1052 unsigned new_count = 0; | 1030 unsigned new_count = 0; |
| 1053 do { | 1031 do { |
| 1054 Consume(i::Token::NEW); | 1032 Consume(Token::NEW); |
| 1055 new_count++; | 1033 new_count++; |
| 1056 } while (peek() == i::Token::NEW); | 1034 } while (peek() == Token::NEW); |
| 1057 | 1035 |
| 1058 return ParseMemberWithNewPrefixesExpression(new_count, ok); | 1036 return ParseMemberWithNewPrefixesExpression(new_count, ok); |
| 1059 } | 1037 } |
| 1060 | 1038 |
| 1061 | 1039 |
| 1062 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { | 1040 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { |
| 1063 return ParseMemberWithNewPrefixesExpression(0, ok); | 1041 return ParseMemberWithNewPrefixesExpression(0, ok); |
| 1064 } | 1042 } |
| 1065 | 1043 |
| 1066 | 1044 |
| 1067 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( | 1045 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
| 1068 unsigned new_count, bool* ok) { | 1046 unsigned new_count, bool* ok) { |
| 1069 // MemberExpression :: | 1047 // MemberExpression :: |
| 1070 // (PrimaryExpression | FunctionLiteral) | 1048 // (PrimaryExpression | FunctionLiteral) |
| 1071 // ('[' Expression ']' | '.' Identifier | Arguments)* | 1049 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 1072 | 1050 |
| 1073 // Parse the initial primary or function expression. | 1051 // Parse the initial primary or function expression. |
| 1074 Expression result = Expression::Default(); | 1052 Expression result = Expression::Default(); |
| 1075 if (peek() == i::Token::FUNCTION) { | 1053 if (peek() == Token::FUNCTION) { |
| 1076 Consume(i::Token::FUNCTION); | 1054 Consume(Token::FUNCTION); |
| 1077 | 1055 |
| 1078 bool is_generator = allow_generators_ && Check(i::Token::MUL); | 1056 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1079 Identifier identifier = Identifier::Default(); | 1057 Identifier identifier = Identifier::Default(); |
| 1080 if (peek_any_identifier()) { | 1058 if (peek_any_identifier()) { |
| 1081 identifier = ParseIdentifier(CHECK_OK); | 1059 identifier = ParseIdentifier(CHECK_OK); |
| 1082 } | 1060 } |
| 1083 result = ParseFunctionLiteral(is_generator, CHECK_OK); | 1061 result = ParseFunctionLiteral(is_generator, CHECK_OK); |
| 1084 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { | 1062 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { |
| 1085 StrictModeIdentifierViolation(scanner_->location(), | 1063 StrictModeIdentifierViolation(scanner()->location(), |
| 1086 "strict_function_name", | 1064 "strict_function_name", |
| 1087 identifier, | 1065 identifier, |
| 1088 ok); | 1066 ok); |
| 1089 return Expression::Default(); | 1067 return Expression::Default(); |
| 1090 } | 1068 } |
| 1091 } else { | 1069 } else { |
| 1092 result = ParsePrimaryExpression(CHECK_OK); | 1070 result = ParsePrimaryExpression(CHECK_OK); |
| 1093 } | 1071 } |
| 1094 | 1072 |
| 1095 while (true) { | 1073 while (true) { |
| 1096 switch (peek()) { | 1074 switch (peek()) { |
| 1097 case i::Token::LBRACK: { | 1075 case Token::LBRACK: { |
| 1098 Consume(i::Token::LBRACK); | 1076 Consume(Token::LBRACK); |
| 1099 ParseExpression(true, CHECK_OK); | 1077 ParseExpression(true, CHECK_OK); |
| 1100 Expect(i::Token::RBRACK, CHECK_OK); | 1078 Expect(Token::RBRACK, CHECK_OK); |
| 1101 if (result.IsThis()) { | 1079 if (result.IsThis()) { |
| 1102 result = Expression::ThisProperty(); | 1080 result = Expression::ThisProperty(); |
| 1103 } else { | 1081 } else { |
| 1104 result = Expression::Default(); | 1082 result = Expression::Default(); |
| 1105 } | 1083 } |
| 1106 break; | 1084 break; |
| 1107 } | 1085 } |
| 1108 case i::Token::PERIOD: { | 1086 case Token::PERIOD: { |
| 1109 Consume(i::Token::PERIOD); | 1087 Consume(Token::PERIOD); |
| 1110 ParseIdentifierName(CHECK_OK); | 1088 ParseIdentifierName(CHECK_OK); |
| 1111 if (result.IsThis()) { | 1089 if (result.IsThis()) { |
| 1112 result = Expression::ThisProperty(); | 1090 result = Expression::ThisProperty(); |
| 1113 } else { | 1091 } else { |
| 1114 result = Expression::Default(); | 1092 result = Expression::Default(); |
| 1115 } | 1093 } |
| 1116 break; | 1094 break; |
| 1117 } | 1095 } |
| 1118 case i::Token::LPAREN: { | 1096 case Token::LPAREN: { |
| 1119 if (new_count == 0) return result; | 1097 if (new_count == 0) return result; |
| 1120 // Consume one of the new prefixes (already parsed). | 1098 // Consume one of the new prefixes (already parsed). |
| 1121 ParseArguments(CHECK_OK); | 1099 ParseArguments(CHECK_OK); |
| 1122 new_count--; | 1100 new_count--; |
| 1123 result = Expression::Default(); | 1101 result = Expression::Default(); |
| 1124 break; | 1102 break; |
| 1125 } | 1103 } |
| 1126 default: | 1104 default: |
| 1127 return result; | 1105 return result; |
| 1128 } | 1106 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1139 // Identifier | 1117 // Identifier |
| 1140 // Number | 1118 // Number |
| 1141 // String | 1119 // String |
| 1142 // ArrayLiteral | 1120 // ArrayLiteral |
| 1143 // ObjectLiteral | 1121 // ObjectLiteral |
| 1144 // RegExpLiteral | 1122 // RegExpLiteral |
| 1145 // '(' Expression ')' | 1123 // '(' Expression ')' |
| 1146 | 1124 |
| 1147 Expression result = Expression::Default(); | 1125 Expression result = Expression::Default(); |
| 1148 switch (peek()) { | 1126 switch (peek()) { |
| 1149 case i::Token::THIS: { | 1127 case Token::THIS: { |
| 1150 Next(); | 1128 Next(); |
| 1151 result = Expression::This(); | 1129 result = Expression::This(); |
| 1152 break; | 1130 break; |
| 1153 } | 1131 } |
| 1154 | 1132 |
| 1155 case i::Token::FUTURE_RESERVED_WORD: | 1133 case Token::FUTURE_RESERVED_WORD: |
| 1156 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 1134 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 1157 case i::Token::YIELD: | 1135 case Token::YIELD: |
| 1158 case i::Token::IDENTIFIER: { | 1136 case Token::IDENTIFIER: { |
| 1159 Identifier id = ParseIdentifier(CHECK_OK); | 1137 Identifier id = ParseIdentifier(CHECK_OK); |
| 1160 result = Expression::FromIdentifier(id); | 1138 result = Expression::FromIdentifier(id); |
| 1161 break; | 1139 break; |
| 1162 } | 1140 } |
| 1163 | 1141 |
| 1164 case i::Token::NULL_LITERAL: | 1142 case Token::NULL_LITERAL: |
| 1165 case i::Token::TRUE_LITERAL: | 1143 case Token::TRUE_LITERAL: |
| 1166 case i::Token::FALSE_LITERAL: | 1144 case Token::FALSE_LITERAL: |
| 1167 case i::Token::NUMBER: { | 1145 case Token::NUMBER: { |
| 1168 Next(); | 1146 Next(); |
| 1169 break; | 1147 break; |
| 1170 } | 1148 } |
| 1171 case i::Token::STRING: { | 1149 case Token::STRING: { |
| 1172 Next(); | 1150 Next(); |
| 1173 result = GetStringSymbol(); | 1151 result = GetStringSymbol(); |
| 1174 break; | 1152 break; |
| 1175 } | 1153 } |
| 1176 | 1154 |
| 1177 case i::Token::ASSIGN_DIV: | 1155 case Token::ASSIGN_DIV: |
| 1178 result = ParseRegExpLiteral(true, CHECK_OK); | 1156 result = ParseRegExpLiteral(true, CHECK_OK); |
| 1179 break; | 1157 break; |
| 1180 | 1158 |
| 1181 case i::Token::DIV: | 1159 case Token::DIV: |
| 1182 result = ParseRegExpLiteral(false, CHECK_OK); | 1160 result = ParseRegExpLiteral(false, CHECK_OK); |
| 1183 break; | 1161 break; |
| 1184 | 1162 |
| 1185 case i::Token::LBRACK: | 1163 case Token::LBRACK: |
| 1186 result = ParseArrayLiteral(CHECK_OK); | 1164 result = ParseArrayLiteral(CHECK_OK); |
| 1187 break; | 1165 break; |
| 1188 | 1166 |
| 1189 case i::Token::LBRACE: | 1167 case Token::LBRACE: |
| 1190 result = ParseObjectLiteral(CHECK_OK); | 1168 result = ParseObjectLiteral(CHECK_OK); |
| 1191 break; | 1169 break; |
| 1192 | 1170 |
| 1193 case i::Token::LPAREN: | 1171 case Token::LPAREN: |
| 1194 Consume(i::Token::LPAREN); | 1172 Consume(Token::LPAREN); |
| 1195 parenthesized_function_ = (peek() == i::Token::FUNCTION); | 1173 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1196 result = ParseExpression(true, CHECK_OK); | 1174 result = ParseExpression(true, CHECK_OK); |
| 1197 Expect(i::Token::RPAREN, CHECK_OK); | 1175 Expect(Token::RPAREN, CHECK_OK); |
| 1198 result = result.Parenthesize(); | 1176 result = result.Parenthesize(); |
| 1199 break; | 1177 break; |
| 1200 | 1178 |
| 1201 case i::Token::MOD: | 1179 case Token::MOD: |
| 1202 result = ParseV8Intrinsic(CHECK_OK); | 1180 result = ParseV8Intrinsic(CHECK_OK); |
| 1203 break; | 1181 break; |
| 1204 | 1182 |
| 1205 default: { | 1183 default: { |
| 1206 Next(); | 1184 Next(); |
| 1207 *ok = false; | 1185 *ok = false; |
| 1208 return Expression::Default(); | 1186 return Expression::Default(); |
| 1209 } | 1187 } |
| 1210 } | 1188 } |
| 1211 | 1189 |
| 1212 return result; | 1190 return result; |
| 1213 } | 1191 } |
| 1214 | 1192 |
| 1215 | 1193 |
| 1216 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { | 1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { |
| 1217 // ArrayLiteral :: | 1195 // ArrayLiteral :: |
| 1218 // '[' Expression? (',' Expression?)* ']' | 1196 // '[' Expression? (',' Expression?)* ']' |
| 1219 Expect(i::Token::LBRACK, CHECK_OK); | 1197 Expect(Token::LBRACK, CHECK_OK); |
| 1220 while (peek() != i::Token::RBRACK) { | 1198 while (peek() != Token::RBRACK) { |
| 1221 if (peek() != i::Token::COMMA) { | 1199 if (peek() != Token::COMMA) { |
| 1222 ParseAssignmentExpression(true, CHECK_OK); | 1200 ParseAssignmentExpression(true, CHECK_OK); |
| 1223 } | 1201 } |
| 1224 if (peek() != i::Token::RBRACK) { | 1202 if (peek() != Token::RBRACK) { |
| 1225 Expect(i::Token::COMMA, CHECK_OK); | 1203 Expect(Token::COMMA, CHECK_OK); |
| 1226 } | 1204 } |
| 1227 } | 1205 } |
| 1228 Expect(i::Token::RBRACK, CHECK_OK); | 1206 Expect(Token::RBRACK, CHECK_OK); |
| 1229 | 1207 |
| 1230 scope_->NextMaterializedLiteralIndex(); | 1208 scope_->NextMaterializedLiteralIndex(); |
| 1231 return Expression::Default(); | 1209 return Expression::Default(); |
| 1232 } | 1210 } |
| 1233 | 1211 |
| 1234 | 1212 |
| 1235 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
| 1236 // ObjectLiteral :: | 1214 // ObjectLiteral :: |
| 1237 // '{' ( | 1215 // '{' ( |
| 1238 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1216 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 1239 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1217 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 1240 // )*[','] '}' | 1218 // )*[','] '}' |
| 1241 | 1219 |
| 1242 i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); | 1220 ObjectLiteralChecker checker(this, language_mode()); |
| 1243 | 1221 |
| 1244 Expect(i::Token::LBRACE, CHECK_OK); | 1222 Expect(Token::LBRACE, CHECK_OK); |
| 1245 while (peek() != i::Token::RBRACE) { | 1223 while (peek() != Token::RBRACE) { |
| 1246 i::Token::Value next = peek(); | 1224 Token::Value next = peek(); |
| 1247 switch (next) { | 1225 switch (next) { |
| 1248 case i::Token::IDENTIFIER: | 1226 case Token::IDENTIFIER: |
| 1249 case i::Token::FUTURE_RESERVED_WORD: | 1227 case Token::FUTURE_RESERVED_WORD: |
| 1250 case i::Token::FUTURE_STRICT_RESERVED_WORD: { | 1228 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1251 bool is_getter = false; | 1229 bool is_getter = false; |
| 1252 bool is_setter = false; | 1230 bool is_setter = false; |
| 1253 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 1231 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 1254 if ((is_getter || is_setter) && peek() != i::Token::COLON) { | 1232 if ((is_getter || is_setter) && peek() != Token::COLON) { |
| 1255 i::Token::Value name = Next(); | 1233 Token::Value name = Next(); |
| 1256 bool is_keyword = i::Token::IsKeyword(name); | 1234 bool is_keyword = Token::IsKeyword(name); |
| 1257 if (name != i::Token::IDENTIFIER && | 1235 if (name != Token::IDENTIFIER && |
| 1258 name != i::Token::FUTURE_RESERVED_WORD && | 1236 name != Token::FUTURE_RESERVED_WORD && |
| 1259 name != i::Token::FUTURE_STRICT_RESERVED_WORD && | 1237 name != Token::FUTURE_STRICT_RESERVED_WORD && |
| 1260 name != i::Token::NUMBER && | 1238 name != Token::NUMBER && |
| 1261 name != i::Token::STRING && | 1239 name != Token::STRING && |
| 1262 !is_keyword) { | 1240 !is_keyword) { |
| 1263 *ok = false; | 1241 *ok = false; |
| 1264 return Expression::Default(); | 1242 return Expression::Default(); |
| 1265 } | 1243 } |
| 1266 if (!is_keyword) { | 1244 if (!is_keyword) { |
| 1267 LogSymbol(); | 1245 LogSymbol(); |
| 1268 } | 1246 } |
| 1269 i::PropertyKind type = is_getter ? i::kGetterProperty | 1247 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
| 1270 : i::kSetterProperty; | |
| 1271 checker.CheckProperty(name, type, CHECK_OK); | 1248 checker.CheckProperty(name, type, CHECK_OK); |
| 1272 ParseFunctionLiteral(false, CHECK_OK); | 1249 ParseFunctionLiteral(false, CHECK_OK); |
| 1273 if (peek() != i::Token::RBRACE) { | 1250 if (peek() != Token::RBRACE) { |
| 1274 Expect(i::Token::COMMA, CHECK_OK); | 1251 Expect(Token::COMMA, CHECK_OK); |
| 1275 } | 1252 } |
| 1276 continue; // restart the while | 1253 continue; // restart the while |
| 1277 } | 1254 } |
| 1278 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1255 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1279 break; | 1256 break; |
| 1280 } | 1257 } |
| 1281 case i::Token::STRING: | 1258 case Token::STRING: |
| 1282 Consume(next); | 1259 Consume(next); |
| 1283 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1260 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1284 GetStringSymbol(); | 1261 GetStringSymbol(); |
| 1285 break; | 1262 break; |
| 1286 case i::Token::NUMBER: | 1263 case Token::NUMBER: |
| 1287 Consume(next); | 1264 Consume(next); |
| 1288 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1265 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1289 break; | 1266 break; |
| 1290 default: | 1267 default: |
| 1291 if (i::Token::IsKeyword(next)) { | 1268 if (Token::IsKeyword(next)) { |
| 1292 Consume(next); | 1269 Consume(next); |
| 1293 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1270 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1294 } else { | 1271 } else { |
| 1295 // Unexpected token. | 1272 // Unexpected token. |
| 1296 *ok = false; | 1273 *ok = false; |
| 1297 return Expression::Default(); | 1274 return Expression::Default(); |
| 1298 } | 1275 } |
| 1299 } | 1276 } |
| 1300 | 1277 |
| 1301 Expect(i::Token::COLON, CHECK_OK); | 1278 Expect(Token::COLON, CHECK_OK); |
| 1302 ParseAssignmentExpression(true, CHECK_OK); | 1279 ParseAssignmentExpression(true, CHECK_OK); |
| 1303 | 1280 |
| 1304 // TODO(1240767): Consider allowing trailing comma. | 1281 // TODO(1240767): Consider allowing trailing comma. |
| 1305 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); | 1282 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 1306 } | 1283 } |
| 1307 Expect(i::Token::RBRACE, CHECK_OK); | 1284 Expect(Token::RBRACE, CHECK_OK); |
| 1308 | 1285 |
| 1309 scope_->NextMaterializedLiteralIndex(); | 1286 scope_->NextMaterializedLiteralIndex(); |
| 1310 return Expression::Default(); | 1287 return Expression::Default(); |
| 1311 } | 1288 } |
| 1312 | 1289 |
| 1313 | 1290 |
| 1314 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, | 1291 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, |
| 1315 bool* ok) { | 1292 bool* ok) { |
| 1316 if (!scanner_->ScanRegExpPattern(seen_equal)) { | 1293 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
| 1317 Next(); | 1294 Next(); |
| 1318 ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL); | 1295 ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL); |
| 1319 *ok = false; | 1296 *ok = false; |
| 1320 return Expression::Default(); | 1297 return Expression::Default(); |
| 1321 } | 1298 } |
| 1322 | 1299 |
| 1323 scope_->NextMaterializedLiteralIndex(); | 1300 scope_->NextMaterializedLiteralIndex(); |
| 1324 | 1301 |
| 1325 if (!scanner_->ScanRegExpFlags()) { | 1302 if (!scanner()->ScanRegExpFlags()) { |
| 1326 Next(); | 1303 Next(); |
| 1327 ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL); | 1304 ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL); |
| 1328 *ok = false; | 1305 *ok = false; |
| 1329 return Expression::Default(); | 1306 return Expression::Default(); |
| 1330 } | 1307 } |
| 1331 Next(); | 1308 Next(); |
| 1332 return Expression::Default(); | 1309 return Expression::Default(); |
| 1333 } | 1310 } |
| 1334 | 1311 |
| 1335 | 1312 |
| 1336 PreParser::Arguments PreParser::ParseArguments(bool* ok) { | 1313 PreParser::Arguments PreParser::ParseArguments(bool* ok) { |
| 1337 // Arguments :: | 1314 // Arguments :: |
| 1338 // '(' (AssignmentExpression)*[','] ')' | 1315 // '(' (AssignmentExpression)*[','] ')' |
| 1339 | 1316 |
| 1340 Expect(i::Token::LPAREN, ok); | 1317 Expect(Token::LPAREN, ok); |
| 1341 if (!*ok) return -1; | 1318 if (!*ok) return -1; |
| 1342 bool done = (peek() == i::Token::RPAREN); | 1319 bool done = (peek() == Token::RPAREN); |
| 1343 int argc = 0; | 1320 int argc = 0; |
| 1344 while (!done) { | 1321 while (!done) { |
| 1345 ParseAssignmentExpression(true, ok); | 1322 ParseAssignmentExpression(true, ok); |
| 1346 if (!*ok) return -1; | 1323 if (!*ok) return -1; |
| 1347 argc++; | 1324 argc++; |
| 1348 done = (peek() == i::Token::RPAREN); | 1325 done = (peek() == Token::RPAREN); |
| 1349 if (!done) { | 1326 if (!done) { |
| 1350 Expect(i::Token::COMMA, ok); | 1327 Expect(Token::COMMA, ok); |
| 1351 if (!*ok) return -1; | 1328 if (!*ok) return -1; |
| 1352 } | 1329 } |
| 1353 } | 1330 } |
| 1354 Expect(i::Token::RPAREN, ok); | 1331 Expect(Token::RPAREN, ok); |
| 1355 return argc; | 1332 return argc; |
| 1356 } | 1333 } |
| 1357 | 1334 |
| 1358 | 1335 |
| 1359 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, | 1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, |
| 1360 bool* ok) { | 1337 bool* ok) { |
| 1361 // Function :: | 1338 // Function :: |
| 1362 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1339 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 1363 | 1340 |
| 1364 // Parse function body. | 1341 // Parse function body. |
| 1365 ScopeType outer_scope_type = scope_->type(); | 1342 ScopeType outer_scope_type = scope_->type(); |
| 1366 bool inside_with = scope_->IsInsideWith(); | 1343 bool inside_with = scope_->IsInsideWith(); |
| 1367 Scope function_scope(&scope_, kFunctionScope); | 1344 Scope function_scope(&scope_, kFunctionScope); |
| 1368 function_scope.set_is_generator(is_generator); | 1345 function_scope.set_is_generator(is_generator); |
| 1369 // FormalParameterList :: | 1346 // FormalParameterList :: |
| 1370 // '(' (Identifier)*[','] ')' | 1347 // '(' (Identifier)*[','] ')' |
| 1371 Expect(i::Token::LPAREN, CHECK_OK); | 1348 Expect(Token::LPAREN, CHECK_OK); |
| 1372 int start_position = scanner_->location().beg_pos; | 1349 int start_position = position(); |
| 1373 bool done = (peek() == i::Token::RPAREN); | 1350 bool done = (peek() == Token::RPAREN); |
| 1374 i::DuplicateFinder duplicate_finder(scanner_->unicode_cache()); | 1351 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 1375 while (!done) { | 1352 while (!done) { |
| 1376 Identifier id = ParseIdentifier(CHECK_OK); | 1353 Identifier id = ParseIdentifier(CHECK_OK); |
| 1377 if (!id.IsValidStrictVariable()) { | 1354 if (!id.IsValidStrictVariable()) { |
| 1378 StrictModeIdentifierViolation(scanner_->location(), | 1355 StrictModeIdentifierViolation(scanner()->location(), |
| 1379 "strict_param_name", | 1356 "strict_param_name", |
| 1380 id, | 1357 id, |
| 1381 CHECK_OK); | 1358 CHECK_OK); |
| 1382 } | 1359 } |
| 1383 int prev_value; | 1360 int prev_value; |
| 1384 if (scanner_->is_literal_ascii()) { | 1361 if (scanner()->is_literal_ascii()) { |
| 1385 prev_value = | 1362 prev_value = |
| 1386 duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1); | 1363 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); |
| 1387 } else { | 1364 } else { |
| 1388 prev_value = | 1365 prev_value = |
| 1389 duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1); | 1366 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); |
| 1390 } | 1367 } |
| 1391 | 1368 |
| 1392 if (prev_value != 0) { | 1369 if (prev_value != 0) { |
| 1393 SetStrictModeViolation(scanner_->location(), | 1370 SetStrictModeViolation(scanner()->location(), |
| 1394 "strict_param_dupe", | 1371 "strict_param_dupe", |
| 1395 CHECK_OK); | 1372 CHECK_OK); |
| 1396 } | 1373 } |
| 1397 done = (peek() == i::Token::RPAREN); | 1374 done = (peek() == Token::RPAREN); |
| 1398 if (!done) { | 1375 if (!done) { |
| 1399 Expect(i::Token::COMMA, CHECK_OK); | 1376 Expect(Token::COMMA, CHECK_OK); |
| 1400 } | 1377 } |
| 1401 } | 1378 } |
| 1402 Expect(i::Token::RPAREN, CHECK_OK); | 1379 Expect(Token::RPAREN, CHECK_OK); |
| 1403 | 1380 |
| 1404 // Determine if the function will be lazily compiled. | 1381 // Determine if the function will be lazily compiled. |
| 1405 // Currently only happens to top-level functions. | 1382 // Currently only happens to top-level functions. |
| 1406 // Optimistically assume that all top-level functions are lazily compiled. | 1383 // Optimistically assume that all top-level functions are lazily compiled. |
| 1407 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && | 1384 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && |
| 1408 !inside_with && allow_lazy_ && | 1385 !inside_with && allow_lazy() && |
| 1409 !parenthesized_function_); | 1386 !parenthesized_function_); |
| 1410 parenthesized_function_ = false; | 1387 parenthesized_function_ = false; |
| 1411 | 1388 |
| 1412 Expect(i::Token::LBRACE, CHECK_OK); | 1389 Expect(Token::LBRACE, CHECK_OK); |
| 1413 if (is_lazily_compiled) { | 1390 if (is_lazily_compiled) { |
| 1414 ParseLazyFunctionLiteralBody(CHECK_OK); | 1391 ParseLazyFunctionLiteralBody(CHECK_OK); |
| 1415 } else { | 1392 } else { |
| 1416 ParseSourceElements(i::Token::RBRACE, ok); | 1393 ParseSourceElements(Token::RBRACE, ok); |
| 1417 } | 1394 } |
| 1418 Expect(i::Token::RBRACE, CHECK_OK); | 1395 Expect(Token::RBRACE, CHECK_OK); |
| 1419 | 1396 |
| 1420 if (!is_classic_mode()) { | 1397 if (!is_classic_mode()) { |
| 1421 int end_position = scanner_->location().end_pos; | 1398 int end_position = scanner()->location().end_pos; |
| 1422 CheckOctalLiteral(start_position, end_position, CHECK_OK); | 1399 CheckOctalLiteral(start_position, end_position, CHECK_OK); |
| 1423 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); | 1400 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); |
| 1424 return Expression::StrictFunction(); | 1401 return Expression::StrictFunction(); |
| 1425 } | 1402 } |
| 1426 | 1403 |
| 1427 return Expression::Default(); | 1404 return Expression::Default(); |
| 1428 } | 1405 } |
| 1429 | 1406 |
| 1430 | 1407 |
| 1431 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { | 1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
| 1432 int body_start = scanner_->location().beg_pos; | 1409 int body_start = position(); |
| 1433 log_->PauseRecording(); | 1410 log_->PauseRecording(); |
| 1434 ParseSourceElements(i::Token::RBRACE, ok); | 1411 ParseSourceElements(Token::RBRACE, ok); |
| 1435 log_->ResumeRecording(); | 1412 log_->ResumeRecording(); |
| 1436 if (!*ok) return; | 1413 if (!*ok) return; |
| 1437 | 1414 |
| 1438 // Position right after terminal '}'. | 1415 // Position right after terminal '}'. |
| 1439 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); | 1416 ASSERT_EQ(Token::RBRACE, scanner()->peek()); |
| 1440 int body_end = scanner_->peek_location().end_pos; | 1417 int body_end = scanner()->peek_location().end_pos; |
| 1441 log_->LogFunction(body_start, body_end, | 1418 log_->LogFunction(body_start, body_end, |
| 1442 scope_->materialized_literal_count(), | 1419 scope_->materialized_literal_count(), |
| 1443 scope_->expected_properties(), | 1420 scope_->expected_properties(), |
| 1444 language_mode()); | 1421 language_mode()); |
| 1445 } | 1422 } |
| 1446 | 1423 |
| 1447 | 1424 |
| 1448 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
| 1449 // CallRuntime :: | 1426 // CallRuntime :: |
| 1450 // '%' Identifier Arguments | 1427 // '%' Identifier Arguments |
| 1451 Expect(i::Token::MOD, CHECK_OK); | 1428 Expect(Token::MOD, CHECK_OK); |
| 1452 if (!allow_natives_syntax_) { | 1429 if (!allow_natives_syntax()) { |
| 1453 *ok = false; | 1430 *ok = false; |
| 1454 return Expression::Default(); | 1431 return Expression::Default(); |
| 1455 } | 1432 } |
| 1456 ParseIdentifier(CHECK_OK); | 1433 ParseIdentifier(CHECK_OK); |
| 1457 ParseArguments(ok); | 1434 ParseArguments(ok); |
| 1458 | 1435 |
| 1459 return Expression::Default(); | 1436 return Expression::Default(); |
| 1460 } | 1437 } |
| 1461 | 1438 |
| 1462 #undef CHECK_OK | 1439 #undef CHECK_OK |
| 1463 | 1440 |
| 1464 | 1441 |
| 1465 void PreParser::ExpectSemicolon(bool* ok) { | |
| 1466 // Check for automatic semicolon insertion according to | |
| 1467 // the rules given in ECMA-262, section 7.9, page 21. | |
| 1468 i::Token::Value tok = peek(); | |
| 1469 if (tok == i::Token::SEMICOLON) { | |
| 1470 Next(); | |
| 1471 return; | |
| 1472 } | |
| 1473 if (scanner_->HasAnyLineTerminatorBeforeNext() || | |
| 1474 tok == i::Token::RBRACE || | |
| 1475 tok == i::Token::EOS) { | |
| 1476 return; | |
| 1477 } | |
| 1478 Expect(i::Token::SEMICOLON, ok); | |
| 1479 } | |
| 1480 | |
| 1481 | |
| 1482 void PreParser::LogSymbol() { | 1442 void PreParser::LogSymbol() { |
| 1483 int identifier_pos = scanner_->location().beg_pos; | 1443 int identifier_pos = position(); |
| 1484 if (scanner_->is_literal_ascii()) { | 1444 if (scanner()->is_literal_ascii()) { |
| 1485 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string()); | 1445 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); |
| 1486 } else { | 1446 } else { |
| 1487 log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string()); | 1447 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); |
| 1488 } | 1448 } |
| 1489 } | 1449 } |
| 1490 | 1450 |
| 1491 | 1451 |
| 1492 PreParser::Expression PreParser::GetStringSymbol() { | 1452 PreParser::Expression PreParser::GetStringSymbol() { |
| 1493 const int kUseStrictLength = 10; | 1453 const int kUseStrictLength = 10; |
| 1494 const char* kUseStrictChars = "use strict"; | 1454 const char* kUseStrictChars = "use strict"; |
| 1495 LogSymbol(); | 1455 LogSymbol(); |
| 1496 if (scanner_->is_literal_ascii() && | 1456 if (scanner()->is_literal_ascii() && |
| 1497 scanner_->literal_length() == kUseStrictLength && | 1457 scanner()->literal_length() == kUseStrictLength && |
| 1498 !scanner_->literal_contains_escapes() && | 1458 !scanner()->literal_contains_escapes() && |
| 1499 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, | 1459 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars, |
| 1500 kUseStrictLength)) { | 1460 kUseStrictLength)) { |
| 1501 return Expression::UseStrictStringLiteral(); | 1461 return Expression::UseStrictStringLiteral(); |
| 1502 } | 1462 } |
| 1503 return Expression::StringLiteral(); | 1463 return Expression::StringLiteral(); |
| 1504 } | 1464 } |
| 1505 | 1465 |
| 1506 | 1466 |
| 1507 PreParser::Identifier PreParser::GetIdentifierSymbol() { | 1467 PreParser::Identifier PreParser::GetIdentifierSymbol() { |
| 1508 LogSymbol(); | 1468 LogSymbol(); |
| 1509 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { | 1469 if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) { |
| 1510 return Identifier::FutureReserved(); | 1470 return Identifier::FutureReserved(); |
| 1511 } else if (scanner_->current_token() == | 1471 } else if (scanner()->current_token() == |
| 1512 i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1472 Token::FUTURE_STRICT_RESERVED_WORD) { |
| 1513 return Identifier::FutureStrictReserved(); | 1473 return Identifier::FutureStrictReserved(); |
| 1514 } else if (scanner_->current_token() == i::Token::YIELD) { | 1474 } else if (scanner()->current_token() == Token::YIELD) { |
| 1515 return Identifier::Yield(); | 1475 return Identifier::Yield(); |
| 1516 } | 1476 } |
| 1517 if (scanner_->is_literal_ascii()) { | 1477 if (scanner()->is_literal_ascii()) { |
| 1518 // Detect strict-mode poison words. | 1478 // Detect strict-mode poison words. |
| 1519 if (scanner_->literal_length() == 4 && | 1479 if (scanner()->literal_length() == 4 && |
| 1520 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { | 1480 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) { |
| 1521 return Identifier::Eval(); | 1481 return Identifier::Eval(); |
| 1522 } | 1482 } |
| 1523 if (scanner_->literal_length() == 9 && | 1483 if (scanner()->literal_length() == 9 && |
| 1524 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { | 1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { |
| 1525 return Identifier::Arguments(); | 1485 return Identifier::Arguments(); |
| 1526 } | 1486 } |
| 1527 } | 1487 } |
| 1528 return Identifier::Default(); | 1488 return Identifier::Default(); |
| 1529 } | 1489 } |
| 1530 | 1490 |
| 1531 | 1491 |
| 1532 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
| 1533 i::Token::Value next = Next(); | 1493 Token::Value next = Next(); |
| 1534 switch (next) { | 1494 switch (next) { |
| 1535 case i::Token::FUTURE_RESERVED_WORD: { | 1495 case Token::FUTURE_RESERVED_WORD: { |
| 1536 i::Scanner::Location location = scanner_->location(); | 1496 Scanner::Location location = scanner()->location(); |
| 1537 ReportMessageAt(location.beg_pos, location.end_pos, | 1497 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1538 "reserved_word", NULL); | 1498 "reserved_word", NULL); |
| 1539 *ok = false; | 1499 *ok = false; |
| 1540 return GetIdentifierSymbol(); | 1500 return GetIdentifierSymbol(); |
| 1541 } | 1501 } |
| 1542 case i::Token::YIELD: | 1502 case Token::YIELD: |
| 1543 if (scope_->is_generator()) { | 1503 if (scope_->is_generator()) { |
| 1544 // 'yield' in a generator is only valid as part of a YieldExpression. | 1504 // 'yield' in a generator is only valid as part of a YieldExpression. |
| 1545 ReportMessageAt(scanner_->location(), "unexpected_token", "yield"); | 1505 ReportMessageAt(scanner()->location(), "unexpected_token", "yield"); |
| 1546 *ok = false; | 1506 *ok = false; |
| 1547 return Identifier::Yield(); | 1507 return Identifier::Yield(); |
| 1548 } | 1508 } |
| 1549 // FALLTHROUGH | 1509 // FALLTHROUGH |
| 1550 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 1510 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 1551 if (!is_classic_mode()) { | 1511 if (!is_classic_mode()) { |
| 1552 i::Scanner::Location location = scanner_->location(); | 1512 Scanner::Location location = scanner()->location(); |
| 1553 ReportMessageAt(location.beg_pos, location.end_pos, | 1513 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1554 "strict_reserved_word", NULL); | 1514 "strict_reserved_word", NULL); |
| 1555 *ok = false; | 1515 *ok = false; |
| 1556 } | 1516 } |
| 1557 // FALLTHROUGH | 1517 // FALLTHROUGH |
| 1558 case i::Token::IDENTIFIER: | 1518 case Token::IDENTIFIER: |
| 1559 return GetIdentifierSymbol(); | 1519 return GetIdentifierSymbol(); |
| 1560 default: | 1520 default: |
| 1561 *ok = false; | 1521 *ok = false; |
| 1562 return Identifier::Default(); | 1522 return Identifier::Default(); |
| 1563 } | 1523 } |
| 1564 } | 1524 } |
| 1565 | 1525 |
| 1566 | 1526 |
| 1567 void PreParser::SetStrictModeViolation(i::Scanner::Location location, | 1527 void PreParser::SetStrictModeViolation(Scanner::Location location, |
| 1568 const char* type, | 1528 const char* type, |
| 1569 bool* ok) { | 1529 bool* ok) { |
| 1570 if (!is_classic_mode()) { | 1530 if (!is_classic_mode()) { |
| 1571 ReportMessageAt(location, type, NULL); | 1531 ReportMessageAt(location, type, NULL); |
| 1572 *ok = false; | 1532 *ok = false; |
| 1573 return; | 1533 return; |
| 1574 } | 1534 } |
| 1575 // Delay report in case this later turns out to be strict code | 1535 // Delay report in case this later turns out to be strict code |
| 1576 // (i.e., for function names and parameters prior to a "use strict" | 1536 // (i.e., for function names and parameters prior to a "use strict" |
| 1577 // directive). | 1537 // directive). |
| 1578 // It's safe to overwrite an existing violation. | 1538 // It's safe to overwrite an existing violation. |
| 1579 // It's either from a function that turned out to be non-strict, | 1539 // It's either from a function that turned out to be non-strict, |
| 1580 // or it's in the current function (and we just need to report | 1540 // or it's in the current function (and we just need to report |
| 1581 // one error), or it's in a unclosed nesting function that wasn't | 1541 // one error), or it's in a unclosed nesting function that wasn't |
| 1582 // strict (otherwise we would already be in strict mode). | 1542 // strict (otherwise we would already be in strict mode). |
| 1583 strict_mode_violation_location_ = location; | 1543 strict_mode_violation_location_ = location; |
| 1584 strict_mode_violation_type_ = type; | 1544 strict_mode_violation_type_ = type; |
| 1585 } | 1545 } |
| 1586 | 1546 |
| 1587 | 1547 |
| 1588 void PreParser::CheckDelayedStrictModeViolation(int beg_pos, | 1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos, |
| 1589 int end_pos, | 1549 int end_pos, |
| 1590 bool* ok) { | 1550 bool* ok) { |
| 1591 i::Scanner::Location location = strict_mode_violation_location_; | 1551 Scanner::Location location = strict_mode_violation_location_; |
| 1592 if (location.IsValid() && | 1552 if (location.IsValid() && |
| 1593 location.beg_pos > beg_pos && location.end_pos < end_pos) { | 1553 location.beg_pos > beg_pos && location.end_pos < end_pos) { |
| 1594 ReportMessageAt(location, strict_mode_violation_type_, NULL); | 1554 ReportMessageAt(location, strict_mode_violation_type_, NULL); |
| 1595 *ok = false; | 1555 *ok = false; |
| 1596 } | 1556 } |
| 1597 } | 1557 } |
| 1598 | 1558 |
| 1599 | 1559 |
| 1600 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location, | 1560 void PreParser::StrictModeIdentifierViolation(Scanner::Location location, |
| 1601 const char* eval_args_type, | 1561 const char* eval_args_type, |
| 1602 Identifier identifier, | 1562 Identifier identifier, |
| 1603 bool* ok) { | 1563 bool* ok) { |
| 1604 const char* type = eval_args_type; | 1564 const char* type = eval_args_type; |
| 1605 if (identifier.IsFutureReserved()) { | 1565 if (identifier.IsFutureReserved()) { |
| 1606 type = "reserved_word"; | 1566 type = "reserved_word"; |
| 1607 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { | 1567 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { |
| 1608 type = "strict_reserved_word"; | 1568 type = "strict_reserved_word"; |
| 1609 } | 1569 } |
| 1610 if (!is_classic_mode()) { | 1570 if (!is_classic_mode()) { |
| 1611 ReportMessageAt(location, type, NULL); | 1571 ReportMessageAt(location, type, NULL); |
| 1612 *ok = false; | 1572 *ok = false; |
| 1613 return; | 1573 return; |
| 1614 } | 1574 } |
| 1615 strict_mode_violation_location_ = location; | 1575 strict_mode_violation_location_ = location; |
| 1616 strict_mode_violation_type_ = type; | 1576 strict_mode_violation_type_ = type; |
| 1617 } | 1577 } |
| 1618 | 1578 |
| 1619 | 1579 |
| 1620 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { | 1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
| 1621 i::Token::Value next = Next(); | 1581 Token::Value next = Next(); |
| 1622 if (i::Token::IsKeyword(next)) { | 1582 if (Token::IsKeyword(next)) { |
| 1623 int pos = scanner_->location().beg_pos; | 1583 int pos = position(); |
| 1624 const char* keyword = i::Token::String(next); | 1584 const char* keyword = Token::String(next); |
| 1625 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, | 1585 log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword))); |
| 1626 i::StrLength(keyword))); | |
| 1627 return Identifier::Default(); | 1586 return Identifier::Default(); |
| 1628 } | 1587 } |
| 1629 if (next == i::Token::IDENTIFIER || | 1588 if (next == Token::IDENTIFIER || |
| 1630 next == i::Token::FUTURE_RESERVED_WORD || | 1589 next == Token::FUTURE_RESERVED_WORD || |
| 1631 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1590 next == Token::FUTURE_STRICT_RESERVED_WORD) { |
| 1632 return GetIdentifierSymbol(); | 1591 return GetIdentifierSymbol(); |
| 1633 } | 1592 } |
| 1634 *ok = false; | 1593 *ok = false; |
| 1635 return Identifier::Default(); | 1594 return Identifier::Default(); |
| 1636 } | 1595 } |
| 1637 | 1596 |
| 1638 #undef CHECK_OK | 1597 #undef CHECK_OK |
| 1639 | 1598 |
| 1640 | 1599 |
| 1641 // This function reads an identifier and determines whether or not it | 1600 // This function reads an identifier and determines whether or not it |
| 1642 // is 'get' or 'set'. | 1601 // is 'get' or 'set'. |
| 1643 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, | 1602 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 1644 bool* is_set, | 1603 bool* is_set, |
| 1645 bool* ok) { | 1604 bool* ok) { |
| 1646 Identifier result = ParseIdentifierName(ok); | 1605 Identifier result = ParseIdentifierName(ok); |
| 1647 if (!*ok) return Identifier::Default(); | 1606 if (!*ok) return Identifier::Default(); |
| 1648 if (scanner_->is_literal_ascii() && | 1607 if (scanner()->is_literal_ascii() && |
| 1649 scanner_->literal_length() == 3) { | 1608 scanner()->literal_length() == 3) { |
| 1650 const char* token = scanner_->literal_ascii_string().start(); | 1609 const char* token = scanner()->literal_ascii_string().start(); |
| 1651 *is_get = strncmp(token, "get", 3) == 0; | 1610 *is_get = strncmp(token, "get", 3) == 0; |
| 1652 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 1611 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 1653 } | 1612 } |
| 1654 return result; | 1613 return result; |
| 1655 } | 1614 } |
| 1656 | 1615 |
| 1657 | 1616 |
| 1658 bool PreParser::peek_any_identifier() { | 1617 void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property, |
| 1659 i::Token::Value next = peek(); | 1618 PropertyKind type, |
| 1660 return next == i::Token::IDENTIFIER || | 1619 bool* ok) { |
| 1661 next == i::Token::FUTURE_RESERVED_WORD || | 1620 int old; |
| 1662 next == i::Token::FUTURE_STRICT_RESERVED_WORD || | 1621 if (property == Token::NUMBER) { |
| 1663 next == i::Token::YIELD; | 1622 old = finder_.AddNumber(scanner()->literal_ascii_string(), type); |
| 1623 } else if (scanner()->is_literal_ascii()) { |
| 1624 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type); |
| 1625 } else { |
| 1626 old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type); |
| 1627 } |
| 1628 PropertyKind old_type = static_cast<PropertyKind>(old); |
| 1629 if (HasConflict(old_type, type)) { |
| 1630 if (IsDataDataConflict(old_type, type)) { |
| 1631 // Both are data properties. |
| 1632 if (language_mode_ == CLASSIC_MODE) return; |
| 1633 parser()->ReportMessageAt(scanner()->location(), |
| 1634 "strict_duplicate_property"); |
| 1635 } else if (IsDataAccessorConflict(old_type, type)) { |
| 1636 // Both a data and an accessor property with the same name. |
| 1637 parser()->ReportMessageAt(scanner()->location(), |
| 1638 "accessor_data_property"); |
| 1639 } else { |
| 1640 ASSERT(IsAccessorAccessorConflict(old_type, type)); |
| 1641 // Both accessors of the same type. |
| 1642 parser()->ReportMessageAt(scanner()->location(), |
| 1643 "accessor_get_set"); |
| 1644 } |
| 1645 *ok = false; |
| 1646 } |
| 1664 } | 1647 } |
| 1665 | 1648 |
| 1666 } } // v8::preparser | 1649 } } // v8::internal |
| OLD | NEW |