From 87f77d6abaf8746719ae1f53b9eb61c1d1cf6a0b Mon Sep 17 00:00:00 2001 From: arv Date: Mon, 23 Feb 2015 15:34:26 -0800 Subject: [PATCH] for-of should throw if result object is not an object This is done using desugaring. Before this we had: result = iterator.next() with this we instead do: !%_IsSpecObject(result = iterator.next()) && %ThrowIteratorResultNotAnObject(result) BUG=v8:3916 LOG=N Review URL: https://codereview.chromium.org/929733003 Cr-Commit-Position: refs/heads/master@{#26805} --- src/ast-value-factory.h | 66 ++--- src/ast.h | 4 +- src/parser.cc | 32 ++- src/runtime/runtime-internal.cc | 10 + src/runtime/runtime.h | 351 ++++++++++++------------ test/mjsunit/es6/iteration-semantics.js | 30 +- 6 files changed, 278 insertions(+), 215 deletions(-) diff --git a/src/ast-value-factory.h b/src/ast-value-factory.h index 39a1732f1c..43fa2d0e2e 100644 --- a/src/ast-value-factory.h +++ b/src/ast-value-factory.h @@ -230,38 +230,40 @@ class AstValue : public ZoneObject { // For generating constants. -#define STRING_CONSTANTS(F) \ - F(anonymous_function, "(anonymous function)") \ - F(arguments, "arguments") \ - F(constructor, "constructor") \ - F(default, "default") \ - F(done, "done") \ - F(dot, ".") \ - F(dot_for, ".for") \ - F(dot_generator, ".generator") \ - F(dot_generator_object, ".generator_object") \ - F(dot_iterator, ".iterator") \ - F(dot_module, ".module") \ - F(dot_result, ".result") \ - F(empty, "") \ - F(eval, "eval") \ - F(get_template_callsite, "GetTemplateCallSite") \ - F(initialize_const_global, "initializeConstGlobal") \ - F(initialize_var_global, "initializeVarGlobal") \ - F(is_construct_call, "_IsConstructCall") \ - F(let, "let") \ - F(make_reference_error, "MakeReferenceErrorEmbedded") \ - F(make_syntax_error, "MakeSyntaxErrorEmbedded") \ - F(make_type_error, "MakeTypeErrorEmbedded") \ - F(native, "native") \ - F(new_target, "new.target") \ - F(next, "next") \ - F(proto, "__proto__") \ - F(prototype, "prototype") \ - F(this, "this") \ - F(use_asm, "use asm") \ - F(use_strong, "use strong") \ - F(use_strict, "use strict") \ +#define STRING_CONSTANTS(F) \ + F(anonymous_function, "(anonymous function)") \ + F(arguments, "arguments") \ + F(constructor, "constructor") \ + F(default, "default") \ + F(done, "done") \ + F(dot, ".") \ + F(dot_for, ".for") \ + F(dot_generator, ".generator") \ + F(dot_generator_object, ".generator_object") \ + F(dot_iterator, ".iterator") \ + F(dot_module, ".module") \ + F(dot_result, ".result") \ + F(empty, "") \ + F(eval, "eval") \ + F(get_template_callsite, "GetTemplateCallSite") \ + F(initialize_const_global, "initializeConstGlobal") \ + F(initialize_var_global, "initializeVarGlobal") \ + F(is_construct_call, "_IsConstructCall") \ + F(is_spec_object, "_IsSpecObject") \ + F(let, "let") \ + F(make_reference_error, "MakeReferenceErrorEmbedded") \ + F(make_syntax_error, "MakeSyntaxErrorEmbedded") \ + F(make_type_error, "MakeTypeErrorEmbedded") \ + F(native, "native") \ + F(new_target, "new.target") \ + F(next, "next") \ + F(proto, "__proto__") \ + F(prototype, "prototype") \ + F(this, "this") \ + F(throw_iterator_result_not_an_object, "ThrowIteratorResultNotAnObject") \ + F(use_asm, "use asm") \ + F(use_strong, "use strong") \ + F(use_strict, "use strict") \ F(value, "value") #define OTHER_CONSTANTS(F) \ diff --git a/src/ast.h b/src/ast.h index faccb90457..9b86d0b512 100644 --- a/src/ast.h +++ b/src/ast.h @@ -942,12 +942,12 @@ class ForOfStatement FINAL : public ForEachStatement { return subject(); } - // var iterator = subject[Symbol.iterator](); + // iterator = subject[Symbol.iterator]() Expression* assign_iterator() const { return assign_iterator_; } - // var result = iterator.next(); + // result = iterator.next() // with type check Expression* next_result() const { return next_result_; } diff --git a/src/parser.cc b/src/parser.cc index 54e4c7cec1..9f4adedca3 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -2925,25 +2925,51 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, Expression* result_done; Expression* assign_each; - // var iterator = subject[Symbol.iterator](); + // iterator = subject[Symbol.iterator]() assign_iterator = factory()->NewAssignment( Token::ASSIGN, factory()->NewVariableProxy(iterator), GetIterator(subject, factory()), subject->position()); - // var result = iterator.next(); + // !%_IsSpecObject(result = iterator.next()) && + // %ThrowIteratorResultNotAnObject(result) { + // result = iterator.next() Expression* iterator_proxy = factory()->NewVariableProxy(iterator); Expression* next_literal = factory()->NewStringLiteral( ast_value_factory()->next_string(), RelocInfo::kNoPosition); Expression* next_property = factory()->NewProperty( iterator_proxy, next_literal, RelocInfo::kNoPosition); ZoneList* next_arguments = - new(zone()) ZoneList(0, zone()); + new (zone()) ZoneList(0, zone()); Expression* next_call = factory()->NewCall(next_property, next_arguments, subject->position()); Expression* result_proxy = factory()->NewVariableProxy(result); next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, subject->position()); + + // %_IsSpecObject(...) + ZoneList* is_spec_object_args = + new (zone()) ZoneList(1, zone()); + is_spec_object_args->Add(next_result, zone()); + Expression* is_spec_object_call = factory()->NewCallRuntime( + ast_value_factory()->is_spec_object_string(), + Runtime::FunctionForId(Runtime::kInlineIsSpecObject), + is_spec_object_args, subject->position()); + + // %ThrowIteratorResultNotAnObject(result) + Expression* result_proxy_again = factory()->NewVariableProxy(result); + ZoneList* throw_arguments = + new (zone()) ZoneList(1, zone()); + throw_arguments->Add(result_proxy_again, zone()); + Expression* throw_call = factory()->NewCallRuntime( + ast_value_factory()->throw_iterator_result_not_an_object_string(), + Runtime::FunctionForId(Runtime::kThrowIteratorResultNotAnObject), + throw_arguments, subject->position()); + + next_result = factory()->NewBinaryOperation( + Token::AND, factory()->NewUnaryOperation( + Token::NOT, is_spec_object_call, subject->position()), + throw_call, subject->position()); } // result.done diff --git a/src/runtime/runtime-internal.cc b/src/runtime/runtime-internal.cc index 50b61921f5..33234cd19f 100644 --- a/src/runtime/runtime-internal.cc +++ b/src/runtime/runtime-internal.cc @@ -55,6 +55,16 @@ RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { } +RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("iterator_result_not_an_object", HandleVector(&value, 1))); +} + + RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) { DCHECK(args.length() == 3); HandleScope scope(isolate); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 1ea85c83ab..88feca21b3 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -22,181 +22,182 @@ namespace internal { // WARNING: RUNTIME_FUNCTION_LIST_ALWAYS_* is a very large macro that caused // MSVC Intellisense to crash. It was broken into two macros to work around // this problem. Please avoid large recursive macros whenever possible. -#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \ - /* Property access */ \ - F(GetProperty, 2, 1) \ - F(KeyedGetProperty, 2, 1) \ - F(DeleteProperty, 3, 1) \ - F(HasOwnProperty, 2, 1) \ - F(HasProperty, 2, 1) \ - F(HasElement, 2, 1) \ - F(IsPropertyEnumerable, 2, 1) \ - F(GetPropertyNames, 1, 1) \ - F(GetPropertyNamesFast, 1, 1) \ - F(GetOwnPropertyNames, 2, 1) \ - F(GetOwnElementNames, 1, 1) \ - F(GetInterceptorInfo, 1, 1) \ - F(GetNamedInterceptorPropertyNames, 1, 1) \ - F(GetIndexedInterceptorElementNames, 1, 1) \ - F(GetArgumentsProperty, 1, 1) \ - F(ToFastProperties, 1, 1) \ - F(FinishArrayPrototypeSetup, 1, 1) \ - F(SpecialArrayFunctions, 0, 1) \ - F(IsSloppyModeFunction, 1, 1) \ - F(GetDefaultReceiver, 1, 1) \ - \ - F(SetPrototype, 2, 1) \ - F(InternalSetPrototype, 2, 1) \ - F(IsInPrototypeChain, 2, 1) \ - \ - F(GetOwnProperty, 2, 1) \ - \ - F(IsExtensible, 1, 1) \ - F(PreventExtensions, 1, 1) \ - \ - /* Utilities */ \ - F(CheckIsBootstrapping, 0, 1) \ - F(GetRootNaN, 0, 1) \ - F(Call, -1 /* >= 2 */, 1) \ - F(Apply, 5, 1) \ - F(GetFunctionDelegate, 1, 1) \ - F(GetConstructorDelegate, 1, 1) \ - F(DeoptimizeFunction, 1, 1) \ - F(ClearFunctionTypeFeedback, 1, 1) \ - F(RunningInSimulator, 0, 1) \ - F(IsConcurrentRecompilationSupported, 0, 1) \ - F(OptimizeFunctionOnNextCall, -1, 1) \ - F(OptimizeOsr, 0, 1) \ - F(NeverOptimizeFunction, 1, 1) \ - F(GetOptimizationStatus, -1, 1) \ - F(GetOptimizationCount, 1, 1) \ - F(UnblockConcurrentRecompilation, 0, 1) \ - F(CompileForOnStackReplacement, 1, 1) \ - F(SetAllocationTimeout, -1 /* 2 || 3 */, 1) \ - F(SetNativeFlag, 1, 1) \ - F(IsConstructor, 1, 1) \ - F(SetInlineBuiltinFlag, 1, 1) \ - F(StoreArrayLiteralElement, 5, 1) \ - F(DebugPrepareStepInIfStepping, 1, 1) \ - F(DebugPushPromise, 1, 1) \ - F(DebugPopPromise, 0, 1) \ - F(DebugPromiseEvent, 1, 1) \ - F(DebugAsyncTaskEvent, 1, 1) \ - F(PromiseRejectEvent, 3, 1) \ - F(PromiseRevokeReject, 1, 1) \ - F(PromiseHasHandlerSymbol, 0, 1) \ - F(FlattenString, 1, 1) \ - F(LoadMutableDouble, 2, 1) \ - F(TryMigrateInstance, 1, 1) \ - F(NotifyContextDisposed, 0, 1) \ - \ - /* Array join support */ \ - F(PushIfAbsent, 2, 1) \ - F(ArrayConcat, 1, 1) \ - \ - /* Conversions */ \ - F(ToBool, 1, 1) \ - F(Typeof, 1, 1) \ - \ - F(StringToNumber, 1, 1) \ - F(StringParseInt, 2, 1) \ - F(StringParseFloat, 1, 1) \ - F(StringToLowerCase, 1, 1) \ - F(StringToUpperCase, 1, 1) \ - F(StringSplit, 3, 1) \ - F(CharFromCode, 1, 1) \ - F(URIEscape, 1, 1) \ - F(URIUnescape, 1, 1) \ - \ - F(NumberToInteger, 1, 1) \ - F(NumberToIntegerMapMinusZero, 1, 1) \ - F(NumberToJSUint32, 1, 1) \ - F(NumberToJSInt32, 1, 1) \ - \ - /* Arithmetic operations */ \ - F(NumberAdd, 2, 1) \ - F(NumberSub, 2, 1) \ - F(NumberMul, 2, 1) \ - F(NumberDiv, 2, 1) \ - F(NumberMod, 2, 1) \ - F(NumberUnaryMinus, 1, 1) \ - F(NumberImul, 2, 1) \ - \ - F(StringBuilderConcat, 3, 1) \ - F(StringBuilderJoin, 3, 1) \ - F(SparseJoinWithSeparator, 3, 1) \ - \ - /* Bit operations */ \ - F(NumberOr, 2, 1) \ - F(NumberAnd, 2, 1) \ - F(NumberXor, 2, 1) \ - \ - F(NumberShl, 2, 1) \ - F(NumberShr, 2, 1) \ - F(NumberSar, 2, 1) \ - \ - /* Comparisons */ \ - F(NumberEquals, 2, 1) \ - F(StringEquals, 2, 1) \ - \ - F(NumberCompare, 3, 1) \ - F(SmiLexicographicCompare, 2, 1) \ - \ - /* Math */ \ - F(MathAcos, 1, 1) \ - F(MathAsin, 1, 1) \ - F(MathAtan, 1, 1) \ - F(MathFloorRT, 1, 1) \ - F(MathAtan2, 2, 1) \ - F(MathExpRT, 1, 1) \ - F(RoundNumber, 1, 1) \ - F(MathFround, 1, 1) \ - F(RemPiO2, 2, 1) \ - \ - /* Regular expressions */ \ - F(RegExpInitializeAndCompile, 3, 1) \ - F(RegExpExecMultiple, 4, 1) \ - \ - /* JSON */ \ - F(ParseJson, 1, 1) \ - F(BasicJSONStringify, 1, 1) \ - F(QuoteJSONString, 1, 1) \ - \ - /* Strings */ \ - F(StringIndexOf, 3, 1) \ - F(StringLastIndexOf, 3, 1) \ - F(StringLocaleCompare, 2, 1) \ - F(StringReplaceGlobalRegExpWithString, 4, 1) \ - F(StringReplaceOneCharWithString, 3, 1) \ - F(StringMatch, 3, 1) \ - F(StringTrim, 3, 1) \ - F(StringToArray, 2, 1) \ - F(NewStringWrapper, 1, 1) \ - F(NewString, 2, 1) \ - F(TruncateString, 2, 1) \ - \ - /* Numbers */ \ - F(NumberToRadixString, 2, 1) \ - F(NumberToFixed, 2, 1) \ - F(NumberToExponential, 2, 1) \ - F(NumberToPrecision, 2, 1) \ - F(IsValidSmi, 1, 1) \ - \ - /* Classes support */ \ - F(ToMethod, 2, 1) \ - F(HomeObjectSymbol, 0, 1) \ - F(DefineClass, 6, 1) \ - F(DefineClassMethod, 3, 1) \ - F(ClassGetSourceCode, 1, 1) \ - F(LoadFromSuper, 3, 1) \ - F(LoadKeyedFromSuper, 3, 1) \ - F(ThrowConstructorNonCallableError, 0, 1) \ - F(ThrowNonMethodError, 0, 1) \ - F(ThrowUnsupportedSuperError, 0, 1) \ - F(HandleStepInForDerivedConstructors, 1, 1) \ - F(StoreToSuper_Strict, 4, 1) \ - F(StoreToSuper_Sloppy, 4, 1) \ - F(StoreKeyedToSuper_Strict, 4, 1) \ +#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \ + /* Property access */ \ + F(GetProperty, 2, 1) \ + F(KeyedGetProperty, 2, 1) \ + F(DeleteProperty, 3, 1) \ + F(HasOwnProperty, 2, 1) \ + F(HasProperty, 2, 1) \ + F(HasElement, 2, 1) \ + F(IsPropertyEnumerable, 2, 1) \ + F(GetPropertyNames, 1, 1) \ + F(GetPropertyNamesFast, 1, 1) \ + F(GetOwnPropertyNames, 2, 1) \ + F(GetOwnElementNames, 1, 1) \ + F(GetInterceptorInfo, 1, 1) \ + F(GetNamedInterceptorPropertyNames, 1, 1) \ + F(GetIndexedInterceptorElementNames, 1, 1) \ + F(GetArgumentsProperty, 1, 1) \ + F(ToFastProperties, 1, 1) \ + F(FinishArrayPrototypeSetup, 1, 1) \ + F(SpecialArrayFunctions, 0, 1) \ + F(IsSloppyModeFunction, 1, 1) \ + F(GetDefaultReceiver, 1, 1) \ + \ + F(SetPrototype, 2, 1) \ + F(InternalSetPrototype, 2, 1) \ + F(IsInPrototypeChain, 2, 1) \ + \ + F(GetOwnProperty, 2, 1) \ + \ + F(IsExtensible, 1, 1) \ + F(PreventExtensions, 1, 1) \ + \ + /* Utilities */ \ + F(CheckIsBootstrapping, 0, 1) \ + F(GetRootNaN, 0, 1) \ + F(Call, -1 /* >= 2 */, 1) \ + F(Apply, 5, 1) \ + F(GetFunctionDelegate, 1, 1) \ + F(GetConstructorDelegate, 1, 1) \ + F(DeoptimizeFunction, 1, 1) \ + F(ClearFunctionTypeFeedback, 1, 1) \ + F(RunningInSimulator, 0, 1) \ + F(IsConcurrentRecompilationSupported, 0, 1) \ + F(OptimizeFunctionOnNextCall, -1, 1) \ + F(OptimizeOsr, 0, 1) \ + F(NeverOptimizeFunction, 1, 1) \ + F(GetOptimizationStatus, -1, 1) \ + F(GetOptimizationCount, 1, 1) \ + F(UnblockConcurrentRecompilation, 0, 1) \ + F(CompileForOnStackReplacement, 1, 1) \ + F(SetAllocationTimeout, -1 /* 2 || 3 */, 1) \ + F(SetNativeFlag, 1, 1) \ + F(IsConstructor, 1, 1) \ + F(SetInlineBuiltinFlag, 1, 1) \ + F(StoreArrayLiteralElement, 5, 1) \ + F(DebugPrepareStepInIfStepping, 1, 1) \ + F(DebugPushPromise, 1, 1) \ + F(DebugPopPromise, 0, 1) \ + F(DebugPromiseEvent, 1, 1) \ + F(DebugAsyncTaskEvent, 1, 1) \ + F(PromiseRejectEvent, 3, 1) \ + F(PromiseRevokeReject, 1, 1) \ + F(PromiseHasHandlerSymbol, 0, 1) \ + F(FlattenString, 1, 1) \ + F(LoadMutableDouble, 2, 1) \ + F(TryMigrateInstance, 1, 1) \ + F(NotifyContextDisposed, 0, 1) \ + F(ThrowIteratorResultNotAnObject, 1, 1) \ + \ + /* Array join support */ \ + F(PushIfAbsent, 2, 1) \ + F(ArrayConcat, 1, 1) \ + \ + /* Conversions */ \ + F(ToBool, 1, 1) \ + F(Typeof, 1, 1) \ + \ + F(StringToNumber, 1, 1) \ + F(StringParseInt, 2, 1) \ + F(StringParseFloat, 1, 1) \ + F(StringToLowerCase, 1, 1) \ + F(StringToUpperCase, 1, 1) \ + F(StringSplit, 3, 1) \ + F(CharFromCode, 1, 1) \ + F(URIEscape, 1, 1) \ + F(URIUnescape, 1, 1) \ + \ + F(NumberToInteger, 1, 1) \ + F(NumberToIntegerMapMinusZero, 1, 1) \ + F(NumberToJSUint32, 1, 1) \ + F(NumberToJSInt32, 1, 1) \ + \ + /* Arithmetic operations */ \ + F(NumberAdd, 2, 1) \ + F(NumberSub, 2, 1) \ + F(NumberMul, 2, 1) \ + F(NumberDiv, 2, 1) \ + F(NumberMod, 2, 1) \ + F(NumberUnaryMinus, 1, 1) \ + F(NumberImul, 2, 1) \ + \ + F(StringBuilderConcat, 3, 1) \ + F(StringBuilderJoin, 3, 1) \ + F(SparseJoinWithSeparator, 3, 1) \ + \ + /* Bit operations */ \ + F(NumberOr, 2, 1) \ + F(NumberAnd, 2, 1) \ + F(NumberXor, 2, 1) \ + \ + F(NumberShl, 2, 1) \ + F(NumberShr, 2, 1) \ + F(NumberSar, 2, 1) \ + \ + /* Comparisons */ \ + F(NumberEquals, 2, 1) \ + F(StringEquals, 2, 1) \ + \ + F(NumberCompare, 3, 1) \ + F(SmiLexicographicCompare, 2, 1) \ + \ + /* Math */ \ + F(MathAcos, 1, 1) \ + F(MathAsin, 1, 1) \ + F(MathAtan, 1, 1) \ + F(MathFloorRT, 1, 1) \ + F(MathAtan2, 2, 1) \ + F(MathExpRT, 1, 1) \ + F(RoundNumber, 1, 1) \ + F(MathFround, 1, 1) \ + F(RemPiO2, 2, 1) \ + \ + /* Regular expressions */ \ + F(RegExpInitializeAndCompile, 3, 1) \ + F(RegExpExecMultiple, 4, 1) \ + \ + /* JSON */ \ + F(ParseJson, 1, 1) \ + F(BasicJSONStringify, 1, 1) \ + F(QuoteJSONString, 1, 1) \ + \ + /* Strings */ \ + F(StringIndexOf, 3, 1) \ + F(StringLastIndexOf, 3, 1) \ + F(StringLocaleCompare, 2, 1) \ + F(StringReplaceGlobalRegExpWithString, 4, 1) \ + F(StringReplaceOneCharWithString, 3, 1) \ + F(StringMatch, 3, 1) \ + F(StringTrim, 3, 1) \ + F(StringToArray, 2, 1) \ + F(NewStringWrapper, 1, 1) \ + F(NewString, 2, 1) \ + F(TruncateString, 2, 1) \ + \ + /* Numbers */ \ + F(NumberToRadixString, 2, 1) \ + F(NumberToFixed, 2, 1) \ + F(NumberToExponential, 2, 1) \ + F(NumberToPrecision, 2, 1) \ + F(IsValidSmi, 1, 1) \ + \ + /* Classes support */ \ + F(ToMethod, 2, 1) \ + F(HomeObjectSymbol, 0, 1) \ + F(DefineClass, 6, 1) \ + F(DefineClassMethod, 3, 1) \ + F(ClassGetSourceCode, 1, 1) \ + F(LoadFromSuper, 3, 1) \ + F(LoadKeyedFromSuper, 3, 1) \ + F(ThrowConstructorNonCallableError, 0, 1) \ + F(ThrowNonMethodError, 0, 1) \ + F(ThrowUnsupportedSuperError, 0, 1) \ + F(HandleStepInForDerivedConstructors, 1, 1) \ + F(StoreToSuper_Strict, 4, 1) \ + F(StoreToSuper_Sloppy, 4, 1) \ + F(StoreKeyedToSuper_Strict, 4, 1) \ F(StoreKeyedToSuper_Sloppy, 4, 1) diff --git a/test/mjsunit/es6/iteration-semantics.js b/test/mjsunit/es6/iteration-semantics.js index 544c94d915..57c558de64 100644 --- a/test/mjsunit/es6/iteration-semantics.js +++ b/test/mjsunit/es6/iteration-semantics.js @@ -200,9 +200,11 @@ assertEquals([undefined, 1, 2, 3], // Done. { value: 4, done: 42 }]))); // Results that are not objects. -assertEquals([undefined, undefined, undefined], - fold(append, [], - results([10, "foo", /qux/, { value: 37, done: true }]))); +assertThrows(function() { + assertEquals([undefined, undefined, undefined], + fold(append, [], + results([10, "foo", /qux/, { value: 37, done: true }]))); +}, TypeError); // Getters (shudder). assertEquals([1, 2], fold(append, [], @@ -334,3 +336,25 @@ function poison_proxy_after(iterable, n) { })); } assertEquals(45, fold(sum, 0, poison_proxy_after(integers_until(10), 10))); + + +function test_iterator_result_object_non_object(value, descr) { + var arr = []; + var ex; + var message = 'Iterator result ' + (descr || value) + ' is not an object'; + try { + fold(append, arr, + results([{value: 1}, {}, value, {value: 2}, {done: true}])); + } catch (e) { + ex = e; + } + assertInstanceof(ex, TypeError); + assertEquals(message, ex.message); + assertArrayEquals([1, undefined], arr); +} +test_iterator_result_object_non_object(null); +test_iterator_result_object_non_object(undefined); +test_iterator_result_object_non_object(42); +test_iterator_result_object_non_object('abc'); +test_iterator_result_object_non_object(false); +test_iterator_result_object_non_object(Symbol('x'), 'Symbol(x)');