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/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 1561 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); |
1562 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? | 1562 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? |
1563 | 1563 |
1564 // Create node to instantiate a new closure. | 1564 // Create node to instantiate a new closure. |
1565 PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; | 1565 PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; |
1566 const Operator* op = javascript()->CreateClosure(shared_info, pretenure); | 1566 const Operator* op = javascript()->CreateClosure(shared_info, pretenure); |
1567 Node* value = NewNode(op); | 1567 Node* value = NewNode(op); |
1568 ast_context()->ProduceValue(expr, value); | 1568 ast_context()->ProduceValue(expr, value); |
1569 } | 1569 } |
1570 | 1570 |
1571 | 1571 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); } |
1572 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { | |
1573 VisitForValueOrTheHole(expr->extends()); | |
1574 VisitForValue(expr->constructor()); | |
1575 | |
1576 // Create node to instantiate a new class. | |
1577 Node* constructor = environment()->Pop(); | |
1578 Node* extends = environment()->Pop(); | |
1579 Node* start = jsgraph()->Constant(expr->start_position()); | |
1580 Node* end = jsgraph()->Constant(expr->end_position()); | |
1581 const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass); | |
1582 Node* literal = NewNode(opc, extends, constructor, start, end); | |
1583 PrepareFrameState(literal, expr->CreateLiteralId(), | |
1584 OutputFrameStateCombine::Push()); | |
1585 environment()->Push(literal); | |
1586 | |
1587 // Load the "prototype" from the constructor. | |
1588 PrepareEagerCheckpoint(expr->CreateLiteralId()); | |
1589 Handle<Name> name = isolate()->factory()->prototype_string(); | |
1590 VectorSlotPair pair = CreateVectorSlotPair(expr->PrototypeSlot()); | |
1591 Node* prototype = BuildNamedLoad(literal, name, pair); | |
1592 PrepareFrameState(prototype, expr->PrototypeId(), | |
1593 OutputFrameStateCombine::Push()); | |
1594 environment()->Push(prototype); | |
1595 | |
1596 // Create nodes to store method values into the literal. | |
1597 for (int i = 0; i < expr->properties()->length(); i++) { | |
1598 ClassLiteral::Property* property = expr->properties()->at(i); | |
1599 environment()->Push(environment()->Peek(property->is_static() ? 1 : 0)); | |
1600 | |
1601 VisitForValue(property->key()); | |
1602 Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i)); | |
1603 environment()->Push(name); | |
1604 | |
1605 // The static prototype property is read only. We handle the non computed | |
1606 // property name case in the parser. Since this is the only case where we | |
1607 // need to check for an own read only property we special case this so we do | |
1608 // not need to do this for every property. | |
1609 if (property->is_static() && property->is_computed_name()) { | |
1610 Node* check = BuildThrowIfStaticPrototype(environment()->Pop(), | |
1611 expr->GetIdForProperty(i)); | |
1612 environment()->Push(check); | |
1613 } | |
1614 | |
1615 VisitForValue(property->value()); | |
1616 Node* value = environment()->Pop(); | |
1617 Node* key = environment()->Pop(); | |
1618 Node* receiver = environment()->Pop(); | |
1619 | |
1620 BuildSetHomeObject(value, receiver, property); | |
1621 | |
1622 switch (property->kind()) { | |
1623 case ClassLiteral::Property::METHOD: { | |
1624 Node* attr = jsgraph()->Constant(DONT_ENUM); | |
1625 Node* set_function_name = | |
1626 jsgraph()->Constant(property->NeedsSetFunctionName()); | |
1627 const Operator* op = | |
1628 javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral); | |
1629 Node* call = NewNode(op, receiver, key, value, attr, set_function_name); | |
1630 PrepareFrameState(call, BailoutId::None()); | |
1631 break; | |
1632 } | |
1633 case ClassLiteral::Property::GETTER: { | |
1634 Node* attr = jsgraph()->Constant(DONT_ENUM); | |
1635 const Operator* op = javascript()->CallRuntime( | |
1636 Runtime::kDefineGetterPropertyUnchecked, 4); | |
1637 NewNode(op, receiver, key, value, attr); | |
1638 break; | |
1639 } | |
1640 case ClassLiteral::Property::SETTER: { | |
1641 Node* attr = jsgraph()->Constant(DONT_ENUM); | |
1642 const Operator* op = javascript()->CallRuntime( | |
1643 Runtime::kDefineSetterPropertyUnchecked, 4); | |
1644 NewNode(op, receiver, key, value, attr); | |
1645 break; | |
1646 } | |
1647 case ClassLiteral::Property::FIELD: { | |
1648 UNREACHABLE(); | |
1649 break; | |
1650 } | |
1651 } | |
1652 } | |
1653 | |
1654 // Set the constructor to have fast properties. | |
1655 prototype = environment()->Pop(); | |
1656 literal = environment()->Pop(); | |
1657 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties); | |
1658 literal = NewNode(op, literal); | |
1659 | |
1660 // Assign to class variable. | |
1661 if (expr->class_variable_proxy() != nullptr) { | |
1662 Variable* var = expr->class_variable_proxy()->var(); | |
1663 VectorSlotPair feedback = CreateVectorSlotPair( | |
1664 expr->NeedsProxySlot() ? expr->ProxySlot() | |
1665 : FeedbackVectorSlot::Invalid()); | |
1666 BuildVariableAssignment(var, literal, Token::INIT, feedback, | |
1667 BailoutId::None()); | |
1668 } | |
1669 ast_context()->ProduceValue(expr, literal); | |
1670 } | |
1671 | |
1672 | 1572 |
1673 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 1573 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
1674 UNREACHABLE(); | 1574 UNREACHABLE(); |
1675 } | 1575 } |
1676 | 1576 |
1677 | 1577 |
1678 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) { | 1578 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) { |
1679 VisitBlock(expr->block()); | 1579 VisitBlock(expr->block()); |
1680 VisitVariableProxy(expr->result()); | 1580 VisitVariableProxy(expr->result()); |
1681 ast_context()->ReplaceValue(expr); | 1581 ast_context()->ReplaceValue(expr); |
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3213 hole_check.If(check); | 3113 hole_check.If(check); |
3214 hole_check.Then(); | 3114 hole_check.Then(); |
3215 environment()->Push(for_hole); | 3115 environment()->Push(for_hole); |
3216 hole_check.Else(); | 3116 hole_check.Else(); |
3217 Node* error = BuildThrowReferenceError(variable, bailout_id); | 3117 Node* error = BuildThrowReferenceError(variable, bailout_id); |
3218 environment()->Push(error); | 3118 environment()->Push(error); |
3219 hole_check.End(); | 3119 hole_check.End(); |
3220 return environment()->Pop(); | 3120 return environment()->Pop(); |
3221 } | 3121 } |
3222 | 3122 |
3223 | |
3224 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name, | |
3225 BailoutId bailout_id) { | |
3226 IfBuilder prototype_check(this); | |
3227 Node* prototype_string = | |
3228 jsgraph()->Constant(isolate()->factory()->prototype_string()); | |
3229 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | |
3230 name, prototype_string); | |
3231 prototype_check.If(check); | |
3232 prototype_check.Then(); | |
3233 Node* error = BuildThrowStaticPrototypeError(bailout_id); | |
3234 environment()->Push(error); | |
3235 prototype_check.Else(); | |
3236 environment()->Push(name); | |
3237 prototype_check.End(); | |
3238 return environment()->Pop(); | |
3239 } | |
3240 | |
3241 | |
3242 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 3123 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, |
3243 BailoutId bailout_id, | 3124 BailoutId bailout_id, |
3244 const VectorSlotPair& feedback, | 3125 const VectorSlotPair& feedback, |
3245 OutputFrameStateCombine combine, | 3126 OutputFrameStateCombine combine, |
3246 TypeofMode typeof_mode) { | 3127 TypeofMode typeof_mode) { |
3247 Node* the_hole = jsgraph()->TheHoleConstant(); | 3128 Node* the_hole = jsgraph()->TheHoleConstant(); |
3248 switch (variable->location()) { | 3129 switch (variable->location()) { |
3249 case VariableLocation::UNALLOCATED: { | 3130 case VariableLocation::UNALLOCATED: { |
3250 // Global var, const, or let variable. | 3131 // Global var, const, or let variable. |
3251 Handle<Name> name = variable->name(); | 3132 Handle<Name> name = variable->name(); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3610 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) { | 3491 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) { |
3611 const Operator* op = | 3492 const Operator* op = |
3612 javascript()->CallRuntime(Runtime::kThrowConstAssignError); | 3493 javascript()->CallRuntime(Runtime::kThrowConstAssignError); |
3613 Node* call = NewNode(op); | 3494 Node* call = NewNode(op); |
3614 PrepareFrameState(call, bailout_id); | 3495 PrepareFrameState(call, bailout_id); |
3615 Node* control = NewNode(common()->Throw(), call); | 3496 Node* control = NewNode(common()->Throw(), call); |
3616 UpdateControlDependencyToLeaveFunction(control); | 3497 UpdateControlDependencyToLeaveFunction(control); |
3617 return call; | 3498 return call; |
3618 } | 3499 } |
3619 | 3500 |
3620 | |
3621 Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) { | |
3622 const Operator* op = | |
3623 javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError); | |
3624 Node* call = NewNode(op); | |
3625 PrepareFrameState(call, bailout_id); | |
3626 Node* control = NewNode(common()->Throw(), call); | |
3627 UpdateControlDependencyToLeaveFunction(control); | |
3628 return call; | |
3629 } | |
3630 | |
3631 | |
3632 Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) { | 3501 Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) { |
3633 const Operator* op = | 3502 const Operator* op = |
3634 javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError); | 3503 javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError); |
3635 Node* call = NewNode(op); | 3504 Node* call = NewNode(op); |
3636 PrepareFrameState(call, bailout_id); | 3505 PrepareFrameState(call, bailout_id); |
3637 Node* control = NewNode(common()->Throw(), call); | 3506 Node* control = NewNode(common()->Throw(), call); |
3638 UpdateControlDependencyToLeaveFunction(control); | 3507 UpdateControlDependencyToLeaveFunction(control); |
3639 return call; | 3508 return call; |
3640 } | 3509 } |
3641 | 3510 |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4132 TypeHintAnalysis* type_hint_analysis, SourcePositionTable* source_positions, | 4001 TypeHintAnalysis* type_hint_analysis, SourcePositionTable* source_positions, |
4133 int inlining_id) | 4002 int inlining_id) |
4134 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, | 4003 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, |
4135 loop_assignment, type_hint_analysis), | 4004 loop_assignment, type_hint_analysis), |
4136 source_positions_(source_positions), | 4005 source_positions_(source_positions), |
4137 start_position_(info->shared_info()->start_position(), inlining_id) {} | 4006 start_position_(info->shared_info()->start_position(), inlining_id) {} |
4138 | 4007 |
4139 } // namespace compiler | 4008 } // namespace compiler |
4140 } // namespace internal | 4009 } // namespace internal |
4141 } // namespace v8 | 4010 } // namespace v8 |
OLD | NEW |