@@ -336,6 +336,7 @@ protected final IteratorRecord getIteratorDirect(Object thisObj) {
336
336
protected abstract static class IteratorMethodWithCallableNode extends IteratorMethodNode {
337
337
338
338
@ Child private IsCallableNode isCallableNode ;
339
+ @ Child private IteratorCloseNode iteratorCloseNode ;
339
340
340
341
protected IteratorMethodWithCallableNode (JSContext context , JSBuiltin builtin ) {
341
342
super (context , builtin );
@@ -345,6 +346,19 @@ protected IteratorMethodWithCallableNode(JSContext context, JSBuiltin builtin) {
345
346
public final boolean isCallable (Object fn ) {
346
347
return isCallableNode .executeBoolean (fn );
347
348
}
349
+
350
+ /**
351
+ * Closes the iterator on argument validation failure.
352
+ *
353
+ * @param iterator the receiver iterator object
354
+ */
355
+ protected final void iteratorCloseDirectAbrupt (Object iterator ) {
356
+ if (iteratorCloseNode == null ) {
357
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
358
+ iteratorCloseNode = insert (IteratorCloseNode .create (getContext ()));
359
+ }
360
+ iteratorCloseNode .executeAbrupt (iterator );
361
+ }
348
362
}
349
363
350
364
protected abstract static class IteratorFromGeneratorNode <T extends IteratorArgs > extends IteratorMethodWithCallableNode {
@@ -500,8 +514,13 @@ public JSDynamicObject map(Object thisObj, Object mapper) {
500
514
}
501
515
502
516
@ Specialization (guards = "!isCallable(mapper)" )
503
- public Object unsupported (@ SuppressWarnings ("unused" ) Object thisObj , @ SuppressWarnings ("unused" ) Object mapper ) {
504
- throw Errors .createTypeErrorCallableExpected ();
517
+ public Object unsupported (Object thisObj , Object mapper ,
518
+ @ Cached IsObjectNode isObjectNode ) {
519
+ if (!isObjectNode .executeBoolean (thisObj )) {
520
+ throw Errors .createTypeErrorNotAnObject (thisObj , this );
521
+ }
522
+ iteratorCloseDirectAbrupt (thisObj );
523
+ throw Errors .createTypeErrorNotAFunction (mapper );
505
524
}
506
525
507
526
protected abstract static class IteratorMapNextNode extends IteratorFromGeneratorImplNode <IteratorMapArgs > {
@@ -568,8 +587,13 @@ public JSDynamicObject filter(Object thisObj, Object filterer) {
568
587
}
569
588
570
589
@ Specialization (guards = "!isCallable(filterer)" )
571
- public Object unsupported (@ SuppressWarnings ("unused" ) Object thisObj , @ SuppressWarnings ("unused" ) Object filterer ) {
572
- throw Errors .createTypeErrorCallableExpected ();
590
+ public Object unsupported (Object thisObj , Object filterer ,
591
+ @ Cached IsObjectNode isObjectNode ) {
592
+ if (!isObjectNode .executeBoolean (thisObj )) {
593
+ throw Errors .createTypeErrorNotAnObject (thisObj , this );
594
+ }
595
+ iteratorCloseDirectAbrupt (thisObj );
596
+ throw Errors .createTypeErrorNotAFunction (filterer );
573
597
}
574
598
575
599
protected abstract static class IteratorFilterNextNode extends IteratorFromGeneratorImplNode <IteratorFilterArgs > {
@@ -647,22 +671,27 @@ public IteratorTakeArgs(IteratorRecord target, double limit) {
647
671
public JSDynamicObject take (Object thisObj , Object limit ,
648
672
@ Cached IsObjectNode isObjectNode ,
649
673
@ Cached InlinedBranchProfile errorBranch ) {
650
-
651
674
if (!isObjectNode .executeBoolean (thisObj )) {
652
675
errorBranch .enter (this );
653
676
throw Errors .createTypeErrorNotAnObject (thisObj , this );
654
677
}
655
678
656
- Number numLimit = toNumberNode .executeNumber (limit );
657
- if (JSRuntime .isNaN (numLimit )) {
658
- errorBranch .enter (this );
659
- throw Errors .createRangeError ("NaN is not allowed" , this );
660
- }
679
+ double integerLimit ;
680
+ try {
681
+ Number numLimit = toNumberNode .executeNumber (limit );
682
+ if (JSRuntime .isNaN (numLimit )) {
683
+ errorBranch .enter (this );
684
+ throw Errors .createRangeError ("NaN is not allowed" , this );
685
+ }
661
686
662
- double integerLimit = JSRuntime .doubleValue (toIntegerOrInfinityNode .executeNumber (numLimit ));
663
- if (integerLimit < 0 ) {
664
- errorBranch .enter (this );
665
- throw Errors .createRangeErrorIndexNegative (this );
687
+ integerLimit = JSRuntime .doubleValue (toIntegerOrInfinityNode .executeNumber (numLimit ));
688
+ if (integerLimit < 0 ) {
689
+ errorBranch .enter (this );
690
+ throw Errors .createRangeErrorIndexNegative (this );
691
+ }
692
+ } catch (AbstractTruffleException e ) {
693
+ iteratorCloseDirectAbrupt (thisObj );
694
+ throw e ;
666
695
}
667
696
668
697
IteratorRecord iterated = getIteratorDirect (thisObj );
@@ -733,22 +762,27 @@ public IteratorDropArgs(IteratorRecord target, double limit) {
733
762
public JSDynamicObject drop (Object thisObj , Object limit ,
734
763
@ Cached IsObjectNode isObjectNode ,
735
764
@ Cached InlinedBranchProfile errorBranch ) {
736
-
737
765
if (!isObjectNode .executeBoolean (thisObj )) {
738
766
errorBranch .enter (this );
739
767
throw Errors .createTypeErrorNotAnObject (thisObj , this );
740
768
}
741
769
742
- Number numLimit = toNumberNode .executeNumber (limit );
743
- if (JSRuntime .isNaN (numLimit )) {
744
- errorBranch .enter (this );
745
- throw Errors .createRangeError ("NaN is not allowed" , this );
746
- }
770
+ double integerLimit ;
771
+ try {
772
+ Number numLimit = toNumberNode .executeNumber (limit );
773
+ if (JSRuntime .isNaN (numLimit )) {
774
+ errorBranch .enter (this );
775
+ throw Errors .createRangeError ("NaN is not allowed" , this );
776
+ }
747
777
748
- double integerLimit = JSRuntime .doubleValue (toIntegerOrInfinityNode .executeNumber (numLimit ));
749
- if (integerLimit < 0 ) {
750
- errorBranch .enter (this );
751
- throw Errors .createRangeErrorIndexNegative (this );
778
+ integerLimit = JSRuntime .doubleValue (toIntegerOrInfinityNode .executeNumber (numLimit ));
779
+ if (integerLimit < 0 ) {
780
+ errorBranch .enter (this );
781
+ throw Errors .createRangeErrorIndexNegative (this );
782
+ }
783
+ } catch (AbstractTruffleException e ) {
784
+ iteratorCloseDirectAbrupt (thisObj );
785
+ throw e ;
752
786
}
753
787
754
788
IteratorRecord iterated = getIteratorDirect (thisObj );
@@ -818,8 +852,13 @@ public JSDynamicObject flatMap(Object thisObj, Object mapper) {
818
852
}
819
853
820
854
@ Specialization (guards = "!isCallable(mapper)" )
821
- public Object unsupported (@ SuppressWarnings ("unused" ) Object thisObj , @ SuppressWarnings ("unused" ) Object mapper ) {
822
- throw Errors .createTypeErrorCallableExpected ();
855
+ public Object unsupported (Object thisObj , Object mapper ,
856
+ @ Cached IsObjectNode isObjectNode ) {
857
+ if (!isObjectNode .executeBoolean (thisObj )) {
858
+ throw Errors .createTypeErrorNotAnObject (thisObj , this );
859
+ }
860
+ iteratorCloseDirectAbrupt (thisObj );
861
+ throw Errors .createTypeErrorNotAFunction (mapper );
823
862
}
824
863
825
864
protected abstract static class IteratorFlatMapNextNode extends IteratorFromGeneratorNode .IteratorFromGeneratorImplNode <IteratorFlatMapArgs > {
@@ -966,7 +1005,11 @@ protected Object compatible(Object thisObj, Object fn,
966
1005
}
967
1006
968
1007
@ Specialization (guards = "!isCallable(fn)" )
969
- protected void incompatible (@ SuppressWarnings ("unused" ) Object thisObj , Object fn ) {
1008
+ protected void incompatible (Object thisObj , Object fn ) {
1009
+ if (!isObjectNode .executeBoolean (thisObj )) {
1010
+ throw Errors .createTypeErrorNotAnObject (thisObj , this );
1011
+ }
1012
+ iteratorCloseDirectAbrupt (thisObj );
970
1013
throw Errors .createTypeErrorNotAFunction (fn );
971
1014
}
972
1015
@@ -1131,7 +1174,12 @@ protected Object reduce(Object thisObj, Object reducer, Object[] args,
1131
1174
}
1132
1175
1133
1176
@ Specialization (guards = "!isCallable(reducer)" )
1134
- protected void incompatible (@ SuppressWarnings ("unused" ) Object thisObj , Object reducer , @ SuppressWarnings ("unused" ) Object [] args ) {
1177
+ protected void incompatible (Object thisObj , Object reducer , @ SuppressWarnings ("unused" ) Object [] args ,
1178
+ @ Cached IsObjectNode isObjectNode ) {
1179
+ if (!isObjectNode .executeBoolean (thisObj )) {
1180
+ throw Errors .createTypeErrorNotAnObject (thisObj , this );
1181
+ }
1182
+ iteratorCloseDirectAbrupt (thisObj );
1135
1183
throw Errors .createTypeErrorNotAFunction (reducer );
1136
1184
}
1137
1185
0 commit comments