| 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 |