OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 if (!len_obj->IsSmi()) { | 851 if (!len_obj->IsSmi()) { |
852 return CallJsBuiltin(isolate, "ArraySlice", args); | 852 return CallJsBuiltin(isolate, "ArraySlice", args); |
853 } | 853 } |
854 len = Smi::cast(len_obj)->value(); | 854 len = Smi::cast(len_obj)->value(); |
855 if (len > elms->length()) { | 855 if (len > elms->length()) { |
856 return CallJsBuiltin(isolate, "ArraySlice", args); | 856 return CallJsBuiltin(isolate, "ArraySlice", args); |
857 } | 857 } |
858 } | 858 } |
859 | 859 |
860 JSObject* object = JSObject::cast(receiver); | 860 JSObject* object = JSObject::cast(receiver); |
861 ElementsKind kind = object->GetElementsKind(); | |
862 | |
863 if (IsHoleyElementsKind(kind)) { | |
864 bool packed = true; | |
865 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind); | |
866 for (int i = 0; i < len; i++) { | |
867 if (!accessor->HasElement(object, object, i, elms)) { | |
868 packed = false; | |
869 break; | |
870 } | |
871 } | |
872 if (packed) { | |
873 kind = GetPackedElementsKind(kind); | |
874 } else if (!receiver->IsJSArray()) { | |
875 return CallJsBuiltin(isolate, "ArraySlice", args); | |
876 } | |
877 } | |
878 | 861 |
879 ASSERT(len >= 0); | 862 ASSERT(len >= 0); |
880 int n_arguments = args.length() - 1; | 863 int n_arguments = args.length() - 1; |
881 | 864 |
882 // Note carefully choosen defaults---if argument is missing, | 865 // Note carefully choosen defaults---if argument is missing, |
883 // it's undefined which gets converted to 0 for relative_start | 866 // it's undefined which gets converted to 0 for relative_start |
884 // and to len for relative_end. | 867 // and to len for relative_end. |
885 int relative_start = 0; | 868 int relative_start = 0; |
886 int relative_end = len; | 869 int relative_end = len; |
887 if (n_arguments > 0) { | 870 if (n_arguments > 0) { |
(...skipping 29 matching lines...) Expand all Loading... |
917 int k = (relative_start < 0) ? Max(len + relative_start, 0) | 900 int k = (relative_start < 0) ? Max(len + relative_start, 0) |
918 : Min(relative_start, len); | 901 : Min(relative_start, len); |
919 | 902 |
920 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. | 903 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. |
921 int final = (relative_end < 0) ? Max(len + relative_end, 0) | 904 int final = (relative_end < 0) ? Max(len + relative_end, 0) |
922 : Min(relative_end, len); | 905 : Min(relative_end, len); |
923 | 906 |
924 // Calculate the length of result array. | 907 // Calculate the length of result array. |
925 int result_len = Max(final - k, 0); | 908 int result_len = Max(final - k, 0); |
926 | 909 |
| 910 ElementsKind kind = object->GetElementsKind(); |
| 911 if (IsHoleyElementsKind(kind)) { |
| 912 bool packed = true; |
| 913 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind); |
| 914 for (int i = k; i < final; i++) { |
| 915 if (!accessor->HasElement(object, object, i, elms)) { |
| 916 packed = false; |
| 917 break; |
| 918 } |
| 919 } |
| 920 if (packed) { |
| 921 kind = GetPackedElementsKind(kind); |
| 922 } else if (!receiver->IsJSArray()) { |
| 923 return CallJsBuiltin(isolate, "ArraySlice", args); |
| 924 } |
| 925 } |
| 926 |
927 JSArray* result_array; | 927 JSArray* result_array; |
928 MaybeObject* maybe_array = heap->AllocateJSArrayAndStorage(kind, | 928 MaybeObject* maybe_array = heap->AllocateJSArrayAndStorage(kind, |
929 result_len, | 929 result_len, |
930 result_len); | 930 result_len); |
931 | 931 |
932 AssertNoAllocation no_gc; | 932 AssertNoAllocation no_gc; |
933 if (result_len == 0) return maybe_array; | 933 if (result_len == 0) return maybe_array; |
934 if (!maybe_array->To(&result_array)) return maybe_array; | 934 if (!maybe_array->To(&result_array)) return maybe_array; |
935 | 935 |
936 ElementsAccessor* accessor = object->GetElementsAccessor(); | 936 ElementsAccessor* accessor = object->GetElementsAccessor(); |
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1942 return Handle<Code>(code_address); \ | 1942 return Handle<Code>(code_address); \ |
1943 } | 1943 } |
1944 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1944 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1945 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1945 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1946 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1946 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1947 #undef DEFINE_BUILTIN_ACCESSOR_C | 1947 #undef DEFINE_BUILTIN_ACCESSOR_C |
1948 #undef DEFINE_BUILTIN_ACCESSOR_A | 1948 #undef DEFINE_BUILTIN_ACCESSOR_A |
1949 | 1949 |
1950 | 1950 |
1951 } } // namespace v8::internal | 1951 } } // namespace v8::internal |
OLD | NEW |