diff options
Diffstat (limited to 'chromium/v8/src/builtins/builtins-typedarray.cc')
-rw-r--r-- | chromium/v8/src/builtins/builtins-typedarray.cc | 296 |
1 files changed, 0 insertions, 296 deletions
diff --git a/chromium/v8/src/builtins/builtins-typedarray.cc b/chromium/v8/src/builtins/builtins-typedarray.cc index 3d40d3755f8..176a79965b2 100644 --- a/chromium/v8/src/builtins/builtins-typedarray.cc +++ b/chromium/v8/src/builtins/builtins-typedarray.cc @@ -277,302 +277,6 @@ BUILTIN(TypedArrayPrototypeReverse) { return *array; } -namespace { -Object* TypedArrayCopyElements(Handle<JSTypedArray> target, - Handle<JSReceiver> source, Object* length_obj) { - size_t length; - CHECK(TryNumberToSize(length_obj, &length)); - - ElementsAccessor* accessor = target->GetElementsAccessor(); - return accessor->CopyElements(source, target, length); -} - -enum class TypedArraySetResultCodes { - // Set from typed array of the same type. - // This is processed by TypedArraySetFastCases - SAME_TYPE, - // Set from typed array of the different type, overlapping in memory. - OVERLAPPING, - // Set from typed array of the different type, non-overlapping. - NONOVERLAPPING, - // Set from non-typed array. - NON_TYPED_ARRAY -}; - -MaybeHandle<Object> TypedArraySetFromArrayLike(Isolate* isolate, - Handle<JSTypedArray> target, - Handle<Object> source, - int source_length, int offset) { - DCHECK_GE(source_length, 0); - DCHECK_GE(offset, 0); - - for (int i = 0; i < source_length; i++) { - Handle<Object> value; - ASSIGN_RETURN_ON_EXCEPTION(isolate, value, - Object::GetElement(isolate, source, i), Object); - ASSIGN_RETURN_ON_EXCEPTION(isolate, value, - Object::SetElement(isolate, target, offset + i, - value, LanguageMode::STRICT), - Object); - } - - return target; -} - -MaybeHandle<Object> TypedArraySetFromOverlapping(Isolate* isolate, - Handle<JSTypedArray> target, - Handle<JSTypedArray> source, - int offset) { - DCHECK_GE(offset, 0); - - size_t sourceElementSize = source->element_size(); - size_t targetElementSize = target->element_size(); - - uint32_t source_length = source->length_value(); - if (source_length == 0) return target; - - // Copy left part. - - // First un-mutated byte after the next write - uint32_t target_ptr = 0; - CHECK(target->byte_offset()->ToUint32(&target_ptr)); - target_ptr += (offset + 1) * targetElementSize; - - // Next read at sourcePtr. We do not care for memory changing before - // sourcePtr - we have already copied it. - uint32_t source_ptr = 0; - CHECK(source->byte_offset()->ToUint32(&source_ptr)); - - uint32_t left_index; - for (left_index = 0; left_index < source_length && target_ptr <= source_ptr; - left_index++) { - Handle<Object> value; - ASSIGN_RETURN_ON_EXCEPTION(isolate, value, - Object::GetElement(isolate, source, left_index), - Object); - ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, - Object::SetElement(isolate, target, offset + left_index, value, - LanguageMode::STRICT), - Object); - - target_ptr += targetElementSize; - source_ptr += sourceElementSize; - } - - // Copy right part; - // First unmutated byte before the next write - CHECK(target->byte_offset()->ToUint32(&target_ptr)); - target_ptr += (offset + source_length - 1) * targetElementSize; - - // Next read before sourcePtr. We do not care for memory changing after - // sourcePtr - we have already copied it. - CHECK(target->byte_offset()->ToUint32(&source_ptr)); - source_ptr += source_length * sourceElementSize; - - uint32_t right_index; - DCHECK_GE(source_length, 1); - for (right_index = source_length - 1; - right_index > left_index && target_ptr >= source_ptr; right_index--) { - Handle<Object> value; - ASSIGN_RETURN_ON_EXCEPTION(isolate, value, - Object::GetElement(isolate, source, right_index), - Object); - ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, - Object::SetElement(isolate, target, offset + right_index, value, - LanguageMode::STRICT), - Object); - - target_ptr -= targetElementSize; - source_ptr -= sourceElementSize; - } - - std::vector<Handle<Object>> temp(right_index + 1 - left_index); - - for (uint32_t i = left_index; i <= right_index; i++) { - Handle<Object> value; - ASSIGN_RETURN_ON_EXCEPTION(isolate, value, - Object::GetElement(isolate, source, i), Object); - temp[i - left_index] = value; - } - - for (uint32_t i = left_index; i <= right_index; i++) { - Handle<Object> value; - - ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, - Object::SetElement(isolate, target, offset + i, temp[i - left_index], - LanguageMode::STRICT), - Object); - } - - return target; -} - -MaybeHandle<Smi> TypedArraySetFastCases(Isolate* isolate, - Handle<JSTypedArray> target, - Handle<Object> source_obj, - Handle<Object> offset_obj) { - if (!source_obj->IsJSTypedArray()) { - return MaybeHandle<Smi>( - Smi::FromEnum(TypedArraySetResultCodes::NON_TYPED_ARRAY), isolate); - } - - Handle<JSTypedArray> source = Handle<JSTypedArray>::cast(source_obj); - - size_t offset = 0; - CHECK(TryNumberToSize(*offset_obj, &offset)); - size_t target_length = target->length_value(); - size_t source_length = source->length_value(); - size_t target_byte_length = NumberToSize(target->byte_length()); - size_t source_byte_length = NumberToSize(source->byte_length()); - if (offset > target_length || offset + source_length > target_length || - offset + source_length < offset) { // overflow - THROW_NEW_ERROR( - isolate, NewRangeError(MessageTemplate::kTypedArraySetSourceTooLarge), - Smi); - } - - size_t target_offset = NumberToSize(target->byte_offset()); - size_t source_offset = NumberToSize(source->byte_offset()); - uint8_t* target_base = - static_cast<uint8_t*>(target->GetBuffer()->backing_store()) + - target_offset; - uint8_t* source_base = - static_cast<uint8_t*>(source->GetBuffer()->backing_store()) + - source_offset; - - // Typed arrays of the same type: use memmove. - if (target->type() == source->type()) { - memmove(target_base + offset * target->element_size(), source_base, - source_byte_length); - return MaybeHandle<Smi>(Smi::FromEnum(TypedArraySetResultCodes::SAME_TYPE), - isolate); - } - - // Typed arrays of different types over the same backing store - if ((source_base <= target_base && - source_base + source_byte_length > target_base) || - (target_base <= source_base && - target_base + target_byte_length > source_base)) { - // We do not support overlapping ArrayBuffers - DCHECK(target->GetBuffer()->backing_store() == - source->GetBuffer()->backing_store()); - return MaybeHandle<Smi>( - Smi::FromEnum(TypedArraySetResultCodes::OVERLAPPING), isolate); - } else { // Non-overlapping typed arrays - return MaybeHandle<Smi>( - Smi::FromEnum(TypedArraySetResultCodes::NONOVERLAPPING), isolate); - } -} - -} // anonymous namespace - -// 22.2.3.23%TypedArray%.prototype.set ( overloaded [ , offset ] ) -BUILTIN(TypedArrayPrototypeSet) { - HandleScope scope(isolate); - - Handle<Object> target = args.receiver(); - Handle<Object> obj = args.atOrUndefined(isolate, 1); - Handle<Object> offset = args.atOrUndefined(isolate, 2); - - if (offset->IsUndefined(isolate)) { - offset = Handle<Object>(Smi::kZero, isolate); - } else { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, offset, - Object::ToInteger(isolate, offset)); - } - - if (offset->Number() < 0) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewRangeError(MessageTemplate::kTypedArraySetNegativeOffset)); - } - - if (offset->Number() > Smi::kMaxValue) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewRangeError(MessageTemplate::kTypedArraySetSourceTooLarge)); - } - - if (!target->IsJSTypedArray()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kNotTypedArray)); - } - auto int_offset = static_cast<int>(offset->Number()); - - Handle<Smi> result_code; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result_code, - TypedArraySetFastCases(isolate, Handle<JSTypedArray>::cast(target), obj, - offset)); - - switch (static_cast<TypedArraySetResultCodes>(result_code->value())) { - case TypedArraySetResultCodes::SAME_TYPE: { - break; - } - case TypedArraySetResultCodes::OVERLAPPING: { - RETURN_FAILURE_ON_EXCEPTION( - isolate, TypedArraySetFromOverlapping( - isolate, Handle<JSTypedArray>::cast(target), - Handle<JSTypedArray>::cast(obj), int_offset)); - break; - } - case TypedArraySetResultCodes::NONOVERLAPPING: { - if (int_offset == 0) { - TypedArrayCopyElements(Handle<JSTypedArray>::cast(target), - Handle<JSTypedArray>::cast(obj), - Handle<JSTypedArray>::cast(obj)->length()); - } else { - RETURN_FAILURE_ON_EXCEPTION( - isolate, - TypedArraySetFromArrayLike( - isolate, Handle<JSTypedArray>::cast(target), obj, - Handle<JSTypedArray>::cast(obj)->length_value(), int_offset)); - } - break; - } - case TypedArraySetResultCodes::NON_TYPED_ARRAY: { - if (obj->IsNumber()) { - // For number as a first argument, throw TypeError - // instead of silently ignoring the call, so that - // users know they did something wrong. - // (Consistent with Firefox and Blink/WebKit) - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kInvalidArgument)); - } - - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj, - Object::ToObject(isolate, obj)); - - Handle<Object> len; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, len, - Object::GetProperty(obj, isolate->factory()->length_string())); - if (len->IsUndefined(isolate)) { - break; - } - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, len, - Object::ToLength(isolate, len)); - - DCHECK_GE(int_offset, 0); - if (int_offset + len->Number() > - Handle<JSTypedArray>::cast(target)->length_value()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, - NewRangeError(MessageTemplate::kTypedArraySetSourceTooLarge)); - } - uint32_t int_l; - CHECK(DoubleToUint32IfEqualToSelf(len->Number(), &int_l)); - RETURN_FAILURE_ON_EXCEPTION( - isolate, TypedArraySetFromArrayLike( - isolate, Handle<JSTypedArray>::cast(target), obj, int_l, - int_offset)); - } break; - } - - return *isolate->factory()->undefined_value(); -} - BUILTIN(TypedArrayPrototypeSlice) { HandleScope scope(isolate); |