OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 449 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
450 Expression* right) { | 450 Expression* right) { |
451 ASSERT(left != NULL); | 451 ASSERT(left != NULL); |
452 if (left->AsProperty() != NULL && | 452 if (left->AsProperty() != NULL && |
453 right->AsFunctionLiteral() != NULL) { | 453 right->AsFunctionLiteral() != NULL) { |
454 right->AsFunctionLiteral()->set_pretenure(); | 454 right->AsFunctionLiteral()->set_pretenure(); |
455 } | 455 } |
456 } | 456 } |
457 | 457 |
458 | 458 |
459 Expression* ParserTraits::ValidateAssignmentLeftHandSide( | |
460 Expression* expression) const { | |
461 ASSERT(expression != NULL); | |
462 if (!expression->IsValidLeftHandSide()) { | |
463 Handle<String> message = | |
464 parser_->isolate()->factory()->invalid_lhs_in_assignment_string(); | |
465 expression = parser_->NewThrowReferenceError(message); | |
466 } | |
467 return expression; | |
468 } | |
469 | |
470 | |
471 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 459 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
472 VariableProxy* proxy = expression != NULL | 460 VariableProxy* proxy = expression != NULL |
473 ? expression->AsVariableProxy() | 461 ? expression->AsVariableProxy() |
474 : NULL; | 462 : NULL; |
475 if (proxy != NULL) proxy->MarkAsLValue(); | 463 if (proxy != NULL) proxy->MarkAsLValue(); |
476 return expression; | 464 return expression; |
477 } | 465 } |
478 | 466 |
479 | 467 |
480 void ParserTraits::CheckStrictModeLValue(Expression* expression, | 468 void ParserTraits::CheckStrictModeLValue(Expression* expression, |
481 bool* ok) { | 469 bool* ok) { |
482 VariableProxy* lhs = expression != NULL | 470 VariableProxy* lhs = expression != NULL |
483 ? expression->AsVariableProxy() | 471 ? expression->AsVariableProxy() |
484 : NULL; | 472 : NULL; |
485 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 473 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
486 parser_->ReportMessage("strict_eval_arguments", | 474 parser_->ReportMessage("strict_eval_arguments", |
487 Vector<const char*>::empty()); | 475 Vector<const char*>::empty()); |
488 *ok = false; | 476 *ok = false; |
489 } | 477 } |
490 } | 478 } |
491 | 479 |
492 | 480 |
493 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 481 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
494 const char* message, | 482 const char* message, |
495 Vector<const char*> args) { | 483 Vector<const char*> args, |
| 484 bool is_reference_error) { |
496 if (parser_->stack_overflow()) { | 485 if (parser_->stack_overflow()) { |
497 // Suppress the error message (syntax error or such) in the presence of a | 486 // Suppress the error message (syntax error or such) in the presence of a |
498 // stack overflow. The isolate allows only one pending exception at at time | 487 // stack overflow. The isolate allows only one pending exception at at time |
499 // and we want to report the stack overflow later. | 488 // and we want to report the stack overflow later. |
500 return; | 489 return; |
501 } | 490 } |
502 MessageLocation location(parser_->script_, | 491 MessageLocation location(parser_->script_, |
503 source_location.beg_pos, | 492 source_location.beg_pos, |
504 source_location.end_pos); | 493 source_location.end_pos); |
505 Factory* factory = parser_->isolate()->factory(); | 494 Factory* factory = parser_->isolate()->factory(); |
506 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 495 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
507 for (int i = 0; i < args.length(); i++) { | 496 for (int i = 0; i < args.length(); i++) { |
508 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | 497 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
509 elements->set(i, *arg_string); | 498 elements->set(i, *arg_string); |
510 } | 499 } |
511 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 500 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
512 Handle<Object> result = factory->NewSyntaxError(message, array); | 501 Handle<Object> result = is_reference_error |
| 502 ? factory->NewReferenceError(message, array) |
| 503 : factory->NewSyntaxError(message, array); |
513 parser_->isolate()->Throw(*result, &location); | 504 parser_->isolate()->Throw(*result, &location); |
514 } | 505 } |
515 | 506 |
516 | 507 |
517 void ParserTraits::ReportMessage(const char* message, | 508 void ParserTraits::ReportMessage(const char* message, |
518 Vector<Handle<String> > args) { | 509 Vector<Handle<String> > args, |
| 510 bool is_reference_error) { |
519 Scanner::Location source_location = parser_->scanner()->location(); | 511 Scanner::Location source_location = parser_->scanner()->location(); |
520 ReportMessageAt(source_location, message, args); | 512 ReportMessageAt(source_location, message, args, is_reference_error); |
521 } | 513 } |
522 | 514 |
523 | 515 |
524 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 516 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
525 const char* message, | 517 const char* message, |
526 Vector<Handle<String> > args) { | 518 Vector<Handle<String> > args, |
| 519 bool is_reference_error) { |
527 if (parser_->stack_overflow()) { | 520 if (parser_->stack_overflow()) { |
528 // Suppress the error message (syntax error or such) in the presence of a | 521 // Suppress the error message (syntax error or such) in the presence of a |
529 // stack overflow. The isolate allows only one pending exception at at time | 522 // stack overflow. The isolate allows only one pending exception at at time |
530 // and we want to report the stack overflow later. | 523 // and we want to report the stack overflow later. |
531 return; | 524 return; |
532 } | 525 } |
533 MessageLocation location(parser_->script_, | 526 MessageLocation location(parser_->script_, |
534 source_location.beg_pos, | 527 source_location.beg_pos, |
535 source_location.end_pos); | 528 source_location.end_pos); |
536 Factory* factory = parser_->isolate()->factory(); | 529 Factory* factory = parser_->isolate()->factory(); |
537 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 530 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
538 for (int i = 0; i < args.length(); i++) { | 531 for (int i = 0; i < args.length(); i++) { |
539 elements->set(i, *args[i]); | 532 elements->set(i, *args[i]); |
540 } | 533 } |
541 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 534 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
542 Handle<Object> result = factory->NewSyntaxError(message, array); | 535 Handle<Object> result = is_reference_error |
| 536 ? factory->NewReferenceError(message, array) |
| 537 : factory->NewSyntaxError(message, array); |
543 parser_->isolate()->Throw(*result, &location); | 538 parser_->isolate()->Throw(*result, &location); |
544 } | 539 } |
545 | 540 |
546 | 541 |
547 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 542 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
548 int symbol_id = -1; | 543 int symbol_id = -1; |
549 if (parser_->pre_parse_data() != NULL) { | 544 if (parser_->pre_parse_data() != NULL) { |
550 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); | 545 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); |
551 } | 546 } |
552 return parser_->LookupSymbol(symbol_id); | 547 return parser_->LookupSymbol(symbol_id); |
(...skipping 2284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2837 for_scope->set_end_position(scanner()->location().end_pos); | 2832 for_scope->set_end_position(scanner()->location().end_pos); |
2838 for_scope = for_scope->FinalizeBlockScope(); | 2833 for_scope = for_scope->FinalizeBlockScope(); |
2839 body_block->set_scope(for_scope); | 2834 body_block->set_scope(for_scope); |
2840 // Parsed for-in loop w/ let declaration. | 2835 // Parsed for-in loop w/ let declaration. |
2841 return loop; | 2836 return loop; |
2842 | 2837 |
2843 } else { | 2838 } else { |
2844 init = variable_statement; | 2839 init = variable_statement; |
2845 } | 2840 } |
2846 } else { | 2841 } else { |
| 2842 Scanner::Location lhs_location = scanner()->peek_location(); |
2847 Expression* expression = ParseExpression(false, CHECK_OK); | 2843 Expression* expression = ParseExpression(false, CHECK_OK); |
2848 ForEachStatement::VisitMode mode; | 2844 ForEachStatement::VisitMode mode; |
2849 bool accept_OF = expression->AsVariableProxy(); | 2845 bool accept_OF = expression->AsVariableProxy(); |
2850 | 2846 |
2851 if (CheckInOrOf(accept_OF, &mode)) { | 2847 if (CheckInOrOf(accept_OF, &mode)) { |
2852 // Signal a reference error if the expression is an invalid | |
2853 // left-hand side expression. We could report this as a syntax | |
2854 // error here but for compatibility with JSC we choose to report | |
2855 // the error at runtime. | |
2856 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2848 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2857 Handle<String> message = | 2849 ReportMessageAt(lhs_location, "invalid_lhs_in_for", true); |
2858 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2850 *ok = false; |
2859 expression = NewThrowReferenceError(message); | 2851 return NULL; |
2860 } | 2852 } |
2861 ForEachStatement* loop = | 2853 ForEachStatement* loop = |
2862 factory()->NewForEachStatement(mode, labels, pos); | 2854 factory()->NewForEachStatement(mode, labels, pos); |
2863 Target target(&this->target_stack_, loop); | 2855 Target target(&this->target_stack_, loop); |
2864 | 2856 |
2865 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2857 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2866 Expect(Token::RPAREN, CHECK_OK); | 2858 Expect(Token::RPAREN, CHECK_OK); |
2867 | 2859 |
2868 Statement* body = ParseStatement(NULL, CHECK_OK); | 2860 Statement* body = ParseStatement(NULL, CHECK_OK); |
2869 InitializeForEachStatement(loop, expression, enumerable, body); | 2861 InitializeForEachStatement(loop, expression, enumerable, body); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3118 return factory()->NewBinaryOperation(Token::BIT_XOR, | 3110 return factory()->NewBinaryOperation(Token::BIT_XOR, |
3119 expression, | 3111 expression, |
3120 factory()->NewNumberLiteral(~0, pos), | 3112 factory()->NewNumberLiteral(~0, pos), |
3121 pos); | 3113 pos); |
3122 } | 3114 } |
3123 | 3115 |
3124 return factory()->NewUnaryOperation(op, expression, pos); | 3116 return factory()->NewUnaryOperation(op, expression, pos); |
3125 | 3117 |
3126 } else if (Token::IsCountOp(op)) { | 3118 } else if (Token::IsCountOp(op)) { |
3127 op = Next(); | 3119 op = Next(); |
| 3120 Scanner::Location lhs_location = scanner()->peek_location(); |
3128 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3121 Expression* expression = ParseUnaryExpression(CHECK_OK); |
3129 // Signal a reference error if the expression is an invalid | |
3130 // left-hand side expression. We could report this as a syntax | |
3131 // error here but for compatibility with JSC we choose to report the | |
3132 // error at runtime. | |
3133 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3122 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3134 Handle<String> message = | 3123 ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true); |
3135 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3124 *ok = false; |
3136 expression = NewThrowReferenceError(message); | 3125 return NULL; |
3137 } | 3126 } |
3138 | 3127 |
3139 if (strict_mode() == STRICT) { | 3128 if (strict_mode() == STRICT) { |
3140 // Prefix expression operand in strict mode may not be eval or arguments. | 3129 // Prefix expression operand in strict mode may not be eval or arguments. |
3141 CheckStrictModeLValue(expression, CHECK_OK); | 3130 CheckStrictModeLValue(expression, CHECK_OK); |
3142 } | 3131 } |
3143 MarkExpressionAsLValue(expression); | 3132 MarkExpressionAsLValue(expression); |
3144 | 3133 |
3145 return factory()->NewCountOperation(op, | 3134 return factory()->NewCountOperation(op, |
3146 true /* prefix */, | 3135 true /* prefix */, |
3147 expression, | 3136 expression, |
3148 position()); | 3137 position()); |
3149 | 3138 |
3150 } else { | 3139 } else { |
3151 return ParsePostfixExpression(ok); | 3140 return ParsePostfixExpression(ok); |
3152 } | 3141 } |
3153 } | 3142 } |
3154 | 3143 |
3155 | 3144 |
3156 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3145 Expression* Parser::ParsePostfixExpression(bool* ok) { |
3157 // PostfixExpression :: | 3146 // PostfixExpression :: |
3158 // LeftHandSideExpression ('++' | '--')? | 3147 // LeftHandSideExpression ('++' | '--')? |
3159 | 3148 |
| 3149 Scanner::Location lhs_location = scanner()->peek_location(); |
3160 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 3150 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
3161 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3151 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
3162 Token::IsCountOp(peek())) { | 3152 Token::IsCountOp(peek())) { |
3163 // Signal a reference error if the expression is an invalid | |
3164 // left-hand side expression. We could report this as a syntax | |
3165 // error here but for compatibility with JSC we choose to report the | |
3166 // error at runtime. | |
3167 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3153 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3168 Handle<String> message = | 3154 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true); |
3169 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3155 *ok = false; |
3170 expression = NewThrowReferenceError(message); | 3156 return NULL; |
3171 } | 3157 } |
3172 | 3158 |
3173 if (strict_mode() == STRICT) { | 3159 if (strict_mode() == STRICT) { |
3174 // Postfix expression operand in strict mode may not be eval or arguments. | 3160 // Postfix expression operand in strict mode may not be eval or arguments. |
3175 CheckStrictModeLValue(expression, CHECK_OK); | 3161 CheckStrictModeLValue(expression, CHECK_OK); |
3176 } | 3162 } |
3177 MarkExpressionAsLValue(expression); | 3163 MarkExpressionAsLValue(expression); |
3178 | 3164 |
3179 Token::Value next = Next(); | 3165 Token::Value next = Next(); |
3180 expression = | 3166 expression = |
(...skipping 1825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5006 ASSERT(info()->isolate()->has_pending_exception()); | 4992 ASSERT(info()->isolate()->has_pending_exception()); |
5007 } else { | 4993 } else { |
5008 result = ParseProgram(); | 4994 result = ParseProgram(); |
5009 } | 4995 } |
5010 } | 4996 } |
5011 info()->SetFunction(result); | 4997 info()->SetFunction(result); |
5012 return (result != NULL); | 4998 return (result != NULL); |
5013 } | 4999 } |
5014 | 5000 |
5015 } } // namespace v8::internal | 5001 } } // namespace v8::internal |
OLD | NEW |