| 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 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 elms->set(WRITABLE_INDEX, heap->false_value()); | 816 elms->set(WRITABLE_INDEX, heap->false_value()); |
| 817 elms->set(ENUMERABLE_INDEX, heap->false_value()); | 817 elms->set(ENUMERABLE_INDEX, heap->false_value()); |
| 818 elms->set(CONFIGURABLE_INDEX, heap->false_value()); | 818 elms->set(CONFIGURABLE_INDEX, heap->false_value()); |
| 819 return *desc; | 819 return *desc; |
| 820 } | 820 } |
| 821 | 821 |
| 822 case JSObject::INTERCEPTED_ELEMENT: | 822 case JSObject::INTERCEPTED_ELEMENT: |
| 823 case JSObject::FAST_ELEMENT: { | 823 case JSObject::FAST_ELEMENT: { |
| 824 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 824 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 825 Handle<Object> value = GetElement(obj, index); | 825 Handle<Object> value = GetElement(obj, index); |
| 826 RETURN_IF_EMPTY_HANDLE(isolate, value); |
| 826 elms->set(VALUE_INDEX, *value); | 827 elms->set(VALUE_INDEX, *value); |
| 827 elms->set(WRITABLE_INDEX, heap->true_value()); | 828 elms->set(WRITABLE_INDEX, heap->true_value()); |
| 828 elms->set(ENUMERABLE_INDEX, heap->true_value()); | 829 elms->set(ENUMERABLE_INDEX, heap->true_value()); |
| 829 elms->set(CONFIGURABLE_INDEX, heap->true_value()); | 830 elms->set(CONFIGURABLE_INDEX, heap->true_value()); |
| 830 return *desc; | 831 return *desc; |
| 831 } | 832 } |
| 832 | 833 |
| 833 case JSObject::DICTIONARY_ELEMENT: { | 834 case JSObject::DICTIONARY_ELEMENT: { |
| 834 Handle<JSObject> holder = obj; | 835 Handle<JSObject> holder = obj; |
| 835 if (obj->IsJSGlobalProxy()) { | 836 if (obj->IsJSGlobalProxy()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 853 } | 854 } |
| 854 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { | 855 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
| 855 elms->set(SETTER_INDEX, callbacks->get(1)); | 856 elms->set(SETTER_INDEX, callbacks->get(1)); |
| 856 } | 857 } |
| 857 break; | 858 break; |
| 858 } | 859 } |
| 859 case NORMAL: { | 860 case NORMAL: { |
| 860 // This is a data property. | 861 // This is a data property. |
| 861 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 862 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 862 Handle<Object> value = GetElement(obj, index); | 863 Handle<Object> value = GetElement(obj, index); |
| 864 ASSERT(!value.is_null()); |
| 863 elms->set(VALUE_INDEX, *value); | 865 elms->set(VALUE_INDEX, *value); |
| 864 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); | 866 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); |
| 865 break; | 867 break; |
| 866 } | 868 } |
| 867 default: | 869 default: |
| 868 UNREACHABLE(); | 870 UNREACHABLE(); |
| 869 break; | 871 break; |
| 870 } | 872 } |
| 871 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); | 873 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); |
| 872 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete())); | 874 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete())); |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 // should have been a const redeclaration error when declaring | 1525 // should have been a const redeclaration error when declaring |
| 1524 // the const property. | 1526 // the const property. |
| 1525 ASSERT(!holder.is_identical_to(context)); | 1527 ASSERT(!holder.is_identical_to(context)); |
| 1526 if ((attributes & READ_ONLY) == 0) { | 1528 if ((attributes & READ_ONLY) == 0) { |
| 1527 Handle<Context>::cast(holder)->set(index, *value); | 1529 Handle<Context>::cast(holder)->set(index, *value); |
| 1528 } | 1530 } |
| 1529 } else { | 1531 } else { |
| 1530 // The holder is an arguments object. | 1532 // The holder is an arguments object. |
| 1531 ASSERT((attributes & READ_ONLY) == 0); | 1533 ASSERT((attributes & READ_ONLY) == 0); |
| 1532 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); | 1534 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); |
| 1533 SetElement(arguments, index, value); | 1535 RETURN_IF_EMPTY_HANDLE(isolate, SetElement(arguments, index, value)); |
| 1534 } | 1536 } |
| 1535 return *value; | 1537 return *value; |
| 1536 } | 1538 } |
| 1537 | 1539 |
| 1538 // The property could not be found, we introduce it in the global | 1540 // The property could not be found, we introduce it in the global |
| 1539 // context. | 1541 // context. |
| 1540 if (attributes == ABSENT) { | 1542 if (attributes == ABSENT) { |
| 1541 Handle<JSObject> global = Handle<JSObject>( | 1543 Handle<JSObject> global = Handle<JSObject>( |
| 1542 isolate->context()->global()); | 1544 isolate->context()->global()); |
| 1543 // Strict mode not needed (const disallowed in strict mode). | 1545 // Strict mode not needed (const disallowed in strict mode). |
| (...skipping 2404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 obj_value, | 3950 obj_value, |
| 3949 attr); | 3951 attr); |
| 3950 } | 3952 } |
| 3951 | 3953 |
| 3952 | 3954 |
| 3953 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, | 3955 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, |
| 3954 Handle<Object> object, | 3956 Handle<Object> object, |
| 3955 Handle<Object> key, | 3957 Handle<Object> key, |
| 3956 Handle<Object> value, | 3958 Handle<Object> value, |
| 3957 PropertyAttributes attr, | 3959 PropertyAttributes attr, |
| 3958 StrictModeFlag strict) { | 3960 StrictModeFlag strict_mode) { |
| 3959 HandleScope scope(isolate); | 3961 HandleScope scope(isolate); |
| 3960 | 3962 |
| 3961 if (object->IsUndefined() || object->IsNull()) { | 3963 if (object->IsUndefined() || object->IsNull()) { |
| 3962 Handle<Object> args[2] = { key, object }; | 3964 Handle<Object> args[2] = { key, object }; |
| 3963 Handle<Object> error = | 3965 Handle<Object> error = |
| 3964 isolate->factory()->NewTypeError("non_object_property_store", | 3966 isolate->factory()->NewTypeError("non_object_property_store", |
| 3965 HandleVector(args, 2)); | 3967 HandleVector(args, 2)); |
| 3966 return isolate->Throw(*error); | 3968 return isolate->Throw(*error); |
| 3967 } | 3969 } |
| 3968 | 3970 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3991 return *value; | 3993 return *value; |
| 3992 } | 3994 } |
| 3993 | 3995 |
| 3994 if (key->IsString()) { | 3996 if (key->IsString()) { |
| 3995 Handle<Object> result; | 3997 Handle<Object> result; |
| 3996 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 3998 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
| 3997 result = SetElement(js_object, index, value); | 3999 result = SetElement(js_object, index, value); |
| 3998 } else { | 4000 } else { |
| 3999 Handle<String> key_string = Handle<String>::cast(key); | 4001 Handle<String> key_string = Handle<String>::cast(key); |
| 4000 key_string->TryFlatten(); | 4002 key_string->TryFlatten(); |
| 4001 result = SetProperty(js_object, key_string, value, attr, strict); | 4003 result = SetProperty(js_object, key_string, value, attr, strict_mode); |
| 4002 } | 4004 } |
| 4003 if (result.is_null()) return Failure::Exception(); | 4005 if (result.is_null()) return Failure::Exception(); |
| 4004 return *value; | 4006 return *value; |
| 4005 } | 4007 } |
| 4006 | 4008 |
| 4007 // Call-back into JavaScript to convert the key to a string. | 4009 // Call-back into JavaScript to convert the key to a string. |
| 4008 bool has_pending_exception = false; | 4010 bool has_pending_exception = false; |
| 4009 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4011 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
| 4010 if (has_pending_exception) return Failure::Exception(); | 4012 if (has_pending_exception) return Failure::Exception(); |
| 4011 Handle<String> name = Handle<String>::cast(converted); | 4013 Handle<String> name = Handle<String>::cast(converted); |
| 4012 | 4014 |
| 4013 if (name->AsArrayIndex(&index)) { | 4015 if (name->AsArrayIndex(&index)) { |
| 4014 // TODO(1220): Implement SetElement strict mode. | 4016 // TODO(1220): Implement SetElement strict mode. |
| 4015 return js_object->SetElement(index, *value); | 4017 return js_object->SetElement(index, *value); |
| 4016 } else { | 4018 } else { |
| 4017 return js_object->SetProperty(*name, *value, attr, strict); | 4019 return js_object->SetProperty(*name, *value, attr, strict_mode); |
| 4018 } | 4020 } |
| 4019 } | 4021 } |
| 4020 | 4022 |
| 4021 | 4023 |
| 4022 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, | 4024 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, |
| 4023 Handle<JSObject> js_object, | 4025 Handle<JSObject> js_object, |
| 4024 Handle<Object> key, | 4026 Handle<Object> key, |
| 4025 Handle<Object> value, | 4027 Handle<Object> value, |
| 4026 PropertyAttributes attr) { | 4028 PropertyAttributes attr) { |
| 4027 HandleScope scope(isolate); | 4029 HandleScope scope(isolate); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4114 Handle<Object> object = args.at<Object>(0); | 4116 Handle<Object> object = args.at<Object>(0); |
| 4115 Handle<Object> key = args.at<Object>(1); | 4117 Handle<Object> key = args.at<Object>(1); |
| 4116 Handle<Object> value = args.at<Object>(2); | 4118 Handle<Object> value = args.at<Object>(2); |
| 4117 CONVERT_SMI_CHECKED(unchecked_attributes, args[3]); | 4119 CONVERT_SMI_CHECKED(unchecked_attributes, args[3]); |
| 4118 RUNTIME_ASSERT( | 4120 RUNTIME_ASSERT( |
| 4119 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4121 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 4120 // Compute attributes. | 4122 // Compute attributes. |
| 4121 PropertyAttributes attributes = | 4123 PropertyAttributes attributes = |
| 4122 static_cast<PropertyAttributes>(unchecked_attributes); | 4124 static_cast<PropertyAttributes>(unchecked_attributes); |
| 4123 | 4125 |
| 4124 StrictModeFlag strict = kNonStrictMode; | 4126 StrictModeFlag strict_mode = kNonStrictMode; |
| 4125 if (args.length() == 5) { | 4127 if (args.length() == 5) { |
| 4126 CONVERT_SMI_CHECKED(strict_unchecked, args[4]); | 4128 CONVERT_SMI_CHECKED(strict_unchecked, args[4]); |
| 4127 RUNTIME_ASSERT(strict_unchecked == kStrictMode || | 4129 RUNTIME_ASSERT(strict_unchecked == kStrictMode || |
| 4128 strict_unchecked == kNonStrictMode); | 4130 strict_unchecked == kNonStrictMode); |
| 4129 strict = static_cast<StrictModeFlag>(strict_unchecked); | 4131 strict_mode = static_cast<StrictModeFlag>(strict_unchecked); |
| 4130 } | 4132 } |
| 4131 | 4133 |
| 4132 return Runtime::SetObjectProperty(isolate, | 4134 return Runtime::SetObjectProperty(isolate, |
| 4133 object, | 4135 object, |
| 4134 key, | 4136 key, |
| 4135 value, | 4137 value, |
| 4136 attributes, | 4138 attributes, |
| 4137 strict); | 4139 strict_mode); |
| 4138 } | 4140 } |
| 4139 | 4141 |
| 4140 | 4142 |
| 4141 // Set a local property, even if it is READ_ONLY. If the property does not | 4143 // Set a local property, even if it is READ_ONLY. If the property does not |
| 4142 // exist, it will be added with attributes NONE. | 4144 // exist, it will be added with attributes NONE. |
| 4143 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty( | 4145 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty( |
| 4144 RUNTIME_CALLING_CONVENTION) { | 4146 RUNTIME_CALLING_CONVENTION) { |
| 4145 RUNTIME_GET_ISOLATE; | 4147 RUNTIME_GET_ISOLATE; |
| 4146 NoHandleAllocation ha; | 4148 NoHandleAllocation ha; |
| 4147 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 4149 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
| (...skipping 3723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7871 RUNTIME_GET_ISOLATE; | 7873 RUNTIME_GET_ISOLATE; |
| 7872 HandleScope scope(isolate); | 7874 HandleScope scope(isolate); |
| 7873 ASSERT(args.length() == 4); | 7875 ASSERT(args.length() == 4); |
| 7874 | 7876 |
| 7875 Handle<Object> value(args[0], isolate); | 7877 Handle<Object> value(args[0], isolate); |
| 7876 CONVERT_ARG_CHECKED(Context, context, 1); | 7878 CONVERT_ARG_CHECKED(Context, context, 1); |
| 7877 CONVERT_ARG_CHECKED(String, name, 2); | 7879 CONVERT_ARG_CHECKED(String, name, 2); |
| 7878 CONVERT_SMI_CHECKED(strict_unchecked, args[3]); | 7880 CONVERT_SMI_CHECKED(strict_unchecked, args[3]); |
| 7879 RUNTIME_ASSERT(strict_unchecked == kStrictMode || | 7881 RUNTIME_ASSERT(strict_unchecked == kStrictMode || |
| 7880 strict_unchecked == kNonStrictMode); | 7882 strict_unchecked == kNonStrictMode); |
| 7881 StrictModeFlag strict = static_cast<StrictModeFlag>(strict_unchecked); | 7883 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked); |
| 7882 | |
| 7883 | 7884 |
| 7884 int index; | 7885 int index; |
| 7885 PropertyAttributes attributes; | 7886 PropertyAttributes attributes; |
| 7886 ContextLookupFlags flags = FOLLOW_CHAINS; | 7887 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 7887 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); | 7888 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); |
| 7888 | 7889 |
| 7889 if (index >= 0) { | 7890 if (index >= 0) { |
| 7890 if (holder->IsContext()) { | 7891 if (holder->IsContext()) { |
| 7891 // Ignore if read_only variable. | 7892 // Ignore if read_only variable. |
| 7892 if ((attributes & READ_ONLY) == 0) { | 7893 if ((attributes & READ_ONLY) == 0) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 7916 // The property was not found. It needs to be stored in the global context. | 7917 // The property was not found. It needs to be stored in the global context. |
| 7917 ASSERT(attributes == ABSENT); | 7918 ASSERT(attributes == ABSENT); |
| 7918 attributes = NONE; | 7919 attributes = NONE; |
| 7919 context_ext = Handle<JSObject>(isolate->context()->global()); | 7920 context_ext = Handle<JSObject>(isolate->context()->global()); |
| 7920 } | 7921 } |
| 7921 | 7922 |
| 7922 // Set the property, but ignore if read_only variable on the context | 7923 // Set the property, but ignore if read_only variable on the context |
| 7923 // extension object itself. | 7924 // extension object itself. |
| 7924 if ((attributes & READ_ONLY) == 0 || | 7925 if ((attributes & READ_ONLY) == 0 || |
| 7925 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { | 7926 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { |
| 7926 RETURN_IF_EMPTY_HANDLE(isolate, | 7927 RETURN_IF_EMPTY_HANDLE( |
| 7927 SetProperty(context_ext, name, value, NONE, strict)); | 7928 isolate, |
| 7928 } else if (strict == kStrictMode && (attributes & READ_ONLY) != 0) { | 7929 SetProperty(context_ext, name, value, NONE, strict_mode)); |
| 7930 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { |
| 7929 // Setting read only property in strict mode. | 7931 // Setting read only property in strict mode. |
| 7930 Handle<Object> error = | 7932 Handle<Object> error = |
| 7931 isolate->factory()->NewTypeError( | 7933 isolate->factory()->NewTypeError( |
| 7932 "strict_cannot_assign", HandleVector(&name, 1)); | 7934 "strict_cannot_assign", HandleVector(&name, 1)); |
| 7933 return isolate->Throw(*error); | 7935 return isolate->Throw(*error); |
| 7934 } | 7936 } |
| 7935 return *value; | 7937 return *value; |
| 7936 } | 7938 } |
| 7937 | 7939 |
| 7938 | 7940 |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8753 | 8755 |
| 8754 | 8756 |
| 8755 /** | 8757 /** |
| 8756 * A helper function that visits elements of a JSArray in numerical | 8758 * A helper function that visits elements of a JSArray in numerical |
| 8757 * order. | 8759 * order. |
| 8758 * | 8760 * |
| 8759 * The visitor argument called for each existing element in the array | 8761 * The visitor argument called for each existing element in the array |
| 8760 * with the element index and the element's value. | 8762 * with the element index and the element's value. |
| 8761 * Afterwards it increments the base-index of the visitor by the array | 8763 * Afterwards it increments the base-index of the visitor by the array |
| 8762 * length. | 8764 * length. |
| 8765 * Returns false if any access threw an exception, otherwise true. |
| 8763 */ | 8766 */ |
| 8764 static void IterateElements(Isolate* isolate, | 8767 static bool IterateElements(Isolate* isolate, |
| 8765 Handle<JSArray> receiver, | 8768 Handle<JSArray> receiver, |
| 8766 ArrayConcatVisitor* visitor) { | 8769 ArrayConcatVisitor* visitor) { |
| 8767 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 8770 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
| 8768 switch (receiver->GetElementsKind()) { | 8771 switch (receiver->GetElementsKind()) { |
| 8769 case JSObject::FAST_ELEMENTS: { | 8772 case JSObject::FAST_ELEMENTS: { |
| 8770 // Run through the elements FixedArray and use HasElement and GetElement | 8773 // Run through the elements FixedArray and use HasElement and GetElement |
| 8771 // to check the prototype for missing elements. | 8774 // to check the prototype for missing elements. |
| 8772 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 8775 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
| 8773 int fast_length = static_cast<int>(length); | 8776 int fast_length = static_cast<int>(length); |
| 8774 ASSERT(fast_length <= elements->length()); | 8777 ASSERT(fast_length <= elements->length()); |
| 8775 for (int j = 0; j < fast_length; j++) { | 8778 for (int j = 0; j < fast_length; j++) { |
| 8776 HandleScope loop_scope(isolate); | 8779 HandleScope loop_scope(isolate); |
| 8777 Handle<Object> element_value(elements->get(j), isolate); | 8780 Handle<Object> element_value(elements->get(j), isolate); |
| 8778 if (!element_value->IsTheHole()) { | 8781 if (!element_value->IsTheHole()) { |
| 8779 visitor->visit(j, element_value); | 8782 visitor->visit(j, element_value); |
| 8780 } else if (receiver->HasElement(j)) { | 8783 } else if (receiver->HasElement(j)) { |
| 8781 // Call GetElement on receiver, not its prototype, or getters won't | 8784 // Call GetElement on receiver, not its prototype, or getters won't |
| 8782 // have the correct receiver. | 8785 // have the correct receiver. |
| 8783 element_value = GetElement(receiver, j); | 8786 element_value = GetElement(receiver, j); |
| 8787 if (element_value.is_null()) return false; |
| 8784 visitor->visit(j, element_value); | 8788 visitor->visit(j, element_value); |
| 8785 } | 8789 } |
| 8786 } | 8790 } |
| 8787 break; | 8791 break; |
| 8788 } | 8792 } |
| 8789 case JSObject::DICTIONARY_ELEMENTS: { | 8793 case JSObject::DICTIONARY_ELEMENTS: { |
| 8790 Handle<NumberDictionary> dict(receiver->element_dictionary()); | 8794 Handle<NumberDictionary> dict(receiver->element_dictionary()); |
| 8791 List<uint32_t> indices(dict->Capacity() / 2); | 8795 List<uint32_t> indices(dict->Capacity() / 2); |
| 8792 // Collect all indices in the object and the prototypes less | 8796 // Collect all indices in the object and the prototypes less |
| 8793 // than length. This might introduce duplicates in the indices list. | 8797 // than length. This might introduce duplicates in the indices list. |
| 8794 CollectElementIndices(receiver, length, &indices); | 8798 CollectElementIndices(receiver, length, &indices); |
| 8795 indices.Sort(&compareUInt32); | 8799 indices.Sort(&compareUInt32); |
| 8796 int j = 0; | 8800 int j = 0; |
| 8797 int n = indices.length(); | 8801 int n = indices.length(); |
| 8798 while (j < n) { | 8802 while (j < n) { |
| 8799 HandleScope loop_scope; | 8803 HandleScope loop_scope; |
| 8800 uint32_t index = indices[j]; | 8804 uint32_t index = indices[j]; |
| 8801 Handle<Object> element = GetElement(receiver, index); | 8805 Handle<Object> element = GetElement(receiver, index); |
| 8806 if (element.is_null()) return false; |
| 8802 visitor->visit(index, element); | 8807 visitor->visit(index, element); |
| 8803 // Skip to next different index (i.e., omit duplicates). | 8808 // Skip to next different index (i.e., omit duplicates). |
| 8804 do { | 8809 do { |
| 8805 j++; | 8810 j++; |
| 8806 } while (j < n && indices[j] == index); | 8811 } while (j < n && indices[j] == index); |
| 8807 } | 8812 } |
| 8808 break; | 8813 break; |
| 8809 } | 8814 } |
| 8810 case JSObject::PIXEL_ELEMENTS: { | 8815 case JSObject::PIXEL_ELEMENTS: { |
| 8811 Handle<PixelArray> pixels(PixelArray::cast(receiver->elements())); | 8816 Handle<PixelArray> pixels(PixelArray::cast(receiver->elements())); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8848 case JSObject::EXTERNAL_FLOAT_ELEMENTS: { | 8853 case JSObject::EXTERNAL_FLOAT_ELEMENTS: { |
| 8849 IterateExternalArrayElements<ExternalFloatArray, float>( | 8854 IterateExternalArrayElements<ExternalFloatArray, float>( |
| 8850 isolate, receiver, false, false, visitor); | 8855 isolate, receiver, false, false, visitor); |
| 8851 break; | 8856 break; |
| 8852 } | 8857 } |
| 8853 default: | 8858 default: |
| 8854 UNREACHABLE(); | 8859 UNREACHABLE(); |
| 8855 break; | 8860 break; |
| 8856 } | 8861 } |
| 8857 visitor->increase_index_offset(length); | 8862 visitor->increase_index_offset(length); |
| 8863 return true; |
| 8858 } | 8864 } |
| 8859 | 8865 |
| 8860 | 8866 |
| 8861 /** | 8867 /** |
| 8862 * Array::concat implementation. | 8868 * Array::concat implementation. |
| 8863 * See ECMAScript 262, 15.4.4.4. | 8869 * See ECMAScript 262, 15.4.4.4. |
| 8864 * TODO(581): Fix non-compliance for very large concatenations and update to | 8870 * TODO(581): Fix non-compliance for very large concatenations and update to |
| 8865 * following the ECMAScript 5 specification. | 8871 * following the ECMAScript 5 specification. |
| 8866 */ | 8872 */ |
| 8867 static MaybeObject* Runtime_ArrayConcat(RUNTIME_CALLING_CONVENTION) { | 8873 static MaybeObject* Runtime_ArrayConcat(RUNTIME_CALLING_CONVENTION) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8931 storage = Handle<FixedArray>::cast( | 8937 storage = Handle<FixedArray>::cast( |
| 8932 isolate->factory()->NewNumberDictionary(at_least_space_for)); | 8938 isolate->factory()->NewNumberDictionary(at_least_space_for)); |
| 8933 } | 8939 } |
| 8934 | 8940 |
| 8935 ArrayConcatVisitor visitor(isolate, storage, fast_case); | 8941 ArrayConcatVisitor visitor(isolate, storage, fast_case); |
| 8936 | 8942 |
| 8937 for (int i = 0; i < argument_count; i++) { | 8943 for (int i = 0; i < argument_count; i++) { |
| 8938 Handle<Object> obj(elements->get(i)); | 8944 Handle<Object> obj(elements->get(i)); |
| 8939 if (obj->IsJSArray()) { | 8945 if (obj->IsJSArray()) { |
| 8940 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 8946 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
| 8941 IterateElements(isolate, array, &visitor); | 8947 if (!IterateElements(isolate, array, &visitor)) { |
| 8948 return Failure::Exception(); |
| 8949 } |
| 8942 } else { | 8950 } else { |
| 8943 visitor.visit(0, obj); | 8951 visitor.visit(0, obj); |
| 8944 visitor.increase_index_offset(1); | 8952 visitor.increase_index_offset(1); |
| 8945 } | 8953 } |
| 8946 } | 8954 } |
| 8947 | 8955 |
| 8948 return *visitor.ToArray(); | 8956 return *visitor.ToArray(); |
| 8949 } | 8957 } |
| 8950 | 8958 |
| 8951 | 8959 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9035 Handle<Object> key2 = args.at<Object>(2); | 9043 Handle<Object> key2 = args.at<Object>(2); |
| 9036 | 9044 |
| 9037 uint32_t index1, index2; | 9045 uint32_t index1, index2; |
| 9038 if (!key1->ToArrayIndex(&index1) | 9046 if (!key1->ToArrayIndex(&index1) |
| 9039 || !key2->ToArrayIndex(&index2)) { | 9047 || !key2->ToArrayIndex(&index2)) { |
| 9040 return isolate->ThrowIllegalOperation(); | 9048 return isolate->ThrowIllegalOperation(); |
| 9041 } | 9049 } |
| 9042 | 9050 |
| 9043 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); | 9051 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); |
| 9044 Handle<Object> tmp1 = GetElement(jsobject, index1); | 9052 Handle<Object> tmp1 = GetElement(jsobject, index1); |
| 9053 RETURN_IF_EMPTY_HANDLE(isolate, tmp1); |
| 9045 Handle<Object> tmp2 = GetElement(jsobject, index2); | 9054 Handle<Object> tmp2 = GetElement(jsobject, index2); |
| 9055 RETURN_IF_EMPTY_HANDLE(isolate, tmp2); |
| 9046 | 9056 |
| 9047 SetElement(jsobject, index1, tmp2); | 9057 RETURN_IF_EMPTY_HANDLE(isolate, SetElement(jsobject, index1, tmp2)); |
| 9048 SetElement(jsobject, index2, tmp1); | 9058 RETURN_IF_EMPTY_HANDLE(isolate, SetElement(jsobject, index2, tmp1)); |
| 9049 | 9059 |
| 9050 return isolate->heap()->undefined_value(); | 9060 return isolate->heap()->undefined_value(); |
| 9051 } | 9061 } |
| 9052 | 9062 |
| 9053 | 9063 |
| 9054 // Returns an array that tells you where in the [0, length) interval an array | 9064 // Returns an array that tells you where in the [0, length) interval an array |
| 9055 // might have elements. Can either return keys (positive integers) or | 9065 // might have elements. Can either return keys (positive integers) or |
| 9056 // intervals (pair of a negative integer (-start-1) followed by a | 9066 // intervals (pair of a negative integer (-start-1) followed by a |
| 9057 // positive (length)) or undefined values. | 9067 // positive (length)) or undefined values. |
| 9058 // Intervals can span over some keys that are not in the object. | 9068 // Intervals can span over some keys that are not in the object. |
| (...skipping 2719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11778 // Collect the raw data for a stack trace. Returns an array of 4 | 11788 // Collect the raw data for a stack trace. Returns an array of 4 |
| 11779 // element segments each containing a receiver, function, code and | 11789 // element segments each containing a receiver, function, code and |
| 11780 // native code offset. | 11790 // native code offset. |
| 11781 static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) { | 11791 static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) { |
| 11782 RUNTIME_GET_ISOLATE; | 11792 RUNTIME_GET_ISOLATE; |
| 11783 ASSERT_EQ(args.length(), 2); | 11793 ASSERT_EQ(args.length(), 2); |
| 11784 Handle<Object> caller = args.at<Object>(0); | 11794 Handle<Object> caller = args.at<Object>(0); |
| 11785 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); | 11795 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); |
| 11786 | 11796 |
| 11787 HandleScope scope(isolate); | 11797 HandleScope scope(isolate); |
| 11798 Factory* factory = isolate->factory(); |
| 11788 | 11799 |
| 11789 limit = Max(limit, 0); // Ensure that limit is not negative. | 11800 limit = Max(limit, 0); // Ensure that limit is not negative. |
| 11790 int initial_size = Min(limit, 10); | 11801 int initial_size = Min(limit, 10); |
| 11791 Handle<JSArray> result = isolate->factory()->NewJSArray(initial_size * 4); | 11802 Handle<FixedArray> elements = |
| 11803 factory->NewFixedArrayWithHoles(initial_size * 4); |
| 11792 | 11804 |
| 11793 StackFrameIterator iter; | 11805 StackFrameIterator iter; |
| 11794 // If the caller parameter is a function we skip frames until we're | 11806 // If the caller parameter is a function we skip frames until we're |
| 11795 // under it before starting to collect. | 11807 // under it before starting to collect. |
| 11796 bool seen_caller = !caller->IsJSFunction(); | 11808 bool seen_caller = !caller->IsJSFunction(); |
| 11797 int cursor = 0; | 11809 int cursor = 0; |
| 11798 int frames_seen = 0; | 11810 int frames_seen = 0; |
| 11799 while (!iter.done() && frames_seen < limit) { | 11811 while (!iter.done() && frames_seen < limit) { |
| 11800 StackFrame* raw_frame = iter.frame(); | 11812 StackFrame* raw_frame = iter.frame(); |
| 11801 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { | 11813 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { |
| 11802 frames_seen++; | 11814 frames_seen++; |
| 11803 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 11815 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
| 11804 List<FrameSummary> frames(3); // Max 2 levels of inlining. | 11816 List<FrameSummary> frames(3); // Max 2 levels of inlining. |
| 11805 frame->Summarize(&frames); | 11817 frame->Summarize(&frames); |
| 11806 for (int i = frames.length() - 1; i >= 0; i--) { | 11818 for (int i = frames.length() - 1; i >= 0; i--) { |
| 11819 if (cursor + 4 > elements->length()) { |
| 11820 int new_capacity = JSObject::NewElementsCapacity(elements->length()); |
| 11821 Handle<FixedArray> new_elements = |
| 11822 factory->NewFixedArrayWithHoles(new_capacity); |
| 11823 for (int i = 0; i < cursor; i++) { |
| 11824 new_elements->set(i, elements->get(i)); |
| 11825 } |
| 11826 elements = new_elements; |
| 11827 } |
| 11828 ASSERT(cursor + 4 <= elements->length()); |
| 11829 |
| 11807 Handle<Object> recv = frames[i].receiver(); | 11830 Handle<Object> recv = frames[i].receiver(); |
| 11808 Handle<JSFunction> fun = frames[i].function(); | 11831 Handle<JSFunction> fun = frames[i].function(); |
| 11809 Handle<Code> code = frames[i].code(); | 11832 Handle<Code> code = frames[i].code(); |
| 11810 Handle<Smi> offset(Smi::FromInt(frames[i].offset())); | 11833 Handle<Smi> offset(Smi::FromInt(frames[i].offset())); |
| 11811 FixedArray* elements = FixedArray::cast(result->elements()); | 11834 elements->set(cursor++, *recv); |
| 11812 if (cursor + 3 < elements->length()) { | 11835 elements->set(cursor++, *fun); |
| 11813 elements->set(cursor++, *recv); | 11836 elements->set(cursor++, *code); |
| 11814 elements->set(cursor++, *fun); | 11837 elements->set(cursor++, *offset); |
| 11815 elements->set(cursor++, *code); | |
| 11816 elements->set(cursor++, *offset); | |
| 11817 } else { | |
| 11818 SetElement(result, cursor++, recv); | |
| 11819 SetElement(result, cursor++, fun); | |
| 11820 SetElement(result, cursor++, code); | |
| 11821 SetElement(result, cursor++, offset); | |
| 11822 } | |
| 11823 } | 11838 } |
| 11824 } | 11839 } |
| 11825 iter.Advance(); | 11840 iter.Advance(); |
| 11826 } | 11841 } |
| 11827 | 11842 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
| 11828 result->set_length(Smi::FromInt(cursor)); | 11843 result->set_length(Smi::FromInt(cursor)); |
| 11829 return *result; | 11844 return *result; |
| 11830 } | 11845 } |
| 11831 | 11846 |
| 11832 | 11847 |
| 11833 // Returns V8 version as a string. | 11848 // Returns V8 version as a string. |
| 11834 static MaybeObject* Runtime_GetV8Version(RUNTIME_CALLING_CONVENTION) { | 11849 static MaybeObject* Runtime_GetV8Version(RUNTIME_CALLING_CONVENTION) { |
| 11835 RUNTIME_GET_ISOLATE; | 11850 RUNTIME_GET_ISOLATE; |
| 11836 ASSERT_EQ(args.length(), 0); | 11851 ASSERT_EQ(args.length(), 0); |
| 11837 | 11852 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11993 return message->script(); | 12008 return message->script(); |
| 11994 } | 12009 } |
| 11995 | 12010 |
| 11996 | 12011 |
| 11997 #ifdef DEBUG | 12012 #ifdef DEBUG |
| 11998 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 12013 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
| 11999 // Exclude the code in release mode. | 12014 // Exclude the code in release mode. |
| 12000 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { | 12015 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { |
| 12001 RUNTIME_GET_ISOLATE; | 12016 RUNTIME_GET_ISOLATE; |
| 12002 ASSERT(args.length() == 0); | 12017 ASSERT(args.length() == 0); |
| 12003 HandleScope scope(isolate); | 12018 HandleScope scope; |
| 12004 Handle<JSArray> result = isolate->factory()->NewJSArray(0); | 12019 #define COUNT_ENTRY(Name, argc, ressize) + 1 |
| 12020 int entry_count = 0 |
| 12021 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) |
| 12022 INLINE_FUNCTION_LIST(COUNT_ENTRY) |
| 12023 INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY); |
| 12024 #undef COUNT_ENTRY |
| 12025 Factory* factory = isolate->factory(); |
| 12026 Handle<FixedArray> elements = factory->NewFixedArray(entry_count); |
| 12005 int index = 0; | 12027 int index = 0; |
| 12006 bool inline_runtime_functions = false; | 12028 bool inline_runtime_functions = false; |
| 12007 #define ADD_ENTRY(Name, argc, ressize) \ | 12029 #define ADD_ENTRY(Name, argc, ressize) \ |
| 12008 { \ | 12030 { \ |
| 12009 HandleScope inner; \ | 12031 HandleScope inner; \ |
| 12010 Handle<String> name; \ | 12032 Handle<String> name; \ |
| 12011 /* Inline runtime functions have an underscore in front of the name. */ \ | 12033 /* Inline runtime functions have an underscore in front of the name. */ \ |
| 12012 if (inline_runtime_functions) { \ | 12034 if (inline_runtime_functions) { \ |
| 12013 name = isolate->factory()->NewStringFromAscii( \ | 12035 name = factory->NewStringFromAscii( \ |
| 12014 Vector<const char>("_" #Name, StrLength("_" #Name))); \ | 12036 Vector<const char>("_" #Name, StrLength("_" #Name))); \ |
| 12015 } else { \ | 12037 } else { \ |
| 12016 name = isolate->factory()->NewStringFromAscii( \ | 12038 name = factory->NewStringFromAscii( \ |
| 12017 Vector<const char>(#Name, StrLength(#Name))); \ | 12039 Vector<const char>(#Name, StrLength(#Name))); \ |
| 12018 } \ | 12040 } \ |
| 12019 Handle<JSArray> pair = isolate->factory()->NewJSArray(0); \ | 12041 Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \ |
| 12020 SetElement(pair, 0, name); \ | 12042 pair_elements->set(0, *name); \ |
| 12021 SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \ | 12043 pair_elements->set(1, Smi::FromInt(argc)); \ |
| 12022 SetElement(result, index++, pair); \ | 12044 Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements); \ |
| 12045 elements->set(index++, *pair); \ |
| 12023 } | 12046 } |
| 12024 inline_runtime_functions = false; | 12047 inline_runtime_functions = false; |
| 12025 RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 12048 RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
| 12026 inline_runtime_functions = true; | 12049 inline_runtime_functions = true; |
| 12027 INLINE_FUNCTION_LIST(ADD_ENTRY) | 12050 INLINE_FUNCTION_LIST(ADD_ENTRY) |
| 12028 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 12051 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
| 12029 #undef ADD_ENTRY | 12052 #undef ADD_ENTRY |
| 12053 ASSERT_EQ(index, entry_count); |
| 12054 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
| 12030 return *result; | 12055 return *result; |
| 12031 } | 12056 } |
| 12032 #endif | 12057 #endif |
| 12033 | 12058 |
| 12034 | 12059 |
| 12035 static MaybeObject* Runtime_Log(RUNTIME_CALLING_CONVENTION) { | 12060 static MaybeObject* Runtime_Log(RUNTIME_CALLING_CONVENTION) { |
| 12036 RUNTIME_GET_ISOLATE; | 12061 RUNTIME_GET_ISOLATE; |
| 12037 ASSERT(args.length() == 2); | 12062 ASSERT(args.length() == 2); |
| 12038 CONVERT_CHECKED(String, format, args[0]); | 12063 CONVERT_CHECKED(String, format, args[0]); |
| 12039 CONVERT_CHECKED(JSArray, elms, args[1]); | 12064 CONVERT_CHECKED(JSArray, elms, args[1]); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12121 } else { | 12146 } else { |
| 12122 // Handle last resort GC and make sure to allow future allocations | 12147 // Handle last resort GC and make sure to allow future allocations |
| 12123 // to grow the heap without causing GCs (if possible). | 12148 // to grow the heap without causing GCs (if possible). |
| 12124 COUNTERS->gc_last_resort_from_js()->Increment(); | 12149 COUNTERS->gc_last_resort_from_js()->Increment(); |
| 12125 HEAP->CollectAllGarbage(false); | 12150 HEAP->CollectAllGarbage(false); |
| 12126 } | 12151 } |
| 12127 } | 12152 } |
| 12128 | 12153 |
| 12129 | 12154 |
| 12130 } } // namespace v8::internal | 12155 } } // namespace v8::internal |
| OLD | NEW |