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

Side by Side 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, 8 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 unified diff | Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/builtins/builtins-definitions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils-gen.h" 5 #include "src/builtins/builtins-utils-gen.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-stub-assembler.h" 7 #include "src/code-stub-assembler.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 context_ = context; 288 context_ = context;
289 this_arg_ = this_arg; 289 this_arg_ = this_arg;
290 callbackfn_ = callbackfn; 290 callbackfn_ = callbackfn;
291 a_.Bind(a); 291 a_.Bind(a);
292 k_.Bind(initial_k); 292 k_.Bind(initial_k);
293 o_ = o; 293 o_ = o;
294 len_ = len; 294 len_ = len;
295 to_.Bind(to); 295 to_.Bind(to);
296 } 296 }
297 297
298 void GenerateIteratingTypedArrayBuiltinBody(
299 const char* name, const BuiltinResultGenerator& generator,
300 const CallResultProcessor& processor, const PostLoopAction& action) {
301 Node* name_string =
302 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name));
303
304 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray
305
306 Label throw_not_typed_array(this, Label::kDeferred),
307 throw_detached(this, Label::kDeferred);
308
309 GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array);
310 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE),
311 &throw_not_typed_array);
312
313 o_ = receiver_;
314 Node* array_buffer = LoadObjectField(o_, JSTypedArray::kBufferOffset);
315 GotoIf(IsDetachedBuffer(array_buffer), &throw_detached);
316
317 len_ = LoadObjectField(o_, JSTypedArray::kLengthOffset);
318
319 Label throw_not_callable(this, Label::kDeferred);
320 Label distinguish_types(this);
321 GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable);
322 Branch(IsCallableMap(LoadMap(callbackfn_)), &distinguish_types,
323 &throw_not_callable);
324
325 Bind(&throw_not_typed_array);
326 {
327 CallRuntime(Runtime::kThrowTypeError, context_,
328 SmiConstant(MessageTemplate::kNotTypedArray));
329 Unreachable();
330 }
331
332 Bind(&throw_detached);
333 {
334 CallRuntime(Runtime::kThrowTypeError, context_,
335 SmiConstant(MessageTemplate::kDetachedOperation),
336 name_string);
337 Unreachable();
338 }
339
340 Bind(&throw_not_callable);
341 {
342 CallRuntime(Runtime::kThrowTypeError, context_,
343 SmiConstant(MessageTemplate::kCalledNonCallable),
344 callbackfn_);
345 Unreachable();
346 }
347
348 Label unexpected_instance_type(this);
349 Bind(&unexpected_instance_type);
350 Unreachable();
351
352 std::vector<int32_t> instance_types = {
353 #define INSTANCE_TYPE(Type, type, TYPE, ctype, size) FIXED_##TYPE##_ARRAY_TYPE,
354 TYPED_ARRAYS(INSTANCE_TYPE)
355 #undef INSTANCE_TYPE
356 };
357 std::vector<Label> labels;
358 for (size_t i = 0; i < instance_types.size(); ++i) {
359 labels.push_back(Label(this));
360 }
361 std::vector<Label*> label_ptrs;
362 for (Label& label : labels) {
363 label_ptrs.push_back(&label);
364 }
365
366 Bind(&distinguish_types);
367 a_.Bind(generator(this));
368 Node* elements_type = LoadInstanceType(LoadElements(o_));
369 Switch(elements_type, &unexpected_instance_type, instance_types.data(),
370 label_ptrs.data(), labels.size());
371
372 for (size_t i = 0; i < labels.size(); ++i) {
373 Bind(&labels[i]);
374 Label done(this);
375 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a
376 // spec violation. Should go to &detached and throw a TypeError instead.
377 VisitAllTypedArrayElements(
378 ElementsKindForInstanceType(
379 static_cast<InstanceType>(instance_types[i])),
380 array_buffer, processor, &done);
381 Goto(&done);
382 action(this);
383 // No exception, return success
384 Bind(&done);
385 Return(a_.value());
386 }
387 }
388
298 void GenerateIteratingArrayBuiltinLoopContinuation( 389 void GenerateIteratingArrayBuiltinLoopContinuation(
299 const CallResultProcessor& processor, const PostLoopAction& action, 390 const CallResultProcessor& processor, const PostLoopAction& action,
300 ForEachDirection direction = ForEachDirection::kForward) { 391 ForEachDirection direction = ForEachDirection::kForward) {
301 Label loop(this, {&k_, &a_, &to_}); 392 Label loop(this, {&k_, &a_, &to_});
302 Label after_loop(this); 393 Label after_loop(this);
303 Goto(&loop); 394 Goto(&loop);
304 Bind(&loop); 395 Bind(&loop);
305 { 396 {
306 if (direction == ForEachDirection::kForward) { 397 if (direction == ForEachDirection::kForward) {
307 // 8. Repeat, while k < len 398 // 8. Repeat, while k < len
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 } 434 }
344 Goto(&loop); 435 Goto(&loop);
345 } 436 }
346 Bind(&after_loop); 437 Bind(&after_loop);
347 438
348 action(this); 439 action(this);
349 Return(a_.value()); 440 Return(a_.value());
350 } 441 }
351 442
352 private: 443 private:
444 static ElementsKind ElementsKindForInstanceType(InstanceType type) {
445 switch (type) {
446 #define INSTANCE_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
447 case FIXED_##TYPE##_ARRAY_TYPE: \
448 return TYPE##_ELEMENTS;
449
450 TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENTS_KIND)
451 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND
452
453 default:
454 UNREACHABLE();
455 return static_cast<ElementsKind>(-1);
456 }
457 }
458
459 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer,
460 const CallResultProcessor& processor,
461 Label* detached) {
462 VariableList list({&a_, &k_, &to_}, zone());
463
464 FastLoopBody body = [&](Node* index) {
465 GotoIf(IsDetachedBuffer(array_buffer), detached);
466 Node* elements = LoadElements(o_);
467 Node* base_ptr =
468 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
469 Node* external_ptr =
470 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
471 MachineType::Pointer());
472 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
473 Node* value = LoadFixedTypedArrayElementAsTagged(data_ptr, index, kind,
474 SMI_PARAMETERS);
475 k_.Bind(index);
476 a_.Bind(processor(this, value, index));
477 };
478 BuildFastLoop(list, SmiConstant(0), len_, body, 1,
479 ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
480 }
481
353 void VisitAllFastElementsOneKind(ElementsKind kind, 482 void VisitAllFastElementsOneKind(ElementsKind kind,
354 const CallResultProcessor& processor, 483 const CallResultProcessor& processor,
355 Label* array_changed, ParameterMode mode, 484 Label* array_changed, ParameterMode mode,
356 ForEachDirection direction) { 485 ForEachDirection direction) {
357 Comment("begin VisitAllFastElementsOneKind"); 486 Comment("begin VisitAllFastElementsOneKind");
358 Variable original_map(this, MachineRepresentation::kTagged); 487 Variable original_map(this, MachineRepresentation::kTagged);
359 original_map.Bind(LoadMap(o())); 488 original_map.Bind(LoadMap(o()));
360 VariableList list({&original_map, &a_, &k_, &to_}, zone()); 489 VariableList list({&original_map, &a_, &k_, &to_}, zone());
361 Node* start = IntPtrOrSmiConstant(0, mode); 490 Node* start = IntPtrOrSmiConstant(0, mode);
362 Node* end = TaggedToParameter(len(), mode); 491 Node* end = TaggedToParameter(len(), mode);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 new_target); 831 new_target);
703 832
704 GenerateIteratingArrayBuiltinBody( 833 GenerateIteratingArrayBuiltinBody(
705 "Array.prototype.some", 834 "Array.prototype.some",
706 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, 835 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator,
707 &ArrayBuiltinCodeStubAssembler::SomeProcessor, 836 &ArrayBuiltinCodeStubAssembler::SomeProcessor,
708 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, 837 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
709 CodeFactory::ArraySomeLoopContinuation(isolate())); 838 CodeFactory::ArraySomeLoopContinuation(isolate()));
710 } 839 }
711 840
841 TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinCodeStubAssembler) {
842 Node* context = Parameter(Descriptor::kContext);
843 Node* receiver = Parameter(Descriptor::kReceiver);
844 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
845 Node* this_arg = Parameter(Descriptor::kThisArg);
846 Node* new_target = Parameter(Descriptor::kNewTarget);
847
848 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
849 new_target);
850
851 GenerateIteratingTypedArrayBuiltinBody(
852 "%TypedArray%.prototype.some",
853 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator,
854 &ArrayBuiltinCodeStubAssembler::SomeProcessor,
855 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
856 }
857
712 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { 858 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) {
713 Node* context = Parameter(Descriptor::kContext); 859 Node* context = Parameter(Descriptor::kContext);
714 Node* receiver = Parameter(Descriptor::kReceiver); 860 Node* receiver = Parameter(Descriptor::kReceiver);
715 Node* callbackfn = Parameter(Descriptor::kCallbackFn); 861 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
716 Node* this_arg = Parameter(Descriptor::kThisArg); 862 Node* this_arg = Parameter(Descriptor::kThisArg);
717 Node* array = Parameter(Descriptor::kArray); 863 Node* array = Parameter(Descriptor::kArray);
718 Node* object = Parameter(Descriptor::kObject); 864 Node* object = Parameter(Descriptor::kObject);
719 Node* initial_k = Parameter(Descriptor::kInitialK); 865 Node* initial_k = Parameter(Descriptor::kInitialK);
720 Node* len = Parameter(Descriptor::kLength); 866 Node* len = Parameter(Descriptor::kLength);
721 Node* to = Parameter(Descriptor::kTo); 867 Node* to = Parameter(Descriptor::kTo);
(...skipping 18 matching lines...) Expand all
740 new_target); 886 new_target);
741 887
742 GenerateIteratingArrayBuiltinBody( 888 GenerateIteratingArrayBuiltinBody(
743 "Array.prototype.every", 889 "Array.prototype.every",
744 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, 890 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator,
745 &ArrayBuiltinCodeStubAssembler::EveryProcessor, 891 &ArrayBuiltinCodeStubAssembler::EveryProcessor,
746 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, 892 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
747 CodeFactory::ArrayEveryLoopContinuation(isolate())); 893 CodeFactory::ArrayEveryLoopContinuation(isolate()));
748 } 894 }
749 895
896 TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinCodeStubAssembler) {
897 Node* context = Parameter(Descriptor::kContext);
898 Node* receiver = Parameter(Descriptor::kReceiver);
899 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
900 Node* this_arg = Parameter(Descriptor::kThisArg);
901 Node* new_target = Parameter(Descriptor::kNewTarget);
902
903 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
904 new_target);
905
906 GenerateIteratingTypedArrayBuiltinBody(
907 "%TypedArray%.prototype.every",
908 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator,
909 &ArrayBuiltinCodeStubAssembler::EveryProcessor,
910 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
911 }
912
750 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) { 913 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) {
751 Node* context = Parameter(Descriptor::kContext); 914 Node* context = Parameter(Descriptor::kContext);
752 Node* receiver = Parameter(Descriptor::kReceiver); 915 Node* receiver = Parameter(Descriptor::kReceiver);
753 Node* callbackfn = Parameter(Descriptor::kCallbackFn); 916 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
754 Node* this_arg = Parameter(Descriptor::kThisArg); 917 Node* this_arg = Parameter(Descriptor::kThisArg);
755 Node* accumulator = Parameter(Descriptor::kAccumulator); 918 Node* accumulator = Parameter(Descriptor::kAccumulator);
756 Node* object = Parameter(Descriptor::kObject); 919 Node* object = Parameter(Descriptor::kObject);
757 Node* initial_k = Parameter(Descriptor::kInitialK); 920 Node* initial_k = Parameter(Descriptor::kInitialK);
758 Node* len = Parameter(Descriptor::kLength); 921 Node* len = Parameter(Descriptor::kLength);
759 Node* to = Parameter(Descriptor::kTo); 922 Node* to = Parameter(Descriptor::kTo);
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 { 2117 {
1955 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); 2118 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
1956 CallRuntime(Runtime::kThrowTypeError, context, message, 2119 CallRuntime(Runtime::kThrowTypeError, context, message,
1957 HeapConstant(operation)); 2120 HeapConstant(operation));
1958 Unreachable(); 2121 Unreachable();
1959 } 2122 }
1960 } 2123 }
1961 2124
1962 } // namespace internal 2125 } // namespace internal
1963 } // namespace v8 2126 } // namespace v8
OLDNEW
« 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