Changeset 42337 in webkit for trunk/JavaScriptCore/parser/Nodes.cpp
- Timestamp:
- Apr 8, 2009, 4:08:28 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/parser/Nodes.cpp
r42065 r42337 405 405 } 406 406 407 bool ArrayNode::isSimpleArray() const 408 { 409 if (m_elision || m_optional) 410 return false; 411 for (ElementNode* ptr = m_element.get(); ptr; ptr = ptr->next()) { 412 if (ptr->elision()) 413 return false; 414 } 415 return true; 416 } 417 418 PassRefPtr<ArgumentListNode> ArrayNode::toArgumentList(JSGlobalData* globalData) const 419 { 420 ASSERT(!m_elision && !m_optional); 421 RefPtr<ArgumentListNode> head; 422 ElementNode* ptr = m_element.get(); 423 if (!ptr) 424 return head; 425 head = new ArgumentListNode(globalData, ptr->value()); 426 ArgumentListNode* tail = head.get(); 427 ptr = ptr->next(); 428 for (; ptr; ptr = ptr->next()) { 429 ASSERT(!ptr->elision()); 430 tail = new ArgumentListNode(globalData, tail, ptr->value()); 431 } 432 return head.release(); 433 } 434 407 435 // ------------------------------ PropertyNode ---------------------------- 408 436 … … 711 739 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr.get()); 712 740 m_args->m_listNode = m_args->m_listNode->m_next; 713 } else {741 } else 714 742 generator.emitLoad(thisRegister.get(), jsNull()); 715 } 743 716 744 generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset()); 717 745 generator.emitJump(end.get()); 718 746 m_args->m_listNode = oldList; 747 } 748 generator.emitLabel(realCall.get()); 749 { 750 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get()); 751 generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset()); 752 } 753 generator.emitLabel(end.get()); 754 return finalDestination.get(); 755 } 756 757 static bool areTrivialApplyArguments(ArgumentsNode* args) 758 { 759 return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next 760 || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray()); 761 } 762 763 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 764 { 765 // A few simple cases can be trivially handled as ordinary functions calls 766 // function.apply(), function.apply(arg) -> identical to function.call 767 // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation 768 bool mayBeCall = areTrivialApplyArguments(m_args.get()); 769 770 RefPtr<Label> realCall = generator.newLabel(); 771 RefPtr<Label> end = generator.newLabel(); 772 RefPtr<RegisterID> base = generator.emitNode(m_base.get()); 773 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 774 RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); 775 RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get()); 776 generator.emitJumpIfNotFunctionApply(function.get(), realCall.get()); 777 { 778 if (mayBeCall) { 779 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get()); 780 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 781 RefPtr<ArgumentListNode> oldList = m_args->m_listNode; 782 if (m_args->m_listNode && m_args->m_listNode->m_expr) { 783 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr.get()); 784 m_args->m_listNode = m_args->m_listNode->m_next; 785 if (m_args->m_listNode) { 786 ASSERT(m_args->m_listNode->m_expr->isSimpleArray()); 787 ASSERT(!m_args->m_listNode->m_next); 788 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr.get())->toArgumentList(generator.globalData()); 789 } 790 } else 791 generator.emitLoad(thisRegister.get(), jsNull()); 792 generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset()); 793 m_args->m_listNode = oldList; 794 } else { 795 ASSERT(m_args->m_listNode && m_args->m_listNode->m_next); 796 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get()); 797 RefPtr<RegisterID> argsCountRegister = generator.newTemporary(); 798 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 799 RefPtr<RegisterID> argsRegister = generator.newTemporary(); 800 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr.get()); 801 ArgumentListNode* args = m_args->m_listNode->m_next.get(); 802 generator.emitNode(argsRegister.get(), args->m_expr.get()); 803 while ((args = args->m_next.get())) 804 generator.emitNode(generator.newTemporary(), args->m_expr.get()); 805 806 generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get()); 807 generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset()); 808 } 809 generator.emitJump(end.get()); 719 810 } 720 811 generator.emitLabel(realCall.get());
Note:
See TracChangeset
for help on using the changeset viewer.