Modified: trunk/Source/_javascript_Core/API/JSWrapperMap.mm (161563 => 161564)
--- trunk/Source/_javascript_Core/API/JSWrapperMap.mm 2014-01-09 19:00:48 UTC (rev 161563)
+++ trunk/Source/_javascript_Core/API/JSWrapperMap.mm 2014-01-09 19:14:55 UTC (rev 161564)
@@ -98,6 +98,16 @@
return result;
}
+static bool constructorHasInstance(JSContextRef ctx, JSObjectRef constructorRef, JSValueRef possibleInstance, JSValueRef*)
+{
+ JSC::ExecState* exec = toJS(ctx);
+ JSC::APIEntryShim entryShim(exec);
+
+ JSC::JSObject* constructor = toJS(constructorRef);
+ JSC::JSValue instance = toJS(exec, possibleInstance);
+ return JSC::JSObject::defaultHasInstance(exec, instance, constructor->get(exec, exec->propertyNames().prototype));
+}
+
static JSObjectRef makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject)
{
JSC::ExecState* exec = toJS(ctx);
@@ -126,6 +136,18 @@
return [JSValue valueWithJSValueRef:result inContext:context];
}
+static JSValue *constructorWithCustomBrand(JSContext *context, NSString *brand, Class cls)
+{
+ JSClassDefinition definition;
+ definition = kJSClassDefinitionEmpty;
+ definition.className = [brand UTF8String];
+ definition.hasInstance = constructorHasInstance;
+ JSClassRef classRef = JSClassCreate(&definition);
+ JSObjectRef result = makeWrapper([context JSGlobalContextRef], classRef, cls);
+ JSClassRelease(classRef);
+ return [JSValue valueWithJSValueRef:result inContext:context];
+}
+
// Look for @optional properties in the prototype containing a selector to property
// name mapping, separated by a __JS_EXPORT_AS__ delimiter.
static NSMutableDictionary *createRenameMap(Protocol *protocol, BOOL isInstanceMethod)
@@ -379,7 +401,7 @@
static JSValue *allocateConstructorForCustomClass(JSContext *context, const char* className, Class cls)
{
if (!supportsInitMethodConstructors())
- return objectWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls);
+ return constructorWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls);
// For each protocol that the class implements, gather all of the init family methods into a hash table.
__block HashMap<String, Protocol *> initTable;
@@ -425,7 +447,7 @@
JSObjectRef method = objCCallbackFunctionForInit(context, cls, initProtocol, initMethod, types);
return [JSValue valueWithJSValueRef:method inContext:context];
}
- return objectWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls);
+ return constructorWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls);
}
- (void)allocateConstructorAndPrototypeWithSuperClassInfo:(JSObjCClassInfo*)superClassInfo
Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (161563 => 161564)
--- trunk/Source/_javascript_Core/API/tests/testapi.mm 2014-01-09 19:00:48 UTC (rev 161563)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm 2014-01-09 19:14:55 UTC (rev 161564)
@@ -37,6 +37,12 @@
#if JSC_OBJC_API_ENABLED
+@interface UnexportedObject : NSObject
+@end
+
+@implementation UnexportedObject
+@end
+
@protocol ParentObject <JSExport>
@end
@@ -1216,6 +1222,16 @@
checkResult(@"fetched context.name was expected", ![fetchedName1 isEqualToString:fetchedName2]);
}
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"UnexportedObject"] = [UnexportedObject class];
+ context[@"makeObject"] = ^{
+ return [[UnexportedObject alloc] init];
+ };
+ JSValue *result = [context evaluateScript:@"(makeObject() instanceof UnexportedObject)"];
+ checkResult(@"makeObject() instanceof UnexportedObject", [result isBoolean] && [result toBool]);
+ }
+
currentThisInsideBlockGetterTest();
}
Modified: trunk/Source/_javascript_Core/ChangeLog (161563 => 161564)
--- trunk/Source/_javascript_Core/ChangeLog 2014-01-09 19:00:48 UTC (rev 161563)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-01-09 19:14:55 UTC (rev 161564)
@@ -1,3 +1,23 @@
+2014-01-09 Mark Hahnenberg <[email protected]>
+
+ Constructors for Objective-C classes do not work properly with instanceof
+ https://bugs.webkit.org/show_bug.cgi?id=126670
+
+ Reviewed by Oliver Hunt.
+
+ This bug is due to the fact that the JS constructors created for Objective-C classes via the JSC
+ API inherit from JSCallbackObject, which overrides hasInstance with its own customHasInstance.
+ JSCallbackObject::customHasInstance only checks the JSClassRefs for hasInstance callbacks.
+ If it doesn't find any callbacks, it returns false.
+
+ This patch adds a hasInstance callback to constructors created for Objective-C wrapper classes.
+
+ * API/JSWrapperMap.mm:
+ (constructorHasInstance):
+ (constructorWithCustomBrand):
+ (allocateConstructorForCustomClass):
+ * API/tests/testapi.mm:
+
2014-01-09 Joseph Pecoraro <[email protected]>
Web Inspector: Move InjectedScript classes into _javascript_Core