From 94ce16b7047dfea907aac64fbea74c843ce40ea8 Mon Sep 17 00:00:00 2001 From: Sathya Gunasekaran Date: Mon, 17 Jul 2017 14:52:23 -0700 Subject: [PATCH] Fix error message while array destructuring undefined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, ➜ v8 (master) ✔ ./out.gn/x64.optdebug/d8 V8 version 6.1.0 (candidate) d8> var x = undefined undefined d8> var [a] = x (d8):1: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined var [a] = x ^ TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined at (d8):1:11 Now, ➜ v8 (fix-iterator) ✔ ./out.gn/x64.optdebug/d8 V8 version 6.1.0 (candidate) d8> var x = undefined undefined d8> var [a] = x (d8):1: TypeError: x is not iterable var [a] = x ^ TypeError: x is not iterable at (d8):1:11 Bug: v8:6599, v8:6513 Change-Id: I71287a19166af0289e8f7708b8f41ad003ae87ae Reviewed-on: https://chromium-review.googlesource.com/571175 Commit-Queue: Sathya Gunasekaran Reviewed-by: Adam Klein Reviewed-by: Jakob Kummerow Cr-Commit-Position: refs/heads/master@{#46723} --- src/ic/ic.cc | 4 ++ src/runtime/runtime-internal.cc | 43 +++++++++++++++---- src/runtime/runtime.h | 3 ++ ...tructuring-array-non-iterable-undefined.js | 6 +++ ...ructuring-array-non-iterable-undefined.out | 5 +++ 5 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 test/message/destructuring-array-non-iterable-undefined.js create mode 100644 test/message/destructuring-array-non-iterable-undefined.out diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 04a829869a..2684d0ba36 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -551,6 +551,10 @@ MaybeHandle LoadIC::Load(Handle object, Handle name) { PatchCache(name, slow_stub()); TRACE_IC("LoadIC", name); } + + if (*name == isolate()->heap()->iterator_symbol()) { + return Runtime::ThrowIteratorError(isolate(), object); + } return TypeError(MessageTemplate::kNonObjectPropertyLoad, object, name); } diff --git a/src/runtime/runtime-internal.cc b/src/runtime/runtime-internal.cc index a7316395e4..e1b6c66b11 100644 --- a/src/runtime/runtime-internal.cc +++ b/src/runtime/runtime-internal.cc @@ -393,19 +393,14 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { } Handle RenderCallSite(Isolate* isolate, Handle object, - MessageTemplate::Template* id) { + CallPrinter::IteratorHint* hint) { MessageLocation location; if (ComputeLocation(isolate, &location)) { ParseInfo info(location.shared()); if (parsing::ParseAny(&info, isolate)) { CallPrinter printer(isolate, location.shared()->IsUserJavaScript()); Handle str = printer.Print(info.literal(), location.start_pos()); - CallPrinter::IteratorHint type = printer.GetIteratorHint(); - if (type == CallPrinter::IteratorHint::kNormal) { - *id = MessageTemplate::kNotIterable; - } else if (type == CallPrinter::IteratorHint::kAsync) { - *id = MessageTemplate::kNotAsyncIterable; - } + *hint = printer.GetIteratorHint(); if (str->length() > 0) return str; } else { isolate->clear_pending_exception(); @@ -414,14 +409,43 @@ Handle RenderCallSite(Isolate* isolate, Handle object, return Object::TypeOf(isolate, object); } +void UpdateIteratorTemplate(CallPrinter::IteratorHint hint, + MessageTemplate::Template* id) { + if (hint == CallPrinter::IteratorHint::kNormal) { + *id = MessageTemplate::kNotIterable; + } + + if (hint == CallPrinter::IteratorHint::kAsync) { + *id = MessageTemplate::kNotAsyncIterable; + } +} + } // namespace +MaybeHandle Runtime::ThrowIteratorError(Isolate* isolate, + Handle object) { + CallPrinter::IteratorHint hint; + Handle callsite = RenderCallSite(isolate, object, &hint); + MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad; + + if (hint == CallPrinter::kNone) { + Handle iterator_symbol = isolate->factory()->iterator_symbol(); + THROW_NEW_ERROR(isolate, NewTypeError(id, iterator_symbol, callsite), + Object); + } + + UpdateIteratorTemplate(hint, &id); + THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object); +} + RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + CallPrinter::IteratorHint hint; + Handle callsite = RenderCallSite(isolate, object, &hint); MessageTemplate::Template id = MessageTemplate::kCalledNonCallable; - Handle callsite = RenderCallSite(isolate, object, &id); + UpdateIteratorTemplate(hint, &id); THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite)); } @@ -437,8 +461,9 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + CallPrinter::IteratorHint hint; + Handle callsite = RenderCallSite(isolate, object, &hint); MessageTemplate::Template id = MessageTemplate::kNotConstructor; - Handle callsite = RenderCallSite(isolate, object, &id); THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite)); } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 90d2252ed4..fedaa098f8 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -781,6 +781,9 @@ class Runtime : public AllStatic { MUST_USE_RESULT static MaybeHandle GetInternalProperties( Isolate* isolate, Handle); + + MUST_USE_RESULT static MaybeHandle ThrowIteratorError( + Isolate* isolate, Handle object); }; diff --git a/test/message/destructuring-array-non-iterable-undefined.js b/test/message/destructuring-array-non-iterable-undefined.js new file mode 100644 index 0000000000..f0eaa30562 --- /dev/null +++ b/test/message/destructuring-array-non-iterable-undefined.js @@ -0,0 +1,6 @@ +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var x = undefined; +var [y] = x; diff --git a/test/message/destructuring-array-non-iterable-undefined.out b/test/message/destructuring-array-non-iterable-undefined.out new file mode 100644 index 0000000000..564d02c91b --- /dev/null +++ b/test/message/destructuring-array-non-iterable-undefined.out @@ -0,0 +1,5 @@ +*%(basename)s:6: TypeError: x is not iterable +var [y] = x; + ^ +TypeError: x is not iterable + at *%(basename)s:6:11