Title: [217240] trunk/Source/_javascript_Core
Revision
217240
Author
[email protected]
Date
2017-05-22 12:48:38 -0700 (Mon, 22 May 2017)

Log Message

[Cocoa] An exported Objective C class’s prototype and constructor don't persist across JSContext deallocation
https://bugs.webkit.org/show_bug.cgi?id=167708

Reviewed by Geoffrey Garen.

This patch moves the Objective C wrapper map to the global object. In order to make this work the JSWrapperMap
class no longer holds a reference to the JSContext. Instead, the context must be provided when getting a wrapper.

Also, this patch fixes a "bug" where we would observe changes to the Object property on the global object when
creating a wrapper for NSObject.

* API/APICast.h:
(toJSGlobalObject):
* API/JSContext.mm:
(-[JSContext ensureWrapperMap]):
(-[JSContext initWithVirtualMachine:]):
(-[JSContext dealloc]):
(-[JSContext wrapperMap]):
(-[JSContext initWithGlobalContextRef:]):
(-[JSContext wrapperForObjCObject:]):
(-[JSContext wrapperForJSObject:]):
* API/JSWrapperMap.h:
* API/JSWrapperMap.mm:
(-[JSObjCClassInfo initForClass:]):
(-[JSObjCClassInfo allocateConstructorAndPrototypeInContext:]):
(-[JSObjCClassInfo wrapperForObject:inContext:]):
(-[JSObjCClassInfo constructorInContext:]):
(-[JSObjCClassInfo prototypeInContext:]):
(-[JSWrapperMap initWithGlobalContextRef:]):
(-[JSWrapperMap classInfoForClass:]):
(-[JSWrapperMap jsWrapperForObject:inContext:]):
(-[JSWrapperMap objcWrapperForJSValueRef:inContext:]):
(-[JSObjCClassInfo initWithContext:forClass:]): Deleted.
(-[JSObjCClassInfo allocateConstructorAndPrototype]): Deleted.
(-[JSObjCClassInfo wrapperForObject:]): Deleted.
(-[JSObjCClassInfo constructor]): Deleted.
(-[JSObjCClassInfo prototype]): Deleted.
(-[JSWrapperMap initWithContext:]): Deleted.
(-[JSWrapperMap jsWrapperForObject:]): Deleted.
(-[JSWrapperMap objcWrapperForJSValueRef:]): Deleted.
* API/tests/JSExportTests.mm:
(wrapperLifetimeIsTiedToGlobalObject):
(runJSExportTests):
* API/tests/testapi.mm:
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::wrapperMap):
(JSC::JSGlobalObject::setWrapperMap):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/APICast.h (217239 => 217240)


--- trunk/Source/_javascript_Core/API/APICast.h	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/API/APICast.h	2017-05-22 19:48:38 UTC (rev 217240)
@@ -60,6 +60,11 @@
     return reinterpret_cast<JSC::ExecState*>(c);
 }
 
+inline JSC::JSGlobalObject* toJSGlobalObject(JSGlobalContextRef context)
+{
+    return toJS(context)->lexicalGlobalObject();
+}
+
 inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v)
 {
     ASSERT_UNUSED(exec, exec);

Modified: trunk/Source/_javascript_Core/API/JSContext.mm (217239 => 217240)


--- trunk/Source/_javascript_Core/API/JSContext.mm	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/API/JSContext.mm	2017-05-22 19:48:38 UTC (rev 217240)
@@ -43,7 +43,6 @@
 @implementation JSContext {
     JSVirtualMachine *m_virtualMachine;
     JSGlobalContextRef m_context;
-    JSWrapperMap *m_wrapperMap;
     JSC::Strong<JSC::JSObject> m_exception;
 }
 
@@ -52,6 +51,12 @@
     return m_context;
 }
 
+- (void)ensureWrapperMap
+{
+    if (!toJS([self JSGlobalContextRef])->lexicalGlobalObject()->wrapperMap())
+        [[JSWrapperMap alloc] initWithGlobalContextRef:[self JSGlobalContextRef]];
+}
+
 - (instancetype)init
 {
     return [self initWithVirtualMachine:[[[JSVirtualMachine alloc] init] autorelease]];
@@ -65,12 +70,12 @@
 
     m_virtualMachine = [virtualMachine retain];
     m_context = JSGlobalContextCreateInGroup(getGroupFromVirtualMachine(virtualMachine), 0);
-    m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self];
 
     self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
         context.exception = exceptionValue;
     };
 
+    [self ensureWrapperMap];
     [m_virtualMachine addContext:self forGlobalContextRef:m_context];
 
     return self;
@@ -79,7 +84,6 @@
 - (void)dealloc
 {
     m_exception.clear();
-    [m_wrapperMap release];
     JSGlobalContextRelease(m_context);
     [m_virtualMachine release];
     [_exceptionHandler release];
@@ -125,7 +129,7 @@
 
 - (JSWrapperMap *)wrapperMap
 {
-    return m_wrapperMap;
+    return toJS(m_context)->lexicalGlobalObject()->wrapperMap();
 }
 
 - (JSValue *)globalObject
@@ -258,7 +262,7 @@
     m_virtualMachine = [[JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&globalObject->vm())] retain];
     ASSERT(m_virtualMachine);
     m_context = JSGlobalContextRetain(context);
-    m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self];
+    [self ensureWrapperMap];
 
     self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
         context.exception = exceptionValue;
@@ -309,13 +313,13 @@
 - (JSValue *)wrapperForObjCObject:(id)object
 {
     JSC::JSLockHolder locker(toJS(m_context));
-    return [m_wrapperMap jsWrapperForObject:object];
+    return [[self wrapperMap] jsWrapperForObject:object inContext:self];
 }
 
 - (JSValue *)wrapperForJSObject:(JSValueRef)value
 {
     JSC::JSLockHolder locker(toJS(m_context));
-    return [m_wrapperMap objcWrapperForJSValueRef:value];
+    return [[self wrapperMap] objcWrapperForJSValueRef:value inContext:self];
 }
 
 + (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext

Modified: trunk/Source/_javascript_Core/API/JSWrapperMap.h (217239 => 217240)


--- trunk/Source/_javascript_Core/API/JSWrapperMap.h	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/API/JSWrapperMap.h	2017-05-22 19:48:38 UTC (rev 217240)
@@ -31,11 +31,11 @@
 
 @interface JSWrapperMap : NSObject
 
-- (id)initWithContext:(JSContext *)context;
+- (id)initWithGlobalContextRef:(JSGlobalContextRef)context;
 
-- (JSValue *)jsWrapperForObject:(id)object;
+- (JSValue *)jsWrapperForObject:(id)object inContext:(JSContext *)context;
 
-- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value;
+- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value inContext:(JSContext *)context;
 
 @end
 

Modified: trunk/Source/_javascript_Core/API/JSWrapperMap.mm (217239 => 217240)


--- trunk/Source/_javascript_Core/API/JSWrapperMap.mm	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/API/JSWrapperMap.mm	2017-05-22 19:48:38 UTC (rev 217240)
@@ -35,6 +35,7 @@
 #import "JSWrapperMap.h"
 #import "ObjCCallbackFunction.h"
 #import "ObjcRuntimeExtras.h"
+#import "ObjectConstructor.h"
 #import "WeakGCMap.h"
 #import "WeakGCMapInlines.h"
 #import <wtf/Vector.h>
@@ -363,7 +364,6 @@
 }
 
 @interface JSObjCClassInfo : NSObject {
-    JSContext *m_context;
     Class m_class;
     bool m_block;
     JSClassRef m_classRef;
@@ -371,16 +371,16 @@
     JSC::Weak<JSC::JSObject> m_constructor;
 }
 
-- (id)initWithContext:(JSContext *)context forClass:(Class)cls;
-- (JSC::JSObject *)wrapperForObject:(id)object;
-- (JSC::JSObject *)constructor;
-- (JSC::JSObject *)prototype;
+- (id)initForClass:(Class)cls;
+- (JSC::JSObject *)wrapperForObject:(id)object inContext:(JSContext *)context;
+- (JSC::JSObject *)constructorInContext:(JSContext *)context;
+- (JSC::JSObject *)prototypeInContext:(JSContext *)context;
 
 @end
 
 @implementation JSObjCClassInfo
 
-- (id)initWithContext:(JSContext *)context forClass:(Class)cls
+- (id)initForClass:(Class)cls
 {
     self = [super init];
     if (!self)
@@ -387,7 +387,6 @@
         return nil;
 
     const char* className = class_getName(cls);
-    m_context = context;
     m_class = cls;
     m_block = [cls isSubclassOfClass:getNSBlockClass()];
     JSClassDefinition definition;
@@ -458,9 +457,9 @@
 
 typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
 
-- (ConstructorPrototypePair)allocateConstructorAndPrototype
+- (ConstructorPrototypePair)allocateConstructorAndPrototypeInContext:(JSContext *)context
 {
-    JSObjCClassInfo* superClassInfo = [m_context.wrapperMap classInfoForClass:class_getSuperclass(m_class)];
+    JSObjCClassInfo* superClassInfo = [context.wrapperMap classInfoForClass:class_getSuperclass(m_class)];
 
     ASSERT(!m_constructor || !m_prototype);
     ASSERT((m_class == [NSObject class]) == !superClassInfo);
@@ -469,39 +468,36 @@
     JSC::JSObject* jsConstructor = m_constructor.get();
 
     if (!superClassInfo) {
-        JSContextRef cContext = [m_context JSGlobalContextRef];
-        JSValue *constructor = m_context[@"Object"];
+        JSC::JSGlobalObject* globalObject = toJSGlobalObject([context JSGlobalContextRef]);
         if (!jsConstructor)
-            jsConstructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
+            jsConstructor = globalObject->objectConstructor();
 
-        if (!jsPrototype) {
-            JSValue *prototype = constructor[@"prototype"];
-            jsPrototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
-        }
+        if (!jsPrototype)
+            jsPrototype = globalObject->objectPrototype();
     } else {
         const char* className = class_getName(m_class);
 
         // Create or grab the prototype/constructor pair.
         if (!jsPrototype)
-            jsPrototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]);
+            jsPrototype = objectWithCustomBrand(context, [NSString stringWithFormat:@"%sPrototype", className]);
 
         if (!jsConstructor)
-            jsConstructor = allocateConstructorForCustomClass(m_context, className, m_class);
+            jsConstructor = allocateConstructorForCustomClass(context, className, m_class);
 
-        JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:m_context];
-        JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:m_context];
+        JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:context];
+        JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:context];
         putNonEnumerable(prototype, @"constructor", constructor);
         putNonEnumerable(constructor, @"prototype", prototype);
 
         Protocol *exportProtocol = getJSExportProtocol();
         forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol){
-            copyPrototypeProperties(m_context, m_class, protocol, prototype);
-            copyMethodsToObject(m_context, m_class, protocol, NO, constructor);
+            copyPrototypeProperties(context, m_class, protocol, prototype);
+            copyMethodsToObject(context, m_class, protocol, NO, constructor);
         });
 
         // Set [Prototype].
-        JSC::JSObject* superClassPrototype = [superClassInfo prototype];
-        JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(jsPrototype), toRef(superClassPrototype));
+        JSC::JSObject* superClassPrototype = [superClassInfo prototypeInContext:context];
+        JSObjectSetPrototype([context JSGlobalContextRef], toRef(jsPrototype), toRef(superClassPrototype));
     }
 
     m_prototype = jsPrototype;
@@ -509,14 +505,14 @@
     return ConstructorPrototypePair(jsConstructor, jsPrototype);
 }
 
-- (JSC::JSObject*)wrapperForObject:(id)object
+- (JSC::JSObject*)wrapperForObject:(id)object inContext:(JSContext *)context
 {
     ASSERT([object isKindOfClass:m_class]);
     ASSERT(m_block == [object isKindOfClass:getNSBlockClass()]);
     if (m_block) {
-        if (JSObjectRef method = objCCallbackFunctionForBlock(m_context, object)) {
-            JSValue *constructor = [JSValue valueWithJSValueRef:method inContext:m_context];
-            JSValue *prototype = [JSValue valueWithNewObjectInContext:m_context];
+        if (JSObjectRef method = objCCallbackFunctionForBlock(context, object)) {
+            JSValue *constructor = [JSValue valueWithJSValueRef:method inContext:context];
+            JSValue *prototype = [JSValue valueWithNewObjectInContext:context];
             putNonEnumerable(constructor, @"prototype", prototype);
             putNonEnumerable(prototype, @"constructor", constructor);
             return toJS(method);
@@ -523,27 +519,27 @@
         }
     }
 
-    JSC::JSObject* prototype = [self prototype];
+    JSC::JSObject* prototype = [self prototypeInContext:context];
 
-    JSC::JSObject* wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object);
-    JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(wrapper), toRef(prototype));
+    JSC::JSObject* wrapper = makeWrapper([context JSGlobalContextRef], m_classRef, object);
+    JSObjectSetPrototype([context JSGlobalContextRef], toRef(wrapper), toRef(prototype));
     return wrapper;
 }
 
-- (JSC::JSObject*)constructor
+- (JSC::JSObject*)constructorInContext:(JSContext *)context
 {
     JSC::JSObject* constructor = m_constructor.get();
     if (!constructor)
-        constructor = [self allocateConstructorAndPrototype].first;
+        constructor = [self allocateConstructorAndPrototypeInContext:context].first;
     ASSERT(!!constructor);
     return constructor;
 }
 
-- (JSC::JSObject*)prototype
+- (JSC::JSObject*)prototypeInContext:(JSContext *)context
 {
     JSC::JSObject* prototype = m_prototype.get();
     if (!prototype)
-        prototype = [self allocateConstructorAndPrototype].second;
+        prototype = [self allocateConstructorAndPrototypeInContext:context].second;
     ASSERT(!!prototype);
     return prototype;
 }
@@ -551,13 +547,12 @@
 @end
 
 @implementation JSWrapperMap {
-    JSContext *m_context;
     NSMutableDictionary *m_classMap;
     std::unique_ptr<JSC::WeakGCMap<id, JSC::JSObject>> m_cachedJSWrappers;
     NSMapTable *m_cachedObjCWrappers;
 }
 
-- (id)initWithContext:(JSContext *)context
+- (id)initWithGlobalContextRef:(JSGlobalContextRef)context
 {
     self = [super init];
     if (!self)
@@ -567,9 +562,10 @@
     NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
     m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
 
-    m_cachedJSWrappers = std::make_unique<JSC::WeakGCMap<id, JSC::JSObject>>(toJS([context JSGlobalContextRef])->vm());
+    m_cachedJSWrappers = std::make_unique<JSC::WeakGCMap<id, JSC::JSObject>>(toJS(context)->vm());
 
-    m_context = context;
+    ASSERT(!toJSGlobalObject(context)->wrapperMap());
+    toJSGlobalObject(context)->setWrapperMap(self);
     m_classMap = [[NSMutableDictionary alloc] init];
     return self;
 }
@@ -594,20 +590,21 @@
     if ('_' == *class_getName(cls))
         return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)];
 
-    return m_classMap[cls] = [[[JSObjCClassInfo alloc] initWithContext:m_context forClass:cls] autorelease];
+    return m_classMap[cls] = [[[JSObjCClassInfo alloc] initForClass:cls] autorelease];
 }
 
-- (JSValue *)jsWrapperForObject:(id)object
+- (JSValue *)jsWrapperForObject:(id)object inContext:(JSContext *)context
 {
+    ASSERT(toJSGlobalObject([context JSGlobalContextRef])->wrapperMap() == self);
     JSC::JSObject* jsWrapper = m_cachedJSWrappers->get(object);
     if (jsWrapper)
-        return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
+        return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:context];
 
     if (class_isMetaClass(object_getClass(object)))
-        jsWrapper = [[self classInfoForClass:(Class)object] constructor];
+        jsWrapper = [[self classInfoForClass:(Class)object] constructorInContext:context];
     else {
         JSObjCClassInfo* classInfo = [self classInfoForClass:[object class]];
-        jsWrapper = [classInfo wrapperForObject:object];
+        jsWrapper = [classInfo wrapperForObject:object inContext:context];
     }
 
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105891
@@ -616,14 +613,15 @@
     // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated _javascript_ objects,
     //     but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
     m_cachedJSWrappers->set(object, jsWrapper);
-    return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
+    return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:context];
 }
 
-- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value
+- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value inContext:context
 {
+    ASSERT(toJSGlobalObject([context JSGlobalContextRef])->wrapperMap() == self);
     JSValue *wrapper = static_cast<JSValue *>(NSMapGet(m_cachedObjCWrappers, value));
     if (!wrapper) {
-        wrapper = [[[JSValue alloc] initWithValue:value inContext:m_context] autorelease];
+        wrapper = [[[JSValue alloc] initWithValue:value inContext:context] autorelease];
         NSMapInsert(m_cachedObjCWrappers, value, wrapper);
     }
     return wrapper;

Modified: trunk/Source/_javascript_Core/API/tests/JSExportTests.mm (217239 => 217240)


--- trunk/Source/_javascript_Core/API/tests/JSExportTests.mm	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/API/tests/JSExportTests.mm	2017-05-22 19:48:38 UTC (rev 217240)
@@ -125,6 +125,46 @@
 }
 @end
 
+@protocol AJSExport <JSExport>
+- (instancetype)init;
+@end
+
+@interface A : NSObject <AJSExport>
+@end
+
+@implementation A
+@end
+
+static void wrapperLifetimeIsTiedToGlobalObject()
+{
+    JSGlobalContextRef contextRef;
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        contextRef = JSGlobalContextRetain(context.JSGlobalContextRef);
+        context[@"A"] = A.class;
+        checkResult(@"Initial wrapper's constructor is itself", [[context evaluateScript:@"new A().constructor === A"] toBool]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [JSContext contextWithJSGlobalContextRef:contextRef];
+        checkResult(@"New context's wrapper's constructor is itself", [[context evaluateScript:@"new A().constructor === A"] toBool]);
+    }
+
+    JSGlobalContextRelease(contextRef);
+}
+
+static void wrapperForNSObjectisObject()
+{
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        context[@"Object"] = [[NSNull alloc] init];
+        context.exception = nil;
+
+        context[@"A"] = NSObject.class;
+        NSLog(@"here: %@", [context exception]);
+    }
+}
+
 void runJSExportTests()
 {
     @autoreleasepool {
@@ -132,6 +172,8 @@
         [JSExportTests exportInstanceMethodWithClassProtocolTest];
         [JSExportTests exportDynamicallyGeneratedProtocolTest];
     }
+    wrapperLifetimeIsTiedToGlobalObject();
+    wrapperForNSObjectisObject();
 }
 
 #endif // JSC_OBJC_API_ENABLED

Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (217239 => 217240)


--- trunk/Source/_javascript_Core/API/tests/testapi.mm	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm	2017-05-22 19:48:38 UTC (rev 217240)
@@ -512,6 +512,8 @@
 
 static void testObjectiveCAPIMain()
 {
+    runJSExportTests();
+
     @autoreleasepool {
         JSVirtualMachine* vm = [[JSVirtualMachine alloc] init];
         JSContext* context = [[JSContext alloc] initWithVirtualMachine:vm];
@@ -1468,7 +1470,7 @@
 
         checkResult(@"Ran code in five concurrent VMs that GC'd", ok);
     }
-    
+
     currentThisInsideBlockGetterTest();
     runDateTests();
     runJSExportTests();
@@ -1507,6 +1509,7 @@
     checkResult(@"Negative number maintained its original value", [[result toString] isEqualToString:@"-1"]);
 }
 
+
 void testObjectiveCAPI()
 {
     NSLog(@"Testing Objective-C API");

Modified: trunk/Source/_javascript_Core/ChangeLog (217239 => 217240)


--- trunk/Source/_javascript_Core/ChangeLog	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-05-22 19:48:38 UTC (rev 217240)
@@ -1,3 +1,53 @@
+2017-05-22  Keith Miller  <[email protected]>
+
+        [Cocoa] An exported Objective C class’s prototype and constructor don't persist across JSContext deallocation
+        https://bugs.webkit.org/show_bug.cgi?id=167708
+
+        Reviewed by Geoffrey Garen.
+
+        This patch moves the Objective C wrapper map to the global object. In order to make this work the JSWrapperMap
+        class no longer holds a reference to the JSContext. Instead, the context must be provided when getting a wrapper.
+
+        Also, this patch fixes a "bug" where we would observe changes to the Object property on the global object when
+        creating a wrapper for NSObject.
+
+        * API/APICast.h:
+        (toJSGlobalObject):
+        * API/JSContext.mm:
+        (-[JSContext ensureWrapperMap]):
+        (-[JSContext initWithVirtualMachine:]):
+        (-[JSContext dealloc]):
+        (-[JSContext wrapperMap]):
+        (-[JSContext initWithGlobalContextRef:]):
+        (-[JSContext wrapperForObjCObject:]):
+        (-[JSContext wrapperForJSObject:]):
+        * API/JSWrapperMap.h:
+        * API/JSWrapperMap.mm:
+        (-[JSObjCClassInfo initForClass:]):
+        (-[JSObjCClassInfo allocateConstructorAndPrototypeInContext:]):
+        (-[JSObjCClassInfo wrapperForObject:inContext:]):
+        (-[JSObjCClassInfo constructorInContext:]):
+        (-[JSObjCClassInfo prototypeInContext:]):
+        (-[JSWrapperMap initWithGlobalContextRef:]):
+        (-[JSWrapperMap classInfoForClass:]):
+        (-[JSWrapperMap jsWrapperForObject:inContext:]):
+        (-[JSWrapperMap objcWrapperForJSValueRef:inContext:]):
+        (-[JSObjCClassInfo initWithContext:forClass:]): Deleted.
+        (-[JSObjCClassInfo allocateConstructorAndPrototype]): Deleted.
+        (-[JSObjCClassInfo wrapperForObject:]): Deleted.
+        (-[JSObjCClassInfo constructor]): Deleted.
+        (-[JSObjCClassInfo prototype]): Deleted.
+        (-[JSWrapperMap initWithContext:]): Deleted.
+        (-[JSWrapperMap jsWrapperForObject:]): Deleted.
+        (-[JSWrapperMap objcWrapperForJSValueRef:]): Deleted.
+        * API/tests/JSExportTests.mm:
+        (wrapperLifetimeIsTiedToGlobalObject):
+        (runJSExportTests):
+        * API/tests/testapi.mm:
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::wrapperMap):
+        (JSC::JSGlobalObject::setWrapperMap):
+
 2017-05-22  Filip Pizlo  <[email protected]>
 
         FTL stack overflow handling should not assume that B3 never selects callee-saves in the prologue

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (217239 => 217240)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2017-05-22 19:44:54 UTC (rev 217239)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2017-05-22 19:48:38 UTC (rev 217240)
@@ -45,9 +45,11 @@
 #include <_javascript_Core/JSBase.h>
 #include <array>
 #include <wtf/HashSet.h>
+#include <wtf/RetainPtr.h>
 
 struct OpaqueJSClass;
 struct OpaqueJSClassContextData;
+OBJC_CLASS JSWrapperMap;
 
 namespace Inspector {
 class JSGlobalObjectInspectorController;
@@ -829,6 +831,11 @@
 
     bool needsSiteSpecificQuirks() const { return m_needsSiteSpecificQuirks; }
 
+#if JSC_OBJC_API_ENABLED
+    JSWrapperMap* wrapperMap() const { return m_wrapperMap.get(); }
+    void setWrapperMap(JSWrapperMap* map) { m_wrapperMap = map; }
+#endif
+
 protected:
     struct GlobalPropertyInfo {
         GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
@@ -858,6 +865,9 @@
     JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
 
     bool m_needsSiteSpecificQuirks { false };
+#if JSC_OBJC_API_ENABLED
+    RetainPtr<JSWrapperMap> m_wrapperMap;
+#endif
 };
 
 JSGlobalObject* asGlobalObject(JSValue);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to