Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: src/parser.cc

Issue 12673: Change implementation of eval to make an exact distinction between direct eva... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 &empty; 740 return &empty;
729 } 741 }
730 }; 742 };
731 743
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« src/codegen-ia32.cc ('K') | « src/heap.h ('k') | src/prettyprinter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698