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/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 2517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2528 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 2528 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
2529 const Runtime::Function* function = expr->function(); | 2529 const Runtime::Function* function = expr->function(); |
2530 | 2530 |
2531 // Handle calls to runtime functions implemented in JavaScript separately as | 2531 // Handle calls to runtime functions implemented in JavaScript separately as |
2532 // the call follows JavaScript ABI and the callee is statically unknown. | 2532 // the call follows JavaScript ABI and the callee is statically unknown. |
2533 if (expr->is_jsruntime()) { | 2533 if (expr->is_jsruntime()) { |
2534 DCHECK(function == NULL && expr->name()->length() > 0); | 2534 DCHECK(function == NULL && expr->name()->length() > 0); |
2535 return VisitCallJSRuntime(expr); | 2535 return VisitCallJSRuntime(expr); |
2536 } | 2536 } |
2537 | 2537 |
2538 // TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed. | |
2539 if (function->function_id == Runtime::kInlineGeneratorNext || | |
2540 function->function_id == Runtime::kInlineGeneratorThrow || | |
2541 function->function_id == Runtime::kInlineDefaultConstructorCallSuper || | |
2542 function->function_id == Runtime::kInlineCallSuperWithSpread) { | |
2543 ast_context()->ProduceValue(jsgraph()->TheHoleConstant()); | |
2544 return SetStackOverflow(); | |
2545 } | |
2546 | |
2538 // Evaluate all arguments to the runtime call. | 2547 // Evaluate all arguments to the runtime call. |
2539 ZoneList<Expression*>* args = expr->arguments(); | 2548 ZoneList<Expression*>* args = expr->arguments(); |
2540 VisitForValues(args); | 2549 VisitForValues(args); |
2541 | 2550 |
2542 // Create node to perform the runtime call. | 2551 // Create node to perform the runtime call. |
2543 Runtime::FunctionId functionId = function->function_id; | 2552 Runtime::FunctionId functionId = function->function_id; |
2544 // TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed. | |
2545 if (functionId == Runtime::kInlineGeneratorNext) SetStackOverflow(); | |
2546 if (functionId == Runtime::kInlineGeneratorThrow) SetStackOverflow(); | |
2547 const Operator* call = javascript()->CallRuntime(functionId, args->length()); | 2553 const Operator* call = javascript()->CallRuntime(functionId, args->length()); |
2548 FrameStateBeforeAndAfter states(this, expr->CallId()); | 2554 FrameStateBeforeAndAfter states(this, expr->CallId()); |
2549 Node* value = ProcessArguments(call, args->length()); | 2555 Node* value = ProcessArguments(call, args->length()); |
2550 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2556 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2551 ast_context()->ProduceValue(value); | 2557 ast_context()->ProduceValue(value); |
2552 } | 2558 } |
2553 | 2559 |
2554 | 2560 |
2555 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 2561 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
2556 switch (expr->op()) { | 2562 switch (expr->op()) { |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2809 VisitForValue(expr->right()); | 2815 VisitForValue(expr->right()); |
2810 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2816 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
2811 Node* right = environment()->Pop(); | 2817 Node* right = environment()->Pop(); |
2812 Node* left = environment()->Pop(); | 2818 Node* left = environment()->Pop(); |
2813 Node* value = NewNode(op, left, right); | 2819 Node* value = NewNode(op, left, right); |
2814 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2820 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2815 ast_context()->ProduceValue(value); | 2821 ast_context()->ProduceValue(value); |
2816 } | 2822 } |
2817 | 2823 |
2818 | 2824 |
2819 void AstGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } | 2825 void AstGraphBuilder::VisitSpread(Spread* expr) { |
2826 // Handled entirely by the parser itself. | |
2827 UNREACHABLE(); | |
2828 } | |
2820 | 2829 |
2821 | 2830 |
2822 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 2831 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
2823 Node* value = GetFunctionClosure(); | 2832 Node* value = GetFunctionClosure(); |
2824 ast_context()->ProduceValue(value); | 2833 ast_context()->ProduceValue(value); |
2825 } | 2834 } |
2826 | 2835 |
2827 | 2836 |
2828 void AstGraphBuilder::VisitSuperPropertyReference( | 2837 void AstGraphBuilder::VisitSuperPropertyReference( |
2829 SuperPropertyReference* expr) { | 2838 SuperPropertyReference* expr) { |
2830 // TODO(turbofan): Implement super here. | 2839 Node* value = BuildThrowUnsupportedSuperError(expr->id()); |
arv (Not doing code reviews)
2015/07/07 15:48:09
Shouldn't this be UNREACHABLE? We are supposed to
Michael Starzinger
2015/07/07 15:59:58
Yeah, I though so too. Please admire patch set #1
arv (Not doing code reviews)
2015/07/07 16:04:43
I see.
This one comes from
delete (super.prop)
| |
2831 SetStackOverflow(); | 2840 ast_context()->ProduceValue(value); |
2832 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | |
2833 } | 2841 } |
2834 | 2842 |
2835 | 2843 |
2836 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { | 2844 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { |
2837 // TODO(turbofan): Implement super here. | 2845 Node* value = BuildThrowUnsupportedSuperError(expr->id()); |
arv (Not doing code reviews)
2015/07/07 15:48:09
Same here. I don't see how these errors can ever b
Michael Starzinger
2015/07/07 15:59:58
Likewise.
arv (Not doing code reviews)
2015/07/07 16:04:43
This one on the other hand I don't think we can ge
| |
2838 SetStackOverflow(); | 2846 ast_context()->ProduceValue(value); |
2839 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | |
2840 } | 2847 } |
2841 | 2848 |
2842 | 2849 |
2843 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } | 2850 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { |
2851 // Handled entirely in VisitSwitch. | |
2852 UNREACHABLE(); | |
2853 } | |
2844 | 2854 |
2845 | 2855 |
2846 void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { | 2856 void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { |
2847 DCHECK(globals()->empty()); | 2857 DCHECK(globals()->empty()); |
2848 AstVisitor::VisitDeclarations(declarations); | 2858 AstVisitor::VisitDeclarations(declarations); |
2849 if (globals()->empty()) return; | 2859 if (globals()->empty()) return; |
2850 int array_index = 0; | 2860 int array_index = 0; |
2851 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( | 2861 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( |
2852 static_cast<int>(globals()->size()), TENURED); | 2862 static_cast<int>(globals()->size()), TENURED); |
2853 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); | 2863 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3264 if (mode == CONST_LEGACY) { | 3274 if (mode == CONST_LEGACY) { |
3265 // Perform check for uninitialized legacy const variables. | 3275 // Perform check for uninitialized legacy const variables. |
3266 if (value->op() == the_hole->op()) { | 3276 if (value->op() == the_hole->op()) { |
3267 value = jsgraph()->UndefinedConstant(); | 3277 value = jsgraph()->UndefinedConstant(); |
3268 } else if (value->opcode() == IrOpcode::kPhi) { | 3278 } else if (value->opcode() == IrOpcode::kPhi) { |
3269 Node* undefined = jsgraph()->UndefinedConstant(); | 3279 Node* undefined = jsgraph()->UndefinedConstant(); |
3270 value = BuildHoleCheckSilent(value, undefined, value); | 3280 value = BuildHoleCheckSilent(value, undefined, value); |
3271 } | 3281 } |
3272 } else if (mode == LET || mode == CONST) { | 3282 } else if (mode == LET || mode == CONST) { |
3273 // Perform check for uninitialized let/const variables. | 3283 // Perform check for uninitialized let/const variables. |
3284 // TODO(mstarzinger): For now we cannot use the below optimization for | |
3285 // the {this} parameter, because JSConstructStubForDerived magically | |
3286 // passes {the_hole} as a receiver. | |
3274 if (value->op() == the_hole->op()) { | 3287 if (value->op() == the_hole->op()) { |
3275 value = BuildThrowReferenceError(variable, bailout_id); | 3288 value = BuildThrowReferenceError(variable, bailout_id); |
3276 } else if (value->opcode() == IrOpcode::kPhi) { | 3289 } else if (value->opcode() == IrOpcode::kPhi || variable->is_this()) { |
3277 value = BuildHoleCheckThrow(value, variable, value, bailout_id); | 3290 value = BuildHoleCheckThrow(value, variable, value, bailout_id); |
3278 } | 3291 } |
3279 } | 3292 } |
3280 return value; | 3293 return value; |
3281 } | 3294 } |
3282 case Variable::CONTEXT: { | 3295 case Variable::CONTEXT: { |
3283 // Context variable (potentially up the context chain). | 3296 // Context variable (potentially up the context chain). |
3284 int depth = current_scope()->ContextChainLength(variable->scope()); | 3297 int depth = current_scope()->ContextChainLength(variable->scope()); |
3285 bool immutable = variable->maybe_assigned() == kNotAssigned; | 3298 bool immutable = variable->maybe_assigned() == kNotAssigned; |
3286 const Operator* op = | 3299 const Operator* op = |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3783 const Operator* op = | 3796 const Operator* op = |
3784 javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError, 0); | 3797 javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError, 0); |
3785 Node* call = NewNode(op); | 3798 Node* call = NewNode(op); |
3786 PrepareFrameState(call, bailout_id); | 3799 PrepareFrameState(call, bailout_id); |
3787 Node* control = NewNode(common()->Throw(), call); | 3800 Node* control = NewNode(common()->Throw(), call); |
3788 UpdateControlDependencyToLeaveFunction(control); | 3801 UpdateControlDependencyToLeaveFunction(control); |
3789 return call; | 3802 return call; |
3790 } | 3803 } |
3791 | 3804 |
3792 | 3805 |
3806 Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) { | |
3807 const Operator* op = | |
3808 javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); | |
3809 Node* call = NewNode(op); | |
3810 PrepareFrameState(call, bailout_id); | |
3811 Node* control = NewNode(common()->Throw(), call); | |
3812 UpdateControlDependencyToLeaveFunction(control); | |
3813 return call; | |
3814 } | |
3815 | |
3816 | |
3793 Node* AstGraphBuilder::BuildReturn(Node* return_value) { | 3817 Node* AstGraphBuilder::BuildReturn(Node* return_value) { |
3794 Node* control = NewNode(common()->Return(), return_value); | 3818 Node* control = NewNode(common()->Return(), return_value); |
3795 UpdateControlDependencyToLeaveFunction(control); | 3819 UpdateControlDependencyToLeaveFunction(control); |
3796 return control; | 3820 return control; |
3797 } | 3821 } |
3798 | 3822 |
3799 | 3823 |
3800 Node* AstGraphBuilder::BuildThrow(Node* exception_value) { | 3824 Node* AstGraphBuilder::BuildThrow(Node* exception_value) { |
3801 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value); | 3825 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value); |
3802 Node* control = NewNode(common()->Throw(), exception_value); | 3826 Node* control = NewNode(common()->Throw(), exception_value); |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4175 // Phi does not exist yet, introduce one. | 4199 // Phi does not exist yet, introduce one. |
4176 value = NewPhi(inputs, value, control); | 4200 value = NewPhi(inputs, value, control); |
4177 value->ReplaceInput(inputs - 1, other); | 4201 value->ReplaceInput(inputs - 1, other); |
4178 } | 4202 } |
4179 return value; | 4203 return value; |
4180 } | 4204 } |
4181 | 4205 |
4182 } // namespace compiler | 4206 } // namespace compiler |
4183 } // namespace internal | 4207 } // namespace internal |
4184 } // namespace v8 | 4208 } // namespace v8 |
OLD | NEW |