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