[runtime] Fix Runtime_InternalSetPrototype

Do not set the name property on any function or classes. This is not
required as per spec #sec-__proto__-property-names-in-object-initializers.

Bug: v8:7773
Change-Id: Iade96573690e5b14b60434c37683f782cf9cb2cb
Reviewed-on: https://chromium-review.googlesource.com/c/1375912
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58239}
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
index f08cb1f..60978b1 100644
--- a/src/runtime/runtime-object.cc
+++ b/src/runtime/runtime-object.cc
@@ -378,17 +378,6 @@
   DCHECK_EQ(2, args.length());
   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  if (prototype->IsJSFunction()) {
-    Handle<JSFunction> function = Handle<JSFunction>::cast(prototype);
-    if (!function->shared()->HasSharedName()) {
-      Handle<Map> function_map(function->map(), isolate);
-      if (!JSFunction::SetName(function, isolate->factory()->proto_string(),
-                               isolate->factory()->empty_string())) {
-        return ReadOnlyRoots(isolate).exception();
-      }
-      CHECK_EQ(*function_map, function->map());
-    }
-  }
   MAYBE_RETURN(JSReceiver::SetPrototype(obj, prototype, false, kThrowOnError),
                ReadOnlyRoots(isolate).exception());
   return *obj;
diff --git a/test/mjsunit/es6/classes.js b/test/mjsunit/es6/classes.js
index fa85faf..27121ec 100644
--- a/test/mjsunit/es6/classes.js
+++ b/test/mjsunit/es6/classes.js
@@ -23,10 +23,41 @@
   assertEquals('D2', D2.name);
 
   var E = class {}
-  assertEquals('E', E.name);  // Should be 'E'.
+  assertEquals('E', E.name);
 
   var F = class { constructor() {} };
-  assertEquals('F', F.name);  // Should be 'F'.
+  assertEquals('F', F.name);
+
+  var literal = { E: class {} };
+  assertEquals('E', literal.E.name);
+
+  literal = { E: class F {} };
+  assertEquals('F', literal.E.name);
+
+  literal = { __proto__: class {} };
+  assertEquals('', literal.__proto__.name);
+  assertEquals(
+      undefined, Object.getOwnPropertyDescriptor(literal.__proto__, 'name'));
+
+  literal = { __proto__: class F {} };
+  assertEquals('F', literal.__proto__.name);
+  assertNotEquals(
+      undefined, Object.getOwnPropertyDescriptor(literal.__proto__, 'name'));
+
+  class G {};
+  literal = { __proto__: G };
+  assertEquals('G', literal.__proto__.name);
+
+  var H = class { static name() { return 'A'; } };
+  literal = { __proto__ : H };
+  assertEquals('A', literal.__proto__.name());
+
+  literal = {
+    __proto__: class {
+      static name() { return 'A'; }
+    }
+  };
+  assertEquals('A', literal.__proto__.name());
 })();
 
 
diff --git a/test/mjsunit/regress/regress-7773.js b/test/mjsunit/regress/regress-7773.js
new file mode 100644
index 0000000..7930ae9
--- /dev/null
+++ b/test/mjsunit/regress/regress-7773.js
@@ -0,0 +1,71 @@
+// 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.
+
+(function testFunctionNames() {
+  let descriptor = {
+    value: '',
+    writable: false,
+    enumerable: false,
+    configurable: true
+  };
+  // Functions have a "name" property by default.
+  assertEquals(
+      descriptor, Object.getOwnPropertyDescriptor(function(){}, 'name'));
+  let a = { fn: function(){} };
+  assertSame('fn', a.fn.name);
+  descriptor.value = 'fn';
+  assertEquals(descriptor, Object.getOwnPropertyDescriptor(a.fn, 'name'));
+
+  let b = { __proto__: function(){} };
+  assertSame('', b.__proto__.name);
+  descriptor.value = '';
+  assertEquals(
+      descriptor, Object.getOwnPropertyDescriptor(b.__proto__, 'name'));
+
+  let c = { fn: function F(){} };
+  assertSame('F', c.fn.name);
+  descriptor.value = 'F';
+  assertEquals(descriptor, Object.getOwnPropertyDescriptor(c.fn, 'name'));
+
+  let d = { __proto__: function E(){} };
+  assertSame('E', d.__proto__.name);
+  descriptor.value = 'E';
+  assertEquals(
+      descriptor, Object.getOwnPropertyDescriptor(d.__proto__, 'name'));
+})();
+
+(function testClassNames() {
+  let descriptor = {
+    value: '',
+    writable: false,
+    enumerable: false,
+    configurable: true
+  };
+
+  // Anonymous classes do not have a "name" property by default.
+  assertSame(undefined, Object.getOwnPropertyDescriptor(class {}, 'name'));
+  descriptor.value = 'C';
+  assertEquals(descriptor, Object.getOwnPropertyDescriptor(class C {}, 'name'));
+
+  let a = { fn: class {} };
+  assertSame('fn', a.fn.name);
+  descriptor.value = 'fn';
+  assertEquals(descriptor, Object.getOwnPropertyDescriptor(a.fn, 'name'));
+
+  let b = { __proto__: class {} };
+  assertSame('', b.__proto__.name);
+  assertSame(
+      undefined, Object.getOwnPropertyDescriptor(b.__proto__, 'name'));
+
+  let c = { fn: class F {} };
+  assertSame('F', c.fn.name);
+  descriptor.value = 'F';
+  assertEquals(descriptor, Object.getOwnPropertyDescriptor(c.fn, 'name'));
+
+  let d = { __proto__: class F {} };
+  assertSame('F', d.__proto__.name);
+  descriptor.value = 'F';
+  assertEquals(
+      descriptor, Object.getOwnPropertyDescriptor(d.__proto__, 'name'));
+})();