Fix error message while array destructuring undefined

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 <gsathya@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46723}
This commit is contained in:
Sathya Gunasekaran 2017-07-17 14:52:23 -07:00 committed by Commit Bot
parent c45b2291a7
commit 94ce16b704
5 changed files with 52 additions and 9 deletions

View File

@ -551,6 +551,10 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> 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);
}

View File

@ -393,19 +393,14 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
}
Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> 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<String> 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<String> RenderCallSite(Isolate* isolate, Handle<Object> 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<Object> Runtime::ThrowIteratorError(Isolate* isolate,
Handle<Object> object) {
CallPrinter::IteratorHint hint;
Handle<String> callsite = RenderCallSite(isolate, object, &hint);
MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad;
if (hint == CallPrinter::kNone) {
Handle<Symbol> 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<String> callsite = RenderCallSite(isolate, object, &hint);
MessageTemplate::Template id = MessageTemplate::kCalledNonCallable;
Handle<String> 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<String> callsite = RenderCallSite(isolate, object, &hint);
MessageTemplate::Template id = MessageTemplate::kNotConstructor;
Handle<String> callsite = RenderCallSite(isolate, object, &id);
THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite));
}

View File

@ -781,6 +781,9 @@ class Runtime : public AllStatic {
MUST_USE_RESULT static MaybeHandle<JSArray> GetInternalProperties(
Isolate* isolate, Handle<Object>);
MUST_USE_RESULT static MaybeHandle<Object> ThrowIteratorError(
Isolate* isolate, Handle<Object> object);
};

View File

@ -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;

View File

@ -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