LCOV - code coverage report
Current view: top level - src/runtime - runtime-typedarray.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 64 76 84.2 %
Date: 2019-01-20 Functions: 9 20 45.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       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"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19        5995 : RUNTIME_FUNCTION(Runtime_ArrayBufferDetach) {
      20        3011 :   HandleScope scope(isolate);
      21             :   DCHECK_EQ(1, args.length());
      22        3011 :   Handle<Object> argument = args.at(0);
      23             :   // This runtime function is exposed in ClusterFuzz and as such has to
      24             :   // support arbitrary arguments.
      25        6022 :   if (!argument->IsJSArrayBuffer()) {
      26           0 :     THROW_NEW_ERROR_RETURN_FAILURE(
      27             :         isolate, NewTypeError(MessageTemplate::kNotTypedArray));
      28             :   }
      29        3011 :   Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(argument);
      30        3011 :   if (!array_buffer->is_detachable()) {
      31             :     return ReadOnlyRoots(isolate).undefined_value();
      32             :   }
      33        2984 :   if (array_buffer->backing_store() == nullptr) {
      34           0 :     CHECK_EQ(0, array_buffer->byte_length());
      35             :     return ReadOnlyRoots(isolate).undefined_value();
      36             :   }
      37             :   // Shared array buffers should never be detached.
      38        2984 :   CHECK(!array_buffer->is_shared());
      39             :   DCHECK(!array_buffer->is_external());
      40        2984 :   void* backing_store = array_buffer->backing_store();
      41        2984 :   size_t byte_length = array_buffer->byte_length();
      42        2984 :   array_buffer->set_is_external(true);
      43        2984 :   isolate->heap()->UnregisterArrayBuffer(*array_buffer);
      44        2984 :   array_buffer->Detach();
      45        2984 :   isolate->array_buffer_allocator()->Free(backing_store, byte_length);
      46        3011 :   return ReadOnlyRoots(isolate).undefined_value();
      47             : }
      48             : 
      49       31150 : RUNTIME_FUNCTION(Runtime_TypedArrayCopyElements) {
      50       31150 :   HandleScope scope(isolate);
      51             :   DCHECK_EQ(3, args.length());
      52       62300 :   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target, 0);
      53       31150 :   CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
      54       62300 :   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 2);
      55             : 
      56             :   size_t length;
      57       31150 :   CHECK(TryNumberToSize(*length_obj, &length));
      58             : 
      59       31150 :   ElementsAccessor* accessor = target->GetElementsAccessor();
      60       62300 :   return accessor->CopyElements(source, target, length);
      61             : }
      62             : 
      63           0 : RUNTIME_FUNCTION(Runtime_TypedArrayGetLength) {
      64           0 :   HandleScope scope(isolate);
      65             :   DCHECK_EQ(1, args.length());
      66           0 :   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
      67           0 :   return holder->length();
      68             : }
      69             : 
      70           0 : RUNTIME_FUNCTION(Runtime_ArrayBufferViewWasDetached) {
      71           0 :   HandleScope scope(isolate);
      72             :   DCHECK_EQ(1, args.length());
      73           0 :   return isolate->heap()->ToBoolean(JSTypedArray::cast(args[0])->WasDetached());
      74             : }
      75             : 
      76         653 : RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
      77         653 :   HandleScope scope(isolate);
      78             :   DCHECK_EQ(1, args.length());
      79        1306 :   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
      80        1306 :   return *holder->GetBuffer();
      81             : }
      82             : 
      83             : 
      84             : namespace {
      85             : 
      86             : template <typename T>
      87         360 : bool CompareNum(T x, T y) {
      88         360 :   if (x < y) {
      89             :     return true;
      90         270 :   } else if (x > y) {
      91             :     return false;
      92             :   } else if (!std::is_integral<T>::value) {
      93         117 :     double _x = x, _y = y;
      94         234 :     if (x == 0 && x == y) {
      95             :       /* -0.0 is less than +0.0 */
      96         180 :       return std::signbit(_x) && !std::signbit(_y);
      97         126 :     } else if (!std::isnan(_x) && std::isnan(_y)) {
      98             :       /* number is less than NaN */
      99             :       return true;
     100             :     }
     101             :   }
     102          72 :   return false;
     103             : }
     104             : 
     105             : }  // namespace
     106             : 
     107         504 : RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
     108         504 :   HandleScope scope(isolate);
     109             :   DCHECK_EQ(1, args.length());
     110             : 
     111         504 :   CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
     112             : 
     113             :   Handle<JSTypedArray> array;
     114             :   const char* method = "%TypedArray%.prototype.sort";
     115        1008 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     116             :       isolate, array, JSTypedArray::Validate(isolate, target_obj, method));
     117             : 
     118             :   // This line can be removed when JSTypedArray::Validate throws
     119             :   // if array.[[ViewedArrayBuffer]] is detached(v8:4648)
     120         504 :   if (V8_UNLIKELY(array->WasDetached())) return *array;
     121             : 
     122         504 :   size_t length = array->length_value();
     123         504 :   if (length <= 1) return *array;
     124             : 
     125             :   Handle<FixedTypedArrayBase> elements(
     126         684 :       FixedTypedArrayBase::cast(array->elements()), isolate);
     127         342 :   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>);    \
     134             :     else                                                    \
     135             :       std::sort(data, data + length);                       \
     136             :     break;                                                  \
     137             :   }
     138             : 
     139         342 :     TYPED_ARRAYS(TYPED_ARRAY_SORT)
     140             : #undef TYPED_ARRAY_SORT
     141             :   }
     142             : 
     143         504 :   return *array;
     144             : }
     145             : 
     146           0 : RUNTIME_FUNCTION(Runtime_IsTypedArray) {
     147           0 :   HandleScope scope(isolate);
     148             :   DCHECK_EQ(1, args.length());
     149           0 :   return isolate->heap()->ToBoolean(args[0]->IsJSTypedArray());
     150             : }
     151             : 
     152             : // 22.2.3.23 %TypedArray%.prototype.set ( overloaded [ , offset ] )
     153        1377 : RUNTIME_FUNCTION(Runtime_TypedArraySet) {
     154        1377 :   HandleScope scope(isolate);
     155        1377 :   Handle<JSTypedArray> target = args.at<JSTypedArray>(0);
     156        1377 :   Handle<Object> obj = args.at(1);
     157        1377 :   Handle<Smi> offset = args.at<Smi>(2);
     158             : 
     159             :   DCHECK(!target->WasDetached());  // Checked in TypedArrayPrototypeSet.
     160             :   DCHECK(!obj->IsJSTypedArray());  // Should be handled by CSA.
     161             :   DCHECK_LE(0, offset->value());
     162             : 
     163        1377 :   const uint32_t uint_offset = static_cast<uint32_t>(offset->value());
     164             : 
     165        2754 :   if (obj->IsNumber()) {
     166             :     // For number as a first argument, throw TypeError
     167             :     // instead of silently ignoring the call, so that
     168             :     // users know they did something wrong.
     169             :     // (Consistent with Firefox and Blink/WebKit)
     170         126 :     THROW_NEW_ERROR_RETURN_FAILURE(
     171             :         isolate, NewTypeError(MessageTemplate::kInvalidArgument));
     172             :   }
     173             : 
     174        2628 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj,
     175             :                                      Object::ToObject(isolate, obj));
     176             : 
     177             :   Handle<Object> len;
     178        3942 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     179             :       isolate, len,
     180             :       Object::GetProperty(isolate, obj, isolate->factory()->length_string()));
     181        2628 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, len,
     182             :                                      Object::ToLength(isolate, len));
     183             : 
     184        3699 :   if (uint_offset + len->Number() > target->length_value()) {
     185          36 :     THROW_NEW_ERROR_RETURN_FAILURE(
     186             :         isolate, NewRangeError(MessageTemplate::kTypedArraySetSourceTooLarge));
     187             :   }
     188             : 
     189             :   uint32_t int_l;
     190        1215 :   CHECK(DoubleToUint32IfEqualToSelf(len->Number(), &int_l));
     191             : 
     192        1215 :   Handle<JSReceiver> source = Handle<JSReceiver>::cast(obj);
     193        1215 :   ElementsAccessor* accessor = target->GetElementsAccessor();
     194        2430 :   return accessor->CopyElements(source, target, int_l, uint_offset);
     195             : }
     196             : 
     197             : }  // namespace internal
     198      183867 : }  // namespace v8

Generated by: LCOV version 1.10