| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "ast.h" | 30 #include "ast.h" |
| 31 #include "jump-target-inl.h" |
| 31 #include "parser.h" | 32 #include "parser.h" |
| 32 #include "scopes.h" | 33 #include "scopes.h" |
| 33 #include "string-stream.h" | 34 #include "string-stream.h" |
| 34 #include "ast-inl.h" | |
| 35 #include "jump-target-inl.h" | |
| 36 | 35 |
| 37 namespace v8 { | 36 namespace v8 { |
| 38 namespace internal { | 37 namespace internal { |
| 39 | 38 |
| 40 | |
| 41 AstSentinels::AstSentinels() | 39 AstSentinels::AstSentinels() |
| 42 : this_proxy_(true), | 40 : this_proxy_(true), |
| 43 identifier_proxy_(false), | 41 identifier_proxy_(false), |
| 44 valid_left_hand_side_sentinel_(), | 42 valid_left_hand_side_sentinel_(), |
| 45 this_property_(&this_proxy_, NULL, 0), | 43 this_property_(&this_proxy_, NULL, 0), |
| 46 call_sentinel_(NULL, NULL, 0) { | 44 call_sentinel_(NULL, NULL, 0) { |
| 47 } | 45 } |
| 48 | 46 |
| 49 | 47 |
| 50 // ---------------------------------------------------------------------------- | 48 // ---------------------------------------------------------------------------- |
| 51 // All the Accept member functions for each syntax tree node type. | 49 // All the Accept member functions for each syntax tree node type. |
| 52 | 50 |
| 51 void Slot::Accept(AstVisitor* v) { v->VisitSlot(this); } |
| 52 |
| 53 #define DECL_ACCEPT(type) \ | 53 #define DECL_ACCEPT(type) \ |
| 54 void type::Accept(AstVisitor* v) { v->Visit##type(this); } | 54 void type::Accept(AstVisitor* v) { v->Visit##type(this); } |
| 55 AST_NODE_LIST(DECL_ACCEPT) | 55 AST_NODE_LIST(DECL_ACCEPT) |
| 56 #undef DECL_ACCEPT | 56 #undef DECL_ACCEPT |
| 57 | 57 |
| 58 | 58 |
| 59 // ---------------------------------------------------------------------------- | 59 // ---------------------------------------------------------------------------- |
| 60 // Implementation of other node functionality. | 60 // Implementation of other node functionality. |
| 61 | 61 |
| 62 Assignment* ExpressionStatement::StatementAsSimpleAssignment() { | 62 Assignment* ExpressionStatement::StatementAsSimpleAssignment() { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 // Ideally CONST-ness should match. However, this is very hard to achieve | 110 // Ideally CONST-ness should match. However, this is very hard to achieve |
| 111 // because we don't know the exact semantics of conflicting (const and | 111 // because we don't know the exact semantics of conflicting (const and |
| 112 // non-const) multiple variable declarations, const vars introduced via | 112 // non-const) multiple variable declarations, const vars introduced via |
| 113 // eval() etc. Const-ness and variable declarations are a complete mess | 113 // eval() etc. Const-ness and variable declarations are a complete mess |
| 114 // in JS. Sigh... | 114 // in JS. Sigh... |
| 115 var_ = var; | 115 var_ = var; |
| 116 var->set_is_used(true); | 116 var->set_is_used(true); |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 Assignment::Assignment(Token::Value op, |
| 121 Expression* target, |
| 122 Expression* value, |
| 123 int pos) |
| 124 : op_(op), |
| 125 target_(target), |
| 126 value_(value), |
| 127 pos_(pos), |
| 128 compound_bailout_id_(kNoNumber), |
| 129 block_start_(false), |
| 130 block_end_(false), |
| 131 is_monomorphic_(false), |
| 132 receiver_types_(NULL) { |
| 133 ASSERT(Token::IsAssignmentOp(op)); |
| 134 binary_operation_ = is_compound() |
| 135 ? new BinaryOperation(binary_op(), target, value, pos + 1) |
| 136 : NULL; |
| 137 if (is_compound()) { |
| 138 compound_bailout_id_ = GetNextId(); |
| 139 } |
| 140 } |
| 141 |
| 142 |
| 120 Token::Value Assignment::binary_op() const { | 143 Token::Value Assignment::binary_op() const { |
| 121 switch (op_) { | 144 switch (op_) { |
| 122 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; | 145 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; |
| 123 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; | 146 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; |
| 124 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; | 147 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; |
| 125 case Token::ASSIGN_SHL: return Token::SHL; | 148 case Token::ASSIGN_SHL: return Token::SHL; |
| 126 case Token::ASSIGN_SAR: return Token::SAR; | 149 case Token::ASSIGN_SAR: return Token::SAR; |
| 127 case Token::ASSIGN_SHR: return Token::SHR; | 150 case Token::ASSIGN_SHR: return Token::SHR; |
| 128 case Token::ASSIGN_ADD: return Token::ADD; | 151 case Token::ASSIGN_ADD: return Token::ADD; |
| 129 case Token::ASSIGN_SUB: return Token::SUB; | 152 case Token::ASSIGN_SUB: return Token::SUB; |
| 130 case Token::ASSIGN_MUL: return Token::MUL; | 153 case Token::ASSIGN_MUL: return Token::MUL; |
| 131 case Token::ASSIGN_DIV: return Token::DIV; | 154 case Token::ASSIGN_DIV: return Token::DIV; |
| 132 case Token::ASSIGN_MOD: return Token::MOD; | 155 case Token::ASSIGN_MOD: return Token::MOD; |
| 133 default: UNREACHABLE(); | 156 default: UNREACHABLE(); |
| 134 } | 157 } |
| 135 return Token::ILLEGAL; | 158 return Token::ILLEGAL; |
| 136 } | 159 } |
| 137 | 160 |
| 138 | 161 |
| 139 bool FunctionLiteral::AllowsLazyCompilation() { | 162 bool FunctionLiteral::AllowsLazyCompilation() { |
| 140 return scope()->AllowsLazyCompilation(); | 163 return scope()->AllowsLazyCompilation(); |
| 141 } | 164 } |
| 142 | 165 |
| 143 | 166 |
| 167 bool FunctionLiteral::AllowOptimize() { |
| 168 // We can't deal with heap-allocated locals. |
| 169 return scope()->num_heap_slots() == 0; |
| 170 } |
| 171 |
| 172 |
| 144 ObjectLiteral::Property::Property(Literal* key, Expression* value) { | 173 ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
| 145 emit_store_ = true; | 174 emit_store_ = true; |
| 146 key_ = key; | 175 key_ = key; |
| 147 value_ = value; | 176 value_ = value; |
| 148 Object* k = *key->handle(); | 177 Object* k = *key->handle(); |
| 149 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { | 178 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { |
| 150 kind_ = PROTOTYPE; | 179 kind_ = PROTOTYPE; |
| 151 } else if (value_->AsMaterializedLiteral() != NULL) { | 180 } else if (value_->AsMaterializedLiteral() != NULL) { |
| 152 kind_ = MATERIALIZED_LITERAL; | 181 kind_ = MATERIALIZED_LITERAL; |
| 153 } else if (value_->AsLiteral() != NULL) { | 182 } else if (value_->AsLiteral() != NULL) { |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 ASSERT(assignment->is_compound()); | 397 ASSERT(assignment->is_compound()); |
| 369 op_ = assignment->binary_op(); | 398 op_ = assignment->binary_op(); |
| 370 left_ = assignment->target(); | 399 left_ = assignment->target(); |
| 371 right_ = assignment->value(); | 400 right_ = assignment->value(); |
| 372 pos_ = assignment->position(); | 401 pos_ = assignment->position(); |
| 373 CopyAnalysisResultsFrom(assignment); | 402 CopyAnalysisResultsFrom(assignment); |
| 374 } | 403 } |
| 375 | 404 |
| 376 | 405 |
| 377 // ---------------------------------------------------------------------------- | 406 // ---------------------------------------------------------------------------- |
| 407 // Inlining support |
| 408 |
| 409 bool Block::IsInlineable() const { |
| 410 const int count = statements_.length(); |
| 411 for (int i = 0; i < count; ++i) { |
| 412 if (!statements_[i]->IsInlineable()) return false; |
| 413 } |
| 414 return true; |
| 415 } |
| 416 |
| 417 |
| 418 bool ExpressionStatement::IsInlineable() const { |
| 419 return expression()->IsInlineable(); |
| 420 } |
| 421 |
| 422 |
| 423 bool IfStatement::IsInlineable() const { |
| 424 return condition()->IsInlineable() && then_statement()->IsInlineable() && |
| 425 else_statement()->IsInlineable(); |
| 426 } |
| 427 |
| 428 |
| 429 bool ReturnStatement::IsInlineable() const { |
| 430 return expression()->IsInlineable(); |
| 431 } |
| 432 |
| 433 |
| 434 bool Conditional::IsInlineable() const { |
| 435 return condition()->IsInlineable() && then_expression()->IsInlineable() && |
| 436 else_expression()->IsInlineable(); |
| 437 } |
| 438 |
| 439 |
| 440 bool VariableProxy::IsInlineable() const { |
| 441 return var()->is_global() || var()->IsStackAllocated(); |
| 442 } |
| 443 |
| 444 |
| 445 bool Assignment::IsInlineable() const { |
| 446 return target()->IsInlineable() && value()->IsInlineable(); |
| 447 } |
| 448 |
| 449 |
| 450 bool Property::IsInlineable() const { |
| 451 return obj()->IsInlineable() && key()->IsInlineable(); |
| 452 } |
| 453 |
| 454 |
| 455 bool Call::IsInlineable() const { |
| 456 if (!expression()->IsInlineable()) return false; |
| 457 const int count = arguments()->length(); |
| 458 for (int i = 0; i < count; ++i) { |
| 459 if (!arguments()->at(i)->IsInlineable()) return false; |
| 460 } |
| 461 return true; |
| 462 } |
| 463 |
| 464 |
| 465 bool CallNew::IsInlineable() const { |
| 466 if (!expression()->IsInlineable()) return false; |
| 467 const int count = arguments()->length(); |
| 468 for (int i = 0; i < count; ++i) { |
| 469 if (!arguments()->at(i)->IsInlineable()) return false; |
| 470 } |
| 471 return true; |
| 472 } |
| 473 |
| 474 |
| 475 bool CallRuntime::IsInlineable() const { |
| 476 const int count = arguments()->length(); |
| 477 for (int i = 0; i < count; ++i) { |
| 478 if (!arguments()->at(i)->IsInlineable()) return false; |
| 479 } |
| 480 return true; |
| 481 } |
| 482 |
| 483 |
| 484 bool UnaryOperation::IsInlineable() const { |
| 485 return expression()->IsInlineable(); |
| 486 } |
| 487 |
| 488 |
| 489 bool BinaryOperation::IsInlineable() const { |
| 490 return left()->IsInlineable() && right()->IsInlineable(); |
| 491 } |
| 492 |
| 493 |
| 494 bool CompareOperation::IsInlineable() const { |
| 495 return left()->IsInlineable() && right()->IsInlineable(); |
| 496 } |
| 497 |
| 498 |
| 499 bool CompareToNull::IsInlineable() const { |
| 500 return expression()->IsInlineable(); |
| 501 } |
| 502 |
| 503 |
| 504 bool CountOperation::IsInlineable() const { |
| 505 return expression()->IsInlineable(); |
| 506 } |
| 507 |
| 508 |
| 509 // ---------------------------------------------------------------------------- |
| 510 // Recording of type feedback |
| 511 |
| 512 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 513 // Record type feedback from the oracle in the AST. |
| 514 is_monomorphic_ = oracle->LoadIsMonomorphic(this); |
| 515 if (key()->IsPropertyName()) { |
| 516 if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_ArrayLength)) { |
| 517 is_array_length_ = true; |
| 518 } else { |
| 519 Literal* lit_key = key()->AsLiteral(); |
| 520 ASSERT(lit_key != NULL && lit_key->handle()->IsString()); |
| 521 Handle<String> name = Handle<String>::cast(lit_key->handle()); |
| 522 ZoneMapList* types = oracle->LoadReceiverTypes(this, name); |
| 523 receiver_types_ = types; |
| 524 } |
| 525 } else if (is_monomorphic_) { |
| 526 monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this); |
| 527 } |
| 528 } |
| 529 |
| 530 |
| 531 void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 532 Property* prop = target()->AsProperty(); |
| 533 ASSERT(prop != NULL); |
| 534 is_monomorphic_ = oracle->StoreIsMonomorphic(this); |
| 535 if (prop->key()->IsPropertyName()) { |
| 536 Literal* lit_key = prop->key()->AsLiteral(); |
| 537 ASSERT(lit_key != NULL && lit_key->handle()->IsString()); |
| 538 Handle<String> name = Handle<String>::cast(lit_key->handle()); |
| 539 ZoneMapList* types = oracle->StoreReceiverTypes(this, name); |
| 540 receiver_types_ = types; |
| 541 } else if (is_monomorphic_) { |
| 542 // Record receiver type for monomorphic keyed loads. |
| 543 monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this); |
| 544 } |
| 545 } |
| 546 |
| 547 |
| 548 void CaseClause::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 549 TypeInfo info = oracle->SwitchType(this); |
| 550 if (info.IsSmi()) { |
| 551 compare_type_ = SMI_ONLY; |
| 552 } else if (info.IsNonPrimitive()) { |
| 553 compare_type_ = OBJECT_ONLY; |
| 554 } else { |
| 555 ASSERT(compare_type_ == NONE); |
| 556 } |
| 557 } |
| 558 |
| 559 |
| 560 static bool CallWithoutIC(Handle<JSFunction> target, int arity) { |
| 561 if (target->NeedsArgumentsAdaption()) { |
| 562 // If the number of formal parameters of the target function |
| 563 // does not match the number of arguments we're passing, we |
| 564 // don't want to deal with it. |
| 565 return target->shared()->formal_parameter_count() == arity; |
| 566 } else { |
| 567 // If the target doesn't need arguments adaption, we can call |
| 568 // it directly, but we avoid to do so if it has a custom call |
| 569 // generator, because that is likely to generate better code. |
| 570 return !target->shared()->HasCustomCallGenerator(); |
| 571 } |
| 572 } |
| 573 |
| 574 |
| 575 bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) { |
| 576 holder_ = Handle<JSObject>::null(); |
| 577 while (true) { |
| 578 LookupResult lookup; |
| 579 type->LookupInDescriptors(NULL, *name, &lookup); |
| 580 // If the function wasn't found directly in the map, we start |
| 581 // looking upwards through the prototype chain. |
| 582 if (!lookup.IsFound() && type->prototype()->IsJSObject()) { |
| 583 holder_ = Handle<JSObject>(JSObject::cast(type->prototype())); |
| 584 type = Handle<Map>(holder()->map()); |
| 585 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { |
| 586 target_ = Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type)); |
| 587 return CallWithoutIC(target_, arguments()->length()); |
| 588 } else { |
| 589 return false; |
| 590 } |
| 591 } |
| 592 } |
| 593 |
| 594 |
| 595 bool Call::ComputeGlobalTarget(Handle<GlobalObject> global, |
| 596 Handle<String> name) { |
| 597 target_ = Handle<JSFunction>::null(); |
| 598 cell_ = Handle<JSGlobalPropertyCell>::null(); |
| 599 LookupResult lookup; |
| 600 global->Lookup(*name, &lookup); |
| 601 if (lookup.IsProperty() && lookup.type() == NORMAL) { |
| 602 cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(&lookup)); |
| 603 if (cell_->value()->IsJSFunction()) { |
| 604 Handle<JSFunction> candidate(JSFunction::cast(cell_->value())); |
| 605 // If the function is in new space we assume it's more likely to |
| 606 // change and thus prefer the general IC code. |
| 607 if (!Isolate::Current()->heap()->InNewSpace(*candidate) |
| 608 && CallWithoutIC(candidate, arguments()->length())) { |
| 609 target_ = candidate; |
| 610 return true; |
| 611 } |
| 612 } |
| 613 } |
| 614 return false; |
| 615 } |
| 616 |
| 617 |
| 618 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 619 Property* property = expression()->AsProperty(); |
| 620 ASSERT(property != NULL); |
| 621 // Specialize for the receiver types seen at runtime. |
| 622 Literal* key = property->key()->AsLiteral(); |
| 623 ASSERT(key != NULL && key->handle()->IsString()); |
| 624 Handle<String> name = Handle<String>::cast(key->handle()); |
| 625 receiver_types_ = oracle->CallReceiverTypes(this, name); |
| 626 #ifdef DEBUG |
| 627 if (FLAG_enable_slow_asserts) { |
| 628 if (receiver_types_ != NULL) { |
| 629 int length = receiver_types_->length(); |
| 630 for (int i = 0; i < length; i++) { |
| 631 Handle<Map> map = receiver_types_->at(i); |
| 632 ASSERT(!map.is_null() && *map != NULL); |
| 633 } |
| 634 } |
| 635 } |
| 636 #endif |
| 637 if (receiver_types_ != NULL && receiver_types_->length() > 0) { |
| 638 Handle<Map> type = receiver_types_->at(0); |
| 639 is_monomorphic_ = oracle->CallIsMonomorphic(this); |
| 640 if (is_monomorphic_) is_monomorphic_ = ComputeTarget(type, name); |
| 641 } |
| 642 } |
| 643 |
| 644 |
| 645 void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 646 TypeInfo left = oracle->BinaryType(this, TypeFeedbackOracle::LEFT); |
| 647 TypeInfo right = oracle->BinaryType(this, TypeFeedbackOracle::RIGHT); |
| 648 is_smi_only_ = left.IsSmi() && right.IsSmi(); |
| 649 } |
| 650 |
| 651 |
| 652 void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 653 TypeInfo left = oracle->CompareType(this, TypeFeedbackOracle::LEFT); |
| 654 TypeInfo right = oracle->CompareType(this, TypeFeedbackOracle::RIGHT); |
| 655 if (left.IsSmi() && right.IsSmi()) { |
| 656 compare_type_ = SMI_ONLY; |
| 657 } else if (left.IsNonPrimitive() && right.IsNonPrimitive()) { |
| 658 compare_type_ = OBJECT_ONLY; |
| 659 } else { |
| 660 ASSERT(compare_type_ == NONE); |
| 661 } |
| 662 } |
| 663 |
| 664 |
| 665 // ---------------------------------------------------------------------------- |
| 378 // Implementation of AstVisitor | 666 // Implementation of AstVisitor |
| 379 | 667 |
| 380 bool AstVisitor::CheckStackOverflow() { | 668 bool AstVisitor::CheckStackOverflow() { |
| 381 if (stack_overflow_) return true; | 669 if (stack_overflow_) return true; |
| 382 StackLimitCheck check(Isolate::Current()); | 670 StackLimitCheck check(Isolate::Current()); |
| 383 if (!check.HasOverflowed()) return false; | 671 if (!check.HasOverflowed()) return false; |
| 384 return (stack_overflow_ = true); | 672 return (stack_overflow_ = true); |
| 385 } | 673 } |
| 386 | 674 |
| 387 | 675 |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 int node_max_match = node->max_match(); | 1025 int node_max_match = node->max_match(); |
| 738 if (kInfinity - max_match_ < node_max_match) { | 1026 if (kInfinity - max_match_ < node_max_match) { |
| 739 max_match_ = kInfinity; | 1027 max_match_ = kInfinity; |
| 740 } else { | 1028 } else { |
| 741 max_match_ += node->max_match(); | 1029 max_match_ += node->max_match(); |
| 742 } | 1030 } |
| 743 } | 1031 } |
| 744 } | 1032 } |
| 745 | 1033 |
| 746 | 1034 |
| 747 WhileStatement::WhileStatement(ZoneStringList* labels) | 1035 CaseClause::CaseClause(Expression* label, |
| 748 : IterationStatement(labels), | 1036 ZoneList<Statement*>* statements, |
| 749 cond_(NULL), | 1037 int pos) |
| 750 may_have_function_literal_(true) { | 1038 : label_(label), |
| 751 } | 1039 statements_(statements), |
| 752 | 1040 position_(pos), |
| 753 | 1041 compare_type_(NONE) {} |
| 754 CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements) | |
| 755 : label_(label), statements_(statements) { | |
| 756 } | |
| 757 | 1042 |
| 758 } } // namespace v8::internal | 1043 } } // namespace v8::internal |
| OLD | NEW |