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

Side by Side Diff: src/builtins/builtins-array-gen.cc

Issue 2775203002: [builtins] Implement %TypedArray%.prototype.{some,every} in the CSA (Closed)
Patch Set: small improvements 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 unified diff | Download patch
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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 context_ = context; 282 context_ = context;
283 this_arg_ = this_arg; 283 this_arg_ = this_arg;
284 callbackfn_ = callbackfn; 284 callbackfn_ = callbackfn;
285 a_.Bind(a); 285 a_.Bind(a);
286 k_.Bind(initial_k); 286 k_.Bind(initial_k);
287 o_ = o; 287 o_ = o;
288 len_ = len; 288 len_ = len;
289 to_.Bind(to); 289 to_.Bind(to);
290 } 290 }
291 291
292 void GenerateIteratingTypedArrayBuiltinBody(
293 const char* name, const BuiltinResultGenerator& generator,
294 const CallResultProcessor& processor, const PostLoopAction& action) {
295 Node* name_string =
296 HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(name));
297
298 // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray
299
300 Label not_typed_array(this, Label::kDeferred),
301 detached(this, Label::kDeferred);
302
303 GotoIf(TaggedIsSmi(receiver_), &not_typed_array);
304 GotoIfNot(HasInstanceType(receiver_, JS_TYPED_ARRAY_TYPE),
305 &not_typed_array);
306
307 o_ = receiver_;
308 Node* array_buffer = LoadObjectField(o_, JSTypedArray::kBufferOffset);
309 GotoIf(IsDetachedBuffer(array_buffer), &detached);
310
311 len_ = LoadObjectField(o_, JSTypedArray::kLengthOffset);
312
313 Label not_callable(this, Label::kDeferred);
314 Label start(this);
315 GotoIf(TaggedIsSmi(callbackfn_), &not_callable);
316 Branch(IsCallableMap(LoadMap(callbackfn_)), &start, &not_callable);
317
318 Bind(&not_typed_array);
319 {
320 CallRuntime(Runtime::kThrowTypeError, context_,
321 SmiConstant(MessageTemplate::kNotTypedArray));
322 Unreachable();
323 }
324
325 Bind(&detached);
326 {
327 CallRuntime(Runtime::kThrowTypeError, context_,
328 SmiConstant(MessageTemplate::kDetachedOperation),
329 name_string);
330 Unreachable();
331 }
332
333 Bind(&not_callable);
334 {
335 CallRuntime(Runtime::kThrowTypeError, context_,
336 SmiConstant(MessageTemplate::kCalledNonCallable),
337 callbackfn_);
338 Unreachable();
339 }
340
341 Label unexpected_instance_type(this);
342 Bind(&unexpected_instance_type);
343 Unreachable();
344
345 std::vector<int32_t> instance_types = {
346 #define INSTANCE_TYPE(Type, type, TYPE, ctype, size) FIXED_##TYPE##_ARRAY_TYPE,
347 TYPED_ARRAYS(INSTANCE_TYPE)
348 #undef INSTANCE_TYPE
349 };
350 std::vector<Label> labels;
351 for (size_t i = 0; i < instance_types.size(); ++i) {
352 labels.push_back(Label(this));
353 }
354 std::vector<Label*> label_ptrs;
355 for (Label& label : labels) {
356 label_ptrs.push_back(&label);
357 }
358
359 Bind(&start);
360 a_.Bind(generator(this));
361 Node* elements_type = LoadInstanceType(LoadElements(o_));
362 Switch(elements_type, &unexpected_instance_type, instance_types.data(),
363 label_ptrs.data(), labels.size());
364
365 for (size_t i = 0; i < labels.size(); ++i) {
366 Bind(&labels[i]);
367 Label done(this);
368 // TODO(tebbi): Silently cancelling the loop on buffer detachment is a
369 // spec violation. Should go to &detached and throw a TypeError instead.
370 VisitAllTypedArrayElements(
371 ElementsKindForInstanceType(
372 static_cast<InstanceType>(instance_types[i])),
373 array_buffer, processor, &done);
374 Goto(&done);
375 action(this);
376 // No exception, return success
377 Bind(&done);
378 Return(a_.value());
379 }
380 }
381
292 void GenerateIteratingArrayBuiltinLoopContinuation( 382 void GenerateIteratingArrayBuiltinLoopContinuation(
293 const CallResultProcessor& processor, const PostLoopAction& action) { 383 const CallResultProcessor& processor, const PostLoopAction& action) {
294 // 8. Repeat, while k < len 384 // 8. Repeat, while k < len
295 Label loop(this, {&k_, &a_, &to_}); 385 Label loop(this, {&k_, &a_, &to_});
296 Label after_loop(this); 386 Label after_loop(this);
297 Goto(&loop); 387 Goto(&loop);
298 Bind(&loop); 388 Bind(&loop);
299 { 389 {
300 GotoUnlessNumberLessThan(k(), len_, &after_loop); 390 GotoUnlessNumberLessThan(k(), len_, &after_loop);
301 391
(...skipping 23 matching lines...) Expand all
325 k_.Bind(NumberInc(k_.value())); 415 k_.Bind(NumberInc(k_.value()));
326 Goto(&loop); 416 Goto(&loop);
327 } 417 }
328 Bind(&after_loop); 418 Bind(&after_loop);
329 419
330 action(this); 420 action(this);
331 Return(a_.value()); 421 Return(a_.value());
332 } 422 }
333 423
334 private: 424 private:
425 static ElementsKind ElementsKindForInstanceType(InstanceType type) {
426 switch (type) {
427 #define INSTANCE_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
428 case FIXED_##TYPE##_ARRAY_TYPE: \
429 return TYPE##_ELEMENTS;
430
431 TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENTS_KIND)
432 #undef INSTANCE_TYPE_TO_ELEMENTS_KIND
433
434 default:
435 UNREACHABLE();
436 return static_cast<ElementsKind>(-1);
437 }
438 }
439
440 void VisitAllTypedArrayElements(ElementsKind kind, Node* array_buffer,
441 const CallResultProcessor& processor,
442 Label* detached) {
443 Node* elements = LoadElements(o_);
444 Node* base_ptr =
445 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
446 Node* external_ptr =
447 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
448 MachineType::Pointer());
449 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
450 VariableList list({&a_, &k_, &to_}, zone());
451 BuildFastLoop(list, SmiConstant(0), len_,
452 [&](Node* index) {
453 GotoIf(IsDetachedBuffer(array_buffer), detached);
454 Node* value = LoadFixedTypedArrayElementAsTagged(
455 data_ptr, index, kind, SMI_PARAMETERS);
456 k_.Bind(index);
457 a_.Bind(processor(this, value, index));
458 },
459 1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
460 }
461
335 void VisitAllFastElementsOneKind(ElementsKind kind, 462 void VisitAllFastElementsOneKind(ElementsKind kind,
336 const CallResultProcessor& processor, 463 const CallResultProcessor& processor,
337 Label* array_changed, ParameterMode mode) { 464 Label* array_changed, ParameterMode mode) {
338 Comment("begin VisitAllFastElementsOneKind"); 465 Comment("begin VisitAllFastElementsOneKind");
339 Variable original_map(this, MachineRepresentation::kTagged); 466 Variable original_map(this, MachineRepresentation::kTagged);
340 original_map.Bind(LoadMap(o())); 467 original_map.Bind(LoadMap(o()));
341 VariableList list({&original_map, &a_, &k_, &to_}, zone()); 468 VariableList list({&original_map, &a_, &k_, &to_}, zone());
342 BuildFastLoop( 469 BuildFastLoop(
343 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len(), mode), 470 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len(), mode),
344 [=, &original_map](Node* index) { 471 [=, &original_map](Node* index) {
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 new_target); 801 new_target);
675 802
676 GenerateIteratingArrayBuiltinBody( 803 GenerateIteratingArrayBuiltinBody(
677 "Array.prototype.some", 804 "Array.prototype.some",
678 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator, 805 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator,
679 &ArrayBuiltinCodeStubAssembler::SomeProcessor, 806 &ArrayBuiltinCodeStubAssembler::SomeProcessor,
680 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, 807 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
681 CodeFactory::ArraySomeLoopContinuation(isolate())); 808 CodeFactory::ArraySomeLoopContinuation(isolate()));
682 } 809 }
683 810
811 TF_BUILTIN(TypedArrayPrototypeSome, ArrayBuiltinCodeStubAssembler) {
812 Node* context = Parameter(Descriptor::kContext);
813 Node* receiver = Parameter(Descriptor::kReceiver);
814 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
815 Node* this_arg = Parameter(Descriptor::kThisArg);
816 Node* new_target = Parameter(Descriptor::kNewTarget);
817
818 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
819 new_target);
820
821 GenerateIteratingTypedArrayBuiltinBody(
822 "%TypedArray%.prototype.some",
823 &ArrayBuiltinCodeStubAssembler::SomeResultGenerator,
824 &ArrayBuiltinCodeStubAssembler::SomeProcessor,
825 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
826 }
827
684 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { 828 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) {
685 Node* context = Parameter(Descriptor::kContext); 829 Node* context = Parameter(Descriptor::kContext);
686 Node* receiver = Parameter(Descriptor::kReceiver); 830 Node* receiver = Parameter(Descriptor::kReceiver);
687 Node* callbackfn = Parameter(Descriptor::kCallbackFn); 831 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
688 Node* this_arg = Parameter(Descriptor::kThisArg); 832 Node* this_arg = Parameter(Descriptor::kThisArg);
689 Node* array = Parameter(Descriptor::kArray); 833 Node* array = Parameter(Descriptor::kArray);
690 Node* object = Parameter(Descriptor::kObject); 834 Node* object = Parameter(Descriptor::kObject);
691 Node* initial_k = Parameter(Descriptor::kInitialK); 835 Node* initial_k = Parameter(Descriptor::kInitialK);
692 Node* len = Parameter(Descriptor::kLength); 836 Node* len = Parameter(Descriptor::kLength);
693 Node* to = Parameter(Descriptor::kTo); 837 Node* to = Parameter(Descriptor::kTo);
(...skipping 18 matching lines...) Expand all
712 new_target); 856 new_target);
713 857
714 GenerateIteratingArrayBuiltinBody( 858 GenerateIteratingArrayBuiltinBody(
715 "Array.prototype.every", 859 "Array.prototype.every",
716 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator, 860 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator,
717 &ArrayBuiltinCodeStubAssembler::EveryProcessor, 861 &ArrayBuiltinCodeStubAssembler::EveryProcessor,
718 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction, 862 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction,
719 CodeFactory::ArrayEveryLoopContinuation(isolate())); 863 CodeFactory::ArrayEveryLoopContinuation(isolate()));
720 } 864 }
721 865
866 TF_BUILTIN(TypedArrayPrototypeEvery, ArrayBuiltinCodeStubAssembler) {
867 Node* context = Parameter(Descriptor::kContext);
868 Node* receiver = Parameter(Descriptor::kReceiver);
869 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
870 Node* this_arg = Parameter(Descriptor::kThisArg);
871 Node* new_target = Parameter(Descriptor::kNewTarget);
872
873 InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg,
874 new_target);
875
876 GenerateIteratingTypedArrayBuiltinBody(
877 "%TypedArray%.prototype.every",
878 &ArrayBuiltinCodeStubAssembler::EveryResultGenerator,
879 &ArrayBuiltinCodeStubAssembler::EveryProcessor,
880 &ArrayBuiltinCodeStubAssembler::NullPostLoopAction);
881 }
882
722 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) { 883 TF_BUILTIN(ArrayReduceLoopContinuation, ArrayBuiltinCodeStubAssembler) {
723 Node* context = Parameter(Descriptor::kContext); 884 Node* context = Parameter(Descriptor::kContext);
724 Node* receiver = Parameter(Descriptor::kReceiver); 885 Node* receiver = Parameter(Descriptor::kReceiver);
725 Node* callbackfn = Parameter(Descriptor::kCallbackFn); 886 Node* callbackfn = Parameter(Descriptor::kCallbackFn);
726 Node* this_arg = Parameter(Descriptor::kThisArg); 887 Node* this_arg = Parameter(Descriptor::kThisArg);
727 Node* accumulator = Parameter(Descriptor::kAccumulator); 888 Node* accumulator = Parameter(Descriptor::kAccumulator);
728 Node* object = Parameter(Descriptor::kObject); 889 Node* object = Parameter(Descriptor::kObject);
729 Node* initial_k = Parameter(Descriptor::kInitialK); 890 Node* initial_k = Parameter(Descriptor::kInitialK);
730 Node* len = Parameter(Descriptor::kLength); 891 Node* len = Parameter(Descriptor::kLength);
731 Node* to = Parameter(Descriptor::kTo); 892 Node* to = Parameter(Descriptor::kTo);
(...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 { 2047 {
1887 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); 2048 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
1888 CallRuntime(Runtime::kThrowTypeError, context, message, 2049 CallRuntime(Runtime::kThrowTypeError, context, message,
1889 HeapConstant(operation)); 2050 HeapConstant(operation));
1890 Unreachable(); 2051 Unreachable();
1891 } 2052 }
1892 } 2053 }
1893 2054
1894 } // namespace internal 2055 } // namespace internal
1895 } // namespace v8 2056 } // namespace v8
OLDNEW
« src/bootstrapper.cc ('K') | « src/builtins/builtins.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698