5 #include "src/arguments-inl.h" 6 #include "src/counters.h" 7 #include "src/elements.h" 8 #include "src/heap/factory.h" 9 #include "src/heap/heap-inl.h" 10 #include "src/message-template.h" 11 #include "src/objects-inl.h" 12 #include "src/objects/js-array-buffer-inl.h" 13 #include "src/runtime/runtime-utils.h" 14 #include "src/runtime/runtime.h" 19 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
20 HandleScope scope(isolate);
21 DCHECK_EQ(1, args.length());
22 Handle<Object> argument = args.at(0);
25 if (!argument->IsJSArrayBuffer()) {
26 THROW_NEW_ERROR_RETURN_FAILURE(
27 isolate, NewTypeError(MessageTemplate::kNotTypedArray));
29 Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(argument);
30 if (!array_buffer->is_neuterable()) {
31 return ReadOnlyRoots(isolate).undefined_value();
33 if (array_buffer->backing_store() ==
nullptr) {
34 CHECK_EQ(0, array_buffer->byte_length());
35 return ReadOnlyRoots(isolate).undefined_value();
38 CHECK(!array_buffer->is_shared());
39 DCHECK(!array_buffer->is_external());
40 void* backing_store = array_buffer->backing_store();
41 size_t byte_length = array_buffer->byte_length();
42 array_buffer->set_is_external(
true);
43 isolate->heap()->UnregisterArrayBuffer(*array_buffer);
44 array_buffer->Neuter();
45 isolate->array_buffer_allocator()->Free(backing_store, byte_length);
46 return ReadOnlyRoots(isolate).undefined_value();
49 RUNTIME_FUNCTION(Runtime_TypedArrayCopyElements) {
50 HandleScope scope(isolate);
51 DCHECK_EQ(3, args.length());
52 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target, 0);
53 CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
54 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 2);
57 CHECK(TryNumberToSize(*length_obj, &length));
59 ElementsAccessor* accessor = target->GetElementsAccessor();
60 return accessor->CopyElements(source, target, length);
63 RUNTIME_FUNCTION(Runtime_TypedArrayGetLength) {
64 HandleScope scope(isolate);
65 DCHECK_EQ(1, args.length());
66 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
67 return holder->length();
70 RUNTIME_FUNCTION(Runtime_ArrayBufferViewWasNeutered) {
71 HandleScope scope(isolate);
72 DCHECK_EQ(1, args.length());
73 return isolate->heap()->ToBoolean(JSTypedArray::cast(args[0])->WasNeutered());
76 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
77 HandleScope scope(isolate);
78 DCHECK_EQ(1, args.length());
79 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
80 return *holder->GetBuffer();
87 bool CompareNum(T x, T y) {
92 }
else if (!std::is_integral<T>::value) {
93 double _x = x, _y = y;
94 if (x == 0 && x == y) {
96 return std::signbit(_x) && !std::signbit(_y);
97 }
else if (!std::isnan(_x) && std::isnan(_y)) {
107 RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
108 HandleScope scope(isolate);
109 DCHECK_EQ(1, args.length());
111 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
113 Handle<JSTypedArray> array;
114 const char* method =
"%TypedArray%.prototype.sort";
115 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
116 isolate, array, JSTypedArray::Validate(isolate, target_obj, method));
120 if (V8_UNLIKELY(array->WasNeutered()))
return *array;
122 size_t length = array->length_value();
123 if (length <= 1)
return *array;
125 Handle<FixedTypedArrayBase> elements(
126 FixedTypedArrayBase::cast(array->elements()), isolate);
127 switch (array->type()) {
128 #define TYPED_ARRAY_SORT(Type, type, TYPE, ctype) \ 129 case kExternal##Type##Array: { \ 130 ctype* data = static_cast<ctype*>(elements->DataPtr()); \ 131 if (kExternal##Type##Array == kExternalFloat64Array || \ 132 kExternal##Type##Array == kExternalFloat32Array) \ 133 std::sort(data, data + length, CompareNum<ctype>); \ 135 std::sort(data, data + length); \ 139 TYPED_ARRAYS(TYPED_ARRAY_SORT)
140 #undef TYPED_ARRAY_SORT 146 RUNTIME_FUNCTION(Runtime_IsTypedArray) {
147 HandleScope scope(isolate);
148 DCHECK_EQ(1, args.length());
149 return isolate->heap()->ToBoolean(args[0]->IsJSTypedArray());
153 RUNTIME_FUNCTION(Runtime_TypedArraySet) {
154 HandleScope scope(isolate);
155 Handle<JSTypedArray> target = args.at<JSTypedArray>(0);
156 Handle<Object> obj = args.at(1);
157 Handle<Smi> offset = args.at<Smi>(2);
159 DCHECK(!target->WasNeutered());
160 DCHECK(!obj->IsJSTypedArray());
161 DCHECK_LE(0, offset->value());
165 if (obj->IsNumber()) {
170 THROW_NEW_ERROR_RETURN_FAILURE(
171 isolate, NewTypeError(MessageTemplate::kInvalidArgument));
174 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj,
175 Object::ToObject(isolate, obj));
178 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
180 Object::GetProperty(isolate, obj, isolate->factory()->length_string()));
181 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, len,
182 Object::ToLength(isolate, len));
184 if (uint_offset + len->Number() > target->length_value()) {
185 THROW_NEW_ERROR_RETURN_FAILURE(
186 isolate, NewRangeError(MessageTemplate::kTypedArraySetSourceTooLarge));
190 CHECK(DoubleToUint32IfEqualToSelf(len->Number(), &int_l));
192 Handle<JSReceiver> source = Handle<JSReceiver>::cast(obj);
193 ElementsAccessor* accessor = target->GetElementsAccessor();
194 return accessor->CopyElements(source, target, int_l, uint_offset);