Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/runtime.cc

Issue 14581005: Implement TypedArray.set function. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed a bug with throwing on invalid argument Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 return typed_array->accessor(); \ 884 return typed_array->accessor(); \
885 } 885 }
886 886
887 TYPED_ARRAY_GETTER(Buffer, buffer) 887 TYPED_ARRAY_GETTER(Buffer, buffer)
888 TYPED_ARRAY_GETTER(ByteLength, byte_length) 888 TYPED_ARRAY_GETTER(ByteLength, byte_length)
889 TYPED_ARRAY_GETTER(ByteOffset, byte_offset) 889 TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
890 TYPED_ARRAY_GETTER(Length, length) 890 TYPED_ARRAY_GETTER(Length, length)
891 891
892 #undef TYPED_ARRAY_GETTER 892 #undef TYPED_ARRAY_GETTER
893 893
894 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetSpecialCases) {
rossberg 2013/05/07 13:53:23 Nit: I'd change the name, since it's the normal ca
Dmitry Lomov (no reviews) 2013/05/07 14:20:00 Done.
895 HandleScope scope(isolate);
896 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
897 CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
898 CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
899 if (!target_obj->IsJSTypedArray() || !source_obj->IsJSTypedArray())
900 return isolate->heap()->false_value();
901
902 Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
903 Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
904 size_t offset = NumberToSize(isolate, *offset_obj);
905 size_t target_length = NumberToSize(isolate, target->length());
906 size_t source_length = NumberToSize(isolate, source->length());
907 size_t target_byte_length = NumberToSize(isolate, target->byte_length());
908 size_t source_byte_length = NumberToSize(isolate, source->byte_length());
909 if (offset > target_length ||
910 offset + source_length > target_length ||
911 offset + source_length < offset) // overflow
912 return isolate->Throw(*isolate->factory()->NewRangeError(
913 "typed_array_set_source_too_long", HandleVector<Object>(NULL, 0)));
914
915 Handle<JSArrayBuffer> target_buffer(JSArrayBuffer::cast(target->buffer()));
916 Handle<JSArrayBuffer> source_buffer(JSArrayBuffer::cast(source->buffer()));
917 size_t target_offset = NumberToSize(isolate, target->byte_offset());
918 size_t source_offset = NumberToSize(isolate, source->byte_offset());
919 uint8_t* target_base =
920 static_cast<uint8_t*>(target_buffer->backing_store()) + target_offset;
921 uint8_t* source_base =
922 static_cast<uint8_t*>(source_buffer->backing_store()) + source_offset;
923
924 // Typed arrays of the same type: use memmove.
925 if (target->type() == source->type()) {
926 memmove(target_base + offset * target->element_size(),
927 source_base, source_byte_length);
928 return isolate->heap()->true_value();
929 }
930
931 // Typed arrays of different types over the same backing store
932 if ((source_base <= target_base &&
933 source_base + source_byte_length > target_base) ||
rossberg 2013/05/07 13:53:23 Style nit: spurious space
Dmitry Lomov (no reviews) 2013/05/07 14:20:00 Done.
934 (target_base <= source_base &&
935 target_base + target_byte_length > source_base)) {
936 size_t target_element_size = target->element_size();
937 size_t source_element_size = source->element_size();
938
939 size_t source_length = NumberToSize(isolate, source->length());
940
941 // Copy left part
942 size_t left_index;
943 {
944 // First un-mutated byte after the next write
945 uint8_t* target_ptr = target_base + (offset + 1) * target_element_size;
946 // Next read at source_ptr. We do not care for memory changing before
947 // source_ptr - we have already copied it.
948 uint8_t* source_ptr = source_base;
949 for (left_index = 0;
950 left_index < source_length && target_ptr <= source_ptr;
951 left_index++) {
952 Handle<Object> v = Object::GetElement(
953 source, static_cast<uint32_t>(left_index));
954 JSObject::SetElement(
955 target, static_cast<uint32_t>(offset + left_index), v,
956 NONE, kNonStrictMode);
957 target_ptr += target_element_size;
958 source_ptr += source_element_size;
959 }
960 }
961 // Copy right part
962 size_t right_index;
963 {
964 // First unmutated byte before the next write
965 uint8_t* target_ptr =
966 target_base + (offset + source_length - 1) * target_element_size;
967 // Next read before source_ptr. We do not care for memory changing after
968 // source_ptr - we have already copied it.
969 uint8_t* source_ptr =
970 source_base + source_length * source_element_size;
971 for (right_index = source_length - 1;
972 right_index >= left_index && target_ptr >= source_ptr;
973 right_index--) {
974 Handle<Object> v = Object::GetElement(
975 source, static_cast<uint32_t>(right_index));
976 JSObject::SetElement(
977 target, static_cast<uint32_t>(offset + right_index), v,
978 NONE, kNonStrictMode);
979 target_ptr -= target_element_size;
980 source_ptr -= source_element_size;
981 }
982 }
983 ASSERT((right_index + 1) - left_index <= 8);
rossberg 2013/05/07 13:53:23 I'd keep a comment similar to the one I had in d8
Dmitry Lomov (no reviews) 2013/05/07 14:20:00 Done.
984 Handle<Object> temp[8];
985 size_t idx;
986 for (idx = left_index; idx <= right_index; idx++) {
987 temp[idx - left_index] = Object::GetElement(
988 source, static_cast<uint32_t>(idx));
989 }
990 for (idx = left_index; idx <= right_index; idx++) {
991 JSObject::SetElement(
992 target, static_cast<uint32_t>(offset + idx), temp[idx-left_index],
993 NONE, kNonStrictMode);
994 }
995 } else { // Non-overlapping typed arrays
rossberg 2013/05/07 13:53:23 Perhaps negate the conditional to put the common a
Dmitry Lomov (no reviews) 2013/05/07 14:20:00 Can I please not? :)) On 2013/05/07 13:53:23, ross
996 for (size_t idx = 0; idx < source_length; idx++) {
997 Handle<Object> value = Object::GetElement(
998 source, static_cast<uint32_t>(idx));
999 JSObject::SetElement(
1000 target, static_cast<uint32_t>(offset + idx), value,
1001 NONE, kNonStrictMode);
1002 }
1003 }
1004
1005 return isolate->heap()->true_value();
1006 }
1007
1008
894 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { 1009 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
895 HandleScope scope(isolate); 1010 HandleScope scope(isolate);
896 ASSERT(args.length() == 1); 1011 ASSERT(args.length() == 1);
897 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 1012 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
898 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); 1013 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
899 holder->set_table(*table); 1014 holder->set_table(*table);
900 return *holder; 1015 return *holder;
901 } 1016 }
902 1017
903 1018
(...skipping 12490 matching lines...) Expand 10 before | Expand all | Expand 10 after
13394 // Handle last resort GC and make sure to allow future allocations 13509 // Handle last resort GC and make sure to allow future allocations
13395 // to grow the heap without causing GCs (if possible). 13510 // to grow the heap without causing GCs (if possible).
13396 isolate->counters()->gc_last_resort_from_js()->Increment(); 13511 isolate->counters()->gc_last_resort_from_js()->Increment();
13397 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13512 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13398 "Runtime::PerformGC"); 13513 "Runtime::PerformGC");
13399 } 13514 }
13400 } 13515 }
13401 13516
13402 13517
13403 } } // namespace v8::internal 13518 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698