[typedarray] Port TypedArray#slice to Torque.
Bug: v8:8906 Change-Id: I7a07482d2d5de13de11fa2611e3c6ae18439e820 Reviewed-on: https://chromium-review.googlesource.com/c/1493136 Commit-Queue: Peter Wong <peter.wm.wong@gmail.com> Reviewed-by: Simon Zünd <szuend@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#60007}
This commit is contained in:
parent
683cf6f43b
commit
acdaa4c713
2
BUILD.gn
2
BUILD.gn
@ -928,6 +928,7 @@ torque_files = [
|
||||
"src/builtins/typed-array-foreach.tq",
|
||||
"src/builtins/typed-array-reduce.tq",
|
||||
"src/builtins/typed-array-reduceright.tq",
|
||||
"src/builtins/typed-array-slice.tq",
|
||||
"src/builtins/typed-array-subarray.tq",
|
||||
"test/torque/test-torque.tq",
|
||||
"third_party/v8/builtins/array-sort.tq",
|
||||
@ -962,6 +963,7 @@ torque_namespaces = [
|
||||
"typed-array-foreach",
|
||||
"typed-array-reduce",
|
||||
"typed-array-reduceright",
|
||||
"typed-array-slice",
|
||||
"typed-array-subarray",
|
||||
]
|
||||
|
||||
|
@ -481,6 +481,10 @@ const kReduceNoInitial: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kReduceNoInitial';
|
||||
const kFirstArgumentNotRegExp: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kFirstArgumentNotRegExp';
|
||||
const kBigIntMixedTypes: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kBigIntMixedTypes';
|
||||
const kTypedArrayTooShort: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kTypedArrayTooShort';
|
||||
|
||||
const kMaxArrayIndex:
|
||||
constexpr uint32 generates 'JSArray::kMaxArrayIndex';
|
||||
@ -846,6 +850,8 @@ extern operator '|' macro Word32Or(int32, int32): int32;
|
||||
extern operator '|' macro Word32Or(uint32, uint32): uint32;
|
||||
extern operator '&' macro Word32And(bool, bool): bool;
|
||||
extern operator '|' macro Word32Or(bool, bool): bool;
|
||||
extern operator '==' macro Word32Equal(bool, bool): bool;
|
||||
extern operator '!=' macro Word32NotEqual(bool, bool): bool;
|
||||
|
||||
extern operator '+' macro Float64Add(float64, float64): float64;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/objects/allocation-site-inl.h"
|
||||
#include "src/objects/arguments-inl.h"
|
||||
#include "src/objects/property-cell.h"
|
||||
#include "torque-generated/builtins-typed-array-createtypedarray-from-dsl-gen.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -96,9 +97,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
|
||||
TNode<Smi> length = CAST(len_);
|
||||
const char* method_name = "%TypedArray%.prototype.map";
|
||||
|
||||
TypedArrayBuiltinsAssembler typedarray_asm(state());
|
||||
TypedArrayCreatetypedarrayBuiltinsFromDSLAssembler typedarray_asm(state());
|
||||
TNode<JSTypedArray> a = typedarray_asm.TypedArraySpeciesCreateByLength(
|
||||
context(), original_array, length, method_name);
|
||||
context(), method_name, original_array, length);
|
||||
// In the Spec and our current implementation, the length check is already
|
||||
// performed in TypedArraySpeciesCreate.
|
||||
CSA_ASSERT(this, SmiLessThanOrEqual(CAST(len_), LoadJSTypedArrayLength(a)));
|
||||
|
@ -1140,9 +1140,6 @@ namespace internal {
|
||||
CPP(TypedArrayPrototypeReverse) \
|
||||
/* ES6 %TypedArray%.prototype.set */ \
|
||||
TFJ(TypedArrayPrototypeSet, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
/* ES6 #sec-%typedarray%.prototype.slice */ \
|
||||
TFJ(TypedArrayPrototypeSlice, \
|
||||
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
/* ES6 #sec-get-%typedarray%.prototype-@@tostringtag */ \
|
||||
TFJ(TypedArrayPrototypeToStringTag, 0, kReceiver) \
|
||||
/* ES6 %TypedArray%.prototype.every */ \
|
||||
|
@ -147,9 +147,9 @@ TNode<FixedTypedArrayBase> TypedArrayBuiltinsAssembler::AllocateOnHeapElements(
|
||||
return CAST(elements);
|
||||
}
|
||||
|
||||
Node* TypedArrayBuiltinsAssembler::LoadDataPtr(Node* typed_array) {
|
||||
CSA_ASSERT(this, IsJSTypedArray(typed_array));
|
||||
Node* elements = LoadElements(typed_array);
|
||||
TNode<RawPtrT> TypedArrayBuiltinsAssembler::LoadDataPtr(
|
||||
TNode<JSTypedArray> typed_array) {
|
||||
TNode<FixedArrayBase> elements = LoadElements(typed_array);
|
||||
CSA_ASSERT(this, IsFixedTypedArray(elements));
|
||||
return LoadFixedTypedArrayBackingStore(CAST(elements));
|
||||
}
|
||||
@ -306,22 +306,6 @@ TNode<JSFunction> TypedArrayBuiltinsAssembler::GetDefaultConstructor(
|
||||
LoadContextElement(LoadNativeContext(context), context_slot.value()));
|
||||
}
|
||||
|
||||
TNode<JSTypedArray>
|
||||
TypedArrayBuiltinsAssembler::TypedArraySpeciesCreateByLength(
|
||||
TNode<Context> context, TNode<JSTypedArray> exemplar, TNode<Smi> len,
|
||||
const char* method_name) {
|
||||
CSA_ASSERT(this, TaggedIsPositiveSmi(len));
|
||||
|
||||
TypedArrayCreatetypedarrayBuiltinsFromDSLAssembler typedarray_asm(state());
|
||||
const int31_t kNumArgs = 1;
|
||||
TNode<JSTypedArray> new_typed_array = typedarray_asm.TypedArraySpeciesCreate(
|
||||
context, method_name, kNumArgs, exemplar, len, UndefinedConstant(),
|
||||
UndefinedConstant());
|
||||
|
||||
ThrowIfLengthLessThan(context, new_typed_array, len);
|
||||
return new_typed_array;
|
||||
}
|
||||
|
||||
TNode<JSTypedArray> TypedArrayBuiltinsAssembler::TypedArrayCreateByLength(
|
||||
TNode<Context> context, TNode<Object> constructor, TNode<Smi> len,
|
||||
const char* method_name) {
|
||||
@ -408,8 +392,8 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
|
||||
|
||||
// Grab pointers and byte lengths we need later on.
|
||||
|
||||
TNode<IntPtrT> target_data_ptr = UncheckedCast<IntPtrT>(LoadDataPtr(target));
|
||||
TNode<IntPtrT> source_data_ptr = UncheckedCast<IntPtrT>(LoadDataPtr(source));
|
||||
TNode<RawPtrT> target_data_ptr = LoadDataPtr(target);
|
||||
TNode<RawPtrT> source_data_ptr = LoadDataPtr(source);
|
||||
|
||||
TNode<Word32T> source_el_kind = LoadElementsKind(source);
|
||||
TNode<Word32T> target_el_kind = LoadElementsKind(target);
|
||||
@ -434,9 +418,9 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
|
||||
|
||||
BIND(&call_memmove);
|
||||
{
|
||||
TNode<IntPtrT> target_start =
|
||||
IntPtrAdd(target_data_ptr, IntPtrMul(offset, target_el_size));
|
||||
CallCMemmove(target_start, source_data_ptr, source_byte_length);
|
||||
TNode<RawPtrT> target_start =
|
||||
RawPtrAdd(target_data_ptr, IntPtrMul(offset, target_el_size));
|
||||
CallCMemmove(target_start, source_data_ptr, Unsigned(source_byte_length));
|
||||
Goto(&out);
|
||||
}
|
||||
|
||||
@ -506,9 +490,9 @@ void TypedArrayBuiltinsAssembler::SetJSArraySource(
|
||||
BIND(&out);
|
||||
}
|
||||
|
||||
void TypedArrayBuiltinsAssembler::CallCMemmove(TNode<IntPtrT> dest_ptr,
|
||||
TNode<IntPtrT> src_ptr,
|
||||
TNode<IntPtrT> byte_length) {
|
||||
void TypedArrayBuiltinsAssembler::CallCMemmove(TNode<RawPtrT> dest_ptr,
|
||||
TNode<RawPtrT> src_ptr,
|
||||
TNode<UintPtrT> byte_length) {
|
||||
TNode<ExternalReference> memmove =
|
||||
ExternalConstant(ExternalReference::libc_memmove_function());
|
||||
CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
|
||||
@ -698,118 +682,6 @@ TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) {
|
||||
ThrowTypeError(context, MessageTemplate::kNotTypedArray);
|
||||
}
|
||||
|
||||
// ES %TypedArray%.prototype.slice
|
||||
TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
|
||||
const char* method_name = "%TypedArray%.prototype.slice";
|
||||
Label call_c(this), call_memmove(this), if_count_is_not_zero(this),
|
||||
if_bigint_mixed_types(this, Label::kDeferred);
|
||||
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
CodeStubArguments args(
|
||||
this,
|
||||
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)));
|
||||
|
||||
TNode<Object> receiver = args.GetReceiver();
|
||||
TNode<JSTypedArray> source =
|
||||
ValidateTypedArray(context, receiver, method_name);
|
||||
|
||||
TNode<Smi> source_length = LoadJSTypedArrayLength(source);
|
||||
|
||||
// Convert start offset argument to integer, and calculate relative offset.
|
||||
TNode<Object> start = args.GetOptionalArgumentValue(0, SmiConstant(0));
|
||||
TNode<Smi> start_index =
|
||||
SmiTag(ConvertToRelativeIndex(context, start, SmiUntag(source_length)));
|
||||
|
||||
// Convert end offset argument to integer, and calculate relative offset.
|
||||
// If end offset is not given or undefined is given, set source_length to
|
||||
// "end_index".
|
||||
TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
|
||||
TNode<Smi> end_index =
|
||||
Select<Smi>(IsUndefined(end), [=] { return source_length; },
|
||||
[=] {
|
||||
return SmiTag(ConvertToRelativeIndex(
|
||||
context, end, SmiUntag(source_length)));
|
||||
});
|
||||
|
||||
// Create a result array by invoking TypedArraySpeciesCreate.
|
||||
TNode<Smi> count = SmiMax(SmiSub(end_index, start_index), SmiConstant(0));
|
||||
TNode<JSTypedArray> result_array =
|
||||
TypedArraySpeciesCreateByLength(context, source, count, method_name);
|
||||
|
||||
// If count is zero, return early.
|
||||
GotoIf(SmiGreaterThan(count, SmiConstant(0)), &if_count_is_not_zero);
|
||||
args.PopAndReturn(result_array);
|
||||
|
||||
BIND(&if_count_is_not_zero);
|
||||
// Check the source array is detached or not. We don't need to check if the
|
||||
// result array is detached or not since TypedArraySpeciesCreate checked it.
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(LoadObjectField(
|
||||
result_array, JSTypedArray::kBufferOffset))));
|
||||
TNode<JSArrayBuffer> receiver_buffer =
|
||||
LoadJSArrayBufferViewBuffer(CAST(receiver));
|
||||
ThrowIfArrayBufferIsDetached(context, receiver_buffer, method_name);
|
||||
|
||||
// result_array could be a different type from source or share the same
|
||||
// buffer with the source because of custom species constructor.
|
||||
// If the types of source and result array are the same and they are not
|
||||
// sharing the same buffer, use memmove.
|
||||
TNode<Word32T> source_el_kind = LoadElementsKind(source);
|
||||
TNode<Word32T> target_el_kind = LoadElementsKind(result_array);
|
||||
GotoIfNot(Word32Equal(source_el_kind, target_el_kind), &call_c);
|
||||
|
||||
TNode<Object> target_buffer =
|
||||
LoadObjectField(result_array, JSTypedArray::kBufferOffset);
|
||||
Branch(WordEqual(receiver_buffer, target_buffer), &call_c, &call_memmove);
|
||||
|
||||
BIND(&call_memmove);
|
||||
{
|
||||
GotoIfForceSlowPath(&call_c);
|
||||
|
||||
TNode<IntPtrT> target_data_ptr =
|
||||
UncheckedCast<IntPtrT>(LoadDataPtr(result_array));
|
||||
TNode<IntPtrT> source_data_ptr =
|
||||
UncheckedCast<IntPtrT>(LoadDataPtr(source));
|
||||
|
||||
TNode<IntPtrT> source_el_size = GetTypedArrayElementSize(source_el_kind);
|
||||
TNode<IntPtrT> source_start_bytes =
|
||||
IntPtrMul(SmiToIntPtr(start_index), source_el_size);
|
||||
TNode<IntPtrT> source_start =
|
||||
IntPtrAdd(source_data_ptr, source_start_bytes);
|
||||
|
||||
TNode<IntPtrT> count_bytes = IntPtrMul(SmiToIntPtr(count), source_el_size);
|
||||
|
||||
#ifdef DEBUG
|
||||
TNode<UintPtrT> target_byte_length =
|
||||
LoadJSArrayBufferViewByteLength(result_array);
|
||||
CSA_ASSERT(this, UintPtrLessThanOrEqual(Unsigned(count_bytes),
|
||||
target_byte_length));
|
||||
TNode<UintPtrT> source_byte_length =
|
||||
LoadJSArrayBufferViewByteLength(source);
|
||||
TNode<UintPtrT> source_size_in_bytes =
|
||||
UintPtrSub(source_byte_length, Unsigned(source_start_bytes));
|
||||
CSA_ASSERT(this, UintPtrLessThanOrEqual(Unsigned(count_bytes),
|
||||
source_size_in_bytes));
|
||||
#endif // DEBUG
|
||||
|
||||
CallCMemmove(target_data_ptr, source_start, count_bytes);
|
||||
args.PopAndReturn(result_array);
|
||||
}
|
||||
|
||||
BIND(&call_c);
|
||||
{
|
||||
GotoIf(Word32NotEqual(IsBigInt64ElementsKind(source_el_kind),
|
||||
IsBigInt64ElementsKind(target_el_kind)),
|
||||
&if_bigint_mixed_types);
|
||||
|
||||
CallCCopyTypedArrayElementsSlice(
|
||||
source, result_array, SmiToIntPtr(start_index), SmiToIntPtr(end_index));
|
||||
args.PopAndReturn(result_array);
|
||||
}
|
||||
|
||||
BIND(&if_bigint_mixed_types);
|
||||
ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes);
|
||||
}
|
||||
|
||||
// ES #sec-get-%typedarray%.prototype-@@tostringtag
|
||||
TF_BUILTIN(TypedArrayPrototypeToStringTag, TypedArrayBuiltinsAssembler) {
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -1289,8 +1161,10 @@ TF_BUILTIN(TypedArrayPrototypeFilter, TypedArrayBuiltinsAssembler) {
|
||||
TNode<Smi> captured = LoadFastJSArrayLength(values_array);
|
||||
|
||||
// 10. Let A be ? TypedArraySpeciesCreate(O, captured).
|
||||
TypedArrayCreatetypedarrayBuiltinsFromDSLAssembler typedarray_asm(state());
|
||||
TNode<JSTypedArray> result_array =
|
||||
TypedArraySpeciesCreateByLength(context, source, captured, method_name);
|
||||
typedarray_asm.TypedArraySpeciesCreateByLength(context, method_name,
|
||||
source, captured);
|
||||
|
||||
// 11. Let n be 0.
|
||||
// 12. For each element e of kept, do
|
||||
|
@ -24,10 +24,6 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<JSTypedArray> exemplar,
|
||||
TArgs... args);
|
||||
|
||||
TNode<JSTypedArray> TypedArraySpeciesCreateByLength(
|
||||
TNode<Context> context, TNode<JSTypedArray> exemplar, TNode<Smi> len,
|
||||
const char* method_name);
|
||||
|
||||
void GenerateTypedArrayPrototypeIterationMethod(TNode<Context> context,
|
||||
TNode<Object> receiver,
|
||||
const char* method_name,
|
||||
@ -52,7 +48,7 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<BoolT> IsMockArrayBufferAllocatorFlag();
|
||||
TNode<UintPtrT> CalculateExternalPointer(TNode<UintPtrT> backing_store,
|
||||
TNode<UintPtrT> byte_offset);
|
||||
Node* LoadDataPtr(Node* typed_array);
|
||||
TNode<RawPtrT> LoadDataPtr(TNode<JSTypedArray> typed_array);
|
||||
|
||||
// Returns true if kind is either UINT8_ELEMENTS or UINT8_CLAMPED_ELEMENTS.
|
||||
TNode<Word32T> IsUint8ElementsKind(TNode<Word32T> kind);
|
||||
@ -95,8 +91,8 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<JSTypedArray> target, TNode<IntPtrT> offset,
|
||||
Label* call_runtime, Label* if_source_too_large);
|
||||
|
||||
void CallCMemmove(TNode<IntPtrT> dest_ptr, TNode<IntPtrT> src_ptr,
|
||||
TNode<IntPtrT> byte_length);
|
||||
void CallCMemmove(TNode<RawPtrT> dest_ptr, TNode<RawPtrT> src_ptr,
|
||||
TNode<UintPtrT> byte_length);
|
||||
|
||||
void CallCMemcpy(TNode<RawPtrT> dest_ptr, TNode<RawPtrT> src_ptr,
|
||||
TNode<UintPtrT> byte_length);
|
||||
|
@ -370,4 +370,19 @@ namespace typed_array_createtypedarray {
|
||||
return typed_array::ValidateTypedArray(context, newObj, methodName);
|
||||
}
|
||||
}
|
||||
|
||||
transitioning macro TypedArraySpeciesCreateByLength(implicit context:
|
||||
Context)(
|
||||
methodName: constexpr string, exemplar: JSTypedArray,
|
||||
length: Smi): JSTypedArray {
|
||||
assert(Is<PositiveSmi>(length));
|
||||
const numArgs: constexpr int31 = 1;
|
||||
const typedArray: JSTypedArray = TypedArraySpeciesCreate(
|
||||
methodName, numArgs, exemplar, length, Undefined, Undefined);
|
||||
if (typedArray.length < length) deferred {
|
||||
ThrowTypeError(kTypedArrayTooShort);
|
||||
}
|
||||
|
||||
return typedArray;
|
||||
}
|
||||
}
|
||||
|
107
src/builtins/typed-array-slice.tq
Normal file
107
src/builtins/typed-array-slice.tq
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2019 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include 'src/builtins/builtins-typed-array-gen.h'
|
||||
|
||||
namespace typed_array_slice {
|
||||
const kBuiltinName: constexpr string = '%TypedArray%.prototype.slice';
|
||||
|
||||
extern macro TypedArrayBuiltinsAssembler::CallCCopyTypedArrayElementsSlice(
|
||||
JSTypedArray, JSTypedArray, intptr, intptr): void;
|
||||
|
||||
macro FastCopy(
|
||||
src: typed_array::AttachedJSTypedArray, dest: JSTypedArray, k: intptr,
|
||||
count: PositiveSmi) labels IfSlow {
|
||||
GotoIfForceSlowPath() otherwise IfSlow;
|
||||
|
||||
const srcKind: ElementsKind = src.elements_kind;
|
||||
const destInfo = typed_array::GetTypedArrayElementsInfo(dest);
|
||||
|
||||
// dest could be a different type from src or share the same buffer
|
||||
// with the src because of custom species constructor. If the types
|
||||
// of src and result array are the same and they are not sharing the
|
||||
// same buffer, use memmove.
|
||||
if (srcKind != destInfo.kind) goto IfSlow;
|
||||
if (BitcastTaggedToWord(dest.buffer) == BitcastTaggedToWord(src.buffer)) {
|
||||
goto IfSlow;
|
||||
}
|
||||
|
||||
const countBytes: uintptr =
|
||||
destInfo.CalculateByteLength(count) otherwise unreachable;
|
||||
const startOffset: uintptr =
|
||||
destInfo.CalculateByteLength(Convert<PositiveSmi>(k))
|
||||
otherwise unreachable;
|
||||
const srcPtr: RawPtr = src.data_ptr + Convert<intptr>(startOffset);
|
||||
|
||||
assert(countBytes <= dest.byte_length);
|
||||
assert(countBytes <= src.byte_length - startOffset);
|
||||
|
||||
typed_array::CallCMemmove(dest.data_ptr, srcPtr, countBytes);
|
||||
}
|
||||
|
||||
macro SlowCopy(implicit context: Context)(
|
||||
src: JSTypedArray, dest: JSTypedArray, k: intptr, final: intptr) {
|
||||
if (typed_array::IsBigInt64ElementsKind(src.elements_kind) !=
|
||||
typed_array::IsBigInt64ElementsKind(dest.elements_kind))
|
||||
deferred {
|
||||
ThrowTypeError(kBigIntMixedTypes);
|
||||
}
|
||||
|
||||
CallCCopyTypedArrayElementsSlice(src, dest, k, final);
|
||||
}
|
||||
|
||||
// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.slice
|
||||
transitioning javascript builtin TypedArrayPrototypeSlice(
|
||||
context: Context, receiver: Object, ...arguments): Object {
|
||||
// arguments[0] = start
|
||||
// arguments[1] = end
|
||||
|
||||
// 1. Let O be the this value.
|
||||
// 2. Perform ? ValidateTypedArray(O).
|
||||
const src: JSTypedArray =
|
||||
typed_array::ValidateTypedArray(context, receiver, kBuiltinName);
|
||||
|
||||
// 3. Let len be O.[[ArrayLength]].
|
||||
const len = Convert<intptr>(src.length);
|
||||
|
||||
// 4. Let relativeStart be ? ToInteger(start).
|
||||
// 5. If relativeStart < 0, let k be max((len + relativeStart), 0);
|
||||
// else let k be min(relativeStart, len).
|
||||
const start = arguments[0];
|
||||
const k: intptr =
|
||||
start != Undefined ? ConvertToRelativeIndex(start, len) : 0;
|
||||
|
||||
// 6. If end is undefined, let relativeEnd be len;
|
||||
// else let relativeEnd be ? ToInteger(end).
|
||||
// 7. If relativeEnd < 0, let final be max((len + relativeEnd), 0);
|
||||
// else let final be min(relativeEnd, len).
|
||||
const end = arguments[1];
|
||||
const final: intptr =
|
||||
end != Undefined ? ConvertToRelativeIndex(end, len) : len;
|
||||
|
||||
// 8. Let count be max(final - k, 0).
|
||||
const count = Convert<PositiveSmi>(IntPtrMax(final - k, 0));
|
||||
|
||||
// 9. Let A be ? TypedArraySpeciesCreate(O, « count »).
|
||||
const dest: JSTypedArray =
|
||||
typed_array_createtypedarray::TypedArraySpeciesCreateByLength(
|
||||
kBuiltinName, src, count);
|
||||
|
||||
if (count > 0) {
|
||||
try {
|
||||
const srcAttached = typed_array::EnsureAttached(src)
|
||||
otherwise IfDetached;
|
||||
FastCopy(srcAttached, dest, k, count) otherwise IfSlow;
|
||||
}
|
||||
label IfDetached deferred {
|
||||
ThrowTypeError(kDetachedOperation, kBuiltinName);
|
||||
}
|
||||
label IfSlow deferred {
|
||||
SlowCopy(src, dest, k, final);
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
}
|
@ -43,12 +43,16 @@ namespace typed_array {
|
||||
|
||||
extern macro TypedArrayBuiltinsAssembler::CallCMemcpy(
|
||||
RawPtr, RawPtr, uintptr): void;
|
||||
extern macro TypedArrayBuiltinsAssembler::CallCMemmove(
|
||||
RawPtr, RawPtr, uintptr): void;
|
||||
extern macro TypedArrayBuiltinsAssembler::CallCMemset(
|
||||
RawPtr, intptr, uintptr): void;
|
||||
extern macro TypedArrayBuiltinsAssembler::GetBuffer(
|
||||
implicit context: Context)(JSTypedArray): JSArrayBuffer;
|
||||
extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(
|
||||
JSTypedArray): TypedArrayElementsInfo;
|
||||
extern macro TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
|
||||
ElementsKind): bool;
|
||||
extern macro LoadFixedTypedArrayElementAsTagged(
|
||||
RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object;
|
||||
extern macro StoreFixedTypedArrayElementFromTagged(
|
||||
|
Loading…
Reference in New Issue
Block a user