| 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 6636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6647 ASSERT(temp.is_valid()); | 6647 ASSERT(temp.is_valid()); |
| 6648 // Check if the object is a JS array or not. | 6648 // Check if the object is a JS array or not. |
| 6649 __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, temp.reg()); | 6649 __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, temp.reg()); |
| 6650 value.Unuse(); | 6650 value.Unuse(); |
| 6651 temp.Unuse(); | 6651 temp.Unuse(); |
| 6652 destination()->Split(equal); | 6652 destination()->Split(equal); |
| 6653 } | 6653 } |
| 6654 | 6654 |
| 6655 | 6655 |
| 6656 void CodeGenerator::GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args) { | 6656 void CodeGenerator::GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args) { |
| 6657 Label bailout, done, one_char_separator, long_separator, |
| 6658 non_trivial_array, not_size_one_array, loop, loop_condition, |
| 6659 loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; |
| 6660 |
| 6657 ASSERT(args->length() == 2); | 6661 ASSERT(args->length() == 2); |
| 6662 // We will leave the separator on the stack until the end of the function. |
| 6658 Load(args->at(1)); | 6663 Load(args->at(1)); |
| 6664 // Load this to eax (= array) |
| 6659 Load(args->at(0)); | 6665 Load(args->at(0)); |
| 6660 Result array_result = frame_->Pop(); | 6666 Result array_result = frame_->Pop(); |
| 6661 array_result.ToRegister(eax); | 6667 array_result.ToRegister(eax); |
| 6662 frame_->SpillAll(); | 6668 frame_->SpillAll(); |
| 6663 | 6669 |
| 6664 Label bailout; | |
| 6665 Label done; | |
| 6666 // All aliases of the same register have disjoint lifetimes. | 6670 // All aliases of the same register have disjoint lifetimes. |
| 6667 Register array = eax; | 6671 Register array = eax; |
| 6668 Register result_pos = no_reg; | 6672 Register elements = no_reg; // Will be eax. |
| 6669 | 6673 |
| 6670 Register index = edi; | 6674 Register index = edx; |
| 6671 | 6675 |
| 6672 Register current_string_length = ecx; // Will be ecx when live. | 6676 Register string_length = ecx; |
| 6673 | 6677 |
| 6674 Register current_string = edx; | 6678 Register string = esi; |
| 6675 | 6679 |
| 6676 Register scratch = ebx; | 6680 Register scratch = ebx; |
| 6677 | 6681 |
| 6678 Register scratch_2 = esi; | 6682 Register array_length = edi; |
| 6679 Register new_padding_chars = scratch_2; | 6683 Register result_pos = no_reg; // Will be edi. |
| 6680 | 6684 |
| 6681 Operand separator = Operand(esp, 4 * kPointerSize); // Already pushed. | 6685 // Separator operand is already pushed. |
| 6682 Operand elements = Operand(esp, 3 * kPointerSize); | 6686 Operand separator_operand = Operand(esp, 2 * kPointerSize); |
| 6683 Operand result = Operand(esp, 2 * kPointerSize); | 6687 Operand result_operand = Operand(esp, 1 * kPointerSize); |
| 6684 Operand padding_chars = Operand(esp, 1 * kPointerSize); | 6688 Operand array_length_operand = Operand(esp, 0); |
| 6685 Operand array_length = Operand(esp, 0); | 6689 __ sub(Operand(esp), Immediate(2 * kPointerSize)); |
| 6686 __ sub(Operand(esp), Immediate(4 * kPointerSize)); | 6690 __ cld(); |
| 6687 | 6691 // Check that the array is a JSArray |
| 6688 // Check that eax is a JSArray | |
| 6689 __ test(array, Immediate(kSmiTagMask)); | 6692 __ test(array, Immediate(kSmiTagMask)); |
| 6690 __ j(zero, &bailout); | 6693 __ j(zero, &bailout); |
| 6691 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); | 6694 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); |
| 6692 __ j(not_equal, &bailout); | 6695 __ j(not_equal, &bailout); |
| 6693 | 6696 |
| 6694 // Check that the array has fast elements. | 6697 // Check that the array has fast elements. |
| 6695 __ test_b(FieldOperand(scratch, Map::kBitField2Offset), | 6698 __ test_b(FieldOperand(scratch, Map::kBitField2Offset), |
| 6696 1 << Map::kHasFastElements); | 6699 1 << Map::kHasFastElements); |
| 6697 __ j(zero, &bailout); | 6700 __ j(zero, &bailout); |
| 6698 | 6701 |
| 6699 // If the array is empty, return the empty string. | 6702 // If the array has length zero, return the empty string. |
| 6700 __ mov(scratch, FieldOperand(array, JSArray::kLengthOffset)); | 6703 __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset)); |
| 6701 __ sar(scratch, 1); | 6704 __ sar(array_length, 1); |
| 6702 Label non_trivial; | 6705 __ j(not_zero, &non_trivial_array); |
| 6703 __ j(not_zero, &non_trivial); | 6706 __ mov(result_operand, FACTORY->empty_string()); |
| 6704 __ mov(result, FACTORY->empty_string()); | 6707 __ jmp(&done); |
| 6705 __ jmp(&done); | 6708 |
| 6706 | 6709 // Save the array length. |
| 6707 __ bind(&non_trivial); | 6710 __ bind(&non_trivial_array); |
| 6708 __ mov(array_length, scratch); | 6711 __ mov(array_length_operand, array_length); |
| 6709 | 6712 |
| 6710 __ mov(scratch, FieldOperand(array, JSArray::kElementsOffset)); | 6713 // Save the FixedArray containing array's elements. |
| 6711 __ mov(elements, scratch); | |
| 6712 | |
| 6713 // End of array's live range. | 6714 // End of array's live range. |
| 6714 result_pos = array; | 6715 elements = array; |
| 6716 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); |
| 6715 array = no_reg; | 6717 array = no_reg; |
| 6716 | 6718 |
| 6717 | 6719 |
| 6718 // Check that the separator is a flat ascii string. | 6720 // Check that all array elements are sequential ASCII strings, and |
| 6719 __ mov(current_string, separator); | 6721 // accumulate the sum of their lengths, as a smi-encoded value. |
| 6720 __ test(current_string, Immediate(kSmiTagMask)); | 6722 __ Set(index, Immediate(0)); |
| 6723 __ Set(string_length, Immediate(0)); |
| 6724 // Loop condition: while (index < length). |
| 6725 // Live loop registers: index, array_length, string, |
| 6726 // scratch, string_length, elements. |
| 6727 __ jmp(&loop_condition); |
| 6728 __ bind(&loop); |
| 6729 __ cmp(index, Operand(array_length)); |
| 6730 __ j(greater_equal, &done); |
| 6731 |
| 6732 __ mov(string, FieldOperand(elements, index, |
| 6733 times_pointer_size, |
| 6734 FixedArray::kHeaderSize)); |
| 6735 __ test(string, Immediate(kSmiTagMask)); |
| 6721 __ j(zero, &bailout); | 6736 __ j(zero, &bailout); |
| 6722 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset)); | 6737 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 6723 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 6738 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 6724 __ and_(scratch, Immediate( | 6739 __ and_(scratch, Immediate( |
| 6725 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); | 6740 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); |
| 6726 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); | 6741 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); |
| 6727 __ j(not_equal, &bailout); | 6742 __ j(not_equal, &bailout); |
| 6728 // If the separator is the empty string, replace it with NULL. | 6743 __ add(string_length, |
| 6729 // The test for NULL is quicker than the empty string test, in a loop. | 6744 FieldOperand(string, SeqAsciiString::kLengthOffset)); |
| 6730 __ cmp(FieldOperand(current_string, SeqAsciiString::kLengthOffset), | 6745 __ j(overflow, &bailout); |
| 6731 Immediate(0)); | 6746 __ add(Operand(index), Immediate(1)); |
| 6732 Label separator_checked; | 6747 __ bind(&loop_condition); |
| 6733 __ j(not_zero, &separator_checked); | 6748 __ cmp(index, Operand(array_length)); |
| 6734 __ mov(separator, Immediate(0)); | 6749 __ j(less, &loop); |
| 6735 __ bind(&separator_checked); | 6750 |
| 6736 | 6751 // If array_length is 1, return elements[0], a string. |
| 6737 // Check that elements[0] is a flat ascii string, and copy it in new space. | 6752 __ cmp(array_length, 1); |
| 6738 __ mov(scratch, elements); | 6753 __ j(not_equal, ¬_size_one_array); |
| 6739 __ mov(current_string, FieldOperand(scratch, FixedArray::kHeaderSize)); | 6754 __ mov(scratch, FieldOperand(elements, FixedArray::kHeaderSize)); |
| 6740 __ test(current_string, Immediate(kSmiTagMask)); | 6755 __ mov(result_operand, scratch); |
| 6756 __ jmp(&done); |
| 6757 |
| 6758 __ bind(¬_size_one_array); |
| 6759 |
| 6760 // End of array_length live range. |
| 6761 result_pos = array_length; |
| 6762 array_length = no_reg; |
| 6763 |
| 6764 // Live registers: |
| 6765 // string_length: Sum of string lengths, as a smi. |
| 6766 // elements: FixedArray of strings. |
| 6767 |
| 6768 // Check that the separator is a flat ASCII string. |
| 6769 __ mov(string, separator_operand); |
| 6770 __ test(string, Immediate(kSmiTagMask)); |
| 6741 __ j(zero, &bailout); | 6771 __ j(zero, &bailout); |
| 6742 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset)); | 6772 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 6743 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 6773 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 6744 __ and_(scratch, Immediate( | 6774 __ and_(scratch, Immediate( |
| 6745 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); | 6775 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); |
| 6746 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); | 6776 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); |
| 6747 __ j(not_equal, &bailout); | 6777 __ j(not_equal, &bailout); |
| 6748 | 6778 |
| 6749 // Allocate space to copy it. Round up the size to the alignment granularity. | 6779 // Add (separator length times array_length) - separator length |
| 6750 __ mov(current_string_length, | 6780 // to string_length. |
| 6751 FieldOperand(current_string, String::kLengthOffset)); | 6781 __ mov(scratch, separator_operand); |
| 6752 __ shr(current_string_length, 1); | 6782 __ mov(scratch, FieldOperand(scratch, SeqAsciiString::kLengthOffset)); |
| 6753 | 6783 __ sub(string_length, Operand(scratch)); // May be negative, temporarily. |
| 6784 __ imul(scratch, array_length_operand); |
| 6785 __ j(overflow, &bailout); |
| 6786 __ add(string_length, Operand(scratch)); |
| 6787 __ j(overflow, &bailout); |
| 6788 |
| 6789 __ shr(string_length, 1); |
| 6754 // Live registers and stack values: | 6790 // Live registers and stack values: |
| 6755 // current_string_length: length of elements[0]. | 6791 // string_length |
| 6756 | 6792 // elements |
| 6757 // New string result in new space = elements[0] | 6793 __ AllocateAsciiString(result_pos, string_length, scratch, |
| 6758 __ AllocateAsciiString(result_pos, current_string_length, scratch_2, | 6794 index, string, &bailout); |
| 6759 index, no_reg, &bailout); | 6795 __ mov(result_operand, result_pos); |
| 6760 __ mov(result, result_pos); | 6796 __ lea(result_pos, FieldOperand(result_pos, SeqAsciiString::kHeaderSize)); |
| 6761 | 6797 |
| 6762 // Adjust current_string_length to include padding bytes at end of string. | 6798 |
| 6763 // Keep track of the number of padding bytes. | 6799 __ mov(string, separator_operand); |
| 6764 __ mov(new_padding_chars, current_string_length); | 6800 __ cmp(FieldOperand(string, SeqAsciiString::kLengthOffset), |
| 6765 __ add(Operand(current_string_length), Immediate(kObjectAlignmentMask)); | 6801 Immediate(Smi::FromInt(1))); |
| 6766 __ and_(Operand(current_string_length), Immediate(~kObjectAlignmentMask)); | 6802 __ j(equal, &one_char_separator); |
| 6767 __ sub(new_padding_chars, Operand(current_string_length)); | 6803 __ j(greater, &long_separator); |
| 6768 __ neg(new_padding_chars); | 6804 |
| 6769 __ mov(padding_chars, new_padding_chars); | 6805 |
| 6770 | 6806 // Empty separator case |
| 6771 Label copy_loop_1_done; | 6807 __ mov(index, Immediate(0)); |
| 6772 Label copy_loop_1; | 6808 __ jmp(&loop_1_condition); |
| 6773 __ test(current_string_length, Operand(current_string_length)); | 6809 // Loop condition: while (index < length). |
| 6774 __ j(zero, ©_loop_1_done); | 6810 __ bind(&loop_1); |
| 6775 __ bind(©_loop_1); | 6811 // Each iteration of the loop concatenates one string to the result. |
| 6776 __ sub(Operand(current_string_length), Immediate(kPointerSize)); | 6812 // Live values in registers: |
| 6777 __ mov(scratch, FieldOperand(current_string, current_string_length, | 6813 // index: which element of the elements array we are adding to the result. |
| 6778 times_1, SeqAsciiString::kHeaderSize)); | 6814 // result_pos: the position to which we are currently copying characters. |
| 6779 __ mov(FieldOperand(result_pos, current_string_length, | 6815 // elements: the FixedArray of strings we are joining. |
| 6780 times_1, SeqAsciiString::kHeaderSize), | 6816 |
| 6781 scratch); | 6817 // Get string = array[index]. |
| 6782 __ j(not_zero, ©_loop_1); | 6818 __ mov(string, FieldOperand(elements, index, |
| 6783 __ bind(©_loop_1_done); | 6819 times_pointer_size, |
| 6784 | 6820 FixedArray::kHeaderSize)); |
| 6785 __ mov(index, Immediate(1)); | 6821 __ mov(string_length, |
| 6786 // Loop condition: while (index < length). | 6822 FieldOperand(string, String::kLengthOffset)); |
| 6787 Label loop; | 6823 __ shr(string_length, 1); |
| 6788 __ bind(&loop); | 6824 __ lea(string, |
| 6789 __ cmp(index, array_length); | 6825 FieldOperand(string, SeqAsciiString::kHeaderSize)); |
| 6790 __ j(greater_equal, &done); | 6826 __ CopyBytes(string, result_pos, string_length, scratch); |
| 6791 | 6827 __ add(Operand(index), Immediate(1)); |
| 6792 // If the separator is the empty string, signalled by NULL, skip it. | 6828 __ bind(&loop_1_condition); |
| 6793 Label separator_done; | 6829 __ cmp(index, array_length_operand); |
| 6794 __ mov(current_string, separator); | 6830 __ j(less, &loop_1); // End while (index < length). |
| 6795 __ test(current_string, Operand(current_string)); | 6831 __ jmp(&done); |
| 6796 __ j(zero, &separator_done); | 6832 |
| 6797 | 6833 |
| 6798 // Append separator to result. It is known to be a flat ascii string. | 6834 |
| 6799 __ AppendStringToTopOfNewSpace(current_string, current_string_length, | 6835 // One-character separator case |
| 6800 result_pos, scratch, scratch_2, result, | 6836 __ bind(&one_char_separator); |
| 6801 padding_chars, &bailout); | 6837 // Replace separator with its ascii character value. |
| 6802 __ bind(&separator_done); | 6838 __ mov_b(scratch, FieldOperand(string, SeqAsciiString::kHeaderSize)); |
| 6803 | 6839 __ mov_b(separator_operand, scratch); |
| 6804 // Add next element of array to the end of the result. | 6840 |
| 6805 // Get current_string = array[index]. | 6841 __ Set(index, Immediate(0)); |
| 6806 __ mov(scratch, elements); | 6842 // Jump into the loop after the code that copies the separator, so the first |
| 6807 __ mov(current_string, FieldOperand(scratch, index, | 6843 // element is not preceded by a separator |
| 6808 times_pointer_size, | 6844 __ jmp(&loop_2_entry); |
| 6809 FixedArray::kHeaderSize)); | 6845 // Loop condition: while (index < length). |
| 6810 // If current != flat ascii string drop result, return undefined. | 6846 __ bind(&loop_2); |
| 6811 __ test(current_string, Immediate(kSmiTagMask)); | 6847 // Each iteration of the loop concatenates one string to the result. |
| 6812 __ j(zero, &bailout); | 6848 // Live values in registers: |
| 6813 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset)); | 6849 // index: which element of the elements array we are adding to the result. |
| 6814 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 6850 // result_pos: the position to which we are currently copying characters. |
| 6815 __ and_(scratch, Immediate( | 6851 |
| 6816 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); | 6852 // Copy the separator character to the result. |
| 6817 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); | 6853 __ mov_b(scratch, separator_operand); |
| 6818 __ j(not_equal, &bailout); | 6854 __ mov_b(Operand(result_pos, 0), scratch); |
| 6819 | 6855 __ inc(result_pos); |
| 6820 // Append current to the result. | 6856 |
| 6821 __ AppendStringToTopOfNewSpace(current_string, current_string_length, | 6857 __ bind(&loop_2_entry); |
| 6822 result_pos, scratch, scratch_2, result, | 6858 // Get string = array[index]. |
| 6823 padding_chars, &bailout); | 6859 __ mov(string, FieldOperand(elements, index, |
| 6824 __ add(Operand(index), Immediate(1)); | 6860 times_pointer_size, |
| 6825 __ jmp(&loop); // End while (index < length). | 6861 FixedArray::kHeaderSize)); |
| 6862 __ mov(string_length, |
| 6863 FieldOperand(string, String::kLengthOffset)); |
| 6864 __ shr(string_length, 1); |
| 6865 __ lea(string, |
| 6866 FieldOperand(string, SeqAsciiString::kHeaderSize)); |
| 6867 __ CopyBytes(string, result_pos, string_length, scratch); |
| 6868 __ add(Operand(index), Immediate(1)); |
| 6869 |
| 6870 __ cmp(index, array_length_operand); |
| 6871 __ j(less, &loop_2); // End while (index < length). |
| 6872 __ jmp(&done); |
| 6873 |
| 6874 |
| 6875 // Long separator case (separator is more than one character). |
| 6876 __ bind(&long_separator); |
| 6877 |
| 6878 __ Set(index, Immediate(0)); |
| 6879 // Jump into the loop after the code that copies the separator, so the first |
| 6880 // element is not preceded by a separator |
| 6881 __ jmp(&loop_3_entry); |
| 6882 // Loop condition: while (index < length). |
| 6883 __ bind(&loop_3); |
| 6884 // Each iteration of the loop concatenates one string to the result. |
| 6885 // Live values in registers: |
| 6886 // index: which element of the elements array we are adding to the result. |
| 6887 // result_pos: the position to which we are currently copying characters. |
| 6888 |
| 6889 // Copy the separator to the result. |
| 6890 __ mov(string, separator_operand); |
| 6891 __ mov(string_length, |
| 6892 FieldOperand(string, String::kLengthOffset)); |
| 6893 __ shr(string_length, 1); |
| 6894 __ lea(string, |
| 6895 FieldOperand(string, SeqAsciiString::kHeaderSize)); |
| 6896 __ CopyBytes(string, result_pos, string_length, scratch); |
| 6897 |
| 6898 __ bind(&loop_3_entry); |
| 6899 // Get string = array[index]. |
| 6900 __ mov(string, FieldOperand(elements, index, |
| 6901 times_pointer_size, |
| 6902 FixedArray::kHeaderSize)); |
| 6903 __ mov(string_length, |
| 6904 FieldOperand(string, String::kLengthOffset)); |
| 6905 __ shr(string_length, 1); |
| 6906 __ lea(string, |
| 6907 FieldOperand(string, SeqAsciiString::kHeaderSize)); |
| 6908 __ CopyBytes(string, result_pos, string_length, scratch); |
| 6909 __ add(Operand(index), Immediate(1)); |
| 6910 |
| 6911 __ cmp(index, array_length_operand); |
| 6912 __ j(less, &loop_3); // End while (index < length). |
| 6913 __ jmp(&done); |
| 6914 |
| 6826 | 6915 |
| 6827 __ bind(&bailout); | 6916 __ bind(&bailout); |
| 6828 __ mov(result, FACTORY->undefined_value()); | 6917 __ mov(result_operand, FACTORY->undefined_value()); |
| 6829 __ bind(&done); | 6918 __ bind(&done); |
| 6830 __ mov(eax, result); | 6919 __ mov(eax, result_operand); |
| 6831 // Drop temp values from the stack, and restore context register. | 6920 // Drop temp values from the stack, and restore context register. |
| 6832 __ add(Operand(esp), Immediate(4 * kPointerSize)); | 6921 __ add(Operand(esp), Immediate(2 * kPointerSize)); |
| 6833 | 6922 |
| 6834 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 6923 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 6835 frame_->Drop(1); | 6924 frame_->Drop(1); |
| 6836 frame_->Push(&array_result); | 6925 frame_->Push(&array_result); |
| 6837 } | 6926 } |
| 6838 | 6927 |
| 6839 | 6928 |
| 6840 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) { | 6929 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) { |
| 6841 ASSERT(args->length() == 1); | 6930 ASSERT(args->length() == 1); |
| 6842 Load(args->at(0)); | 6931 Load(args->at(0)); |
| (...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8139 Slot* slot = variable->AsSlot(); | 8228 Slot* slot = variable->AsSlot(); |
| 8140 if (variable->is_global()) { | 8229 if (variable->is_global()) { |
| 8141 LoadGlobal(); | 8230 LoadGlobal(); |
| 8142 frame_->Push(variable->name()); | 8231 frame_->Push(variable->name()); |
| 8143 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, | 8232 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, |
| 8144 CALL_FUNCTION, 2); | 8233 CALL_FUNCTION, 2); |
| 8145 frame_->Push(&answer); | 8234 frame_->Push(&answer); |
| 8146 return; | 8235 return; |
| 8147 | 8236 |
| 8148 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 8237 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 8149 // Call the runtime to look up the context holding the named | 8238 // Call the runtime to delete from the context holding the named |
| 8150 // variable. Sync the virtual frame eagerly so we can push the | 8239 // variable. Sync the virtual frame eagerly so we can push the |
| 8151 // arguments directly into place. | 8240 // arguments directly into place. |
| 8152 frame_->SyncRange(0, frame_->element_count() - 1); | 8241 frame_->SyncRange(0, frame_->element_count() - 1); |
| 8153 frame_->EmitPush(esi); | 8242 frame_->EmitPush(esi); |
| 8154 frame_->EmitPush(Immediate(variable->name())); | 8243 frame_->EmitPush(Immediate(variable->name())); |
| 8155 Result context = frame_->CallRuntime(Runtime::kLookupContext, 2); | 8244 Result answer = frame_->CallRuntime(Runtime::kDeleteContextSlot, 2); |
| 8156 ASSERT(context.is_register()); | |
| 8157 frame_->EmitPush(context.reg()); | |
| 8158 context.Unuse(); | |
| 8159 frame_->EmitPush(Immediate(variable->name())); | |
| 8160 Result answer = frame_->InvokeBuiltin(Builtins::DELETE, | |
| 8161 CALL_FUNCTION, 2); | |
| 8162 frame_->Push(&answer); | 8245 frame_->Push(&answer); |
| 8163 return; | 8246 return; |
| 8164 } | 8247 } |
| 8165 | 8248 |
| 8166 // Default: Result of deleting non-global, not dynamically | 8249 // Default: Result of deleting non-global, not dynamically |
| 8167 // introduced variables is false. | 8250 // introduced variables is false. |
| 8168 frame_->Push(FACTORY->false_value()); | 8251 frame_->Push(FACTORY->false_value()); |
| 8169 | 8252 |
| 8170 } else { | 8253 } else { |
| 8171 // Default: Result of deleting expressions is true. | 8254 // Default: Result of deleting expressions is true. |
| (...skipping 2065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10237 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); | 10320 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); |
| 10238 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); | 10321 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); |
| 10239 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); | 10322 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); |
| 10240 } | 10323 } |
| 10241 | 10324 |
| 10242 #undef __ | 10325 #undef __ |
| 10243 | 10326 |
| 10244 } } // namespace v8::internal | 10327 } } // namespace v8::internal |
| 10245 | 10328 |
| 10246 #endif // V8_TARGET_ARCH_IA32 | 10329 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |