| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { | 660 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { |
| 661 if (obj == VariableProxySentinel::this_proxy()) { | 661 if (obj == VariableProxySentinel::this_proxy()) { |
| 662 return Property::this_property(); | 662 return Property::this_property(); |
| 663 } else { | 663 } else { |
| 664 return ValidLeftHandSideSentinel::instance(); | 664 return ValidLeftHandSideSentinel::instance(); |
| 665 } | 665 } |
| 666 } | 666 } |
| 667 | 667 |
| 668 virtual Expression* NewCall(Expression* expression, | 668 virtual Expression* NewCall(Expression* expression, |
| 669 ZoneList<Expression*>* arguments, | 669 ZoneList<Expression*>* arguments, |
| 670 bool is_eval, int pos) { | 670 int pos) { |
| 671 return Call::sentinel(); | 671 return Call::sentinel(); |
| 672 } | 672 } |
| 673 | 673 |
| 674 virtual Expression* NewCallEval(Expression* expression, |
| 675 ZoneList<Expression*>* arguments, |
| 676 int pos) { |
| 677 return CallEval::sentinel(); |
| 678 } |
| 679 |
| 674 virtual Statement* EmptyStatement() { | 680 virtual Statement* EmptyStatement() { |
| 675 return NULL; | 681 return NULL; |
| 676 } | 682 } |
| 677 | 683 |
| 678 template <typename T> ZoneListWrapper<T> NewList(int size) { | 684 template <typename T> ZoneListWrapper<T> NewList(int size) { |
| 679 return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size); | 685 return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size); |
| 680 } | 686 } |
| 681 | 687 |
| 682 private: | 688 private: |
| 683 bool is_pre_parsing_; | 689 bool is_pre_parsing_; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 710 virtual Handle<String> EmptySymbol() { | 716 virtual Handle<String> EmptySymbol() { |
| 711 return Factory::empty_symbol(); | 717 return Factory::empty_symbol(); |
| 712 } | 718 } |
| 713 | 719 |
| 714 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { | 720 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { |
| 715 return new Property(obj, key, pos); | 721 return new Property(obj, key, pos); |
| 716 } | 722 } |
| 717 | 723 |
| 718 virtual Expression* NewCall(Expression* expression, | 724 virtual Expression* NewCall(Expression* expression, |
| 719 ZoneList<Expression*>* arguments, | 725 ZoneList<Expression*>* arguments, |
| 720 bool is_eval, int pos) { | 726 int pos) { |
| 721 return new Call(expression, arguments, is_eval, pos); | 727 return new Call(expression, arguments, pos); |
| 728 } |
| 729 |
| 730 virtual Expression* NewCallEval(Expression* expression, |
| 731 ZoneList<Expression*>* arguments, |
| 732 int pos) { |
| 733 return new CallEval(expression, arguments, pos); |
| 722 } | 734 } |
| 723 | 735 |
| 724 virtual Statement* EmptyStatement() { | 736 virtual Statement* EmptyStatement() { |
| 725 // Use a statically allocated empty statement singleton to avoid | 737 // Use a statically allocated empty statement singleton to avoid |
| 726 // allocating lots and lots of empty statements. | 738 // allocating lots and lots of empty statements. |
| 727 static v8::internal::EmptyStatement empty; | 739 static v8::internal::EmptyStatement empty; |
| 728 return ∅ | 740 return ∅ |
| 729 } | 741 } |
| 730 }; | 742 }; |
| 731 | 743 |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 // is always the function scope. | 1348 // is always the function scope. |
| 1337 | 1349 |
| 1338 // If a function scope exists, then we can statically declare this | 1350 // If a function scope exists, then we can statically declare this |
| 1339 // variable and also set its mode. In any case, a Declaration node | 1351 // variable and also set its mode. In any case, a Declaration node |
| 1340 // will be added to the scope so that the declaration can be added | 1352 // will be added to the scope so that the declaration can be added |
| 1341 // to the corresponding activation frame at runtime if necessary. | 1353 // to the corresponding activation frame at runtime if necessary. |
| 1342 // For instance declarations inside an eval scope need to be added | 1354 // For instance declarations inside an eval scope need to be added |
| 1343 // to the calling function context. | 1355 // to the calling function context. |
| 1344 if (top_scope_->is_function_scope()) { | 1356 if (top_scope_->is_function_scope()) { |
| 1345 // Declare the variable in the function scope. | 1357 // Declare the variable in the function scope. |
| 1346 var = top_scope_->Lookup(name); | 1358 var = top_scope_->LookupLocal(name); |
| 1347 if (var == NULL) { | 1359 if (var == NULL) { |
| 1348 // Declare the name. | 1360 // Declare the name. |
| 1349 var = top_scope_->Declare(name, mode); | 1361 var = top_scope_->Declare(name, mode); |
| 1350 } else { | 1362 } else { |
| 1351 // The name was declared before; check for conflicting | 1363 // The name was declared before; check for conflicting |
| 1352 // re-declarations. If the previous declaration was a const or the | 1364 // re-declarations. If the previous declaration was a const or the |
| 1353 // current declaration is a const then we have a conflict. There is | 1365 // current declaration is a const then we have a conflict. There is |
| 1354 // similar code in runtime.cc in the Declare functions. | 1366 // similar code in runtime.cc in the Declare functions. |
| 1355 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { | 1367 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { |
| 1356 // We only have vars and consts in declarations. | 1368 // We only have vars and consts in declarations. |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2617 result = factory()->NewProperty(result, index, pos); | 2629 result = factory()->NewProperty(result, index, pos); |
| 2618 Expect(Token::RBRACK, CHECK_OK); | 2630 Expect(Token::RBRACK, CHECK_OK); |
| 2619 break; | 2631 break; |
| 2620 } | 2632 } |
| 2621 | 2633 |
| 2622 case Token::LPAREN: { | 2634 case Token::LPAREN: { |
| 2623 int pos = scanner().location().beg_pos; | 2635 int pos = scanner().location().beg_pos; |
| 2624 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 2636 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 2625 | 2637 |
| 2626 // Keep track of eval() calls since they disable all local variable | 2638 // Keep track of eval() calls since they disable all local variable |
| 2627 // optimizations. We can ignore locally declared variables with | 2639 // optimizations. |
| 2628 // name 'eval' since they override the global 'eval' function. We | 2640 // The calls that need special treatment are the |
| 2629 // only need to look at unresolved variables (VariableProxies). | 2641 // direct (i.e. not aliased) eval calls. These calls are all of the |
| 2642 // form eval(...) with no explicit receiver object where eval is not |
| 2643 // declared in the current scope chain. These calls are marked as |
| 2644 // potentially direct eval calls. Whether they are actually direct calls |
| 2645 // to eval is determined at run time. |
| 2630 | 2646 |
| 2647 bool is_potentially_direct_eval = false; |
| 2631 if (!is_pre_parsing_) { | 2648 if (!is_pre_parsing_) { |
| 2632 // We assume that only a function called 'eval' can be used | |
| 2633 // to invoke the global eval() implementation. This permits | |
| 2634 // for massive optimizations. | |
| 2635 VariableProxy* callee = result->AsVariableProxy(); | 2649 VariableProxy* callee = result->AsVariableProxy(); |
| 2636 if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) { | 2650 if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) { |
| 2637 // We do not allow direct calls to 'eval' in our internal | 2651 Handle<String> name = callee->name(); |
| 2638 // JS files. Use builtin functions instead. | 2652 Variable* var = top_scope_->Lookup(name); |
| 2639 ASSERT(!Bootstrapper::IsActive()); | 2653 if (var == NULL) { |
| 2640 top_scope_->RecordEvalCall(); | 2654 // We do not allow direct calls to 'eval' in our internal |
| 2641 } else { | 2655 // JS files. Use builtin functions instead. |
| 2642 // This is rather convoluted code to check if we're calling | 2656 ASSERT(!Bootstrapper::IsActive()); |
| 2643 // a function named 'eval' through a property access. If so, | 2657 top_scope_->RecordEvalCall(); |
| 2644 // we mark it as a possible eval call (we don't know if the | 2658 is_potentially_direct_eval = true; |
| 2645 // receiver will resolve to the global object or not), but | |
| 2646 // we do not treat the call as an eval() call - we let the | |
| 2647 // call get through to the JavaScript eval code defined in | |
| 2648 // v8natives.js. | |
| 2649 Property* property = result->AsProperty(); | |
| 2650 if (property != NULL) { | |
| 2651 Literal* key = property->key()->AsLiteral(); | |
| 2652 if (key != NULL && | |
| 2653 key->handle().is_identical_to(Factory::eval_symbol())) { | |
| 2654 // We do not allow direct calls to 'eval' in our | |
| 2655 // internal JS files. Use builtin functions instead. | |
| 2656 ASSERT(!Bootstrapper::IsActive()); | |
| 2657 top_scope_->RecordEvalCall(); | |
| 2658 } | |
| 2659 } | 2659 } |
| 2660 } | 2660 } |
| 2661 } | 2661 } |
| 2662 | 2662 |
| 2663 // Optimize the eval() case w/o arguments so we | 2663 if (is_potentially_direct_eval) { |
| 2664 // don't need to handle it every time at runtime. | 2664 result = factory()->NewCallEval(result, args, pos); |
| 2665 // | |
| 2666 // Note: For now we don't do static eval analysis | |
| 2667 // as it appears that we need to be able to call | |
| 2668 // eval() via alias names. We leave the code as | |
| 2669 // is, in case we want to enable this again in the | |
| 2670 // future. | |
| 2671 const bool is_eval = false; | |
| 2672 if (is_eval && args->length() == 0) { | |
| 2673 result = NEW(Literal(Factory::undefined_value())); | |
| 2674 } else { | 2665 } else { |
| 2675 result = factory()->NewCall(result, args, is_eval, pos); | 2666 result = factory()->NewCall(result, args, pos); |
| 2676 } | 2667 } |
| 2677 break; | 2668 break; |
| 2678 } | 2669 } |
| 2679 | 2670 |
| 2680 case Token::PERIOD: { | 2671 case Token::PERIOD: { |
| 2681 Consume(Token::PERIOD); | 2672 Consume(Token::PERIOD); |
| 2682 int pos = scanner().location().beg_pos; | 2673 int pos = scanner().location().beg_pos; |
| 2683 Handle<String> name = ParseIdentifier(CHECK_OK); | 2674 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2684 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 2675 result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
| 2685 break; | 2676 break; |
| (...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4360 start_position, | 4351 start_position, |
| 4361 is_expression); | 4352 is_expression); |
| 4362 return result; | 4353 return result; |
| 4363 } | 4354 } |
| 4364 | 4355 |
| 4365 | 4356 |
| 4366 #undef NEW | 4357 #undef NEW |
| 4367 | 4358 |
| 4368 | 4359 |
| 4369 } } // namespace v8::internal | 4360 } } // namespace v8::internal |
| OLD | NEW |