[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}
This commit is contained in:
parent
19d39a0f33
commit
fb434f1c6c
@ -378,17 +378,6 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
|
||||
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;
|
||||
|
@ -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());
|
||||
})();
|
||||
|
||||
|
||||
|
71
test/mjsunit/regress/regress-7773.js
Normal file
71
test/mjsunit/regress/regress-7773.js
Normal file
@ -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'));
|
||||
})();
|
Loading…
Reference in New Issue
Block a user