Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: src/builtins/builtins-array-gen.cc

Issue 2775203002: [builtins] Implement %TypedArray%.prototype.{some,every} in the CSA (Closed)
Patch Set: addressed comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/builtins/builtins-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « src/bootstrapper.cc ('k') | src/builtins/builtins-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698