Commit 80dd5e62 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[js weak refs] Implement spec change: cleanup must be callable

See https://github.com/tc39/proposal-weakrefs/issues/37

Drive-by: fix error messages.

BUG=v8:8179

Change-Id: I8608d09ec5a58c8b62eea4580be9415f6bb41586
Reviewed-on: https://chromium-review.googlesource.com/c/1319758
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57347}
parent 20affe10
...@@ -20,13 +20,16 @@ BUILTIN(WeakFactoryConstructor) { ...@@ -20,13 +20,16 @@ BUILTIN(WeakFactoryConstructor) {
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target()); Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
Handle<Object> cleanup = args.atOrUndefined(isolate, 1); Handle<Object> cleanup = args.atOrUndefined(isolate, 1);
if (!cleanup->IsCallable()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kWeakRefsCleanupMustBeCallable));
}
Handle<JSObject> result; Handle<JSObject> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, isolate, result,
JSObject::New(target, new_target, Handle<AllocationSite>::null())); JSObject::New(target, new_target, Handle<AllocationSite>::null()));
// TODO(marja): (spec) here we could return an error if cleanup is not a
// function, if the spec said so.
Handle<JSWeakFactory> weak_factory = Handle<JSWeakFactory>::cast(result); Handle<JSWeakFactory> weak_factory = Handle<JSWeakFactory>::cast(result);
weak_factory->set_native_context(*isolate->native_context()); weak_factory->set_native_context(*isolate->native_context());
weak_factory->set_cleanup(*cleanup); weak_factory->set_cleanup(*cleanup);
...@@ -44,9 +47,8 @@ BUILTIN(WeakFactoryMakeCell) { ...@@ -44,9 +47,8 @@ BUILTIN(WeakFactoryMakeCell) {
Handle<Object> target = args.atOrUndefined(isolate, 1); Handle<Object> target = args.atOrUndefined(isolate, 1);
if (!target->IsJSReceiver()) { if (!target->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kMakeCellTargetMustBeObject, isolate,
isolate->factory()->NewStringFromAsciiChecked( NewTypeError(MessageTemplate::kWeakRefsMakeCellTargetMustBeObject));
method_name)));
} }
Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target); Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target);
Handle<Object> holdings = args.atOrUndefined(isolate, 2); Handle<Object> holdings = args.atOrUndefined(isolate, 2);
...@@ -54,8 +56,7 @@ BUILTIN(WeakFactoryMakeCell) { ...@@ -54,8 +56,7 @@ BUILTIN(WeakFactoryMakeCell) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, isolate,
NewTypeError( NewTypeError(
MessageTemplate::kMakeCellTargetAndHoldingsMustNotBeSame, MessageTemplate::kWeakRefsMakeCellTargetAndHoldingsMustNotBeSame));
isolate->factory()->NewStringFromAsciiChecked(method_name)));
} }
// TODO(marja): Realms. // TODO(marja): Realms.
...@@ -84,9 +85,8 @@ BUILTIN(WeakFactoryMakeRef) { ...@@ -84,9 +85,8 @@ BUILTIN(WeakFactoryMakeRef) {
Handle<Object> target = args.atOrUndefined(isolate, 1); Handle<Object> target = args.atOrUndefined(isolate, 1);
if (!target->IsJSReceiver()) { if (!target->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kMakeRefTargetMustBeObject, isolate,
isolate->factory()->NewStringFromAsciiChecked( NewTypeError(MessageTemplate::kWeakRefsMakeRefTargetMustBeObject));
method_name)));
} }
Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target); Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target);
Handle<Object> holdings = args.atOrUndefined(isolate, 2); Handle<Object> holdings = args.atOrUndefined(isolate, 2);
...@@ -94,8 +94,7 @@ BUILTIN(WeakFactoryMakeRef) { ...@@ -94,8 +94,7 @@ BUILTIN(WeakFactoryMakeRef) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, isolate,
NewTypeError( NewTypeError(
MessageTemplate::kMakeRefTargetAndHoldingsMustNotBeSame, MessageTemplate::kWeakRefsMakeRefTargetAndHoldingsMustNotBeSame));
isolate->factory()->NewStringFromAsciiChecked(method_name)));
} }
// TODO(marja): Realms. // TODO(marja): Realms.
......
...@@ -534,14 +534,15 @@ namespace internal { ...@@ -534,14 +534,15 @@ namespace internal {
T(TraceEventPhaseError, "Trace event phase must be a number.") \ T(TraceEventPhaseError, "Trace event phase must be a number.") \
T(TraceEventIDError, "Trace event id must be a number.") \ T(TraceEventIDError, "Trace event id must be a number.") \
/* Weak refs */ \ /* Weak refs */ \
T(MakeCellTargetMustBeObject, \ T(WeakRefsCleanupMustBeCallable, "WeakFactory: cleanup must be callable") \
"WeakFactory.makeCell: target must be an object") \ T(WeakRefsMakeCellTargetMustBeObject, \
T(MakeCellTargetAndHoldingsMustNotBeSame, \ "WeakFactory.prototype.makeCell: target must be an object") \
"WeakFactory.makeCell: target and holdings must not be same") \ T(WeakRefsMakeCellTargetAndHoldingsMustNotBeSame, \
T(MakeRefTargetMustBeObject, \ "WeakFactory.prototype.makeCell: target and holdings must not be same") \
"WeakFactory.makeRef: target must be an object") \ T(WeakRefsMakeRefTargetMustBeObject, \
T(MakeRefTargetAndHoldingsMustNotBeSame, \ "WeakFactory.prototype.makeRef: target must be an object") \
"WeakFactory.makeRef: target and holdings must not be same") T(WeakRefsMakeRefTargetAndHoldingsMustNotBeSame, \
"WeakFactory.prototype.makeRef: target and holdings must not be same")
enum class MessageTemplate { enum class MessageTemplate {
#define TEMPLATE(NAME, STRING) k##NAME, #define TEMPLATE(NAME, STRING) k##NAME,
......
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
// Flags: --harmony-weak-refs // Flags: --harmony-weak-refs
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
wf.makeCell(1); wf.makeCell(1);
*%(basename)s:8: TypeError: WeakFactory.makeCell: target must be an object *%(basename)s:8: TypeError: WeakFactory.prototype.makeCell: target must be an object
wf.makeCell(1); wf.makeCell(1);
^ ^
TypeError: WeakFactory.makeCell: target must be an object TypeError: WeakFactory.prototype.makeCell: target must be an object
at WeakFactory.makeCell (<anonymous>) at WeakFactory.makeCell (<anonymous>)
at *%(basename)s:8:4 at *%(basename)s:8:4
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
// Flags: --harmony-weak-refs // Flags: --harmony-weak-refs
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let o = {}; let o = {};
wf.makeCell(o, o); wf.makeCell(o, o);
*%(basename)s:9: TypeError: WeakFactory.makeCell: target and holdings must not be same *%(basename)s:9: TypeError: WeakFactory.prototype.makeCell: target and holdings must not be same
wf.makeCell(o, o); wf.makeCell(o, o);
^ ^
TypeError: WeakFactory.makeCell: target and holdings must not be same TypeError: WeakFactory.prototype.makeCell: target and holdings must not be same
at WeakFactory.makeCell (<anonymous>) at WeakFactory.makeCell (<anonymous>)
at *%(basename)s:9:4 at *%(basename)s:9:4
// 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.
// Flags: --harmony-weak-refs
let wf = new WeakFactory();
*%(basename)s:7: TypeError: WeakFactory: cleanup must be callable
let wf = new WeakFactory();
^
TypeError: WeakFactory: cleanup must be callable
at new WeakFactory (<anonymous>)
at *%(basename)s:7:10
// 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.
// Flags: --harmony-weak-refs
let wf = new WeakFactory({});
*%(basename)s:7: TypeError: WeakFactory: cleanup must be callable
let wf = new WeakFactory({});
^
TypeError: WeakFactory: cleanup must be callable
at new WeakFactory (<anonymous>)
at *%(basename)s:7:10
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
// Flags: --harmony-weak-refs // Flags: --harmony-weak-refs
(function TestConstructWeakFactory() { (function TestConstructWeakFactory() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
assertEquals(wf.toString(), "[object WeakFactory]"); assertEquals(wf.toString(), "[object WeakFactory]");
assertNotSame(wf.__proto__, Object.prototype); assertNotSame(wf.__proto__, Object.prototype);
assertSame(wf.__proto__.__proto__, Object.prototype); assertSame(wf.__proto__.__proto__, Object.prototype);
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
let caught = false; let caught = false;
let message = ""; let message = "";
try { try {
let f = WeakFactory(); let f = WeakFactory(() => {});
} catch (e) { } catch (e) {
message = e.message; message = e.message;
caught = true; caught = true;
...@@ -25,8 +25,30 @@ ...@@ -25,8 +25,30 @@
} }
})(); })();
(function TestConstructWeakFactoryCleanupNotCallable() {
let message = "WeakFactory: cleanup must be callable";
assertThrows(() => { let wf = new WeakFactory(); }, TypeError, message);
assertThrows(() => { let wf = new WeakFactory(1); }, TypeError, message);
assertThrows(() => { let wf = new WeakFactory(null); }, TypeError, message);
})();
(function TestConstructWeakFactoryWithCallableProxyAsCleanup() {
let handler = {};
let obj = () => {};
let proxy = new Proxy(obj, handler);
let wf = new WeakFactory(proxy);
})();
(function TestConstructWeakFactoryWithNonCallableProxyAsCleanup() {
let message = "WeakFactory: cleanup must be callable";
let handler = {};
let obj = {};
let proxy = new Proxy(obj, handler);
assertThrows(() => { let wf = new WeakFactory(proxy); }, TypeError, message);
})();
(function TestMakeCell() { (function TestMakeCell() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wc = wf.makeCell({}); let wc = wf.makeCell({});
assertEquals(wc.toString(), "[object WeakCell]"); assertEquals(wc.toString(), "[object WeakCell]");
assertNotSame(wc.__proto__, Object.prototype); assertNotSame(wc.__proto__, Object.prototype);
...@@ -46,7 +68,7 @@ ...@@ -46,7 +68,7 @@
})(); })();
(function TestMakeCellWithHoldings() { (function TestMakeCellWithHoldings() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
let holdings = {b: 2}; let holdings = {b: 2};
let wc = wf.makeCell(obj, holdings); let wc = wf.makeCell(obj, holdings);
...@@ -54,7 +76,7 @@ ...@@ -54,7 +76,7 @@
})(); })();
(function TestMakeCellWithHoldingsSetHoldings() { (function TestMakeCellWithHoldingsSetHoldings() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
let holdings = {b: 2}; let holdings = {b: 2};
let wc = wf.makeCell(obj, holdings); let wc = wf.makeCell(obj, holdings);
...@@ -65,7 +87,7 @@ ...@@ -65,7 +87,7 @@
(function TestMakeCellWithHoldingsSetHoldingsStrict() { (function TestMakeCellWithHoldingsSetHoldingsStrict() {
"use strict"; "use strict";
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
let holdings = {b: 2}; let holdings = {b: 2};
let wc = wf.makeCell(obj, holdings); let wc = wf.makeCell(obj, holdings);
...@@ -75,8 +97,8 @@ ...@@ -75,8 +97,8 @@
})(); })();
(function TestMakeCellWithNonObject() { (function TestMakeCellWithNonObject() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let message = "WeakFactory.makeCell: target must be an object"; let message = "WeakFactory.prototype.makeCell: target must be an object";
assertThrows(() => wf.makeCell(), TypeError, message); assertThrows(() => wf.makeCell(), TypeError, message);
assertThrows(() => wf.makeCell(1), TypeError, message); assertThrows(() => wf.makeCell(1), TypeError, message);
assertThrows(() => wf.makeCell(false), TypeError, message); assertThrows(() => wf.makeCell(false), TypeError, message);
...@@ -90,16 +112,16 @@ ...@@ -90,16 +112,16 @@
let handler = {}; let handler = {};
let obj = {}; let obj = {};
let proxy = new Proxy(obj, handler); let proxy = new Proxy(obj, handler);
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wc = wf.makeCell(proxy); let wc = wf.makeCell(proxy);
})(); })();
(function TestMakeCellTargetAndHoldingsSameValue() { (function TestMakeCellTargetAndHoldingsSameValue() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
// SameValue(target, holdings) not ok // SameValue(target, holdings) not ok
assertThrows(() => wf.makeCell(obj, obj), TypeError, assertThrows(() => wf.makeCell(obj, obj), TypeError,
"WeakFactory.makeCell: target and holdings must not be same"); "WeakFactory.prototype.makeCell: target and holdings must not be same");
let holdings = {a: 1}; let holdings = {a: 1};
let wc = wf.makeCell(obj, holdings); let wc = wf.makeCell(obj, holdings);
})(); })();
...@@ -107,12 +129,12 @@ ...@@ -107,12 +129,12 @@
(function TestMakeCellWithoutWeakFactory() { (function TestMakeCellWithoutWeakFactory() {
assertThrows(() => WeakFactory.prototype.makeCell.call({}, {}), TypeError); assertThrows(() => WeakFactory.prototype.makeCell.call({}, {}), TypeError);
// Does not throw: // Does not throw:
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
WeakFactory.prototype.makeCell.call(wf, {}); WeakFactory.prototype.makeCell.call(wf, {});
})(); })();
(function TestHoldingsWithoutWeakCell() { (function TestHoldingsWithoutWeakCell() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wc = wf.makeCell({}); let wc = wf.makeCell({});
let holdings_getter = Object.getOwnPropertyDescriptor(wc.__proto__, "holdings").get; let holdings_getter = Object.getOwnPropertyDescriptor(wc.__proto__, "holdings").get;
assertThrows(() => holdings_getter.call({}), TypeError); assertThrows(() => holdings_getter.call({}), TypeError);
...@@ -121,7 +143,7 @@ ...@@ -121,7 +143,7 @@
})(); })();
(function TestClearWithoutWeakCell() { (function TestClearWithoutWeakCell() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wc = wf.makeCell({}); let wc = wf.makeCell({});
let clear = Object.getOwnPropertyDescriptor(wc.__proto__, "clear").value; let clear = Object.getOwnPropertyDescriptor(wc.__proto__, "clear").value;
assertThrows(() => clear.call({}), TypeError); assertThrows(() => clear.call({}), TypeError);
...@@ -130,7 +152,7 @@ ...@@ -130,7 +152,7 @@
})(); })();
(function TestMakeRef() { (function TestMakeRef() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wr = wf.makeRef({}); let wr = wf.makeRef({});
let wc = wf.makeCell({}); let wc = wf.makeCell({});
assertEquals(wr.toString(), "[object WeakRef]"); assertEquals(wr.toString(), "[object WeakRef]");
...@@ -145,7 +167,7 @@ ...@@ -145,7 +167,7 @@
})(); })();
(function TestMakeRefWithHoldings() { (function TestMakeRefWithHoldings() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
let holdings = {b: 2}; let holdings = {b: 2};
let wr = wf.makeRef(obj, holdings); let wr = wf.makeRef(obj, holdings);
...@@ -153,7 +175,7 @@ ...@@ -153,7 +175,7 @@
})(); })();
(function TestMakeRefWithHoldingsSetHoldings() { (function TestMakeRefWithHoldingsSetHoldings() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
let holdings = {b: 2}; let holdings = {b: 2};
let wr = wf.makeRef(obj, holdings); let wr = wf.makeRef(obj, holdings);
...@@ -164,7 +186,7 @@ ...@@ -164,7 +186,7 @@
(function TestMakeRefWithHoldingsSetHoldingsStrict() { (function TestMakeRefWithHoldingsSetHoldingsStrict() {
"use strict"; "use strict";
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
let holdings = {b: 2}; let holdings = {b: 2};
let wr = wf.makeRef(obj, holdings); let wr = wf.makeRef(obj, holdings);
...@@ -174,8 +196,8 @@ ...@@ -174,8 +196,8 @@
})(); })();
(function TestMakeRefWithNonObject() { (function TestMakeRefWithNonObject() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let message = "WeakFactory.makeRef: target must be an object"; let message = "WeakFactory.prototype.makeRef: target must be an object";
assertThrows(() => wf.makeRef(), TypeError, message); assertThrows(() => wf.makeRef(), TypeError, message);
assertThrows(() => wf.makeRef(1), TypeError, message); assertThrows(() => wf.makeRef(1), TypeError, message);
assertThrows(() => wf.makeRef(false), TypeError, message); assertThrows(() => wf.makeRef(false), TypeError, message);
...@@ -189,16 +211,16 @@ ...@@ -189,16 +211,16 @@
let handler = {}; let handler = {};
let obj = {}; let obj = {};
let proxy = new Proxy(obj, handler); let proxy = new Proxy(obj, handler);
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wr = wf.makeRef(proxy); let wr = wf.makeRef(proxy);
})(); })();
(function TestMakeRefTargetAndHoldingsSameValue() { (function TestMakeRefTargetAndHoldingsSameValue() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let obj = {a: 1}; let obj = {a: 1};
// SameValue(target, holdings) not ok // SameValue(target, holdings) not ok
assertThrows(() => wf.makeRef(obj, obj), TypeError, assertThrows(() => wf.makeRef(obj, obj), TypeError,
"WeakFactory.makeRef: target and holdings must not be same"); "WeakFactory.prototype.makeRef: target and holdings must not be same");
let holdings = {a: 1}; let holdings = {a: 1};
let wr = wf.makeRef(obj, holdings); let wr = wf.makeRef(obj, holdings);
})(); })();
...@@ -206,12 +228,12 @@ ...@@ -206,12 +228,12 @@
(function TestMakeRefWithoutWeakFactory() { (function TestMakeRefWithoutWeakFactory() {
assertThrows(() => WeakFactory.prototype.makeRef.call({}, {}), TypeError); assertThrows(() => WeakFactory.prototype.makeRef.call({}, {}), TypeError);
// Does not throw: // Does not throw:
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
WeakFactory.prototype.makeRef.call(wf, {}); WeakFactory.prototype.makeRef.call(wf, {});
})(); })();
(function TestDerefWithoutWeakRef() { (function TestDerefWithoutWeakRef() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wc = wf.makeCell({}); let wc = wf.makeCell({});
let wr = wf.makeRef({}); let wr = wf.makeRef({});
let deref = Object.getOwnPropertyDescriptor(wr.__proto__, "deref").value; let deref = Object.getOwnPropertyDescriptor(wr.__proto__, "deref").value;
...@@ -222,7 +244,7 @@ ...@@ -222,7 +244,7 @@
})(); })();
(function TestWeakRefClearAfterProtoChange() { (function TestWeakRefClearAfterProtoChange() {
let wf = new WeakFactory(); let wf = new WeakFactory(() => {});
let wc = wf.makeCell({}); let wc = wf.makeCell({});
let wr = wf.makeRef({}); let wr = wf.makeRef({});
// Does not throw: // Does not throw:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment