Bug 122124 - Assertion failure under -[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:] if no classes conform to JSExport
Summary: Assertion failure under -[JSObjCClassInfo allocateConstructorAndPrototypeWith...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: mitz
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2013-09-30 14:34 PDT by mitz
Modified: 2013-09-30 15:51 PDT (History)
3 users (show)

See Also:


Attachments
Define a class that conforms to the JSExport protocol in JavaScriptCore. (1.44 KB, patch)
2013-09-30 15:00 PDT, mitz
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description mitz 2013-09-30 14:34:53 PDT
<rdar://problem/15114974>

Defining an NSBlock-valued property on a JSValue in a program that doesn’t load any classes that conform to JSExport causes an assertion failure.

To reproduce, build and run this:

#import <JavaScriptCore/JavaScriptCore.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        JSContext *context = [[JSContext alloc] init];
        [[context globalObject] defineProperty:@"doSomething" descriptor:@{
            JSPropertyDescriptorValueKey : ^{ }
        }];
    }
    return 0;
}

* RESULTS
ASSERTION FAILED: target
Source/JavaScriptCore/API/ObjcRuntimeExtras.h(47) : void forEachProtocolImplementingProtocol(Class, Protocol *, void (^)(Protocol *))
1   0x1005d66f0 WTFCrash
2   0x1004120d0 forEachProtocolImplementingProtocol(objc_class*, Protocol*, void (Protocol*) block_pointer)
3   0x10040e92b -[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]
4   0x10040e0ab -[JSObjCClassInfo initWithContext:forClass:superClassInfo:]
5   0x10040ff2d -[JSWrapperMap classInfoForClass:]
6   0x10040fe5e -[JSWrapperMap classInfoForClass:]
7   0x10040fe5e -[JSWrapperMap classInfoForClass:]
8   0x10041008b -[JSWrapperMap jsWrapperForObject:]
9   0x100373d57 -[JSContext(Internal) wrapperForObjCObject:]
10  0x1003f868e objectToValueWithoutCopy(JSContext*, objc_object*)
11  0x1003f7ddf ObjcContainerConvertor::convert(objc_object*)
12  0x1003f3435 objectToValue(JSContext*, objc_object*)
13  0x1003f6016 -[JSValue invokeMethod:withArguments:]
14  0x1003f51d1 -[JSValue defineProperty:descriptor:]
15  0x100000e1f main
16  0x7fff878195fd start

* NOTES
This happens because objc_getProtocol("JSExport") returns nil. Note that getJSExportProtocol() caches this result, which means that if a class that conforms to JSExport is loaded (or registered dynamically) later, getJSExportProtocol() would still return nil. This seems like an actual correctness issue in production builds.
Comment 1 mitz 2013-09-30 15:00:08 PDT
Created attachment 213038 [details]
Define a class that conforms to the JSExport protocol in JavaScriptCore.
Comment 2 Darin Adler 2013-09-30 15:11:19 PDT
Is there a similar problem with the NSBlock class? If not, why not?
Comment 3 mitz 2013-09-30 15:23:02 PDT
(In reply to comment #2)
> Is there a similar problem with the NSBlock class? If not, why not?

No. the NSBlock class is defined in Core Foundation, which JavaScriptCore links against. The only reason getNSBlockClass() doesn’t use [NSBlock self] is that the class is not declared in a public header.
Comment 4 WebKit Commit Bot 2013-09-30 15:51:20 PDT
Comment on attachment 213038 [details]
Define a class that conforms to the JSExport protocol in JavaScriptCore.

Clearing flags on attachment: 213038

Committed r156684: <http://trac.webkit.org/changeset/156684>
Comment 5 WebKit Commit Bot 2013-09-30 15:51:22 PDT
All reviewed patches have been landed.  Closing bug.