LCOV - code coverage report
Current view: top level - src/runtime - runtime-typedarray.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 61 89 68.5 %
Date: 2017-10-20 Functions: 11 30 36.7 %

          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/runtime/runtime-utils.h"
       6             : 
       7             : #include "src/arguments.h"
       8             : #include "src/elements.h"
       9             : #include "src/factory.h"
      10             : #include "src/messages.h"
      11             : #include "src/objects-inl.h"
      12             : #include "src/runtime/runtime.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17           0 : RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
      18             :   SealHandleScope shs(isolate);
      19             :   DCHECK_EQ(1, args.length());
      20           0 :   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
      21           0 :   return holder->byte_length();
      22             : }
      23             : 
      24             : 
      25        5858 : RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
      26        1956 :   HandleScope scope(isolate);
      27             :   DCHECK_EQ(1, args.length());
      28        1956 :   Handle<Object> argument = args.at(0);
      29             :   // This runtime function is exposed in ClusterFuzz and as such has to
      30             :   // support arbitrary arguments.
      31        1956 :   if (!argument->IsJSArrayBuffer()) {
      32           0 :     THROW_NEW_ERROR_RETURN_FAILURE(
      33             :         isolate, NewTypeError(MessageTemplate::kNotTypedArray));
      34             :   }
      35        1956 :   Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(argument);
      36        1956 :   if (!array_buffer->is_neuterable()) {
      37           0 :     return isolate->heap()->undefined_value();
      38             :   }
      39        1956 :   if (array_buffer->backing_store() == nullptr) {
      40          10 :     CHECK_EQ(Smi::kZero, array_buffer->byte_length());
      41          10 :     return isolate->heap()->undefined_value();
      42             :   }
      43             :   // Shared array buffers should never be neutered.
      44        1946 :   CHECK(!array_buffer->is_shared());
      45             :   DCHECK(!array_buffer->is_external());
      46             :   void* backing_store = array_buffer->backing_store();
      47        1946 :   size_t byte_length = NumberToSize(array_buffer->byte_length());
      48        1946 :   array_buffer->set_is_external(true);
      49        1946 :   isolate->heap()->UnregisterArrayBuffer(*array_buffer);
      50        1946 :   array_buffer->Neuter();
      51        1946 :   isolate->array_buffer_allocator()->Free(backing_store, byte_length);
      52        1946 :   return isolate->heap()->undefined_value();
      53             : }
      54             : 
      55       50726 : RUNTIME_FUNCTION(Runtime_TypedArrayCopyElements) {
      56       25363 :   HandleScope scope(isolate);
      57             :   DCHECK_EQ(3, args.length());
      58       50726 :   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target, 0);
      59       50726 :   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, source, 1);
      60       50726 :   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 2);
      61             : 
      62             :   size_t length;
      63       25363 :   CHECK(TryNumberToSize(*length_obj, &length));
      64             : 
      65       25363 :   ElementsAccessor* accessor = target->GetElementsAccessor();
      66       50726 :   return accessor->CopyElements(source, target, length);
      67             : }
      68             : 
      69             : #define BUFFER_VIEW_GETTER(Type, getter, accessor)   \
      70             :   RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {    \
      71             :     HandleScope scope(isolate);                      \
      72             :     DCHECK_EQ(1, args.length());                     \
      73             :     CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
      74             :     return holder->accessor();                       \
      75             :   }
      76             : 
      77        6056 : BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
      78       33796 : BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
      79       72156 : BUFFER_VIEW_GETTER(TypedArray, Length, length)
      80             : 
      81             : #undef BUFFER_VIEW_GETTER
      82             : 
      83       35336 : RUNTIME_FUNCTION(Runtime_ArrayBufferViewWasNeutered) {
      84       17668 :   HandleScope scope(isolate);
      85             :   DCHECK_EQ(1, args.length());
      86       17668 :   return isolate->heap()->ToBoolean(JSTypedArray::cast(args[0])->WasNeutered());
      87             : }
      88             : 
      89       22200 : RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
      90       11100 :   HandleScope scope(isolate);
      91             :   DCHECK_EQ(1, args.length());
      92       22200 :   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
      93       22200 :   return *holder->GetBuffer();
      94             : }
      95             : 
      96             : 
      97             : namespace {
      98             : 
      99             : template <typename T>
     100         360 : bool CompareNum(T x, T y) {
     101         360 :   if (x < y) {
     102             :     return true;
     103         270 :   } else if (x > y) {
     104             :     return false;
     105             :   } else if (!std::is_integral<T>::value) {
     106         117 :     double _x = x, _y = y;
     107         234 :     if (x == 0 && x == y) {
     108             :       /* -0.0 is less than +0.0 */
     109         180 :       return std::signbit(_x) && !std::signbit(_y);
     110         126 :     } else if (!std::isnan(_x) && std::isnan(_y)) {
     111             :       /* number is less than NaN */
     112             :       return true;
     113             :     }
     114             :   }
     115          72 :   return false;
     116             : }
     117             : 
     118             : }  // namespace
     119             : 
     120         866 : RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
     121         433 :   HandleScope scope(isolate);
     122             :   DCHECK_EQ(1, args.length());
     123             : 
     124         433 :   CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
     125             : 
     126             :   Handle<JSTypedArray> array;
     127             :   const char* method = "%TypedArray%.prototype.sort";
     128         866 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     129             :       isolate, array, JSTypedArray::Validate(isolate, target_obj, method));
     130             : 
     131             :   // This line can be removed when JSTypedArray::Validate throws
     132             :   // if array.[[ViewedArrayBuffer]] is neutered(v8:4648)
     133         433 :   if (V8_UNLIKELY(array->WasNeutered())) return *array;
     134             : 
     135         433 :   size_t length = array->length_value();
     136         433 :   if (length <= 1) return *array;
     137             : 
     138             :   Handle<FixedTypedArrayBase> elements(
     139         271 :       FixedTypedArrayBase::cast(array->elements()));
     140         271 :   switch (array->type()) {
     141             : #define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size)     \
     142             :   case kExternal##Type##Array: {                            \
     143             :     ctype* data = static_cast<ctype*>(elements->DataPtr()); \
     144             :     if (kExternal##Type##Array == kExternalFloat64Array ||  \
     145             :         kExternal##Type##Array == kExternalFloat32Array)    \
     146             :       std::sort(data, data + length, CompareNum<ctype>);    \
     147             :     else                                                    \
     148             :       std::sort(data, data + length);                       \
     149             :     break;                                                  \
     150             :   }
     151             : 
     152         271 :     TYPED_ARRAYS(TYPED_ARRAY_SORT)
     153             : #undef TYPED_ARRAY_SORT
     154             :   }
     155             : 
     156         433 :   return *array;
     157             : }
     158             : 
     159           0 : RUNTIME_FUNCTION(Runtime_IsTypedArray) {
     160           0 :   HandleScope scope(isolate);
     161             :   DCHECK_EQ(1, args.length());
     162           0 :   return isolate->heap()->ToBoolean(args[0]->IsJSTypedArray());
     163             : }
     164             : 
     165           0 : RUNTIME_FUNCTION(Runtime_IsSharedTypedArray) {
     166           0 :   HandleScope scope(isolate);
     167             :   DCHECK_EQ(1, args.length());
     168             :   return isolate->heap()->ToBoolean(
     169           0 :       args[0]->IsJSTypedArray() &&
     170           0 :       JSTypedArray::cast(args[0])->GetBuffer()->is_shared());
     171             : }
     172             : 
     173             : 
     174           0 : RUNTIME_FUNCTION(Runtime_IsSharedIntegerTypedArray) {
     175           0 :   HandleScope scope(isolate);
     176             :   DCHECK_EQ(1, args.length());
     177           0 :   if (!args[0]->IsJSTypedArray()) {
     178           0 :     return isolate->heap()->false_value();
     179             :   }
     180             : 
     181           0 :   Handle<JSTypedArray> obj(JSTypedArray::cast(args[0]));
     182           0 :   return isolate->heap()->ToBoolean(obj->GetBuffer()->is_shared() &&
     183           0 :                                     obj->type() != kExternalFloat32Array &&
     184           0 :                                     obj->type() != kExternalFloat64Array &&
     185           0 :                                     obj->type() != kExternalUint8ClampedArray);
     186             : }
     187             : 
     188             : 
     189           0 : RUNTIME_FUNCTION(Runtime_IsSharedInteger32TypedArray) {
     190           0 :   HandleScope scope(isolate);
     191             :   DCHECK_EQ(1, args.length());
     192           0 :   if (!args[0]->IsJSTypedArray()) {
     193           0 :     return isolate->heap()->false_value();
     194             :   }
     195             : 
     196           0 :   Handle<JSTypedArray> obj(JSTypedArray::cast(args[0]));
     197           0 :   return isolate->heap()->ToBoolean(obj->GetBuffer()->is_shared() &&
     198           0 :                                     obj->type() == kExternalInt32Array);
     199             : }
     200             : 
     201        2920 : RUNTIME_FUNCTION(Runtime_TypedArraySpeciesCreateByLength) {
     202        1460 :   HandleScope scope(isolate);
     203             :   DCHECK_EQ(args.length(), 2);
     204        1460 :   Handle<JSTypedArray> exemplar = args.at<JSTypedArray>(0);
     205        1460 :   Handle<Object> length = args.at(1);
     206             :   int argc = 1;
     207        2920 :   ScopedVector<Handle<Object>> argv(argc);
     208        1460 :   argv[0] = length;
     209             :   Handle<JSTypedArray> result_array;
     210             :   // TODO(tebbi): Pass correct method name.
     211        2920 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     212             :       isolate, result_array,
     213             :       JSTypedArray::SpeciesCreate(isolate, exemplar, argc, argv.start(), ""));
     214        1460 :   return *result_array;
     215             : }
     216             : 
     217             : }  // namespace internal
     218             : }  // namespace v8

Generated by: LCOV version 1.10