 Chromium Code Reviews
 Chromium Code Reviews Issue 613683002:
  [turbofan] Some javascript operators are globally shared singletons.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 613683002:
  [turbofan] Some javascript operators are globally shared singletons.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| OLD | NEW | 
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" | 
| 6 | 6 | 
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" | 
| 8 #include "src/compiler/control-builders.h" | 8 #include "src/compiler/control-builders.h" | 
| 9 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" | 
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 Node* inner = BuildLocalFunctionContext(outer, closure); | 68 Node* inner = BuildLocalFunctionContext(outer, closure); | 
| 69 | 69 | 
| 70 // Push top-level function scope for the function body. | 70 // Push top-level function scope for the function body. | 
| 71 ContextScope top_context(this, scope, inner); | 71 ContextScope top_context(this, scope, inner); | 
| 72 | 72 | 
| 73 // Build the arguments object if it is used. | 73 // Build the arguments object if it is used. | 
| 74 BuildArgumentsObject(scope->arguments()); | 74 BuildArgumentsObject(scope->arguments()); | 
| 75 | 75 | 
| 76 // Emit tracing call if requested to do so. | 76 // Emit tracing call if requested to do so. | 
| 77 if (FLAG_trace) { | 77 if (FLAG_trace) { | 
| 78 NewNode(javascript()->Runtime(Runtime::kTraceEnter, 0)); | 78 NewNode(javascript()->CallRuntime( | 
| 79 CallRuntimeParameters(Runtime::kTraceEnter, 0))); | |
| 
Michael Starzinger
2014/09/29 15:24:06
I think we should continue to let the factory meth
 
Benedikt Meurer
2014/09/30 04:44:05
Done.
 | |
| 79 } | 80 } | 
| 80 | 81 | 
| 81 // Visit implicit declaration of the function name. | 82 // Visit implicit declaration of the function name. | 
| 82 if (scope->is_function_scope() && scope->function() != NULL) { | 83 if (scope->is_function_scope() && scope->function() != NULL) { | 
| 83 VisitVariableDeclaration(scope->function()); | 84 VisitVariableDeclaration(scope->function()); | 
| 84 } | 85 } | 
| 85 | 86 | 
| 86 // Visit declarations within the function scope. | 87 // Visit declarations within the function scope. | 
| 87 VisitDeclarations(scope->declarations()); | 88 VisitDeclarations(scope->declarations()); | 
| 88 | 89 | 
| 89 // TODO(mstarzinger): This should do an inlined stack check. | 90 // TODO(mstarzinger): This should do an inlined stack check. | 
| 90 Node* node = NewNode(javascript()->Runtime(Runtime::kStackGuard, 0)); | 91 Node* node = NewNode(javascript()->CallRuntime( | 
| 92 CallRuntimeParameters(Runtime::kStackGuard, 0))); | |
| 91 PrepareFrameState(node, BailoutId::FunctionEntry()); | 93 PrepareFrameState(node, BailoutId::FunctionEntry()); | 
| 92 | 94 | 
| 93 // Visit statements in the function body. | 95 // Visit statements in the function body. | 
| 94 VisitStatements(info()->function()->body()); | 96 VisitStatements(info()->function()->body()); | 
| 95 if (HasStackOverflow()) return false; | 97 if (HasStackOverflow()) return false; | 
| 96 | 98 | 
| 97 // Emit tracing call if requested to do so. | 99 // Emit tracing call if requested to do so. | 
| 98 if (FLAG_trace) { | 100 if (FLAG_trace) { | 
| 99 // TODO(mstarzinger): Only traces implicit return. | 101 // TODO(mstarzinger): Only traces implicit return. | 
| 100 Node* return_value = jsgraph()->UndefinedConstant(); | 102 Node* return_value = jsgraph()->UndefinedConstant(); | 
| 101 NewNode(javascript()->Runtime(Runtime::kTraceExit, 1), return_value); | 103 NewNode(javascript()->CallRuntime( | 
| 104 CallRuntimeParameters(Runtime::kTraceExit, 1)), | |
| 105 return_value); | |
| 102 } | 106 } | 
| 103 | 107 | 
| 104 // Return 'undefined' in case we can fall off the end. | 108 // Return 'undefined' in case we can fall off the end. | 
| 105 Node* control = NewNode(common()->Return(), jsgraph()->UndefinedConstant()); | 109 Node* control = NewNode(common()->Return(), jsgraph()->UndefinedConstant()); | 
| 106 UpdateControlDependencyToLeaveFunction(control); | 110 UpdateControlDependencyToLeaveFunction(control); | 
| 107 | 111 | 
| 108 // Finish the basic structure of the graph. | 112 // Finish the basic structure of the graph. | 
| 109 environment()->UpdateControlDependency(exit_control()); | 113 environment()->UpdateControlDependency(exit_control()); | 
| 110 graph()->SetEnd(NewNode(common()->End())); | 114 graph()->SetEnd(NewNode(common()->End())); | 
| 111 | 115 | 
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 case Variable::PARAMETER: | 371 case Variable::PARAMETER: | 
| 368 case Variable::LOCAL: | 372 case Variable::LOCAL: | 
| 369 if (hole_init) { | 373 if (hole_init) { | 
| 370 Node* value = jsgraph()->TheHoleConstant(); | 374 Node* value = jsgraph()->TheHoleConstant(); | 
| 371 environment()->Bind(variable, value); | 375 environment()->Bind(variable, value); | 
| 372 } | 376 } | 
| 373 break; | 377 break; | 
| 374 case Variable::CONTEXT: | 378 case Variable::CONTEXT: | 
| 375 if (hole_init) { | 379 if (hole_init) { | 
| 376 Node* value = jsgraph()->TheHoleConstant(); | 380 Node* value = jsgraph()->TheHoleConstant(); | 
| 377 const Operator* op = javascript()->StoreContext(0, variable->index()); | 381 const Operator* op = | 
| 382 javascript()->StoreContext(ContextAccess(0, variable->index())); | |
| 378 NewNode(op, current_context(), value); | 383 NewNode(op, current_context(), value); | 
| 379 } | 384 } | 
| 380 break; | 385 break; | 
| 381 case Variable::LOOKUP: | 386 case Variable::LOOKUP: | 
| 382 UNIMPLEMENTED(); | 387 UNIMPLEMENTED(); | 
| 383 } | 388 } | 
| 384 } | 389 } | 
| 385 | 390 | 
| 386 | 391 | 
| 387 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 392 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 399 case Variable::PARAMETER: | 404 case Variable::PARAMETER: | 
| 400 case Variable::LOCAL: { | 405 case Variable::LOCAL: { | 
| 401 VisitForValue(decl->fun()); | 406 VisitForValue(decl->fun()); | 
| 402 Node* value = environment()->Pop(); | 407 Node* value = environment()->Pop(); | 
| 403 environment()->Bind(variable, value); | 408 environment()->Bind(variable, value); | 
| 404 break; | 409 break; | 
| 405 } | 410 } | 
| 406 case Variable::CONTEXT: { | 411 case Variable::CONTEXT: { | 
| 407 VisitForValue(decl->fun()); | 412 VisitForValue(decl->fun()); | 
| 408 Node* value = environment()->Pop(); | 413 Node* value = environment()->Pop(); | 
| 409 const Operator* op = javascript()->StoreContext(0, variable->index()); | 414 const Operator* op = | 
| 415 javascript()->StoreContext(ContextAccess(0, variable->index())); | |
| 410 NewNode(op, current_context(), value); | 416 NewNode(op, current_context(), value); | 
| 411 break; | 417 break; | 
| 412 } | 418 } | 
| 413 case Variable::LOOKUP: | 419 case Variable::LOOKUP: | 
| 414 UNIMPLEMENTED(); | 420 UNIMPLEMENTED(); | 
| 415 } | 421 } | 
| 416 } | 422 } | 
| 417 | 423 | 
| 418 | 424 | 
| 419 void AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) { | 425 void AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) { | 
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant()); | 641 NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant()); | 
| 636 is_null.If(is_null_cond); | 642 is_null.If(is_null_cond); | 
| 637 is_null.Then(); | 643 is_null.Then(); | 
| 638 is_null.Else(); | 644 is_null.Else(); | 
| 639 // Convert object to jsobject. | 645 // Convert object to jsobject. | 
| 640 // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 646 // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 
| 641 obj = NewNode(javascript()->ToObject(), obj); | 647 obj = NewNode(javascript()->ToObject(), obj); | 
| 642 environment()->Push(obj); | 648 environment()->Push(obj); | 
| 643 // TODO(dcarney): should do a fast enum cache check here to skip runtime. | 649 // TODO(dcarney): should do a fast enum cache check here to skip runtime. | 
| 644 environment()->Push(obj); | 650 environment()->Push(obj); | 
| 645 Node* cache_type = ProcessArguments( | 651 Node* cache_type = | 
| 646 javascript()->Runtime(Runtime::kGetPropertyNamesFast, 1), 1); | 652 ProcessArguments(javascript()->CallRuntime(CallRuntimeParameters( | 
| 653 Runtime::kGetPropertyNamesFast, 1)), | |
| 654 1); | |
| 647 // TODO(dcarney): these next runtime calls should be removed in favour of | 655 // TODO(dcarney): these next runtime calls should be removed in favour of | 
| 648 // a few simplified instructions. | 656 // a few simplified instructions. | 
| 649 environment()->Push(obj); | 657 environment()->Push(obj); | 
| 650 environment()->Push(cache_type); | 658 environment()->Push(cache_type); | 
| 651 Node* cache_pair = | 659 Node* cache_pair = | 
| 652 ProcessArguments(javascript()->Runtime(Runtime::kForInInit, 2), 2); | 660 ProcessArguments(javascript()->CallRuntime( | 
| 661 CallRuntimeParameters(Runtime::kForInInit, 2)), | |
| 662 2); | |
| 653 // cache_type may have been replaced. | 663 // cache_type may have been replaced. | 
| 654 Node* cache_array = NewNode(common()->Projection(0), cache_pair); | 664 Node* cache_array = NewNode(common()->Projection(0), cache_pair); | 
| 655 cache_type = NewNode(common()->Projection(1), cache_pair); | 665 cache_type = NewNode(common()->Projection(1), cache_pair); | 
| 656 environment()->Push(cache_type); | 666 environment()->Push(cache_type); | 
| 657 environment()->Push(cache_array); | 667 environment()->Push(cache_array); | 
| 658 Node* cache_length = ProcessArguments( | 668 Node* cache_length = | 
| 659 javascript()->Runtime(Runtime::kForInCacheArrayLength, 2), 2); | 669 ProcessArguments(javascript()->CallRuntime(CallRuntimeParameters( | 
| 670 Runtime::kForInCacheArrayLength, 2)), | |
| 671 2); | |
| 660 { | 672 { | 
| 661 // TODO(dcarney): this check is actually supposed to be for the | 673 // TODO(dcarney): this check is actually supposed to be for the | 
| 662 // empty enum case only. | 674 // empty enum case only. | 
| 663 IfBuilder have_no_properties(this); | 675 IfBuilder have_no_properties(this); | 
| 664 Node* empty_array_cond = NewNode(javascript()->StrictEqual(), | 676 Node* empty_array_cond = NewNode(javascript()->StrictEqual(), | 
| 665 cache_length, jsgraph()->ZeroConstant()); | 677 cache_length, jsgraph()->ZeroConstant()); | 
| 666 have_no_properties.If(empty_array_cond); | 678 have_no_properties.If(empty_array_cond); | 
| 667 have_no_properties.Then(); | 679 have_no_properties.Then(); | 
| 668 // Pop obj and skip loop. | 680 // Pop obj and skip loop. | 
| 669 environment()->Pop(); | 681 environment()->Pop(); | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 686 for_loop.BreakUnless(exit_cond); | 698 for_loop.BreakUnless(exit_cond); | 
| 687 // TODO(dcarney): this runtime call should be a handful of | 699 // TODO(dcarney): this runtime call should be a handful of | 
| 688 // simplified instructions that | 700 // simplified instructions that | 
| 689 // basically produce | 701 // basically produce | 
| 690 // value = array[index] | 702 // value = array[index] | 
| 691 environment()->Push(obj); | 703 environment()->Push(obj); | 
| 692 environment()->Push(cache_array); | 704 environment()->Push(cache_array); | 
| 693 environment()->Push(cache_type); | 705 environment()->Push(cache_type); | 
| 694 environment()->Push(index); | 706 environment()->Push(index); | 
| 695 Node* pair = | 707 Node* pair = | 
| 696 ProcessArguments(javascript()->Runtime(Runtime::kForInNext, 4), 4); | 708 ProcessArguments(javascript()->CallRuntime( | 
| 709 CallRuntimeParameters(Runtime::kForInNext, 4)), | |
| 710 4); | |
| 697 Node* value = NewNode(common()->Projection(0), pair); | 711 Node* value = NewNode(common()->Projection(0), pair); | 
| 698 Node* should_filter = NewNode(common()->Projection(1), pair); | 712 Node* should_filter = NewNode(common()->Projection(1), pair); | 
| 699 environment()->Push(value); | 713 environment()->Push(value); | 
| 700 { | 714 { | 
| 701 // Test if FILTER_KEY needs to be called. | 715 // Test if FILTER_KEY needs to be called. | 
| 702 IfBuilder test_should_filter(this); | 716 IfBuilder test_should_filter(this); | 
| 703 Node* should_filter_cond = | 717 Node* should_filter_cond = | 
| 704 NewNode(javascript()->StrictEqual(), should_filter, | 718 NewNode(javascript()->StrictEqual(), should_filter, | 
| 705 jsgraph()->TrueConstant()); | 719 jsgraph()->TrueConstant()); | 
| 706 test_should_filter.If(should_filter_cond); | 720 test_should_filter.If(should_filter_cond); | 
| 707 test_should_filter.Then(); | 721 test_should_filter.Then(); | 
| 708 value = environment()->Pop(); | 722 value = environment()->Pop(); | 
| 709 Node* builtins = BuildLoadBuiltinsObject(); | 723 Node* builtins = BuildLoadBuiltinsObject(); | 
| 710 Node* function = BuildLoadObjectField( | 724 Node* function = BuildLoadObjectField( | 
| 711 builtins, | 725 builtins, | 
| 712 JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY)); | 726 JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY)); | 
| 713 // Callee. | 727 // Callee. | 
| 714 environment()->Push(function); | 728 environment()->Push(function); | 
| 715 // Receiver. | 729 // Receiver. | 
| 716 environment()->Push(obj); | 730 environment()->Push(obj); | 
| 717 // Args. | 731 // Args. | 
| 718 environment()->Push(value); | 732 environment()->Push(value); | 
| 719 // result is either the string key or Smi(0) indicating the property | 733 // result is either the string key or Smi(0) indicating the property | 
| 720 // is gone. | 734 // is gone. | 
| 721 Node* res = ProcessArguments( | 735 Node* res = ProcessArguments( | 
| 722 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); | 736 javascript()->CallFunction( | 
| 737 CallFunctionParameters(3, NO_CALL_FUNCTION_FLAGS)), | |
| 738 3); | |
| 723 // TODO(jarin): provide real bailout id. | 739 // TODO(jarin): provide real bailout id. | 
| 724 PrepareFrameState(res, BailoutId::None()); | 740 PrepareFrameState(res, BailoutId::None()); | 
| 725 Node* property_missing = NewNode(javascript()->StrictEqual(), res, | 741 Node* property_missing = NewNode(javascript()->StrictEqual(), res, | 
| 726 jsgraph()->ZeroConstant()); | 742 jsgraph()->ZeroConstant()); | 
| 727 { | 743 { | 
| 728 IfBuilder is_property_missing(this); | 744 IfBuilder is_property_missing(this); | 
| 729 is_property_missing.If(property_missing); | 745 is_property_missing.If(property_missing); | 
| 730 is_property_missing.Then(); | 746 is_property_missing.Then(); | 
| 731 // Inc counter and continue. | 747 // Inc counter and continue. | 
| 732 Node* index_inc = | 748 Node* index_inc = | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 778 } | 794 } | 
| 779 | 795 | 
| 780 | 796 | 
| 781 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 797 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 
| 782 UNREACHABLE(); | 798 UNREACHABLE(); | 
| 783 } | 799 } | 
| 784 | 800 | 
| 785 | 801 | 
| 786 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 802 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 
| 787 // TODO(turbofan): Do we really need a separate reloc-info for this? | 803 // TODO(turbofan): Do we really need a separate reloc-info for this? | 
| 788 Node* node = NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0)); | 804 Node* node = NewNode(javascript()->CallRuntime( | 
| 805 CallRuntimeParameters(Runtime::kDebugBreak, 0))); | |
| 789 PrepareFrameState(node, stmt->DebugBreakId()); | 806 PrepareFrameState(node, stmt->DebugBreakId()); | 
| 790 } | 807 } | 
| 791 | 808 | 
| 792 | 809 | 
| 793 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 810 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 
| 794 Node* context = current_context(); | 811 Node* context = current_context(); | 
| 795 | 812 | 
| 796 // Build a new shared function info if we cannot find one in the baseline | 813 // Build a new shared function info if we cannot find one in the baseline | 
| 797 // code. We also have a stack overflow if the recursive compilation did. | 814 // code. We also have a stack overflow if the recursive compilation did. | 
| 798 Handle<SharedFunctionInfo> shared_info = | 815 Handle<SharedFunctionInfo> shared_info = | 
| 799 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); | 816 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); | 
| 800 if (shared_info.is_null()) { | 817 if (shared_info.is_null()) { | 
| 801 shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info()); | 818 shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info()); | 
| 802 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? | 819 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? | 
| 803 } | 820 } | 
| 804 | 821 | 
| 805 // Create node to instantiate a new closure. | 822 // Create node to instantiate a new closure. | 
| 806 Node* info = jsgraph()->Constant(shared_info); | 823 Node* info = jsgraph()->Constant(shared_info); | 
| 807 Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant() | 824 Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant() | 
| 808 : jsgraph()->FalseConstant(); | 825 : jsgraph()->FalseConstant(); | 
| 809 const Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3); | 826 const Operator* op = | 
| 827 javascript()->CallRuntime(CallRuntimeParameters(Runtime::kNewClosure, 3)); | |
| 810 Node* value = NewNode(op, context, info, pretenure); | 828 Node* value = NewNode(op, context, info, pretenure); | 
| 811 ast_context()->ProduceValue(value); | 829 ast_context()->ProduceValue(value); | 
| 812 } | 830 } | 
| 813 | 831 | 
| 814 | 832 | 
| 815 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { | 833 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { | 
| 816 // TODO(arv): Implement. | 834 // TODO(arv): Implement. | 
| 817 UNREACHABLE(); | 835 UNREACHABLE(); | 
| 818 } | 836 } | 
| 819 | 837 | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 851 | 869 | 
| 852 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 870 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 
| 853 Node* closure = GetFunctionClosure(); | 871 Node* closure = GetFunctionClosure(); | 
| 854 | 872 | 
| 855 // Create node to materialize a regular expression literal. | 873 // Create node to materialize a regular expression literal. | 
| 856 Node* literals_array = | 874 Node* literals_array = | 
| 857 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 875 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 
| 858 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 876 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 
| 859 Node* pattern = jsgraph()->Constant(expr->pattern()); | 877 Node* pattern = jsgraph()->Constant(expr->pattern()); | 
| 860 Node* flags = jsgraph()->Constant(expr->flags()); | 878 Node* flags = jsgraph()->Constant(expr->flags()); | 
| 861 const Operator* op = | 879 const Operator* op = javascript()->CallRuntime( | 
| 862 javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4); | 880 CallRuntimeParameters(Runtime::kMaterializeRegExpLiteral, 4)); | 
| 863 Node* literal = NewNode(op, literals_array, literal_index, pattern, flags); | 881 Node* literal = NewNode(op, literals_array, literal_index, pattern, flags); | 
| 864 ast_context()->ProduceValue(literal); | 882 ast_context()->ProduceValue(literal); | 
| 865 } | 883 } | 
| 866 | 884 | 
| 867 | 885 | 
| 868 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 886 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 
| 869 Node* closure = GetFunctionClosure(); | 887 Node* closure = GetFunctionClosure(); | 
| 870 | 888 | 
| 871 // Create node to deep-copy the literal boilerplate. | 889 // Create node to deep-copy the literal boilerplate. | 
| 872 expr->BuildConstantProperties(isolate()); | 890 expr->BuildConstantProperties(isolate()); | 
| 873 Node* literals_array = | 891 Node* literals_array = | 
| 874 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 892 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 
| 875 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 893 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 
| 876 Node* constants = jsgraph()->Constant(expr->constant_properties()); | 894 Node* constants = jsgraph()->Constant(expr->constant_properties()); | 
| 877 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); | 895 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); | 
| 878 const Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4); | 896 const Operator* op = javascript()->CallRuntime( | 
| 897 CallRuntimeParameters(Runtime::kCreateObjectLiteral, 4)); | |
| 879 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); | 898 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); | 
| 880 | 899 | 
| 881 // The object is expected on the operand stack during computation of the | 900 // The object is expected on the operand stack during computation of the | 
| 882 // property values and is the value of the entire expression. | 901 // property values and is the value of the entire expression. | 
| 883 environment()->Push(literal); | 902 environment()->Push(literal); | 
| 884 | 903 | 
| 885 // Mark all computed expressions that are bound to a key that is shadowed by | 904 // Mark all computed expressions that are bound to a key that is shadowed by | 
| 886 // a later occurrence of the same key. For the marked expressions, no store | 905 // a later occurrence of the same key. For the marked expressions, no store | 
| 887 // code is emitted. | 906 // code is emitted. | 
| 888 expr->CalculateEmitStore(zone()); | 907 expr->CalculateEmitStore(zone()); | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 901 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 920 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 
| 902 // Fall through. | 921 // Fall through. | 
| 903 case ObjectLiteral::Property::COMPUTED: { | 922 case ObjectLiteral::Property::COMPUTED: { | 
| 904 // It is safe to use [[Put]] here because the boilerplate already | 923 // It is safe to use [[Put]] here because the boilerplate already | 
| 905 // contains computed properties with an uninitialized value. | 924 // contains computed properties with an uninitialized value. | 
| 906 if (key->value()->IsInternalizedString()) { | 925 if (key->value()->IsInternalizedString()) { | 
| 907 if (property->emit_store()) { | 926 if (property->emit_store()) { | 
| 908 VisitForValue(property->value()); | 927 VisitForValue(property->value()); | 
| 909 Node* value = environment()->Pop(); | 928 Node* value = environment()->Pop(); | 
| 910 Unique<Name> name = MakeUnique(key->AsPropertyName()); | 929 Unique<Name> name = MakeUnique(key->AsPropertyName()); | 
| 911 Node* store = NewNode(javascript()->StoreNamed(strict_mode(), name), | 930 Node* store = NewNode(javascript()->StoreNamed(StoreNamedParameters( | 
| 931 strict_mode(), name)), | |
| 912 literal, value); | 932 literal, value); | 
| 913 PrepareFrameState(store, key->id()); | 933 PrepareFrameState(store, key->id()); | 
| 914 } else { | 934 } else { | 
| 915 VisitForEffect(property->value()); | 935 VisitForEffect(property->value()); | 
| 916 } | 936 } | 
| 917 break; | 937 break; | 
| 918 } | 938 } | 
| 919 environment()->Push(literal); // Duplicate receiver. | 939 environment()->Push(literal); // Duplicate receiver. | 
| 920 VisitForValue(property->key()); | 940 VisitForValue(property->key()); | 
| 921 VisitForValue(property->value()); | 941 VisitForValue(property->value()); | 
| 922 Node* value = environment()->Pop(); | 942 Node* value = environment()->Pop(); | 
| 923 Node* key = environment()->Pop(); | 943 Node* key = environment()->Pop(); | 
| 924 Node* receiver = environment()->Pop(); | 944 Node* receiver = environment()->Pop(); | 
| 925 if (property->emit_store()) { | 945 if (property->emit_store()) { | 
| 926 Node* strict = jsgraph()->Constant(SLOPPY); | 946 Node* strict = jsgraph()->Constant(SLOPPY); | 
| 927 const Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4); | 947 const Operator* op = javascript()->CallRuntime( | 
| 948 CallRuntimeParameters(Runtime::kSetProperty, 4)); | |
| 928 NewNode(op, receiver, key, value, strict); | 949 NewNode(op, receiver, key, value, strict); | 
| 929 } | 950 } | 
| 930 break; | 951 break; | 
| 931 } | 952 } | 
| 932 case ObjectLiteral::Property::PROTOTYPE: { | 953 case ObjectLiteral::Property::PROTOTYPE: { | 
| 933 environment()->Push(literal); // Duplicate receiver. | 954 environment()->Push(literal); // Duplicate receiver. | 
| 934 VisitForValue(property->value()); | 955 VisitForValue(property->value()); | 
| 935 Node* value = environment()->Pop(); | 956 Node* value = environment()->Pop(); | 
| 936 Node* receiver = environment()->Pop(); | 957 Node* receiver = environment()->Pop(); | 
| 937 if (property->emit_store()) { | 958 if (property->emit_store()) { | 
| 938 const Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2); | 959 const Operator* op = javascript()->CallRuntime( | 
| 960 CallRuntimeParameters(Runtime::kSetPrototype, 2)); | |
| 939 NewNode(op, receiver, value); | 961 NewNode(op, receiver, value); | 
| 940 } | 962 } | 
| 941 break; | 963 break; | 
| 942 } | 964 } | 
| 943 case ObjectLiteral::Property::GETTER: | 965 case ObjectLiteral::Property::GETTER: | 
| 944 accessor_table.lookup(key)->second->getter = property->value(); | 966 accessor_table.lookup(key)->second->getter = property->value(); | 
| 945 break; | 967 break; | 
| 946 case ObjectLiteral::Property::SETTER: | 968 case ObjectLiteral::Property::SETTER: | 
| 947 accessor_table.lookup(key)->second->setter = property->value(); | 969 accessor_table.lookup(key)->second->setter = property->value(); | 
| 948 break; | 970 break; | 
| 949 } | 971 } | 
| 950 } | 972 } | 
| 951 | 973 | 
| 952 // Create nodes to define accessors, using only a single call to the runtime | 974 // Create nodes to define accessors, using only a single call to the runtime | 
| 953 // for each pair of corresponding getters and setters. | 975 // for each pair of corresponding getters and setters. | 
| 954 for (AccessorTable::Iterator it = accessor_table.begin(); | 976 for (AccessorTable::Iterator it = accessor_table.begin(); | 
| 955 it != accessor_table.end(); ++it) { | 977 it != accessor_table.end(); ++it) { | 
| 956 VisitForValue(it->first); | 978 VisitForValue(it->first); | 
| 957 VisitForValueOrNull(it->second->getter); | 979 VisitForValueOrNull(it->second->getter); | 
| 958 VisitForValueOrNull(it->second->setter); | 980 VisitForValueOrNull(it->second->setter); | 
| 959 Node* setter = environment()->Pop(); | 981 Node* setter = environment()->Pop(); | 
| 960 Node* getter = environment()->Pop(); | 982 Node* getter = environment()->Pop(); | 
| 961 Node* name = environment()->Pop(); | 983 Node* name = environment()->Pop(); | 
| 962 Node* attr = jsgraph()->Constant(NONE); | 984 Node* attr = jsgraph()->Constant(NONE); | 
| 963 const Operator* op = | 985 const Operator* op = javascript()->CallRuntime( | 
| 964 javascript()->Runtime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 986 CallRuntimeParameters(Runtime::kDefineAccessorPropertyUnchecked, 5)); | 
| 965 Node* call = NewNode(op, literal, name, getter, setter, attr); | 987 Node* call = NewNode(op, literal, name, getter, setter, attr); | 
| 966 PrepareFrameState(call, it->first->id()); | 988 PrepareFrameState(call, it->first->id()); | 
| 967 } | 989 } | 
| 968 | 990 | 
| 969 // Transform literals that contain functions to fast properties. | 991 // Transform literals that contain functions to fast properties. | 
| 970 if (expr->has_function()) { | 992 if (expr->has_function()) { | 
| 971 const Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1); | 993 const Operator* op = javascript()->CallRuntime( | 
| 994 CallRuntimeParameters(Runtime::kToFastProperties, 1)); | |
| 972 NewNode(op, literal); | 995 NewNode(op, literal); | 
| 973 } | 996 } | 
| 974 | 997 | 
| 975 ast_context()->ProduceValue(environment()->Pop()); | 998 ast_context()->ProduceValue(environment()->Pop()); | 
| 976 } | 999 } | 
| 977 | 1000 | 
| 978 | 1001 | 
| 979 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 1002 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 
| 980 Node* closure = GetFunctionClosure(); | 1003 Node* closure = GetFunctionClosure(); | 
| 981 | 1004 | 
| 982 // Create node to deep-copy the literal boilerplate. | 1005 // Create node to deep-copy the literal boilerplate. | 
| 983 expr->BuildConstantElements(isolate()); | 1006 expr->BuildConstantElements(isolate()); | 
| 984 Node* literals_array = | 1007 Node* literals_array = | 
| 985 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 1008 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 
| 986 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 1009 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 
| 987 Node* constants = jsgraph()->Constant(expr->constant_elements()); | 1010 Node* constants = jsgraph()->Constant(expr->constant_elements()); | 
| 988 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); | 1011 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); | 
| 989 const Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4); | 1012 const Operator* op = javascript()->CallRuntime( | 
| 1013 CallRuntimeParameters(Runtime::kCreateArrayLiteral, 4)); | |
| 990 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); | 1014 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); | 
| 991 | 1015 | 
| 992 // The array and the literal index are both expected on the operand stack | 1016 // The array and the literal index are both expected on the operand stack | 
| 993 // during computation of the element values. | 1017 // during computation of the element values. | 
| 994 environment()->Push(literal); | 1018 environment()->Push(literal); | 
| 995 environment()->Push(literal_index); | 1019 environment()->Push(literal_index); | 
| 996 | 1020 | 
| 997 // Create nodes to evaluate all the non-constant subexpressions and to store | 1021 // Create nodes to evaluate all the non-constant subexpressions and to store | 
| 998 // them into the newly cloned array. | 1022 // them into the newly cloned array. | 
| 999 for (int i = 0; i < expr->values()->length(); i++) { | 1023 for (int i = 0; i < expr->values()->length(); i++) { | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1028 BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None()); | 1052 BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None()); | 
| 1029 break; | 1053 break; | 
| 1030 } | 1054 } | 
| 1031 case NAMED_PROPERTY: { | 1055 case NAMED_PROPERTY: { | 
| 1032 environment()->Push(value); | 1056 environment()->Push(value); | 
| 1033 VisitForValue(property->obj()); | 1057 VisitForValue(property->obj()); | 
| 1034 Node* object = environment()->Pop(); | 1058 Node* object = environment()->Pop(); | 
| 1035 value = environment()->Pop(); | 1059 value = environment()->Pop(); | 
| 1036 Unique<Name> name = | 1060 Unique<Name> name = | 
| 1037 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1061 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 
| 1038 Node* store = | 1062 Node* store = NewNode( | 
| 1039 NewNode(javascript()->StoreNamed(strict_mode(), name), object, value); | 1063 javascript()->StoreNamed(StoreNamedParameters(strict_mode(), name)), | 
| 1064 object, value); | |
| 1040 // TODO(jarin) Fill in the correct bailout id. | 1065 // TODO(jarin) Fill in the correct bailout id. | 
| 1041 PrepareFrameState(store, BailoutId::None()); | 1066 PrepareFrameState(store, BailoutId::None()); | 
| 1042 break; | 1067 break; | 
| 1043 } | 1068 } | 
| 1044 case KEYED_PROPERTY: { | 1069 case KEYED_PROPERTY: { | 
| 1045 environment()->Push(value); | 1070 environment()->Push(value); | 
| 1046 VisitForValue(property->obj()); | 1071 VisitForValue(property->obj()); | 
| 1047 VisitForValue(property->key()); | 1072 VisitForValue(property->key()); | 
| 1048 Node* key = environment()->Pop(); | 1073 Node* key = environment()->Pop(); | 
| 1049 Node* object = environment()->Pop(); | 1074 Node* object = environment()->Pop(); | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1087 switch (assign_type) { | 1112 switch (assign_type) { | 
| 1088 case VARIABLE: { | 1113 case VARIABLE: { | 
| 1089 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1114 Variable* variable = expr->target()->AsVariableProxy()->var(); | 
| 1090 old_value = BuildVariableLoad(variable, expr->target()->id()); | 1115 old_value = BuildVariableLoad(variable, expr->target()->id()); | 
| 1091 break; | 1116 break; | 
| 1092 } | 1117 } | 
| 1093 case NAMED_PROPERTY: { | 1118 case NAMED_PROPERTY: { | 
| 1094 Node* object = environment()->Top(); | 1119 Node* object = environment()->Top(); | 
| 1095 Unique<Name> name = | 1120 Unique<Name> name = | 
| 1096 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1121 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 
| 1097 old_value = NewNode(javascript()->LoadNamed(name), object); | 1122 old_value = | 
| 1123 NewNode(javascript()->LoadNamed(LoadNamedParameters(name)), object); | |
| 1098 PrepareFrameState(old_value, property->LoadId(), kPushOutput); | 1124 PrepareFrameState(old_value, property->LoadId(), kPushOutput); | 
| 1099 break; | 1125 break; | 
| 1100 } | 1126 } | 
| 1101 case KEYED_PROPERTY: { | 1127 case KEYED_PROPERTY: { | 
| 1102 Node* key = environment()->Top(); | 1128 Node* key = environment()->Top(); | 
| 1103 Node* object = environment()->Peek(1); | 1129 Node* object = environment()->Peek(1); | 
| 1104 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1130 old_value = NewNode(javascript()->LoadProperty(), object, key); | 
| 1105 PrepareFrameState(old_value, property->LoadId(), kPushOutput); | 1131 PrepareFrameState(old_value, property->LoadId(), kPushOutput); | 
| 1106 break; | 1132 break; | 
| 1107 } | 1133 } | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1123 case VARIABLE: { | 1149 case VARIABLE: { | 
| 1124 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1150 Variable* variable = expr->target()->AsVariableProxy()->var(); | 
| 1125 BuildVariableAssignment(variable, value, expr->op(), | 1151 BuildVariableAssignment(variable, value, expr->op(), | 
| 1126 expr->AssignmentId()); | 1152 expr->AssignmentId()); | 
| 1127 break; | 1153 break; | 
| 1128 } | 1154 } | 
| 1129 case NAMED_PROPERTY: { | 1155 case NAMED_PROPERTY: { | 
| 1130 Node* object = environment()->Pop(); | 1156 Node* object = environment()->Pop(); | 
| 1131 Unique<Name> name = | 1157 Unique<Name> name = | 
| 1132 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1158 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 
| 1133 Node* store = | 1159 Node* store = NewNode( | 
| 1134 NewNode(javascript()->StoreNamed(strict_mode(), name), object, value); | 1160 javascript()->StoreNamed(StoreNamedParameters(strict_mode(), name)), | 
| 1161 object, value); | |
| 1135 PrepareFrameState(store, expr->AssignmentId()); | 1162 PrepareFrameState(store, expr->AssignmentId()); | 
| 1136 break; | 1163 break; | 
| 1137 } | 1164 } | 
| 1138 case KEYED_PROPERTY: { | 1165 case KEYED_PROPERTY: { | 
| 1139 Node* key = environment()->Pop(); | 1166 Node* key = environment()->Pop(); | 
| 1140 Node* object = environment()->Pop(); | 1167 Node* object = environment()->Pop(); | 
| 1141 Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object, | 1168 Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object, | 
| 1142 key, value); | 1169 key, value); | 
| 1143 PrepareFrameState(store, expr->AssignmentId()); | 1170 PrepareFrameState(store, expr->AssignmentId()); | 
| 1144 break; | 1171 break; | 
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1155 environment()->Pop(); | 1182 environment()->Pop(); | 
| 1156 environment()->Pop(); | 1183 environment()->Pop(); | 
| 1157 // TODO(turbofan): VisitYield | 1184 // TODO(turbofan): VisitYield | 
| 1158 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 1185 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 
| 1159 } | 1186 } | 
| 1160 | 1187 | 
| 1161 | 1188 | 
| 1162 void AstGraphBuilder::VisitThrow(Throw* expr) { | 1189 void AstGraphBuilder::VisitThrow(Throw* expr) { | 
| 1163 VisitForValue(expr->exception()); | 1190 VisitForValue(expr->exception()); | 
| 1164 Node* exception = environment()->Pop(); | 1191 Node* exception = environment()->Pop(); | 
| 1165 const Operator* op = javascript()->Runtime(Runtime::kThrow, 1); | 1192 const Operator* op = | 
| 1193 javascript()->CallRuntime(CallRuntimeParameters(Runtime::kThrow, 1)); | |
| 1166 Node* value = NewNode(op, exception); | 1194 Node* value = NewNode(op, exception); | 
| 1167 ast_context()->ProduceValue(value); | 1195 ast_context()->ProduceValue(value); | 
| 1168 } | 1196 } | 
| 1169 | 1197 | 
| 1170 | 1198 | 
| 1171 void AstGraphBuilder::VisitProperty(Property* expr) { | 1199 void AstGraphBuilder::VisitProperty(Property* expr) { | 
| 1172 Node* value; | 1200 Node* value; | 
| 1173 if (expr->key()->IsPropertyName()) { | 1201 if (expr->key()->IsPropertyName()) { | 
| 1174 VisitForValue(expr->obj()); | 1202 VisitForValue(expr->obj()); | 
| 1175 Node* object = environment()->Pop(); | 1203 Node* object = environment()->Pop(); | 
| 1176 Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); | 1204 Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); | 
| 1177 value = NewNode(javascript()->LoadNamed(name), object); | 1205 value = NewNode(javascript()->LoadNamed(LoadNamedParameters(name)), object); | 
| 1178 } else { | 1206 } else { | 
| 1179 VisitForValue(expr->obj()); | 1207 VisitForValue(expr->obj()); | 
| 1180 VisitForValue(expr->key()); | 1208 VisitForValue(expr->key()); | 
| 1181 Node* key = environment()->Pop(); | 1209 Node* key = environment()->Pop(); | 
| 1182 Node* object = environment()->Pop(); | 1210 Node* object = environment()->Pop(); | 
| 1183 value = NewNode(javascript()->LoadProperty(), object, key); | 1211 value = NewNode(javascript()->LoadProperty(), object, key); | 
| 1184 } | 1212 } | 
| 1185 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 1213 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 1186 ast_context()->ProduceValue(value); | 1214 ast_context()->ProduceValue(value); | 
| 1187 } | 1215 } | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1201 case Call::GLOBAL_CALL: { | 1229 case Call::GLOBAL_CALL: { | 
| 1202 Variable* variable = callee->AsVariableProxy()->var(); | 1230 Variable* variable = callee->AsVariableProxy()->var(); | 
| 1203 callee_value = BuildVariableLoad(variable, expr->expression()->id()); | 1231 callee_value = BuildVariableLoad(variable, expr->expression()->id()); | 
| 1204 receiver_value = jsgraph()->UndefinedConstant(); | 1232 receiver_value = jsgraph()->UndefinedConstant(); | 
| 1205 break; | 1233 break; | 
| 1206 } | 1234 } | 
| 1207 case Call::LOOKUP_SLOT_CALL: { | 1235 case Call::LOOKUP_SLOT_CALL: { | 
| 1208 Variable* variable = callee->AsVariableProxy()->var(); | 1236 Variable* variable = callee->AsVariableProxy()->var(); | 
| 1209 DCHECK(variable->location() == Variable::LOOKUP); | 1237 DCHECK(variable->location() == Variable::LOOKUP); | 
| 1210 Node* name = jsgraph()->Constant(variable->name()); | 1238 Node* name = jsgraph()->Constant(variable->name()); | 
| 1211 const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2); | 1239 const Operator* op = javascript()->CallRuntime( | 
| 1240 CallRuntimeParameters(Runtime::kLoadLookupSlot, 2)); | |
| 1212 Node* pair = NewNode(op, current_context(), name); | 1241 Node* pair = NewNode(op, current_context(), name); | 
| 1213 callee_value = NewNode(common()->Projection(0), pair); | 1242 callee_value = NewNode(common()->Projection(0), pair); | 
| 1214 receiver_value = NewNode(common()->Projection(1), pair); | 1243 receiver_value = NewNode(common()->Projection(1), pair); | 
| 1215 break; | 1244 break; | 
| 1216 } | 1245 } | 
| 1217 case Call::PROPERTY_CALL: { | 1246 case Call::PROPERTY_CALL: { | 
| 1218 Property* property = callee->AsProperty(); | 1247 Property* property = callee->AsProperty(); | 
| 1219 VisitForValue(property->obj()); | 1248 VisitForValue(property->obj()); | 
| 1220 Node* object = environment()->Top(); | 1249 Node* object = environment()->Top(); | 
| 1221 if (property->key()->IsPropertyName()) { | 1250 if (property->key()->IsPropertyName()) { | 
| 1222 Unique<Name> name = | 1251 Unique<Name> name = | 
| 1223 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1252 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 
| 1224 callee_value = NewNode(javascript()->LoadNamed(name), object); | 1253 callee_value = | 
| 1254 NewNode(javascript()->LoadNamed(LoadNamedParameters(name)), object); | |
| 1225 } else { | 1255 } else { | 
| 1226 VisitForValue(property->key()); | 1256 VisitForValue(property->key()); | 
| 1227 Node* key = environment()->Pop(); | 1257 Node* key = environment()->Pop(); | 
| 1228 callee_value = NewNode(javascript()->LoadProperty(), object, key); | 1258 callee_value = NewNode(javascript()->LoadProperty(), object, key); | 
| 1229 } | 1259 } | 
| 1230 PrepareFrameState(callee_value, property->LoadId(), kPushOutput); | 1260 PrepareFrameState(callee_value, property->LoadId(), kPushOutput); | 
| 1231 receiver_value = environment()->Pop(); | 1261 receiver_value = environment()->Pop(); | 
| 1232 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 1262 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 
| 1233 // object for sloppy callees. This could also be modeled explicitly here, | 1263 // object for sloppy callees. This could also be modeled explicitly here, | 
| 1234 // thereby obsoleting the need for a flag to the call operator. | 1264 // thereby obsoleting the need for a flag to the call operator. | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1261 | 1291 | 
| 1262 // Extract callee and source string from the environment. | 1292 // Extract callee and source string from the environment. | 
| 1263 Node* callee = environment()->Peek(arg_count + 1); | 1293 Node* callee = environment()->Peek(arg_count + 1); | 
| 1264 Node* source = environment()->Peek(arg_count - 1); | 1294 Node* source = environment()->Peek(arg_count - 1); | 
| 1265 | 1295 | 
| 1266 // Create node to ask for help resolving potential eval call. This will | 1296 // Create node to ask for help resolving potential eval call. This will | 
| 1267 // provide a fully resolved callee and the corresponding receiver. | 1297 // provide a fully resolved callee and the corresponding receiver. | 
| 1268 Node* receiver = environment()->Lookup(info()->scope()->receiver()); | 1298 Node* receiver = environment()->Lookup(info()->scope()->receiver()); | 
| 1269 Node* strict = jsgraph()->Constant(strict_mode()); | 1299 Node* strict = jsgraph()->Constant(strict_mode()); | 
| 1270 Node* position = jsgraph()->Constant(info()->scope()->start_position()); | 1300 Node* position = jsgraph()->Constant(info()->scope()->start_position()); | 
| 1271 const Operator* op = | 1301 const Operator* op = javascript()->CallRuntime( | 
| 1272 javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 5); | 1302 CallRuntimeParameters(Runtime::kResolvePossiblyDirectEval, 5)); | 
| 1273 Node* pair = NewNode(op, callee, source, receiver, strict, position); | 1303 Node* pair = NewNode(op, callee, source, receiver, strict, position); | 
| 1274 Node* new_callee = NewNode(common()->Projection(0), pair); | 1304 Node* new_callee = NewNode(common()->Projection(0), pair); | 
| 1275 Node* new_receiver = NewNode(common()->Projection(1), pair); | 1305 Node* new_receiver = NewNode(common()->Projection(1), pair); | 
| 1276 | 1306 | 
| 1277 // Patch callee and receiver on the environment. | 1307 // Patch callee and receiver on the environment. | 
| 1278 environment()->Poke(arg_count + 1, new_callee); | 1308 environment()->Poke(arg_count + 1, new_callee); | 
| 1279 environment()->Poke(arg_count + 0, new_receiver); | 1309 environment()->Poke(arg_count + 0, new_receiver); | 
| 1280 } | 1310 } | 
| 1281 | 1311 | 
| 1282 // Create node to perform the function call. | 1312 // Create node to perform the function call. | 
| 1283 const Operator* call = javascript()->Call(args->length() + 2, flags); | 1313 const Operator* call = javascript()->CallFunction( | 
| 1314 CallFunctionParameters(args->length() + 2, flags)); | |
| 1284 Node* value = ProcessArguments(call, args->length() + 2); | 1315 Node* value = ProcessArguments(call, args->length() + 2); | 
| 1285 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 1316 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 1286 ast_context()->ProduceValue(value); | 1317 ast_context()->ProduceValue(value); | 
| 1287 } | 1318 } | 
| 1288 | 1319 | 
| 1289 | 1320 | 
| 1290 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 1321 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 
| 1291 VisitForValue(expr->expression()); | 1322 VisitForValue(expr->expression()); | 
| 1292 | 1323 | 
| 1293 // Evaluate all arguments to the construct call. | 1324 // Evaluate all arguments to the construct call. | 
| 1294 ZoneList<Expression*>* args = expr->arguments(); | 1325 ZoneList<Expression*>* args = expr->arguments(); | 
| 1295 VisitForValues(args); | 1326 VisitForValues(args); | 
| 1296 | 1327 | 
| 1297 // Create node to perform the construct call. | 1328 // Create node to perform the construct call. | 
| 1298 const Operator* call = javascript()->CallNew(args->length() + 1); | 1329 const Operator* call = javascript()->CallConstruct(args->length() + 1); | 
| 1299 Node* value = ProcessArguments(call, args->length() + 1); | 1330 Node* value = ProcessArguments(call, args->length() + 1); | 
| 1300 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 1331 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 1301 ast_context()->ProduceValue(value); | 1332 ast_context()->ProduceValue(value); | 
| 1302 } | 1333 } | 
| 1303 | 1334 | 
| 1304 | 1335 | 
| 1305 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 1336 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 
| 1306 Handle<String> name = expr->name(); | 1337 Handle<String> name = expr->name(); | 
| 1307 | 1338 | 
| 1308 // The callee and the receiver both have to be pushed onto the operand stack | 1339 // The callee and the receiver both have to be pushed onto the operand stack | 
| 1309 // before arguments are being evaluated. | 1340 // before arguments are being evaluated. | 
| 1310 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1341 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 
| 1311 Node* receiver_value = BuildLoadBuiltinsObject(); | 1342 Node* receiver_value = BuildLoadBuiltinsObject(); | 
| 1312 Unique<String> unique = MakeUnique(name); | 1343 Unique<String> unique = MakeUnique(name); | 
| 1313 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); | 1344 Node* callee_value = NewNode( | 
| 1345 javascript()->LoadNamed(LoadNamedParameters(unique)), receiver_value); | |
| 1314 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft | 1346 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft | 
| 1315 // refuses to optimize functions with jsruntime calls). | 1347 // refuses to optimize functions with jsruntime calls). | 
| 1316 PrepareFrameState(callee_value, BailoutId::None(), kPushOutput); | 1348 PrepareFrameState(callee_value, BailoutId::None(), kPushOutput); | 
| 1317 environment()->Push(callee_value); | 1349 environment()->Push(callee_value); | 
| 1318 environment()->Push(receiver_value); | 1350 environment()->Push(receiver_value); | 
| 1319 | 1351 | 
| 1320 // Evaluate all arguments to the JS runtime call. | 1352 // Evaluate all arguments to the JS runtime call. | 
| 1321 ZoneList<Expression*>* args = expr->arguments(); | 1353 ZoneList<Expression*>* args = expr->arguments(); | 
| 1322 VisitForValues(args); | 1354 VisitForValues(args); | 
| 1323 | 1355 | 
| 1324 // Create node to perform the JS runtime call. | 1356 // Create node to perform the JS runtime call. | 
| 1325 const Operator* call = javascript()->Call(args->length() + 2, flags); | 1357 const Operator* call = javascript()->CallFunction( | 
| 1358 CallFunctionParameters(args->length() + 2, flags)); | |
| 1326 Node* value = ProcessArguments(call, args->length() + 2); | 1359 Node* value = ProcessArguments(call, args->length() + 2); | 
| 1327 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 1360 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 1328 ast_context()->ProduceValue(value); | 1361 ast_context()->ProduceValue(value); | 
| 1329 } | 1362 } | 
| 1330 | 1363 | 
| 1331 | 1364 | 
| 1332 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 1365 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 
| 1333 const Runtime::Function* function = expr->function(); | 1366 const Runtime::Function* function = expr->function(); | 
| 1334 | 1367 | 
| 1335 // Handle calls to runtime functions implemented in JavaScript separately as | 1368 // Handle calls to runtime functions implemented in JavaScript separately as | 
| 1336 // the call follows JavaScript ABI and the callee is statically unknown. | 1369 // the call follows JavaScript ABI and the callee is statically unknown. | 
| 1337 if (expr->is_jsruntime()) { | 1370 if (expr->is_jsruntime()) { | 
| 1338 DCHECK(function == NULL && expr->name()->length() > 0); | 1371 DCHECK(function == NULL && expr->name()->length() > 0); | 
| 1339 return VisitCallJSRuntime(expr); | 1372 return VisitCallJSRuntime(expr); | 
| 1340 } | 1373 } | 
| 1341 | 1374 | 
| 1342 // Evaluate all arguments to the runtime call. | 1375 // Evaluate all arguments to the runtime call. | 
| 1343 ZoneList<Expression*>* args = expr->arguments(); | 1376 ZoneList<Expression*>* args = expr->arguments(); | 
| 1344 VisitForValues(args); | 1377 VisitForValues(args); | 
| 1345 | 1378 | 
| 1346 // Create node to perform the runtime call. | 1379 // Create node to perform the runtime call. | 
| 1347 Runtime::FunctionId functionId = function->function_id; | 1380 Runtime::FunctionId functionId = function->function_id; | 
| 1348 const Operator* call = javascript()->Runtime(functionId, args->length()); | 1381 const Operator* call = javascript()->CallRuntime( | 
| 1382 CallRuntimeParameters(functionId, args->length())); | |
| 1349 Node* value = ProcessArguments(call, args->length()); | 1383 Node* value = ProcessArguments(call, args->length()); | 
| 1350 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 1384 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 1351 ast_context()->ProduceValue(value); | 1385 ast_context()->ProduceValue(value); | 
| 1352 } | 1386 } | 
| 1353 | 1387 | 
| 1354 | 1388 | 
| 1355 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 1389 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 
| 1356 switch (expr->op()) { | 1390 switch (expr->op()) { | 
| 1357 case Token::DELETE: | 1391 case Token::DELETE: | 
| 1358 return VisitDelete(expr); | 1392 return VisitDelete(expr); | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1387 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 1421 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 
| 1388 old_value = BuildVariableLoad(variable, expr->expression()->id()); | 1422 old_value = BuildVariableLoad(variable, expr->expression()->id()); | 
| 1389 stack_depth = 0; | 1423 stack_depth = 0; | 
| 1390 break; | 1424 break; | 
| 1391 } | 1425 } | 
| 1392 case NAMED_PROPERTY: { | 1426 case NAMED_PROPERTY: { | 
| 1393 VisitForValue(property->obj()); | 1427 VisitForValue(property->obj()); | 
| 1394 Node* object = environment()->Top(); | 1428 Node* object = environment()->Top(); | 
| 1395 Unique<Name> name = | 1429 Unique<Name> name = | 
| 1396 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1430 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 
| 1397 old_value = NewNode(javascript()->LoadNamed(name), object); | 1431 old_value = | 
| 1432 NewNode(javascript()->LoadNamed(LoadNamedParameters(name)), object); | |
| 1398 PrepareFrameState(old_value, property->LoadId(), kPushOutput); | 1433 PrepareFrameState(old_value, property->LoadId(), kPushOutput); | 
| 1399 stack_depth = 1; | 1434 stack_depth = 1; | 
| 1400 break; | 1435 break; | 
| 1401 } | 1436 } | 
| 1402 case KEYED_PROPERTY: { | 1437 case KEYED_PROPERTY: { | 
| 1403 VisitForValue(property->obj()); | 1438 VisitForValue(property->obj()); | 
| 1404 VisitForValue(property->key()); | 1439 VisitForValue(property->key()); | 
| 1405 Node* key = environment()->Top(); | 1440 Node* key = environment()->Top(); | 
| 1406 Node* object = environment()->Peek(1); | 1441 Node* object = environment()->Peek(1); | 
| 1407 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1442 old_value = NewNode(javascript()->LoadProperty(), object, key); | 
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1431 environment()->Push(value); | 1466 environment()->Push(value); | 
| 1432 BuildVariableAssignment(variable, value, expr->op(), | 1467 BuildVariableAssignment(variable, value, expr->op(), | 
| 1433 expr->AssignmentId()); | 1468 expr->AssignmentId()); | 
| 1434 environment()->Pop(); | 1469 environment()->Pop(); | 
| 1435 break; | 1470 break; | 
| 1436 } | 1471 } | 
| 1437 case NAMED_PROPERTY: { | 1472 case NAMED_PROPERTY: { | 
| 1438 Node* object = environment()->Pop(); | 1473 Node* object = environment()->Pop(); | 
| 1439 Unique<Name> name = | 1474 Unique<Name> name = | 
| 1440 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1475 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 
| 1441 Node* store = | 1476 Node* store = NewNode( | 
| 1442 NewNode(javascript()->StoreNamed(strict_mode(), name), object, value); | 1477 javascript()->StoreNamed(StoreNamedParameters(strict_mode(), name)), | 
| 1478 object, value); | |
| 1443 environment()->Push(value); | 1479 environment()->Push(value); | 
| 1444 PrepareFrameState(store, expr->AssignmentId()); | 1480 PrepareFrameState(store, expr->AssignmentId()); | 
| 1445 environment()->Pop(); | 1481 environment()->Pop(); | 
| 1446 break; | 1482 break; | 
| 1447 } | 1483 } | 
| 1448 case KEYED_PROPERTY: { | 1484 case KEYED_PROPERTY: { | 
| 1449 Node* key = environment()->Pop(); | 1485 Node* key = environment()->Pop(); | 
| 1450 Node* object = environment()->Pop(); | 1486 Node* object = environment()->Pop(); | 
| 1451 Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object, | 1487 Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object, | 
| 1452 key, value); | 1488 key, value); | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1550 AstVisitor::VisitDeclarations(declarations); | 1586 AstVisitor::VisitDeclarations(declarations); | 
| 1551 if (globals()->is_empty()) return; | 1587 if (globals()->is_empty()) return; | 
| 1552 Handle<FixedArray> data = | 1588 Handle<FixedArray> data = | 
| 1553 isolate()->factory()->NewFixedArray(globals()->length(), TENURED); | 1589 isolate()->factory()->NewFixedArray(globals()->length(), TENURED); | 
| 1554 for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i)); | 1590 for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i)); | 
| 1555 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 1591 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 
| 1556 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 1592 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 
| 1557 DeclareGlobalsStrictMode::encode(strict_mode()); | 1593 DeclareGlobalsStrictMode::encode(strict_mode()); | 
| 1558 Node* flags = jsgraph()->Constant(encoded_flags); | 1594 Node* flags = jsgraph()->Constant(encoded_flags); | 
| 1559 Node* pairs = jsgraph()->Constant(data); | 1595 Node* pairs = jsgraph()->Constant(data); | 
| 1560 const Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3); | 1596 const Operator* op = javascript()->CallRuntime( | 
| 1597 CallRuntimeParameters(Runtime::kDeclareGlobals, 3)); | |
| 1561 NewNode(op, current_context(), pairs, flags); | 1598 NewNode(op, current_context(), pairs, flags); | 
| 1562 globals()->Rewind(0); | 1599 globals()->Rewind(0); | 
| 1563 } | 1600 } | 
| 1564 | 1601 | 
| 1565 | 1602 | 
| 1566 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { | 1603 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { | 
| 1567 if (stmt == NULL) return; | 1604 if (stmt == NULL) return; | 
| 1568 Visit(stmt); | 1605 Visit(stmt); | 
| 1569 } | 1606 } | 
| 1570 | 1607 | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1657 environment()->Pop(); | 1694 environment()->Pop(); | 
| 1658 Visit(expr->right()); | 1695 Visit(expr->right()); | 
| 1659 } else if (ast_context()->IsEffect()) { | 1696 } else if (ast_context()->IsEffect()) { | 
| 1660 environment()->Pop(); | 1697 environment()->Pop(); | 
| 1661 } | 1698 } | 
| 1662 compare_if.End(); | 1699 compare_if.End(); | 
| 1663 ast_context()->ReplaceValue(); | 1700 ast_context()->ReplaceValue(); | 
| 1664 } | 1701 } | 
| 1665 | 1702 | 
| 1666 | 1703 | 
| 1704 StrictMode AstGraphBuilder::strict_mode() const { | |
| 1705 return info()->strict_mode(); | |
| 1706 } | |
| 1707 | |
| 1708 | |
| 1667 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) { | 1709 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) { | 
| 1668 DCHECK(environment()->stack_height() >= arity); | 1710 DCHECK(environment()->stack_height() >= arity); | 
| 1669 Node** all = info()->zone()->NewArray<Node*>(arity); | 1711 Node** all = info()->zone()->NewArray<Node*>(arity); | 
| 1670 for (int i = arity - 1; i >= 0; --i) { | 1712 for (int i = arity - 1; i >= 0; --i) { | 
| 1671 all[i] = environment()->Pop(); | 1713 all[i] = environment()->Pop(); | 
| 1672 } | 1714 } | 
| 1673 Node* value = NewNode(op, arity, all); | 1715 Node* value = NewNode(op, arity, all); | 
| 1674 return value; | 1716 return value; | 
| 1675 } | 1717 } | 
| 1676 | 1718 | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1688 // Copy parameters into context if necessary. | 1730 // Copy parameters into context if necessary. | 
| 1689 int num_parameters = info()->scope()->num_parameters(); | 1731 int num_parameters = info()->scope()->num_parameters(); | 
| 1690 for (int i = 0; i < num_parameters; i++) { | 1732 for (int i = 0; i < num_parameters; i++) { | 
| 1691 Variable* variable = info()->scope()->parameter(i); | 1733 Variable* variable = info()->scope()->parameter(i); | 
| 1692 if (!variable->IsContextSlot()) continue; | 1734 if (!variable->IsContextSlot()) continue; | 
| 1693 // Temporary parameter node. The parameter indices are shifted by 1 | 1735 // Temporary parameter node. The parameter indices are shifted by 1 | 
| 1694 // (receiver is parameter index -1 but environment index 0). | 1736 // (receiver is parameter index -1 but environment index 0). | 
| 1695 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | 1737 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | 
| 1696 // Context variable (at bottom of the context chain). | 1738 // Context variable (at bottom of the context chain). | 
| 1697 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 1739 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 
| 1698 const Operator* op = javascript()->StoreContext(0, variable->index()); | 1740 const Operator* op = | 
| 1741 javascript()->StoreContext(ContextAccess(0, variable->index())); | |
| 1699 NewNode(op, local_context, parameter); | 1742 NewNode(op, local_context, parameter); | 
| 1700 } | 1743 } | 
| 1701 | 1744 | 
| 1702 return local_context; | 1745 return local_context; | 
| 1703 } | 1746 } | 
| 1704 | 1747 | 
| 1705 | 1748 | 
| 1706 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { | 1749 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { | 
| 1707 if (arguments == NULL) return NULL; | 1750 if (arguments == NULL) return NULL; | 
| 1708 | 1751 | 
| 1709 // Allocate and initialize a new arguments object. | 1752 // Allocate and initialize a new arguments object. | 
| 1710 Node* callee = GetFunctionClosure(); | 1753 Node* callee = GetFunctionClosure(); | 
| 1711 const Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1); | 1754 const Operator* op = javascript()->CallRuntime( | 
| 1755 CallRuntimeParameters(Runtime::kNewArguments, 1)); | |
| 1712 Node* object = NewNode(op, callee); | 1756 Node* object = NewNode(op, callee); | 
| 1713 | 1757 | 
| 1714 // Assign the object to the arguments variable. | 1758 // Assign the object to the arguments variable. | 
| 1715 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 1759 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 
| 1716 // This should never lazy deopt, so it is fine to send invalid bailout id. | 1760 // This should never lazy deopt, so it is fine to send invalid bailout id. | 
| 1717 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None()); | 1761 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None()); | 
| 1718 | 1762 | 
| 1719 return object; | 1763 return object; | 
| 1720 } | 1764 } | 
| 1721 | 1765 | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1753 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 1797 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 
| 1754 BailoutId bailout_id, | 1798 BailoutId bailout_id, | 
| 1755 ContextualMode contextual_mode) { | 1799 ContextualMode contextual_mode) { | 
| 1756 Node* the_hole = jsgraph()->TheHoleConstant(); | 1800 Node* the_hole = jsgraph()->TheHoleConstant(); | 
| 1757 VariableMode mode = variable->mode(); | 1801 VariableMode mode = variable->mode(); | 
| 1758 switch (variable->location()) { | 1802 switch (variable->location()) { | 
| 1759 case Variable::UNALLOCATED: { | 1803 case Variable::UNALLOCATED: { | 
| 1760 // Global var, const, or let variable. | 1804 // Global var, const, or let variable. | 
| 1761 Node* global = BuildLoadGlobalObject(); | 1805 Node* global = BuildLoadGlobalObject(); | 
| 1762 Unique<Name> name = MakeUnique(variable->name()); | 1806 Unique<Name> name = MakeUnique(variable->name()); | 
| 1763 const Operator* op = javascript()->LoadNamed(name, contextual_mode); | 1807 const Operator* op = | 
| 1808 javascript()->LoadNamed(LoadNamedParameters(name, contextual_mode)); | |
| 1764 Node* node = NewNode(op, global); | 1809 Node* node = NewNode(op, global); | 
| 1765 PrepareFrameState(node, bailout_id, kPushOutput); | 1810 PrepareFrameState(node, bailout_id, kPushOutput); | 
| 1766 return node; | 1811 return node; | 
| 1767 } | 1812 } | 
| 1768 case Variable::PARAMETER: | 1813 case Variable::PARAMETER: | 
| 1769 case Variable::LOCAL: { | 1814 case Variable::LOCAL: { | 
| 1770 // Local var, const, or let variable. | 1815 // Local var, const, or let variable. | 
| 1771 Node* value = environment()->Lookup(variable); | 1816 Node* value = environment()->Lookup(variable); | 
| 1772 if (mode == CONST_LEGACY) { | 1817 if (mode == CONST_LEGACY) { | 
| 1773 // Perform check for uninitialized legacy const variables. | 1818 // Perform check for uninitialized legacy const variables. | 
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1784 } else if (value->opcode() == IrOpcode::kPhi) { | 1829 } else if (value->opcode() == IrOpcode::kPhi) { | 
| 1785 value = BuildHoleCheckThrow(value, variable, value); | 1830 value = BuildHoleCheckThrow(value, variable, value); | 
| 1786 } | 1831 } | 
| 1787 } | 1832 } | 
| 1788 return value; | 1833 return value; | 
| 1789 } | 1834 } | 
| 1790 case Variable::CONTEXT: { | 1835 case Variable::CONTEXT: { | 
| 1791 // Context variable (potentially up the context chain). | 1836 // Context variable (potentially up the context chain). | 
| 1792 int depth = current_scope()->ContextChainLength(variable->scope()); | 1837 int depth = current_scope()->ContextChainLength(variable->scope()); | 
| 1793 bool immutable = variable->maybe_assigned() == kNotAssigned; | 1838 bool immutable = variable->maybe_assigned() == kNotAssigned; | 
| 1794 const Operator* op = | 1839 const Operator* op = javascript()->LoadContext( | 
| 1795 javascript()->LoadContext(depth, variable->index(), immutable); | 1840 ContextAccess(depth, variable->index(), immutable)); | 
| 1796 Node* value = NewNode(op, current_context()); | 1841 Node* value = NewNode(op, current_context()); | 
| 1797 // TODO(titzer): initialization checks are redundant for already | 1842 // TODO(titzer): initialization checks are redundant for already | 
| 1798 // initialized immutable context loads, but only specialization knows. | 1843 // initialized immutable context loads, but only specialization knows. | 
| 1799 // Maybe specializer should be a parameter to the graph builder? | 1844 // Maybe specializer should be a parameter to the graph builder? | 
| 1800 if (mode == CONST_LEGACY) { | 1845 if (mode == CONST_LEGACY) { | 
| 1801 // Perform check for uninitialized legacy const variables. | 1846 // Perform check for uninitialized legacy const variables. | 
| 1802 Node* undefined = jsgraph()->UndefinedConstant(); | 1847 Node* undefined = jsgraph()->UndefinedConstant(); | 
| 1803 value = BuildHoleCheckSilent(value, undefined, value); | 1848 value = BuildHoleCheckSilent(value, undefined, value); | 
| 1804 } else if (mode == LET || mode == CONST) { | 1849 } else if (mode == LET || mode == CONST) { | 
| 1805 // Perform check for uninitialized let/const variables. | 1850 // Perform check for uninitialized let/const variables. | 
| 1806 value = BuildHoleCheckThrow(value, variable, value); | 1851 value = BuildHoleCheckThrow(value, variable, value); | 
| 1807 } | 1852 } | 
| 1808 return value; | 1853 return value; | 
| 1809 } | 1854 } | 
| 1810 case Variable::LOOKUP: { | 1855 case Variable::LOOKUP: { | 
| 1811 // Dynamic lookup of context variable (anywhere in the chain). | 1856 // Dynamic lookup of context variable (anywhere in the chain). | 
| 1812 Node* name = jsgraph()->Constant(variable->name()); | 1857 Node* name = jsgraph()->Constant(variable->name()); | 
| 1813 Runtime::FunctionId function_id = | 1858 Runtime::FunctionId function_id = | 
| 1814 (contextual_mode == CONTEXTUAL) | 1859 (contextual_mode == CONTEXTUAL) | 
| 1815 ? Runtime::kLoadLookupSlot | 1860 ? Runtime::kLoadLookupSlot | 
| 1816 : Runtime::kLoadLookupSlotNoReferenceError; | 1861 : Runtime::kLoadLookupSlotNoReferenceError; | 
| 1817 const Operator* op = javascript()->Runtime(function_id, 2); | 1862 const Operator* op = | 
| 1863 javascript()->CallRuntime(CallRuntimeParameters(function_id, 2)); | |
| 1818 Node* pair = NewNode(op, current_context(), name); | 1864 Node* pair = NewNode(op, current_context(), name); | 
| 1819 return NewNode(common()->Projection(0), pair); | 1865 return NewNode(common()->Projection(0), pair); | 
| 1820 } | 1866 } | 
| 1821 } | 1867 } | 
| 1822 UNREACHABLE(); | 1868 UNREACHABLE(); | 
| 1823 return NULL; | 1869 return NULL; | 
| 1824 } | 1870 } | 
| 1825 | 1871 | 
| 1826 | 1872 | 
| 1827 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) { | 1873 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) { | 
| 1828 switch (variable->location()) { | 1874 switch (variable->location()) { | 
| 1829 case Variable::UNALLOCATED: { | 1875 case Variable::UNALLOCATED: { | 
| 1830 // Global var, const, or let variable. | 1876 // Global var, const, or let variable. | 
| 1831 Node* global = BuildLoadGlobalObject(); | 1877 Node* global = BuildLoadGlobalObject(); | 
| 1832 Node* name = jsgraph()->Constant(variable->name()); | 1878 Node* name = jsgraph()->Constant(variable->name()); | 
| 1833 const Operator* op = javascript()->DeleteProperty(strict_mode()); | 1879 const Operator* op = javascript()->DeleteProperty(strict_mode()); | 
| 1834 return NewNode(op, global, name); | 1880 return NewNode(op, global, name); | 
| 1835 } | 1881 } | 
| 1836 case Variable::PARAMETER: | 1882 case Variable::PARAMETER: | 
| 1837 case Variable::LOCAL: | 1883 case Variable::LOCAL: | 
| 1838 case Variable::CONTEXT: | 1884 case Variable::CONTEXT: | 
| 1839 // Local var, const, or let variable or context variable. | 1885 // Local var, const, or let variable or context variable. | 
| 1840 return variable->is_this() ? jsgraph()->TrueConstant() | 1886 return variable->is_this() ? jsgraph()->TrueConstant() | 
| 1841 : jsgraph()->FalseConstant(); | 1887 : jsgraph()->FalseConstant(); | 
| 1842 case Variable::LOOKUP: { | 1888 case Variable::LOOKUP: { | 
| 1843 // Dynamic lookup of context variable (anywhere in the chain). | 1889 // Dynamic lookup of context variable (anywhere in the chain). | 
| 1844 Node* name = jsgraph()->Constant(variable->name()); | 1890 Node* name = jsgraph()->Constant(variable->name()); | 
| 1845 const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2); | 1891 const Operator* op = javascript()->CallRuntime( | 
| 1892 CallRuntimeParameters(Runtime::kDeleteLookupSlot, 2)); | |
| 1846 return NewNode(op, current_context(), name); | 1893 return NewNode(op, current_context(), name); | 
| 1847 } | 1894 } | 
| 1848 } | 1895 } | 
| 1849 UNREACHABLE(); | 1896 UNREACHABLE(); | 
| 1850 return NULL; | 1897 return NULL; | 
| 1851 } | 1898 } | 
| 1852 | 1899 | 
| 1853 | 1900 | 
| 1854 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, | 1901 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, | 
| 1855 Token::Value op, | 1902 Token::Value op, | 
| 1856 BailoutId bailout_id) { | 1903 BailoutId bailout_id) { | 
| 1857 Node* the_hole = jsgraph()->TheHoleConstant(); | 1904 Node* the_hole = jsgraph()->TheHoleConstant(); | 
| 1858 VariableMode mode = variable->mode(); | 1905 VariableMode mode = variable->mode(); | 
| 1859 switch (variable->location()) { | 1906 switch (variable->location()) { | 
| 1860 case Variable::UNALLOCATED: { | 1907 case Variable::UNALLOCATED: { | 
| 1861 // Global var, const, or let variable. | 1908 // Global var, const, or let variable. | 
| 1862 Node* global = BuildLoadGlobalObject(); | 1909 Node* global = BuildLoadGlobalObject(); | 
| 1863 Unique<Name> name = MakeUnique(variable->name()); | 1910 Unique<Name> name = MakeUnique(variable->name()); | 
| 1864 const Operator* op = javascript()->StoreNamed(strict_mode(), name); | 1911 const Operator* op = | 
| 1912 javascript()->StoreNamed(StoreNamedParameters(strict_mode(), name)); | |
| 1865 Node* store = NewNode(op, global, value); | 1913 Node* store = NewNode(op, global, value); | 
| 1866 PrepareFrameState(store, bailout_id); | 1914 PrepareFrameState(store, bailout_id); | 
| 1867 return store; | 1915 return store; | 
| 1868 } | 1916 } | 
| 1869 case Variable::PARAMETER: | 1917 case Variable::PARAMETER: | 
| 1870 case Variable::LOCAL: | 1918 case Variable::LOCAL: | 
| 1871 // Local var, const, or let variable. | 1919 // Local var, const, or let variable. | 
| 1872 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 1920 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 
| 1873 // Perform an initialization check for legacy const variables. | 1921 // Perform an initialization check for legacy const variables. | 
| 1874 Node* current = environment()->Lookup(variable); | 1922 Node* current = environment()->Lookup(variable); | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1894 UNREACHABLE(); | 1942 UNREACHABLE(); | 
| 1895 } | 1943 } | 
| 1896 environment()->Bind(variable, value); | 1944 environment()->Bind(variable, value); | 
| 1897 return value; | 1945 return value; | 
| 1898 case Variable::CONTEXT: { | 1946 case Variable::CONTEXT: { | 
| 1899 // Context variable (potentially up the context chain). | 1947 // Context variable (potentially up the context chain). | 
| 1900 int depth = current_scope()->ContextChainLength(variable->scope()); | 1948 int depth = current_scope()->ContextChainLength(variable->scope()); | 
| 1901 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 1949 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 
| 1902 // Perform an initialization check for legacy const variables. | 1950 // Perform an initialization check for legacy const variables. | 
| 1903 const Operator* op = | 1951 const Operator* op = | 
| 1904 javascript()->LoadContext(depth, variable->index(), false); | 1952 javascript()->LoadContext(ContextAccess(depth, variable->index())); | 
| 1905 Node* current = NewNode(op, current_context()); | 1953 Node* current = NewNode(op, current_context()); | 
| 1906 value = BuildHoleCheckSilent(current, value, current); | 1954 value = BuildHoleCheckSilent(current, value, current); | 
| 1907 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { | 1955 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { | 
| 1908 // Non-initializing assignments to legacy const is ignored. | 1956 // Non-initializing assignments to legacy const is ignored. | 
| 1909 return value; | 1957 return value; | 
| 1910 } else if (mode == LET && op != Token::INIT_LET) { | 1958 } else if (mode == LET && op != Token::INIT_LET) { | 
| 1911 // Perform an initialization check for let declared variables. | 1959 // Perform an initialization check for let declared variables. | 
| 1912 const Operator* op = | 1960 const Operator* op = | 
| 1913 javascript()->LoadContext(depth, variable->index(), false); | 1961 javascript()->LoadContext(ContextAccess(depth, variable->index())); | 
| 1914 Node* current = NewNode(op, current_context()); | 1962 Node* current = NewNode(op, current_context()); | 
| 1915 value = BuildHoleCheckThrow(current, variable, value); | 1963 value = BuildHoleCheckThrow(current, variable, value); | 
| 1916 } else if (mode == CONST && op != Token::INIT_CONST) { | 1964 } else if (mode == CONST && op != Token::INIT_CONST) { | 
| 1917 // All assignments to const variables are early errors. | 1965 // All assignments to const variables are early errors. | 
| 1918 UNREACHABLE(); | 1966 UNREACHABLE(); | 
| 1919 } | 1967 } | 
| 1920 const Operator* op = javascript()->StoreContext(depth, variable->index()); | 1968 const Operator* op = | 
| 1969 javascript()->StoreContext(ContextAccess(depth, variable->index())); | |
| 1921 return NewNode(op, current_context(), value); | 1970 return NewNode(op, current_context(), value); | 
| 1922 } | 1971 } | 
| 1923 case Variable::LOOKUP: { | 1972 case Variable::LOOKUP: { | 
| 1924 // Dynamic lookup of context variable (anywhere in the chain). | 1973 // Dynamic lookup of context variable (anywhere in the chain). | 
| 1925 Node* name = jsgraph()->Constant(variable->name()); | 1974 Node* name = jsgraph()->Constant(variable->name()); | 
| 1926 Node* strict = jsgraph()->Constant(strict_mode()); | 1975 Node* strict = jsgraph()->Constant(strict_mode()); | 
| 1927 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for | 1976 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for | 
| 1928 // initializations of const declarations. | 1977 // initializations of const declarations. | 
| 1929 const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4); | 1978 const Operator* op = javascript()->CallRuntime( | 
| 1979 CallRuntimeParameters(Runtime::kStoreLookupSlot, 4)); | |
| 1930 return NewNode(op, value, current_context(), name, strict); | 1980 return NewNode(op, value, current_context(), name, strict); | 
| 1931 } | 1981 } | 
| 1932 } | 1982 } | 
| 1933 UNREACHABLE(); | 1983 UNREACHABLE(); | 
| 1934 return NULL; | 1984 return NULL; | 
| 1935 } | 1985 } | 
| 1936 | 1986 | 
| 1937 | 1987 | 
| 1938 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { | 1988 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { | 
| 1939 // TODO(sigurds) Use simplified load here once it is ready. | 1989 // TODO(sigurds) Use simplified load here once it is ready. | 
| 1940 Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, | 1990 Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, | 
| 1941 jsgraph()->Int32Constant(offset - kHeapObjectTag)); | 1991 jsgraph()->Int32Constant(offset - kHeapObjectTag)); | 
| 1942 return field_load; | 1992 return field_load; | 
| 1943 } | 1993 } | 
| 1944 | 1994 | 
| 1945 | 1995 | 
| 1946 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { | 1996 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { | 
| 1947 Node* global = BuildLoadGlobalObject(); | 1997 Node* global = BuildLoadGlobalObject(); | 
| 1948 Node* builtins = | 1998 Node* builtins = | 
| 1949 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); | 1999 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); | 
| 1950 return builtins; | 2000 return builtins; | 
| 1951 } | 2001 } | 
| 1952 | 2002 | 
| 1953 | 2003 | 
| 1954 Node* AstGraphBuilder::BuildLoadGlobalObject() { | 2004 Node* AstGraphBuilder::BuildLoadGlobalObject() { | 
| 1955 Node* context = GetFunctionContext(); | 2005 Node* context = GetFunctionContext(); | 
| 1956 const Operator* load_op = | 2006 const Operator* load_op = javascript()->LoadContext( | 
| 1957 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); | 2007 ContextAccess(0, Context::GLOBAL_OBJECT_INDEX, true)); | 
| 1958 return NewNode(load_op, context); | 2008 return NewNode(load_op, context); | 
| 1959 } | 2009 } | 
| 1960 | 2010 | 
| 1961 | 2011 | 
| 1962 Node* AstGraphBuilder::BuildToBoolean(Node* value) { | 2012 Node* AstGraphBuilder::BuildToBoolean(Node* value) { | 
| 1963 // TODO(mstarzinger): Possible optimization is to NOP for boolean values. | 2013 // TODO(mstarzinger): Possible optimization is to NOP for boolean values. | 
| 1964 return NewNode(javascript()->ToBoolean(), value); | 2014 return NewNode(javascript()->ToBoolean(), value); | 
| 1965 } | 2015 } | 
| 1966 | 2016 | 
| 1967 | 2017 | 
| 1968 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) { | 2018 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) { | 
| 1969 // TODO(mstarzinger): Should be unified with the VisitThrow implementation. | 2019 // TODO(mstarzinger): Should be unified with the VisitThrow implementation. | 
| 1970 Node* variable_name = jsgraph()->Constant(variable->name()); | 2020 Node* variable_name = jsgraph()->Constant(variable->name()); | 
| 1971 const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1); | 2021 const Operator* op = javascript()->CallRuntime( | 
| 2022 CallRuntimeParameters(Runtime::kThrowReferenceError, 1)); | |
| 1972 return NewNode(op, variable_name); | 2023 return NewNode(op, variable_name); | 
| 1973 } | 2024 } | 
| 1974 | 2025 | 
| 1975 | 2026 | 
| 1976 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { | 2027 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { | 
| 1977 const Operator* js_op; | 2028 const Operator* js_op; | 
| 1978 switch (op) { | 2029 switch (op) { | 
| 1979 case Token::BIT_OR: | 2030 case Token::BIT_OR: | 
| 1980 js_op = javascript()->BitwiseOr(); | 2031 js_op = javascript()->BitwiseOr(); | 
| 1981 break; | 2032 break; | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2023 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == | 2074 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == | 
| 2024 IrOpcode::kDead); | 2075 IrOpcode::kDead); | 
| 2025 NodeProperties::ReplaceFrameStateInput( | 2076 NodeProperties::ReplaceFrameStateInput( | 
| 2026 node, environment()->Checkpoint(ast_id, combine)); | 2077 node, environment()->Checkpoint(ast_id, combine)); | 
| 2027 } | 2078 } | 
| 2028 } | 2079 } | 
| 2029 | 2080 | 
| 2030 } | 2081 } | 
| 2031 } | 2082 } | 
| 2032 } // namespace v8::internal::compiler | 2083 } // namespace v8::internal::compiler | 
| OLD | NEW |