* TEST: JSContext *context = [[[JSContext alloc] init] autorelease]; [[JSValue valueWithInt32:42 inContext:context] toDictionary]; * ASSERT ASSERTION FAILED: isValidAllocation(bytes) /Volumes/Data/Code/safari/OpenSource/Source/JavaScriptCore/heap/Heap.h(467) : void *JSC::Heap::allocateWithoutDestructor(size_t) 1 0x10a94ce50 WTFCrash 2 0x10a1ce54b JSC::Heap::allocateWithoutDestructor(unsigned long) 3 0x10a4ea107 void* JSC::allocateCell<JSC::ErrorInstance>(JSC::Heap&, unsigned long) 4 0x10a4e986f void* JSC::allocateCell<JSC::ErrorInstance>(JSC::Heap&) 5 0x10a4e8ffb JSC::ErrorInstance::create(JSC::VM&, JSC::Structure*, WTF::String const&, WTF::Vector<JSC::StackFrame, 0ul, WTF::CrashOnOverflow>) 6 0x10a4e88f7 JSC::createTypeError(JSC::JSGlobalObject*, WTF::String const&) 7 0x10a4e8b35 JSC::createTypeError(JSC::ExecState*, WTF::String const&) 8 0x10a6d5af5 valueToDictionary(OpaqueJSContext*, OpaqueJSValue const*, OpaqueJSValue const**) 9 0x10a6d5921 -[JSValue toDictionary] 10 0x10a1b5f04 main 11 0x7fff8cbbf5f1 start Specifically, vm->identifierTable != wtfThreadData().currentIdentifierTable. My guess is that the ObjC API has to grab the APIEntryShim before it calls into JSC (via JSC::createTypeError). Most of the ObjC API uses the C API which already does this implicitly.
There are a number of create calls throughout the ObjC API. They will all need to be audited: shell> ack 'create.*?Error' API/*.mm API/JSValue.mm 784: *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray")); 800: *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSDictionary")); API/ObjCCallbackFunction.mm 132: *exception = toRef(JSC::createTypeError(toJS(contextRef), "Argument does not match Objective-C Class")); 456: // (2) We're calling some JSC internals that require us to be on the 'inside' - e.g. createTypeError. 499: *exception = toRef(JSC::createTypeError(toJS(contextRef), "Objective-C blocks called as constructors must return an object.")); 565: *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method")); 575: *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method"));
> My guess is that the ObjC API has to grab the APIEntryShim before it calls into JSC (via JSC::createTypeError). Right.
Created attachment 224250 [details] Patch
(In reply to comment #1) > There are a number of create calls throughout the ObjC API. They will all need to be audited: > > shell> ack 'create.*?Error' API/*.mm > API/JSValue.mm > 784: *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray")); > 800: *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSDictionary")); > > API/ObjCCallbackFunction.mm > 132: *exception = toRef(JSC::createTypeError(toJS(contextRef), "Argument does not match Objective-C Class")); > 456: // (2) We're calling some JSC internals that require us to be on the 'inside' - e.g. createTypeError. > 499: *exception = toRef(JSC::createTypeError(toJS(contextRef), "Objective-C blocks called as constructors must return an object.")); > 565: *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method")); > 575: *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method")); I audited the other call sites and other than these two they are all in places where we already hold the API lock.
Comment on attachment 224250 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=224250&action=review r=me > Source/JavaScriptCore/API/JSValue.mm:785 > *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray")); Nit: You could ASCIILiteral(...) the string being passed to createTypeError, since it is a string literal turning into a WTF::String. Is the lock needed by the "tryUnwrapObjcObject" call at the top of these functions? Otherwise this is identical to the local fix I had.
(In reply to comment #5) > (From update of attachment 224250 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=224250&action=review > > r=me > > > Source/JavaScriptCore/API/JSValue.mm:785 > > *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray")); > > Nit: You could ASCIILiteral(...) the string being passed to createTypeError, since it is a string literal turning into a WTF::String. > Will do. > Is the lock needed by the "tryUnwrapObjcObject" call at the top of these functions? > I don't think so. We don't create any objects in it, and the object is always reachable from the stack. If I missed something and we do need to take the shim for things that happen inside tryUnwrapObjcObject then the shim should probably go in there instead of out here.
Committed r164136: <http://trac.webkit.org/changeset/164136>