Diff
Modified: trunk/LayoutTests/ChangeLog (246564 => 246565)
--- trunk/LayoutTests/ChangeLog 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/LayoutTests/ChangeLog 2019-06-18 21:02:19 UTC (rev 246565)
@@ -1,3 +1,45 @@
+2019-06-18 Keith Miller <keith_mil...@apple.com>
+
+ Add support for WeakRef
+ https://bugs.webkit.org/show_bug.cgi?id=198710
+
+ Reviewed by Yusuke Suzuki.
+
+ Add an asyncTestStart that mirrors the asyncTestStart behavior in
+ the JSC cli.
+
+ * http/tests/resources/js-test-pre.js:
+ (asyncTestStart):
+ * js/script-tests/weakref-async-is-collected.js: Added.
+ (makeWeakRef):
+ (turnEventLoop):
+ (async.foo):
+ (async.test):
+ * js/script-tests/weakref-eventually-collects-values.js: Added.
+ (makeWeakRef):
+ (turnEventLoop):
+ (let.weakRefs.async.test):
+ * js/script-tests/weakref-microtasks-dont-collect.js: Added.
+ (asyncTestStart.1.makeWeakRef):
+ (turnEventLoop):
+ (async.foo):
+ (async.test):
+ * js/script-tests/weakref-weakset-consistency.js: Added.
+ (makeWeakRef):
+ (turnEventLoop):
+ (async.foo):
+ (async.test):
+ * js/weakref-async-is-collected-expected.txt: Added.
+ * js/weakref-async-is-collected.html: Added.
+ * js/weakref-eventually-collects-values-expected.txt: Added.
+ * js/weakref-eventually-collects-values.html: Added.
+ * js/weakref-microtasks-dont-collect-expected.txt: Added.
+ * js/weakref-microtasks-dont-collect.html: Added.
+ * js/weakref-weakset-consistency-expected.txt: Added.
+ * js/weakref-weakset-consistency.html: Added.
+ * resources/js-test-pre.js:
+ (asyncTestStart):
+
2019-06-18 Daniel Bates <daba...@apple.com>
[iOS] Pressing key while holding Command should not insert character
Modified: trunk/LayoutTests/http/tests/resources/js-test-pre.js (246564 => 246565)
--- trunk/LayoutTests/http/tests/resources/js-test-pre.js 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/LayoutTests/http/tests/resources/js-test-pre.js 2019-06-18 21:02:19 UTC (rev 246565)
@@ -757,6 +757,16 @@
debug('<br /><span class="pass">TEST COMPLETE</span>');
}
+function asyncTestStart() {
+ if (self.testRunner)
+ testRunner.waitUntilDone();
+}
+
+function asyncTestPassed() {
+ if (self.testRunner)
+ testRunner.notifyDone();
+}
+
// It's possible for an async test to call finishJSTest() before js-test-post.js
// has been parsed.
function finishJSTest()
Added: trunk/LayoutTests/js/script-tests/weakref-async-is-collected.js (0 => 246565)
--- trunk/LayoutTests/js/script-tests/weakref-async-is-collected.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-async-is-collected.js 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,45 @@
+asyncTestStart(1);
+function makeWeakRef() { return new WeakRef({foo: 1 }); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+function turnEventLoop() {
+ return new Promise(function(resolve, reject) {
+ if (globalThis.window) {
+ // Turns out the test times out if we turn the event loop 10000 times...
+ loopCount = 1000;
+ window.setTimeout(() => {
+ resolve();
+ }, 0);
+ } else {
+ releaseWeakRefs();
+ resolve();
+ }
+ });
+}
+
+let weakRefs = [];
+
+async function* foo() {
+ let weak = makeWeakRef();
+ await 2;
+ if (weak.deref().foo !== 1)
+ throw new Error("Weak ref was collected too early");
+ await turnEventLoop();
+ weakRefs.push(weak);
+}
+
+async function test() {
+ for (let i = 0; i < loopCount; i++) {
+ for await (value of foo()) { }
+ if (i % 100 === 0)
+ gc();
+ }
+ gc();
+
+ if (weakRefs.find((weak) => weak.deref() === null) === undefined)
+ throw new Error("No weak ref value was collected");
+ asyncTestPassed();
+}
+
+test().catch(e => debug(e));
Added: trunk/LayoutTests/js/script-tests/weakref-eventually-collects-values.js (0 => 246565)
--- trunk/LayoutTests/js/script-tests/weakref-eventually-collects-values.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-eventually-collects-values.js 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,40 @@
+asyncTestStart(1);
+
+function makeWeakRef() { return new WeakRef({foo: 1}); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+function turnEventLoop() {
+ return new Promise(function(resolve, reject) {
+ if (globalThis.window) {
+ // Turns out the test times out if we turn the event loop 10000 times...
+ loopCount = 1000;
+ window.setTimeout(() => {
+ resolve();
+ }, 0);
+ } else {
+ releaseWeakRefs();
+ resolve();
+ }
+ });
+}
+
+let weakRefs = []
+
+async function test() {
+
+ for (let i = 0; i < loopCount; i++) {
+ let weak = makeWeakRef();
+ if (weak.deref().foo != 1)
+ throw new Error("weak ref was freed too early.");
+ weakRefs.push(weak);
+ }
+ await turnEventLoop();
+ gc();
+
+ if (!weakRefs.find((weak) => weak.deref() === null))
+ throw new Error("no weak ref was collected");
+ asyncTestPassed();
+}
+
+test().catch(e => debug(e));
Added: trunk/LayoutTests/js/script-tests/weakref-microtasks-dont-collect.js (0 => 246565)
--- trunk/LayoutTests/js/script-tests/weakref-microtasks-dont-collect.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-microtasks-dont-collect.js 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,48 @@
+asyncTestStart(1);
+
+function makeWeakRef() { return new WeakRef({foo: 1 }); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+
+function turnEventLoop() {
+ return new Promise(function(resolve, reject) {
+ if (globalThis.window) {
+ // Turns out the test times out if we turn the event loop 10000 times...
+ loopCount = 1000;
+ window.setTimeout(() => {
+ resolve();
+ }, 0);
+ } else {
+ releaseWeakRefs();
+ resolve();
+ }
+ });
+}
+
+let weakRefs = [];
+
+async function* foo() {
+ let weak = makeWeakRef();
+ let object = weak.deref();
+ yield await 1;
+ if (weak.deref() !== object)
+ throw new Error("Object appears to have been collected incorrectly");
+ object = null;
+ yield await turnEventLoop();
+ weakRefs.push(weak);
+}
+
+async function test() {
+ for (let i = 0; i < loopCount; i++) {
+ for await (value of foo()) { }
+ }
+ gc();
+
+ if (weakRefs.find((weak) => weak.deref() === null) === undefined)
+ throw new Error("No weak ref value was collected");
+ asyncTestPassed();
+}
+
+
+test().catch(e => debug(e));
Added: trunk/LayoutTests/js/script-tests/weakref-weakset-consistency.js (0 => 246565)
--- trunk/LayoutTests/js/script-tests/weakref-weakset-consistency.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-weakset-consistency.js 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,42 @@
+asyncTestStart(1);
+function makeWeakRef() { return new WeakRef({foo: 1 }); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+function turnEventLoop() {
+ return new Promise(function(resolve, reject) {
+ if (globalThis.window) {
+ // Turns out the test times out if we turn the event loop 10000 times...
+ loopCount = 1000;
+ window.setTimeout(() => {
+ resolve();
+ }, 0);
+ } else {
+ releaseWeakRefs();
+ resolve();
+ }
+ });
+}
+
+let weakSet = new WeakSet();
+let weakRefs = [];
+
+async function* foo() {
+ let weak = makeWeakRef();
+ weakSet.add(weak.deref());
+ await turnEventLoop();
+ weakRefs.push(weak);
+}
+
+async function test() {
+ for (let i = 0; i < loopCount; i++) {
+ for await (value of foo()) { }
+ }
+ gc();
+
+ if (weakRefs.find((weak) => weak.deref() && !weakSet.has(weak.deref())))
+ throw new Error("Weak ref has target but weak set lost reference." )
+ asyncTestPassed();
+}
+
+test().catch(e => debug(e));
Added: trunk/LayoutTests/js/weakref-async-is-collected-expected.txt (0 => 246565)
--- trunk/LayoutTests/js/weakref-async-is-collected-expected.txt (rev 0)
+++ trunk/LayoutTests/js/weakref-async-is-collected-expected.txt 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/weakref-async-is-collected.html (0 => 246565)
--- trunk/LayoutTests/js/weakref-async-is-collected.html (rev 0)
+++ trunk/LayoutTests/js/weakref-async-is-collected.html 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/weakref-eventually-collects-values-expected.txt (0 => 246565)
--- trunk/LayoutTests/js/weakref-eventually-collects-values-expected.txt (rev 0)
+++ trunk/LayoutTests/js/weakref-eventually-collects-values-expected.txt 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/weakref-eventually-collects-values.html (0 => 246565)
--- trunk/LayoutTests/js/weakref-eventually-collects-values.html (rev 0)
+++ trunk/LayoutTests/js/weakref-eventually-collects-values.html 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/weakref-microtasks-dont-collect-expected.txt (0 => 246565)
--- trunk/LayoutTests/js/weakref-microtasks-dont-collect-expected.txt (rev 0)
+++ trunk/LayoutTests/js/weakref-microtasks-dont-collect-expected.txt 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/weakref-microtasks-dont-collect.html (0 => 246565)
--- trunk/LayoutTests/js/weakref-microtasks-dont-collect.html (rev 0)
+++ trunk/LayoutTests/js/weakref-microtasks-dont-collect.html 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/weakref-weakset-consistency-expected.txt (0 => 246565)
--- trunk/LayoutTests/js/weakref-weakset-consistency-expected.txt (rev 0)
+++ trunk/LayoutTests/js/weakref-weakset-consistency-expected.txt 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/weakref-weakset-consistency.html (0 => 246565)
--- trunk/LayoutTests/js/weakref-weakset-consistency.html (rev 0)
+++ trunk/LayoutTests/js/weakref-weakset-consistency.html 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/resources/js-test-pre.js (246564 => 246565)
--- trunk/LayoutTests/resources/js-test-pre.js 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/LayoutTests/resources/js-test-pre.js 2019-06-18 21:02:19 UTC (rev 246565)
@@ -757,6 +757,16 @@
debug('<br /><span class="pass">TEST COMPLETE</span>');
}
+function asyncTestStart() {
+ if (self.testRunner)
+ testRunner.waitUntilDone();
+}
+
+function asyncTestPassed() {
+ if (self.testRunner)
+ testRunner.notifyDone();
+}
+
// It's possible for an async test to call finishJSTest() before js-test-post.js
// has been parsed.
function finishJSTest()
Modified: trunk/Source/_javascript_Core/ChangeLog (246564 => 246565)
--- trunk/Source/_javascript_Core/ChangeLog 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-06-18 21:02:19 UTC (rev 246565)
@@ -1,3 +1,63 @@
+2019-06-18 Keith Miller <keith_mil...@apple.com>
+
+ Add support for WeakRef
+ https://bugs.webkit.org/show_bug.cgi?id=198710
+
+ Reviewed by Yusuke Suzuki.
+
+ Add support for WeakRefs which are now at stage 3
+ (https://tc39.es/proposal-weakrefs). This patch doesn't add
+ support for FinalizationGroups, which I'll add in another patch.
+
+ Some other things of interest. Per the spec, we cannot collect a
+ weak refs target unless it has not been dereffed (or created) in
+ the current microtask turn. i.e. WeakRefs are only allowed to be
+ collected at the end of a drain of the Microtask queue. My
+ understanding for this behavior is to reduce implementation
+ dependence on specific GC behavior in a given browser.
+
+ We track if a WeakRef is retaining its target by using a version
+ number on each WeakRef as well as on the VM. Whenever a WeakRef is
+ derefed we update its version number to match the VM's then
+ WriteBarrier ourselves. During marking if the VM and the WeakRef
+ have the same version number, the target is visited.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * heap/Heap.cpp:
+ (JSC::Heap::finalizeUnconditionalFinalizers):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionReleaseWeakRefs):
+ * runtime/CommonIdentifiers.h:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObject.h:
+ * runtime/JSWeakObjectRef.cpp: Added.
+ (JSC::JSWeakObjectRef::finishCreation):
+ (JSC::JSWeakObjectRef::visitChildren):
+ (JSC::JSWeakObjectRef::finalizeUnconditionally):
+ (JSC::JSWeakObjectRef::toStringName):
+ * runtime/JSWeakObjectRef.h: Added.
+ * runtime/VM.cpp:
+ (JSC::VM::drainMicrotasks):
+ * runtime/VM.h:
+ (JSC::VM::setOnEachMicrotaskTick):
+ (JSC::VM::finalizeSynchronousJSExecution):
+ (JSC::VM::currentWeakRefVersion const):
+ * runtime/WeakObjectRefConstructor.cpp: Added.
+ (JSC::WeakObjectRefConstructor::finishCreation):
+ (JSC::WeakObjectRefConstructor::WeakObjectRefConstructor):
+ (JSC::callWeakRef):
+ (JSC::constructWeakRef):
+ * runtime/WeakObjectRefConstructor.h: Added.
+ (JSC::WeakObjectRefConstructor::create):
+ (JSC::WeakObjectRefConstructor::createStructure):
+ * runtime/WeakObjectRefPrototype.cpp: Added.
+ (JSC::WeakObjectRefPrototype::finishCreation):
+ (JSC::getWeakRef):
+ (JSC::protoFuncWeakRefDeref):
+ * runtime/WeakObjectRefPrototype.h: Added.
+
2019-06-18 Tadeu Zagallo <tzaga...@apple.com>
Add missing mutator fence in compileNewFunction
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (246564 => 246565)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-06-18 21:02:19 UTC (rev 246565)
@@ -1076,6 +1076,9 @@
5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
5381B9391E60E97D0090F794 /* WasmFaultSignalHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
+ 539930C822AD3B9A0051CDE2 /* WeakObjectRefConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 539930C722AD3B9A0051CDE2 /* WeakObjectRefConstructor.h */; };
+ 539BFBAE22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 539BFBAD22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h */; };
+ 539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */; };
539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
53B4BD121F68B32500D2BEA3 /* WasmOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 533B15DE1DC7F463004D500A /* WasmOps.h */; settings = {ATTRIBUTES = (Private, ); }; };
53B601EC2034B8C5006BE667 /* JSCast.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B601EB2034B8C5006BE667 /* JSCast.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3639,6 +3642,8 @@
536B319F1F7369BD0037FC33 /* glib */ = {isa = PBXFileReference; lastKnownFileType = folder; path = glib; sourceTree = "<group>"; };
5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdaptiveInferredPropertyValueWatchpointBase.cpp; sourceTree = "<group>"; };
5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = "<group>"; };
+ 5373B4D322AD8BF700803572 /* WeakObjectRefPrototype.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeakObjectRefPrototype.cpp; sourceTree = "<group>"; };
+ 5373B4D422ADB31400803572 /* WeakObjectRefConstructor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeakObjectRefConstructor.cpp; sourceTree = "<group>"; };
5381B9361E60E9660090F794 /* WasmFaultSignalHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmFaultSignalHandler.cpp; sourceTree = "<group>"; };
5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmFaultSignalHandler.h; sourceTree = "<group>"; };
5383AA2F1E65E8A100A532FC /* JSWebAssemblyCodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyCodeBlock.cpp; path = js/JSWebAssemblyCodeBlock.cpp; sourceTree = "<group>"; };
@@ -3645,6 +3650,10 @@
53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
+ 539930C722AD3B9A0051CDE2 /* WeakObjectRefConstructor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeakObjectRefConstructor.h; sourceTree = "<group>"; };
+ 539BFBAD22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeakObjectRefPrototype.h; sourceTree = "<group>"; };
+ 539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectRef.h; sourceTree = "<group>"; };
+ 539BFBB122AD3D8C0023F4C0 /* JSWeakObjectRef.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectRef.cpp; sourceTree = "<group>"; };
539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = "<group>"; };
53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetterSetterAccessCase.cpp; sourceTree = "<group>"; };
53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyableAccessCase.cpp; sourceTree = "<group>"; };
@@ -7128,6 +7137,8 @@
0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */,
A7CA3AE217DA41AE006538AF /* JSWeakMap.h */,
+ 539BFBB122AD3D8C0023F4C0 /* JSWeakObjectRef.cpp */,
+ 539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */,
709FB8611AE335C60039D069 /* JSWeakSet.cpp */,
709FB8621AE335C60039D069 /* JSWeakSet.h */,
1442565F15EDE98D0066A49B /* JSWithScope.cpp */,
@@ -7372,6 +7383,10 @@
E393ADD71FE702CC0022D681 /* WeakMapImplInlines.h */,
A7CA3ADF17DA41AE006538AF /* WeakMapPrototype.cpp */,
A7CA3AE017DA41AE006538AF /* WeakMapPrototype.h */,
+ 5373B4D422ADB31400803572 /* WeakObjectRefConstructor.cpp */,
+ 539930C722AD3B9A0051CDE2 /* WeakObjectRefConstructor.h */,
+ 5373B4D322AD8BF700803572 /* WeakObjectRefPrototype.cpp */,
+ 539BFBAD22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h */,
709FB8631AE335C60039D069 /* WeakSetConstructor.cpp */,
709FB8641AE335C60039D069 /* WeakSetConstructor.h */,
709FB8651AE335C60039D069 /* WeakSetPrototype.cpp */,
@@ -9561,6 +9576,7 @@
A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
+ 539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */,
0F0B286B1EB8E6CF000EB5D2 /* JSWeakPrivate.h in Headers */,
709FB8681AE335C60039D069 /* JSWeakSet.h in Headers */,
7A9774A8206B82E4008D03D0 /* JSWeakValue.h in Headers */,
@@ -10010,6 +10026,8 @@
E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */,
E393ADD81FE702D00022D681 /* WeakMapImplInlines.h in Headers */,
A7CA3AE617DA41AE006538AF /* WeakMapPrototype.h in Headers */,
+ 539930C822AD3B9A0051CDE2 /* WeakObjectRefConstructor.h in Headers */,
+ 539BFBAE22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h in Headers */,
14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */,
709FB86A1AE335C60039D069 /* WeakSetConstructor.h in Headers */,
14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (246564 => 246565)
--- trunk/Source/_javascript_Core/Sources.txt 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/Sources.txt 2019-06-18 21:02:19 UTC (rev 246565)
@@ -873,6 +873,7 @@
runtime/JSTypedArrayViewPrototype.cpp
runtime/JSTypedArrays.cpp
runtime/JSWeakMap.cpp
+runtime/JSWeakObjectRef.cpp
runtime/JSWeakSet.cpp
runtime/JSWithScope.cpp
runtime/JSWrapperObject.cpp
@@ -969,6 +970,8 @@
runtime/WeakMapConstructor.cpp
runtime/WeakMapImpl.cpp
runtime/WeakMapPrototype.cpp
+runtime/WeakObjectRefConstructor.cpp
+runtime/WeakObjectRefPrototype.cpp
runtime/WeakSetConstructor.cpp
runtime/WeakSetPrototype.cpp
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (246564 => 246565)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -53,6 +53,7 @@
#include "JSLock.h"
#include "JSVirtualMachineInternal.h"
#include "JSWeakMap.h"
+#include "JSWeakObjectRef.h"
#include "JSWeakSet.h"
#include "JSWebAssemblyCodeBlock.h"
#include "MachineStackMarker.h"
@@ -611,6 +612,8 @@
finalizeMarkedUnconditionalFinalizers<JSWeakSet>(*vm()->m_weakSetSpace);
if (vm()->m_weakMapSpace)
finalizeMarkedUnconditionalFinalizers<JSWeakMap>(*vm()->m_weakMapSpace);
+ if (vm()->m_weakObjectRefSpace)
+ finalizeMarkedUnconditionalFinalizers<JSWeakObjectRef>(*vm()->m_weakObjectRefSpace);
if (vm()->m_errorInstanceSpace)
finalizeMarkedUnconditionalFinalizers<ErrorInstance>(*vm()->m_errorInstanceSpace);
Modified: trunk/Source/_javascript_Core/jsc.cpp (246564 => 246565)
--- trunk/Source/_javascript_Core/jsc.cpp 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/jsc.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -329,6 +329,7 @@
static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionDrainMicrotasks(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionReleaseWeakRefs(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*);
@@ -557,6 +558,7 @@
addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
addFunction(vm, "drainMicrotasks", functionDrainMicrotasks, 0);
+ addFunction(vm, "releaseWeakRefs", functionReleaseWeakRefs, 0);
addFunction(vm, "getRandomSeed", functionGetRandomSeed, 0);
addFunction(vm, "setRandomSeed", functionSetRandomSeed, 1);
@@ -2209,6 +2211,13 @@
return JSValue::encode(jsUndefined());
}
+EncodedJSValue JSC_HOST_CALL functionReleaseWeakRefs(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ vm.finalizeSynchronousJSExecution();
+ return JSValue::encode(jsUndefined());
+}
+
EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*)
{
#if USE(JSVALUE64)
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (246564 => 246565)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -88,6 +88,7 @@
macro(counters) \
macro(day) \
macro(defineProperty) \
+ macro(deref) \
macro(description) \
macro(descriptions) \
macro(detail) \
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (246564 => 246565)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -122,6 +122,7 @@
#include "JSTypedArrayViewPrototype.h"
#include "JSTypedArrays.h"
#include "JSWeakMap.h"
+#include "JSWeakObjectRef.h"
#include "JSWeakSet.h"
#include "JSWebAssembly.h"
#include "JSWithScope.h"
@@ -172,6 +173,8 @@
#include "WeakGCMapInlines.h"
#include "WeakMapConstructor.h"
#include "WeakMapPrototype.h"
+#include "WeakObjectRefConstructor.h"
+#include "WeakObjectRefPrototype.h"
#include "WeakSetConstructor.h"
#include "WeakSetPrototype.h"
#include "WebAssemblyPrototype.h"
@@ -359,6 +362,7 @@
Number JSGlobalObject::m_numberObjectStructure DontEnum|ClassStructure
Symbol JSGlobalObject::m_symbolObjectStructure DontEnum|ClassStructure
WeakMap JSGlobalObject::m_weakMapStructure DontEnum|ClassStructure
+ WeakRef JSGlobalObject::m_weakObjectRefStructure DontEnum|ClassStructure
WeakSet JSGlobalObject::m_weakSetStructure DontEnum|ClassStructure
@end
*/
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (246564 => 246565)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -149,6 +149,7 @@
macro(Error, error, error, ErrorInstance, Error, object) \
macro(Number, number, numberObject, NumberObject, Number, object) \
macro(Symbol, symbol, symbolObject, SymbolObject, Symbol, object) \
+ macro(WeakObjectRef, weakObjectRef, weakObjectRef, JSWeakObjectRef, WeakRef, object) \
DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \
DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \
Added: trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.cpp (0 => 246565)
--- trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSWeakObjectRef.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSWeakObjectRef::s_info = { "WeakRef", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWeakObjectRef) };
+
+void JSWeakObjectRef::finishCreation(VM& vm, JSObject* value)
+{
+ m_lastAccessVersion = vm.currentWeakRefVersion();
+ m_value.set(vm, this, value);
+ Base::finishCreation(vm);
+}
+
+void JSWeakObjectRef::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ auto* thisObject = jsCast<JSWeakObjectRef*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+ // This doesn't need to be atomic because if we are out of date we will get write barriered and revisit ourselves.
+ if (visitor.vm().currentWeakRefVersion() == thisObject->m_lastAccessVersion) {
+ ASSERT(thisObject->m_value);
+ visitor.append(thisObject->m_value);
+ }
+}
+
+void JSWeakObjectRef::finalizeUnconditionally(VM& vm)
+{
+ if (m_value && !vm.heap.isMarked(m_value.get()))
+ m_value.clear();
+}
+
+String JSWeakObjectRef::toStringName(const JSC::JSObject*, ExecState*)
+{
+ return "Object"_s;
+}
+
+}
+
Added: trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.h (0 => 246565)
--- trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class JSWeakObjectRef final : public JSNonFinalObject {
+public:
+ using Base = JSNonFinalObject;
+
+ DECLARE_EXPORT_INFO;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+ }
+
+ static JSWeakObjectRef* create(VM& vm, Structure* structure, JSObject* target)
+ {
+ JSWeakObjectRef* instance = new (NotNull, allocateCell<JSWeakObjectRef>(vm.heap)) JSWeakObjectRef(vm, structure);
+ instance->finishCreation(vm, target);
+ return instance;
+ }
+
+ JSObject* deref(VM& vm)
+ {
+ if (m_value && vm.currentWeakRefVersion() != m_lastAccessVersion) {
+ m_lastAccessVersion = vm.currentWeakRefVersion();
+ // Perform a GC barrier here so we rescan this object and keep the object alive if we wouldn't otherwise.
+ vm.heap.writeBarrier(this);
+ }
+
+ return m_value.get();
+ }
+
+ template<typename CellType, SubspaceAccess mode>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ return vm.weakObjectRefSpace<mode>();
+ }
+
+ void finalizeUnconditionally(VM&);
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+private:
+ JSWeakObjectRef(VM& vm, Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+
+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* value);
+
+ static String toStringName(const JSObject*, ExecState*);
+
+ uintptr_t m_lastAccessVersion;
+ WriteBarrier<JSObject> m_value;
+};
+
+} // namespace JSC
+
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (246564 => 246565)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -99,6 +99,7 @@
#include "JSStringHeapCellType.h"
#include "JSTemplateObjectDescriptor.h"
#include "JSWeakMap.h"
+#include "JSWeakObjectRef.h"
#include "JSWeakSet.h"
#include "JSWebAssembly.h"
#include "JSWebAssemblyCodeBlock.h"
@@ -1095,6 +1096,7 @@
if (m_onEachMicrotaskTick)
m_onEachMicrotaskTick(*this);
}
+ finalizeSynchronousJSExecution();
}
void QueuedTask::run()
@@ -1249,6 +1251,7 @@
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(proxyRevokeSpace, destructibleObjectHeapCellType.get(), ProxyRevoke)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakMapSpace, destructibleObjectHeapCellType.get(), JSWeakMap)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakSetSpace, destructibleObjectHeapCellType.get(), JSWeakSet)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakObjectRefSpace, cellHeapCellType.get(), JSWeakObjectRef)
#if JSC_OBJC_API_ENABLED
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(objCCallbackFunctionSpace, destructibleObjectHeapCellType.get(), ObjCCallbackFunction)
#endif
Modified: trunk/Source/_javascript_Core/runtime/VM.h (246564 => 246565)
--- trunk/Source/_javascript_Core/runtime/VM.h 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -403,6 +403,7 @@
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(errorInstanceSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(nativeStdFunctionSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(proxyRevokeSpace)
+ DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(weakObjectRefSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(weakSetSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(weakMapSpace)
#if ENABLE(WEBASSEMBLY)
@@ -887,7 +888,10 @@
void queueMicrotask(JSGlobalObject&, Ref<Microtask>&&);
JS_EXPORT_PRIVATE void drainMicrotasks();
- ALWAYS_INLINE void setOnEachMicrotaskTick(WTF::Function<void(VM&)>&& func) { m_onEachMicrotaskTick = WTFMove(func); }
+ void setOnEachMicrotaskTick(WTF::Function<void(VM&)>&& func) { m_onEachMicrotaskTick = WTFMove(func); }
+ void finalizeSynchronousJSExecution() { ASSERT(currentThreadIsHoldingAPILock()); m_currentWeakRefVersion++; }
+ uint64_t currentWeakRefVersion() const { return m_currentWeakRefVersion; }
+
void setGlobalConstRedeclarationShouldThrow(bool globalConstRedeclarationThrow) { m_globalConstRedeclarationShouldThrow = globalConstRedeclarationThrow; }
ALWAYS_INLINE bool globalConstRedeclarationShouldThrow() const { return m_globalConstRedeclarationShouldThrow; }
@@ -1057,6 +1061,7 @@
std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;
WTF::Function<void(VM&)> m_onEachMicrotaskTick;
+ uintptr_t m_currentWeakRefVersion { 0 };
#if ENABLE(JIT)
#if !ASSERT_DISABLED
Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.cpp (0 => 246565)
--- trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WeakObjectRefConstructor.h"
+
+#include "Error.h"
+#include "IteratorOperations.h"
+#include "JSCInlines.h"
+#include "JSGlobalObject.h"
+#include "JSObjectInlines.h"
+#include "JSWeakObjectRef.h"
+#include "WeakObjectRefPrototype.h"
+
+namespace JSC {
+
+const ClassInfo WeakObjectRefConstructor::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WeakObjectRefConstructor) };
+
+void WeakObjectRefConstructor::finishCreation(VM& vm, WeakObjectRefPrototype* prototype)
+{
+ Base::finishCreation(vm, "WeakRef"_s, NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
+ putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+}
+
+static EncodedJSValue JSC_HOST_CALL callWeakRef(ExecState*);
+static EncodedJSValue JSC_HOST_CALL constructWeakRef(ExecState*);
+
+WeakObjectRefConstructor::WeakObjectRefConstructor(VM& vm, Structure* structure)
+ : Base(vm, structure, callWeakRef, constructWeakRef)
+{
+}
+
+static EncodedJSValue JSC_HOST_CALL callWeakRef(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(exec, scope, "WeakRef"));
+}
+
+static EncodedJSValue JSC_HOST_CALL constructWeakRef(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (!exec->argument(0).isObject())
+ return throwVMTypeError(exec, scope, "First argument to WeakRef should be an object"_s);
+
+ JSGlobalObject* globalObject = jsCast<InternalFunction*>(exec->jsCallee())->globalObject(vm);
+ Structure* WeakObjectRefStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->weakObjectRefStructure());
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RELEASE_AND_RETURN(scope, JSValue::encode(JSWeakObjectRef::create(vm, WeakObjectRefStructure, exec->uncheckedArgument(0).getObject())));
+}
+
+}
+
Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.h (0 => 246565)
--- trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace JSC {
+
+class WeakObjectRefConstructor final : public InternalFunction {
+public:
+ using Base = InternalFunction;
+
+ static WeakObjectRefConstructor* create(VM& vm, Structure* structure, WeakObjectRefPrototype* prototype, GetterSetter*)
+ {
+ WeakObjectRefConstructor* constructor = new (NotNull, allocateCell<WeakObjectRefConstructor>(vm.heap)) WeakObjectRefConstructor(vm, structure);
+ constructor->finishCreation(vm, prototype);
+ return constructor;
+ }
+
+ DECLARE_INFO;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+ }
+
+private:
+ WeakObjectRefConstructor(VM&, Structure*);
+ void finishCreation(VM&, WeakObjectRefPrototype*);
+};
+
+static_assert(sizeof(WeakObjectRefConstructor) == sizeof(InternalFunction));
+
+}
Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.cpp (0 => 246565)
--- trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WeakObjectRefPrototype.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "JSWeakObjectRef.h"
+
+namespace JSC {
+
+const ClassInfo WeakObjectRefPrototype::s_info = { "WeakRef", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WeakObjectRefPrototype) };
+
+static EncodedJSValue JSC_HOST_CALL protoFuncWeakRefDeref(ExecState*);
+
+void WeakObjectRefPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(vm, info()));
+ didBecomePrototype();
+
+ // FIXME: It wouldn't be hard to make this an intrinsic.
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deref, protoFuncWeakRefDeref, static_cast<unsigned>(PropertyAttribute::DontEnum), 0);
+
+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WeakRef"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+}
+
+ALWAYS_INLINE static JSWeakObjectRef* getWeakRef(CallFrame* callFrame, JSValue value)
+{
+ VM& vm = callFrame->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (UNLIKELY(!value.isObject())) {
+ throwTypeError(callFrame, scope, "Called WeakRef function on non-object"_s);
+ return nullptr;
+ }
+
+ auto* ref = jsDynamicCast<JSWeakObjectRef*>(vm, asObject(value));
+ if (LIKELY(ref))
+ return ref;
+
+ throwTypeError(callFrame, scope, "Called WeakRef function on a non-WeakRef object"_s);
+ return nullptr;
+}
+
+EncodedJSValue JSC_HOST_CALL protoFuncWeakRefDeref(CallFrame* callFrame)
+{
+ VM& vm = callFrame->vm();
+ auto* ref = getWeakRef(callFrame, callFrame->thisValue());
+ if (!ref)
+ return JSValue::encode(jsUndefined());
+
+ auto* value = ref->deref(vm);
+ return value ? JSValue::encode(value) : JSValue::encode(jsNull());
+}
+
+}
Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.h (0 => 246565)
--- trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class WeakObjectRefPrototype final : public JSNonFinalObject {
+public:
+ using Base = JSNonFinalObject;
+
+ static WeakObjectRefPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+ {
+ WeakObjectRefPrototype* prototype = new (NotNull, allocateCell<WeakObjectRefPrototype>(vm.heap)) WeakObjectRefPrototype(vm, structure);
+ prototype->finishCreation(vm, globalObject);
+ return prototype;
+ }
+
+ DECLARE_INFO;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+ }
+
+private:
+ WeakObjectRefPrototype(VM& vm, Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+ void finishCreation(VM&, JSGlobalObject*);
+};
+
+}
+
Modified: trunk/Source/WebCore/ChangeLog (246564 => 246565)
--- trunk/Source/WebCore/ChangeLog 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/ChangeLog 2019-06-18 21:02:19 UTC (rev 246565)
@@ -1,3 +1,32 @@
+2019-06-18 Keith Miller <keith_mil...@apple.com>
+
+ Add support for WeakRef
+ https://bugs.webkit.org/show_bug.cgi?id=198710
+
+ Reviewed by Yusuke Suzuki.
+
+ We need to make sure the Web MicrotaskQueue notifies the JSC VM
+ that it has finished performing a microtask checkpoint. This lets
+ the JSC VM know it is safe to collect referenced WeakRefs. Since
+ there was no way to get the VM from the MicrotaskQueue I have
+ added a RefPtr to the queue's VM. For the main thread the VM lives
+ forever so is fine. For workers the queue and the VM share an
+ owner so this shouldn't matter either.
+
+ Tests: js/weakref-async-is-collected.html
+ js/weakref-eventually-collects-values.html
+ js/weakref-microtasks-dont-collect.html
+ js/weakref-weakset-consistency.html
+
+ * dom/Microtasks.cpp:
+ (WebCore::MicrotaskQueue::MicrotaskQueue):
+ (WebCore::MicrotaskQueue::mainThreadQueue):
+ (WebCore::MicrotaskQueue::performMicrotaskCheckpoint):
+ * dom/Microtasks.h:
+ (WebCore::MicrotaskQueue::vm const):
+ * workers/WorkerGlobalScope.cpp:
+ (WebCore::WorkerGlobalScope::WorkerGlobalScope):
+
2019-06-18 Kenneth Russell <k...@chromium.org>
Add preliminary ANGLE backend to WebCore
Modified: trunk/Source/WebCore/dom/Microtasks.cpp (246564 => 246565)
--- trunk/Source/WebCore/dom/Microtasks.cpp 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/dom/Microtasks.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -22,6 +22,7 @@
#include "config.h"
#include "Microtasks.h"
+#include "CommonVM.h"
#include "WorkerGlobalScope.h"
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
@@ -34,8 +35,9 @@
queue.remove(*this);
}
-MicrotaskQueue::MicrotaskQueue()
- : m_timer(*this, &MicrotaskQueue::timerFired)
+MicrotaskQueue::MicrotaskQueue(JSC::VM& vm)
+ : m_vm(makeRef(vm))
+ , m_timer(*this, &MicrotaskQueue::timerFired)
{
}
@@ -44,7 +46,7 @@
MicrotaskQueue& MicrotaskQueue::mainThreadQueue()
{
ASSERT(isMainThread());
- static NeverDestroyed<MicrotaskQueue> queue;
+ static NeverDestroyed<MicrotaskQueue> queue(commonVM());
return queue;
}
@@ -87,6 +89,7 @@
return;
SetForScope<bool> change(m_performingMicrotaskCheckpoint, true);
+ JSC::JSLockHolder locker(vm());
Vector<std::unique_ptr<Microtask>> toKeep;
while (!m_microtaskQueue.isEmpty()) {
@@ -103,6 +106,7 @@
}
}
+ vm().finalizeSynchronousJSExecution();
m_microtaskQueue = WTFMove(toKeep);
}
Modified: trunk/Source/WebCore/dom/Microtasks.h (246564 => 246565)
--- trunk/Source/WebCore/dom/Microtasks.h 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/dom/Microtasks.h 2019-06-18 21:02:19 UTC (rev 246565)
@@ -72,19 +72,23 @@
WEBCORE_EXPORT static MicrotaskQueue& mainThreadQueue();
WEBCORE_EXPORT static MicrotaskQueue& contextQueue(ScriptExecutionContext&);
- WEBCORE_EXPORT MicrotaskQueue();
+ WEBCORE_EXPORT MicrotaskQueue(JSC::VM&);
WEBCORE_EXPORT ~MicrotaskQueue();
WEBCORE_EXPORT void append(std::unique_ptr<Microtask>&&);
WEBCORE_EXPORT void performMicrotaskCheckpoint();
+ JSC::VM& vm() const { return m_vm.get(); }
+
private:
WEBCORE_EXPORT void remove(const Microtask&);
void timerFired();
- bool m_performingMicrotaskCheckpoint = false;
+ bool m_performingMicrotaskCheckpoint { false };
Vector<std::unique_ptr<Microtask>> m_microtaskQueue;
+ // For the main thread the VM lives forever. For workers it's lifetime is tied to our owning WorkerGlobalScope. Regardless, we retain the VM here to be safe.
+ Ref<JSC::VM> m_vm;
// FIXME: Instead of a Timer, we should have a centralized Event Loop that calls performMicrotaskCheckpoint()
// on every iteration, implementing https://html.spec.whatwg.org/multipage/webappapis.html#processing-model-9
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (246564 => 246565)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2019-06-18 21:02:19 UTC (rev 246565)
@@ -64,7 +64,7 @@
, m_thread(thread)
, m_script(std::make_unique<WorkerScriptController>(this))
, m_inspectorController(std::make_unique<WorkerInspectorController>(*this))
- , m_microtaskQueue(std::make_unique<MicrotaskQueue>())
+ , m_microtaskQueue(std::make_unique<MicrotaskQueue>(m_script->vm()))
, m_isOnline(isOnline)
, m_shouldBypassMainWorldContentSecurityPolicy(shouldBypassMainWorldContentSecurityPolicy)
, m_eventQueue(*this)