[errors] Give a more informative error message for `new Map(1)`

Previously the error was "undefined is not a function". Now it is
"1 is not iterable".

Bug: v8:6522
Change-Id: If338ddefca78fd6a10cc12b26f0dec632900f32b
Reviewed-on: https://chromium-review.googlesource.com/959728
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51918}
diff --git a/src/builtins/builtins-iterator-gen.cc b/src/builtins/builtins-iterator-gen.cc
index be77117..f2de364 100644
--- a/src/builtins/builtins-iterator-gen.cc
+++ b/src/builtins/builtins-iterator-gen.cc
@@ -31,27 +31,42 @@
                                                       Variable* exception) {
   GotoIfException(method, if_exception, exception);
 
-  Callable callable = CodeFactory::Call(isolate());
-  Node* iterator = CallJS(callable, context, method, object);
-  GotoIfException(iterator, if_exception, exception);
+  Label if_not_callable(this, Label::kDeferred), if_callable(this);
+  GotoIf(TaggedIsSmi(method), &if_not_callable);
+  Branch(IsCallable(method), &if_callable, &if_not_callable);
 
-  Label get_next(this), if_notobject(this, Label::kDeferred);
-  GotoIf(TaggedIsSmi(iterator), &if_notobject);
-  Branch(IsJSReceiver(iterator), &get_next, &if_notobject);
-
-  BIND(&if_notobject);
+  BIND(&if_not_callable);
   {
-    Node* ret = CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context);
+    Node* ret = CallRuntime(Runtime::kThrowTypeError, context,
+                            SmiConstant(MessageTemplate::kNotIterable), object);
     GotoIfException(ret, if_exception, exception);
     Unreachable();
   }
 
-  BIND(&get_next);
-  Node* const next = GetProperty(context, iterator, factory()->next_string());
-  GotoIfException(next, if_exception, exception);
+  BIND(&if_callable);
+  {
+    Callable callable = CodeFactory::Call(isolate());
+    Node* iterator = CallJS(callable, context, method, object);
+    GotoIfException(iterator, if_exception, exception);
 
-  return IteratorRecord{TNode<JSReceiver>::UncheckedCast(iterator),
-                        TNode<Object>::UncheckedCast(next)};
+    Label get_next(this), if_notobject(this, Label::kDeferred);
+    GotoIf(TaggedIsSmi(iterator), &if_notobject);
+    Branch(IsJSReceiver(iterator), &get_next, &if_notobject);
+
+    BIND(&if_notobject);
+    {
+      Node* ret = CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context);
+      GotoIfException(ret, if_exception, exception);
+      Unreachable();
+    }
+
+    BIND(&get_next);
+    Node* const next = GetProperty(context, iterator, factory()->next_string());
+    GotoIfException(next, if_exception, exception);
+
+    return IteratorRecord{TNode<JSReceiver>::UncheckedCast(iterator),
+                          TNode<Object>::UncheckedCast(next)};
+  }
 }
 
 Node* IteratorBuiltinsAssembler::IteratorStep(
diff --git a/test/message/fail/map-arg-non-iterable.js b/test/message/fail/map-arg-non-iterable.js
new file mode 100644
index 0000000..d4cb7a7
--- /dev/null
+++ b/test/message/fail/map-arg-non-iterable.js
@@ -0,0 +1,5 @@
+// Copyright 2018 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.
+
+new Map(1);
diff --git a/test/message/fail/map-arg-non-iterable.out b/test/message/fail/map-arg-non-iterable.out
new file mode 100644
index 0000000..78aa8ef
--- /dev/null
+++ b/test/message/fail/map-arg-non-iterable.out
@@ -0,0 +1,6 @@
+*%(basename)s:5: TypeError: 1 is not iterable
+new Map(1);
+^
+TypeError: 1 is not iterable
+    at new Map (<anonymous>)
+    at *%(basename)s:5:1