| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2295 // Signal a reference error if the expression is an invalid left-hand | 2295 // Signal a reference error if the expression is an invalid left-hand |
| 2296 // side expression. We could report this as a syntax error here but | 2296 // side expression. We could report this as a syntax error here but |
| 2297 // for compatibility with JSC we choose to report the error at | 2297 // for compatibility with JSC we choose to report the error at |
| 2298 // runtime. | 2298 // runtime. |
| 2299 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2299 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2300 Handle<String> type = | 2300 Handle<String> type = |
| 2301 isolate()->factory()->invalid_lhs_in_assignment_symbol(); | 2301 isolate()->factory()->invalid_lhs_in_assignment_symbol(); |
| 2302 expression = NewThrowReferenceError(type); | 2302 expression = NewThrowReferenceError(type); |
| 2303 } | 2303 } |
| 2304 | 2304 |
| 2305 if (temp_scope_->StrictMode()) { |
| 2306 // Assignment to eval or arguments is disallowed in strict mode. |
| 2307 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2308 } |
| 2309 |
| 2305 Token::Value op = Next(); // Get assignment operator. | 2310 Token::Value op = Next(); // Get assignment operator. |
| 2306 int pos = scanner().location().beg_pos; | 2311 int pos = scanner().location().beg_pos; |
| 2307 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2312 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2308 | 2313 |
| 2309 // TODO(1231235): We try to estimate the set of properties set by | 2314 // TODO(1231235): We try to estimate the set of properties set by |
| 2310 // constructors. We define a new property whenever there is an | 2315 // constructors. We define a new property whenever there is an |
| 2311 // assignment to a property of 'this'. We should probably only add | 2316 // assignment to a property of 'this'. We should probably only add |
| 2312 // properties if we haven't seen them before. Otherwise we'll | 2317 // properties if we haven't seen them before. Otherwise we'll |
| 2313 // probably overestimate the number of properties. | 2318 // probably overestimate the number of properties. |
| 2314 Property* property = expression ? expression->AsProperty() : NULL; | 2319 Property* property = expression ? expression->AsProperty() : NULL; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2522 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2527 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2523 // Signal a reference error if the expression is an invalid | 2528 // Signal a reference error if the expression is an invalid |
| 2524 // left-hand side expression. We could report this as a syntax | 2529 // left-hand side expression. We could report this as a syntax |
| 2525 // error here but for compatibility with JSC we choose to report the | 2530 // error here but for compatibility with JSC we choose to report the |
| 2526 // error at runtime. | 2531 // error at runtime. |
| 2527 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2532 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2528 Handle<String> type = | 2533 Handle<String> type = |
| 2529 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); | 2534 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); |
| 2530 expression = NewThrowReferenceError(type); | 2535 expression = NewThrowReferenceError(type); |
| 2531 } | 2536 } |
| 2537 |
| 2538 if (temp_scope_->StrictMode()) { |
| 2539 // Prefix expression operand in strict mode may not be eval or arguments. |
| 2540 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2541 } |
| 2542 |
| 2532 int position = scanner().location().beg_pos; | 2543 int position = scanner().location().beg_pos; |
| 2533 IncrementOperation* increment = new IncrementOperation(op, expression); | 2544 IncrementOperation* increment = new IncrementOperation(op, expression); |
| 2534 return new CountOperation(true /* prefix */, increment, position); | 2545 return new CountOperation(true /* prefix */, increment, position); |
| 2535 | 2546 |
| 2536 } else { | 2547 } else { |
| 2537 return ParsePostfixExpression(ok); | 2548 return ParsePostfixExpression(ok); |
| 2538 } | 2549 } |
| 2539 } | 2550 } |
| 2540 | 2551 |
| 2541 | 2552 |
| 2542 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2553 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 2543 // PostfixExpression :: | 2554 // PostfixExpression :: |
| 2544 // LeftHandSideExpression ('++' | '--')? | 2555 // LeftHandSideExpression ('++' | '--')? |
| 2545 | 2556 |
| 2546 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 2557 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 2547 if (!scanner().has_line_terminator_before_next() && | 2558 if (!scanner().has_line_terminator_before_next() && |
| 2548 Token::IsCountOp(peek())) { | 2559 Token::IsCountOp(peek())) { |
| 2549 // Signal a reference error if the expression is an invalid | 2560 // Signal a reference error if the expression is an invalid |
| 2550 // left-hand side expression. We could report this as a syntax | 2561 // left-hand side expression. We could report this as a syntax |
| 2551 // error here but for compatibility with JSC we choose to report the | 2562 // error here but for compatibility with JSC we choose to report the |
| 2552 // error at runtime. | 2563 // error at runtime. |
| 2553 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2564 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2554 Handle<String> type = | 2565 Handle<String> type = |
| 2555 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); | 2566 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); |
| 2556 expression = NewThrowReferenceError(type); | 2567 expression = NewThrowReferenceError(type); |
| 2557 } | 2568 } |
| 2569 |
| 2570 if (temp_scope_->StrictMode()) { |
| 2571 // Postfix expression operand in strict mode may not be eval or arguments. |
| 2572 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2573 } |
| 2574 |
| 2558 Token::Value next = Next(); | 2575 Token::Value next = Next(); |
| 2559 int position = scanner().location().beg_pos; | 2576 int position = scanner().location().beg_pos; |
| 2560 IncrementOperation* increment = new IncrementOperation(next, expression); | 2577 IncrementOperation* increment = new IncrementOperation(next, expression); |
| 2561 expression = new CountOperation(false /* postfix */, increment, position); | 2578 expression = new CountOperation(false /* postfix */, increment, position); |
| 2562 } | 2579 } |
| 2563 return expression; | 2580 return expression; |
| 2564 } | 2581 } |
| 2565 | 2582 |
| 2566 | 2583 |
| 2567 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 2584 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3024 return expression->AsLiteral()->handle(); | 3041 return expression->AsLiteral()->handle(); |
| 3025 } | 3042 } |
| 3026 if (CompileTimeValue::IsCompileTimeValue(expression)) { | 3043 if (CompileTimeValue::IsCompileTimeValue(expression)) { |
| 3027 return CompileTimeValue::GetValue(expression); | 3044 return CompileTimeValue::GetValue(expression); |
| 3028 } | 3045 } |
| 3029 return isolate()->factory()->undefined_value(); | 3046 return isolate()->factory()->undefined_value(); |
| 3030 } | 3047 } |
| 3031 | 3048 |
| 3032 // Defined in ast.cc | 3049 // Defined in ast.cc |
| 3033 bool IsEqualString(void* first, void* second); | 3050 bool IsEqualString(void* first, void* second); |
| 3034 bool IsEqualSmi(void* first, void* second); | 3051 bool IsEqualNumber(void* first, void* second); |
| 3035 | 3052 |
| 3036 | 3053 |
| 3037 // Validation per 11.1.5 Object Initialiser | 3054 // Validation per 11.1.5 Object Initialiser |
| 3038 class ObjectLiteralPropertyChecker { | 3055 class ObjectLiteralPropertyChecker { |
| 3039 public: | 3056 public: |
| 3040 ObjectLiteralPropertyChecker(Parser* parser, bool strict) : | 3057 ObjectLiteralPropertyChecker(Parser* parser, bool strict) : |
| 3041 props(&IsEqualString), | 3058 props(&IsEqualString), |
| 3042 elems(&IsEqualSmi), | 3059 elems(&IsEqualNumber), |
| 3043 parser_(parser), | 3060 parser_(parser), |
| 3044 strict_(strict) { | 3061 strict_(strict) { |
| 3045 } | 3062 } |
| 3046 | 3063 |
| 3047 void CheckProperty( | 3064 void CheckProperty( |
| 3048 ObjectLiteral::Property* property, | 3065 ObjectLiteral::Property* property, |
| 3049 Scanner::Location loc, | 3066 Scanner::Location loc, |
| 3050 bool* ok); | 3067 bool* ok); |
| 3051 | 3068 |
| 3052 private: | 3069 private: |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3081 bool* ok) { | 3098 bool* ok) { |
| 3082 | 3099 |
| 3083 ASSERT(property != NULL); | 3100 ASSERT(property != NULL); |
| 3084 | 3101 |
| 3085 Literal *lit = property->key(); | 3102 Literal *lit = property->key(); |
| 3086 Handle<Object> handle = lit->handle(); | 3103 Handle<Object> handle = lit->handle(); |
| 3087 | 3104 |
| 3088 uint32_t hash; | 3105 uint32_t hash; |
| 3089 HashMap* map; | 3106 HashMap* map; |
| 3090 void* key; | 3107 void* key; |
| 3091 Smi* smi_key_location; | |
| 3092 | 3108 |
| 3093 if (handle->IsSymbol()) { | 3109 if (handle->IsSymbol()) { |
| 3094 Handle<String> name(String::cast(*handle)); | 3110 Handle<String> name(String::cast(*handle)); |
| 3095 if (name->AsArrayIndex(&hash)) { | 3111 if (name->AsArrayIndex(&hash)) { |
| 3096 smi_key_location = Smi::FromInt(hash); | 3112 Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash); |
| 3097 key = &smi_key_location; | 3113 key = key_handle.location(); |
| 3098 map = &elems; | 3114 map = &elems; |
| 3099 } else { | 3115 } else { |
| 3100 key = handle.location(); | 3116 key = handle.location(); |
| 3101 hash = name->Hash(); | 3117 hash = name->Hash(); |
| 3102 map = &props; | 3118 map = &props; |
| 3103 } | 3119 } |
| 3104 } else if (handle->ToArrayIndex(&hash)) { | 3120 } else if (handle->ToArrayIndex(&hash)) { |
| 3105 key = handle.location(); | 3121 key = handle.location(); |
| 3106 map = &elems; | 3122 map = &elems; |
| 3107 } else { | 3123 } else { |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3700 Handle<String> Parser::ParseIdentifierName(bool* ok) { | 3716 Handle<String> Parser::ParseIdentifierName(bool* ok) { |
| 3701 Token::Value next = Next(); | 3717 Token::Value next = Next(); |
| 3702 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { | 3718 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { |
| 3703 ReportUnexpectedToken(next); | 3719 ReportUnexpectedToken(next); |
| 3704 *ok = false; | 3720 *ok = false; |
| 3705 return Handle<String>(); | 3721 return Handle<String>(); |
| 3706 } | 3722 } |
| 3707 return GetSymbol(ok); | 3723 return GetSymbol(ok); |
| 3708 } | 3724 } |
| 3709 | 3725 |
| 3726 |
| 3727 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 3728 // in strict mode. |
| 3729 void Parser::CheckStrictModeLValue(Expression* expression, |
| 3730 const char* error, |
| 3731 bool* ok) { |
| 3732 ASSERT(temp_scope_->StrictMode()); |
| 3733 VariableProxy* lhs = expression != NULL |
| 3734 ? expression->AsVariableProxy() |
| 3735 : NULL; |
| 3736 |
| 3737 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 3738 ReportMessage(error, Vector<const char*>::empty()); |
| 3739 *ok = false; |
| 3740 } |
| 3741 } |
| 3742 |
| 3743 |
| 3710 // Checks whether octal literal last seen is between beg_pos and end_pos. | 3744 // Checks whether octal literal last seen is between beg_pos and end_pos. |
| 3711 // If so, reports an error. | 3745 // If so, reports an error. |
| 3712 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 3746 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 3713 int octal = scanner().octal_position(); | 3747 int octal = scanner().octal_position(); |
| 3714 if (beg_pos <= octal && octal <= end_pos) { | 3748 if (beg_pos <= octal && octal <= end_pos) { |
| 3715 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", | 3749 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", |
| 3716 Vector<const char*>::empty()); | 3750 Vector<const char*>::empty()); |
| 3717 scanner().clear_octal_position(); | 3751 scanner().clear_octal_position(); |
| 3718 *ok = false; | 3752 *ok = false; |
| 3719 } | 3753 } |
| (...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4993 Handle<String> source = Handle<String>(String::cast(script->source())); | 5027 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4994 result = parser.ParseProgram(source, info->is_global()); | 5028 result = parser.ParseProgram(source, info->is_global()); |
| 4995 } | 5029 } |
| 4996 } | 5030 } |
| 4997 | 5031 |
| 4998 info->SetFunction(result); | 5032 info->SetFunction(result); |
| 4999 return (result != NULL); | 5033 return (result != NULL); |
| 5000 } | 5034 } |
| 5001 | 5035 |
| 5002 } } // namespace v8::internal | 5036 } } // namespace v8::internal |
| OLD | NEW |