| Index: src/builtins/builtins-array-gen.cc
|
| diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc
|
| index f8163ff345f5a22543856f2bac01a158691bc9f0..6a51a4ac36e02255bec75da15be8c6baa9b1a747 100644
|
| --- a/src/builtins/builtins-array-gen.cc
|
| +++ b/src/builtins/builtins-array-gen.cc
|
| @@ -295,6 +295,97 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
| to_.Bind(to);
|
| }
|
|
|
| + void GenerateIteratingTypedArrayBuiltinBody(
|
| + const char* name, const BuiltinResultGenerator& generator,
|
| + const CallResultProcessor& processor, const PostLoopAction& action) {
|
| + Node* name_string =
|
| + HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name));
|
| +
|
| + // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray
|
| +
|
| + Label throw_not_typed_array(this, Label::kDeferred),
|
| + throw_detached(this, Label::kDeferred);
|
| +
|
| + GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array);
|
| + GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE),
|
| + &throw_not_typed_array);
|
| +
|
| + o_ = receiver_;
|
| + Node* array_buffer = LoadObjectField(o_, JSTypedArray::kBufferOffset);
|
| + GotoIf(IsDetachedBuffer(array_buffer), &throw_detached);
|
| +
|
| + len_ = LoadObjectField(o_, JSTypedArray::kLengthOffset);
|
| +
|
| + Label throw_not_callable(this, Label::kDeferred);
|
| + Label distinguish_types(this);
|
| + GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable);
|
| + Branch(IsCallableMap(LoadMap(callbackfn_)), &distinguish_types,
|
| + &throw_not_callable);
|
| +
|
| + Bind(&throw_not_typed_array);
|
| + {
|
| + CallRuntime(Runtime::kThrowTypeError, context_,
|
| + SmiConstant(MessageTemplate::kNotTypedArray));
|
| + Unreachable();
|
| + }
|
| +
|
| + Bind(&throw_detached);
|
| + {
|
| + CallRuntime(Runtime::kThrowTypeError, context_,
|
| + SmiConstant(MessageTemplate::kDetachedOperation),
|
| + name_string);
|
| + Unreachable();
|
| + }
|
| +
|
| + Bind(&throw_not_callable);
|
| + {
|
| + CallRuntime(Runtime::kThrowTypeError, context_,
|
| + SmiConstant(MessageTemplate::kCalledNonCallable),
|
| + callbackfn_);
|
| + Unreachable();
|
| + }
|
| +
|
| + Label unexpected_instance_type(this);
|
| + Bind(&unexpected_instance_type);
|
| + Unreachable();
|
| +
|
| + std::vector<int32_t> instance_types = {
|
| +#define INSTANCE_TYPE(Type, type, TYPE, ctype, size) FIXED_##TYPE##_ARRAY_TYPE,
|
| + TYPED_ARRAYS(INSTANCE_TYPE)
|
| +#undef INSTANCE_TYPE
|
| + };
|
| + std::vector<Label> labels;
|
| + for (size_t i = 0; i < instance_types.size(); ++i) {
|
| + labels.push_back(Label(this));
|
| + }
|
| + std::vector<Label*> label_ptrs;
|
| + for (Label& label : labels) {
|
| + label_ptrs.push_back(&label);
|
| + }
|
| +
|
| + Bind(&distinguish_types);
|
| + a_.Bind(generator(this));
|
| + Node* elements_type = LoadInstanceType(LoadElements(o_));
|
| + Switch(elements_type, &unexpected_instance_type, instance_types.data(),
|
| + label_ptrs.data(), labels.size());
|
| +
|
| + for (size_t i = 0; i < labels.size(); ++i) {
|
| + Bind(&labels[i]);
|
| + Label done(this);
|
| + // TODO(tebbi): Silently cancelling the loop on buffer detachment is a
|
| + // spec violation. Should go to &detached and throw a TypeError instead.
|
| + VisitAllTypedArrayElements(
|
| + ElementsKindForInstanceType(
|
| + static_cast<InstanceType>(instance_types[i])),
|
| + array_buffer, processor, &done);
|
| + Goto(&done);
|
| + action(this);
|
| + // No exception, return success
|
| + Bind(&done);
|
| + Return(a_.value());
|
| + }
|
| + }
|
| +
|
| void GenerateIteratingArrayBuiltinLoopContinuation(
|
| const CallResultProcessor& processor, const PostLoopAction& action,
|
| ForEachDirection direction = ForEachDirection::kForward) {
|
| @@ -350,6 +441,44 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
| }
|
|
|
| private:
|
| + static ElementsKind ElementsKindForInstanceType(InstanceType type) {
|
| + switch (type) {
|
| +#define INSTANCE_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
|
| + case FIXED_##TYPE##_ARRAY_TYPE: \
|
| + return TYPE##_ELEMENTS;
|
| +
|
| + TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENTS_KIND)
|
| +#undef INSTANCE_TYPE_TO_ELEMENTS_KIND
|
| +
|
| + default:
|
| + UNREACHABLE();
|
| + return static_cast<ElementsKind>(-1);
|
| + }
|
| + }
|
| +
|
| + void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer,
|
| + const CallResultProcessor& processor,
|
| + Label* detached) {
|
| + VariableList list({&a_, &k_, &to_}, zone());
|
| +
|
| + FastLoopBody body = [&](Node* index) {
|
| + GotoIf(IsDetachedBuffer(array_buffer), detached);
|
| + Node* elements = LoadElements(o_);
|
| + Node* base_ptr =
|
| + LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
|
| + Node* external_ptr =
|
| + LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
|
| + MachineType::Pointer());
|
| + Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
|
| + Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind,
|
| + SMI_PARAMETERS);
|
| + k_.Bind(index);
|
| + a_.Bind(processor(this, value, index));
|
| + };
|
| + BuildFastLoop(list, SmiConstant(0), len_, body, 1,
|
| + ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
|
| + }
|
| +
|
| void VisitAllFastElementsOneKind(ElementsKind kind,
|
| const CallResultProcessor& processor,
|
| Label* array_changed, ParameterMode mode,
|
| @@ -709,6 +838,23 @@ TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) {
|
| CodeFactory::ArraySomeLoopContinuation(isolate()));
|
| }
|
|
|
| +TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinCodeStubAssembler) {
|
| + Node* context = Parameter(Descriptor::kContext);
|
| + Node* receiver = Parameter(Descriptor::kReceiver);
|
| + Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
| + Node* this_arg = Parameter(Descriptor::kThisArg);
|
| + Node* new_target = Parameter(Descriptor::kNewTarget);
|
| +
|
| + InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
|
| + new_target);
|
| +
|
| + GenerateIteratingTypedArrayBuiltinBody(
|
| + "%TypedArray%.prototype.some",
|
| + &ArrayBuiltinCodeStubAssembler::SomeResultGenerator,
|
| + &ArrayBuiltinCodeStubAssembler::SomeProcessor,
|
| + &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
|
| +}
|
| +
|
| TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) {
|
| Node* context = Parameter(Descriptor::kContext);
|
| Node* receiver = Parameter(Descriptor::kReceiver);
|
| @@ -747,6 +893,23 @@ TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) {
|
| CodeFactory::ArrayEveryLoopContinuation(isolate()));
|
| }
|
|
|
| +TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinCodeStubAssembler) {
|
| + Node* context = Parameter(Descriptor::kContext);
|
| + Node* receiver = Parameter(Descriptor::kReceiver);
|
| + Node* callbackfn = Parameter(Descriptor::kCallbackFn);
|
| + Node* this_arg = Parameter(Descriptor::kThisArg);
|
| + Node* new_target = Parameter(Descriptor::kNewTarget);
|
| +
|
| + InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
|
| + new_target);
|
| +
|
| + GenerateIteratingTypedArrayBuiltinBody(
|
| + "%TypedArray%.prototype.every",
|
| + &ArrayBuiltinCodeStubAssembler::EveryResultGenerator,
|
| + &ArrayBuiltinCodeStubAssembler::EveryProcessor,
|
| + &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
|
| +}
|
| +
|
| TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) {
|
| Node* context = Parameter(Descriptor::kContext);
|
| Node* receiver = Parameter(Descriptor::kReceiver);
|
|
|