WebKit Bugzilla
Attachment 371736 Details for
Bug 198710
: Add support for WeakRef
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-198710-20190610153935.patch (text/plain), 43.76 KB, created by
Keith Miller
on 2019-06-10 06:39:36 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Keith Miller
Created:
2019-06-10 06:39:36 PDT
Size:
43.76 KB
patch
obsolete
>Subversion Revision: 246238 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 6b0d019eefb09d55c061850a76a8a94954011b77..da3d4f9ce23ecfe6f2e0e69ff62d4477fc7c9973 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,59 @@ >+2019-06-10 Keith Miller <keith_miller@apple.com> >+ >+ Add support for WeakRef >+ https://bugs.webkit.org/show_bug.cgi?id=198710 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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 tick. i.e. During synchronous JS execution >+ if we have observed the target of a WeakRef it cannot be collected. >+ >+ 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. >+ >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * heap/Heap.cpp: >+ (JSC::Heap::finalizeUnconditionalFinalizers): >+ * 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. >+ * runtime/WeakRefConstructor.h: Added. >+ > 2019-06-09 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] Use mergePrediction in ValuePow prediction propagation >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 6750a65b6e3a908f339b211ab3410b4d6039991d..b405a2a8a8257114a91333a57e6b4f7642f1603d 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -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,12 +3642,18 @@ > 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>"; }; > 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 */, >diff --git a/Source/JavaScriptCore/Sources.txt b/Source/JavaScriptCore/Sources.txt >index b8893ba8fcbc617d5381b5e6ea2434e905bec1e5..ecc21a25eafaf79c0759bea6200bb5209a6c2d2f 100644 >--- a/Source/JavaScriptCore/Sources.txt >+++ b/Source/JavaScriptCore/Sources.txt >@@ -873,6 +873,7 @@ runtime/JSTypedArrayViewConstructor.cpp > 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/Watchdog.cpp > runtime/WeakMapConstructor.cpp > runtime/WeakMapImpl.cpp > runtime/WeakMapPrototype.cpp >+runtime/WeakObjectRefConstructor.cpp >+runtime/WeakObjectRefPrototype.cpp > runtime/WeakSetConstructor.cpp > runtime/WeakSetPrototype.cpp > >diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp >index 6663b4f0d39ebbef9d270de03d2b5fc5e33d6482..f131bcb4d1219609d621f1bb4f795c70bf241b27 100644 >--- a/Source/JavaScriptCore/heap/Heap.cpp >+++ b/Source/JavaScriptCore/heap/Heap.cpp >@@ -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" >@@ -610,6 +611,8 @@ void Heap::finalizeUnconditionalFinalizers() > 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); > >diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h >index c06f7ec75c88bb99be64f498cce719917fca424a..ab203b506275f3adbcfcb3c2541d426f957c0a77 100644 >--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h >+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h >@@ -88,6 +88,7 @@ > macro(counters) \ > macro(day) \ > macro(defineProperty) \ >+ macro(deref) \ > macro(description) \ > macro(descriptions) \ > macro(detail) \ >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >index d2aab783e361d89555e7ccf05b6ec3e547d91fe5..3c98dfbaa7dd75393908c89ef4acc4d625fcff81 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >@@ -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 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { > 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 > */ >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h >index 451719568002f6baf69650b146afc125f180b1bf..02607c92748096b81399db4ebdec2e0b6bbc7974 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h >@@ -149,6 +149,7 @@ template<typename Watchpoint> class ObjectPropertyChangeAdaptiveWatchpoint; > 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) \ > >diff --git a/Source/JavaScriptCore/runtime/JSWeakObjectRef.cpp b/Source/JavaScriptCore/runtime/JSWeakObjectRef.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..1c46fafaff05db548e329f73cf2550c0a38e6979 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSWeakObjectRef.cpp >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2015-2016 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; >+} >+ >+} >+ >diff --git a/Source/JavaScriptCore/runtime/JSWeakObjectRef.h b/Source/JavaScriptCore/runtime/JSWeakObjectRef.h >new file mode 100644 >index 0000000000000000000000000000000000000000..ec730df835fd18afb5cfce1fe2428ce0e6cef7f6 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSWeakObjectRef.h >@@ -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 JSObject { >+public: >+ using Base = JSObject; >+ >+ 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 >+ >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 45fa20269215afeb7fa896575d65479fd3e70b8b..ab8f8960700c12f95088fcb9b4dfc96afae99fc4 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -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,10 +1096,12 @@ void VM::queueMicrotask(JSGlobalObject& globalObject, Ref<Microtask>&& task) > > void VM::drainMicrotasks() > { >+ finalizeSynchronousJSExecution(); > while (!m_microtaskQueue.isEmpty()) { > m_microtaskQueue.takeFirst()->run(); > if (m_onEachMicrotaskTick) > m_onEachMicrotaskTick(*this); >+ finalizeSynchronousJSExecution(); > } > } > >@@ -1254,6 +1257,7 @@ DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(nativeStdFunctionSpace, cellHeapCellType > 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 >diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h >index 11c87dfc74498f456e1f393a832625d260edefa1..84d14a06f663fe735020385198e3fba0abdcaf2e 100644 >--- a/Source/JavaScriptCore/runtime/VM.h >+++ b/Source/JavaScriptCore/runtime/VM.h >@@ -403,6 +403,7 @@ public: > 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) >@@ -879,7 +880,10 @@ public: > > 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; } > >@@ -1049,6 +1053,7 @@ private: > std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry; > > WTF::Function<void(VM&)> m_onEachMicrotaskTick; >+ uintptr_t m_currentWeakRefVersion { 0 }; > > #if ENABLE(JIT) > #if !ASSERT_DISABLED >diff --git a/Source/JavaScriptCore/runtime/WeakObjectRefConstructor.cpp b/Source/JavaScriptCore/runtime/WeakObjectRefConstructor.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..4b6b75e461e717560a90a0068396fc5baeeadc84 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/WeakObjectRefConstructor.cpp >@@ -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 "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()); >+ JSWeakObjectRef* WeakObjectRef = JSWeakObjectRef::create(vm, WeakObjectRefStructure, exec->uncheckedArgument(0).getObject()); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ return JSValue::encode(WeakObjectRef); >+} >+ >+} >+ >diff --git a/Source/JavaScriptCore/runtime/WeakObjectRefConstructor.h b/Source/JavaScriptCore/runtime/WeakObjectRefConstructor.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e9eadad1963c6eced776f806b0061df2c18b9eb2 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/WeakObjectRefConstructor.h >@@ -0,0 +1,53 @@ >+/* >+ * 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 : public InternalFunction { >+public: >+ typedef InternalFunction Base; >+ >+ 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*); >+}; >+ >+} >diff --git a/Source/JavaScriptCore/runtime/WeakObjectRefPrototype.cpp b/Source/JavaScriptCore/runtime/WeakObjectRefPrototype.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..035ceb2dde5d5e3f90763551ba94c2b8aa62d079 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/WeakObjectRefPrototype.cpp >@@ -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()); >+} >+ >+} >diff --git a/Source/JavaScriptCore/runtime/WeakObjectRefPrototype.h b/Source/JavaScriptCore/runtime/WeakObjectRefPrototype.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b14941bc195cc6b5b67c5fdc738ebb4f109ab5e9 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/WeakObjectRefPrototype.h >@@ -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: >+ typedef JSNonFinalObject Base; >+ >+ 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*); >+}; >+ >+} >+ >diff --git a/Source/JavaScriptCore/runtime/WeakRefConstructor.h b/Source/JavaScriptCore/runtime/WeakRefConstructor.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5933e7613ad10ee6815c56e69a2f3eaeb14b1181 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/WeakRefConstructor.h >@@ -0,0 +1,53 @@ >+/* >+ * 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  à : public InternalFunction { >+public: >+ typedef InternalFunction Base; >+ >+ static WeakRefConstructor* create(VM& vm, Structure* structure, WeakObjectRefPrototype* prototype, GetterSetter*) >+ { >+ WeakRefConstructor* constructor = new (NotNull, allocateCell<WeakRefConstructor>(vm.heap)) WeakRefConstructor(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: >+ WeakRefConstructor(VM&, Structure*); >+ void finishCreation(VM&, WeakObjectRefPrototype*); >+} >+ >+} >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 9c5d57dda589cd37cda9a892bce413bada87320e..67403731c2f92abde44feaf6982b7fd3e63c5724 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,26 @@ >+2019-06-10 Keith Miller <keith_miller@apple.com> >+ >+ Add support for WeakRef >+ https://bugs.webkit.org/show_bug.cgi?id=198710 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/weak-ref-async-is-collected.js: Added. >+ (makeWeakRef): >+ (async.foo): >+ (async.test): >+ * stress/weak-ref-microtasks-dont-collect.js: Added. >+ (asyncTestStart.1.makeWeakRef): >+ (async.foo): >+ (async.test): >+ * stress/weakref-eventually-collects-values.js: Added. >+ (makeWeakRef): >+ (let.weakRefs.async.test): >+ * stress/weakref-weakset-consistency.js: Added. >+ (makeWeakRef): >+ (async.foo): >+ (async.test): >+ > 2019-06-09 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] Use mergePrediction in ValuePow prediction propagation >diff --git a/JSTests/stress/weak-ref-async-is-collected.js b/JSTests/stress/weak-ref-async-is-collected.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5b580466cb498c17b87a95c9c8c2beec84406b42 >--- /dev/null >+++ b/JSTests/stress/weak-ref-async-is-collected.js >@@ -0,0 +1,24 @@ >+asyncTestStart(1); >+function makeWeakRef() { return new WeakRef({foo: 1 }); } >+noInline(makeWeakRef); >+ >+let weakRefs = []; >+ >+async function* foo() { >+ let weak = makeWeakRef(); >+ await 2; >+ weakRefs.push(weak); >+} >+ >+async function test() { >+ for (let i = 0; i < 10000; 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 => print(e)); >diff --git a/JSTests/stress/weak-ref-microtasks-dont-collect.js b/JSTests/stress/weak-ref-microtasks-dont-collect.js >new file mode 100644 >index 0000000000000000000000000000000000000000..83102ec291f41c649a0caaafdab36339fc441130 >--- /dev/null >+++ b/JSTests/stress/weak-ref-microtasks-dont-collect.js >@@ -0,0 +1,29 @@ >+asyncTestStart(1) >+function makeWeakRef() { return new WeakRef({foo: 1 }); } >+noInline(makeWeakRef); >+ >+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 2; >+ weakRefs.push(weak); >+} >+ >+async function test() { >+ for (let i = 0; i < 10000; 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 => print(e)); >diff --git a/JSTests/stress/weakref-eventually-collects-values.js b/JSTests/stress/weakref-eventually-collects-values.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d692ca427db0705f8f5fc6054cffabc2ad76d869 >--- /dev/null >+++ b/JSTests/stress/weakref-eventually-collects-values.js >@@ -0,0 +1,23 @@ >+asyncTestStart(1); >+ >+function makeWeakRef() { return new WeakRef({foo: 1}); } >+ >+let weakRefs = [] >+ >+async function test() { >+ >+ for (let i = 0; i < 10000; i++) { >+ let weak = makeWeakRef(); >+ if (weak.deref().foo != 1) >+ throw new Error("weak ref was freed too early."); >+ weakRefs.push(weak); >+ } >+ await 1; >+ gc(); >+ >+ if (!weakRefs.find((weak) => weak.deref() === null)) >+ throw new Error("no weak ref was collected"); >+ asyncTestPassed(); >+} >+ >+test().catch(e => print(e)); >diff --git a/JSTests/stress/weakref-weakset-consistency.js b/JSTests/stress/weakref-weakset-consistency.js >new file mode 100644 >index 0000000000000000000000000000000000000000..4e8cc6e8845f227d8d95ba10bf978876159823ae >--- /dev/null >+++ b/JSTests/stress/weakref-weakset-consistency.js >@@ -0,0 +1,26 @@ >+asyncTestStart(1); >+function makeWeakRef() { return new WeakRef({foo: 1 }); } >+noInline(makeWeakRef); >+ >+let weakSet = new WeakSet(); >+let weakRefs = []; >+ >+async function* foo() { >+ let weak = makeWeakRef(); >+ weakSet.add(weak.deref()); >+ await 2; >+ weakRefs.push(weak); >+} >+ >+async function test() { >+ for (let i = 0; i < 10000; 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 => print(e));
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198710
:
371736
|
371952
|
371958
|
371959
|
371960
|
371961
|
371970
|
372038
|
372044
|
372046
|
372370