X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/12899fa232562c774004a3a9d7d3149944dec712..2656c66b5b30d5597e842a751c7f19ad6c2fe31a:/API/ObjCCallbackFunction.mm?ds=sidebyside diff --git a/API/ObjCCallbackFunction.mm b/API/ObjCCallbackFunction.mm index e0bd2d7..c62b731 100644 --- a/API/ObjCCallbackFunction.mm +++ b/API/ObjCCallbackFunction.mm @@ -30,7 +30,7 @@ #import "APICallbackFunction.h" #import "APICast.h" -#import "APIShims.h" +#import "DelayedReleaseScope.h" #import "Error.h" #import "JSCJSValueInlines.h" #import "JSCell.h" @@ -128,7 +128,7 @@ private: return; } - *exception = toRef(JSC::createTypeError(toJS(contextRef), "Argument does not match Objective-C Class")); + *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("Argument does not match Objective-C Class"))); } Class m_class; @@ -395,9 +395,8 @@ namespace JSC { class ObjCCallbackFunctionImpl { public: - ObjCCallbackFunctionImpl(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr arguments, PassOwnPtr result) - : m_context(context) - , m_type(type) + ObjCCallbackFunctionImpl(NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr arguments, PassOwnPtr result) + : m_type(type) , m_instanceClass([instanceClass retain]) , m_invocation(invocation) , m_arguments(arguments) @@ -406,28 +405,17 @@ public: ASSERT((type != CallbackInstanceMethod && type != CallbackInitMethod) || instanceClass); } - ~ObjCCallbackFunctionImpl() + void destroy(Heap& heap) { - // We need to explicity release the target since we didn't call + // We need to explicitly release the target since we didn't call // -retainArguments on m_invocation (and we don't want to do so). if (m_type == CallbackBlock || m_type == CallbackClassMethod) - [[m_invocation.get() target] release]; + heap.releaseSoon(adoptNS([m_invocation.get() target])); [m_instanceClass release]; } JSValueRef call(JSContext *context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - JSContext *context() - { - return m_context.get(); - } - - void setContext(JSContext *context) - { - ASSERT(!m_context.get()); - m_context.set(context); - } - id wrappedBlock() { return m_type == CallbackBlock ? [m_invocation target] : nil; @@ -453,7 +441,6 @@ public: String name(); private: - WeakContextRef m_context; CallbackType m_type; Class m_instanceClass; RetainPtr m_invocation; @@ -467,20 +454,16 @@ static JSValueRef objCCallbackFunctionCallAsFunction(JSContextRef callerContext, // (1) We don't want to support the C-API's confusing drops-locks-once policy - should only drop locks if we can do so recursively. // (2) We're calling some JSC internals that require us to be on the 'inside' - e.g. createTypeError. // (3) We need to be locked (per context would be fine) against conflicting usage of the ObjCCallbackFunction's NSInvocation. - JSC::APIEntryShim entryShim(toJS(callerContext)); + JSC::JSLockHolder locker(toJS(callerContext)); ObjCCallbackFunction* callback = static_cast(toJS(function)); ObjCCallbackFunctionImpl* impl = callback->impl(); - JSContext *context = impl->context(); - if (!context) { - context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(toJS(callerContext)->lexicalGlobalObject()->globalExec())]; - impl->setContext(context); - } + JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(callback->globalObject()->globalExec())]; CallbackData callbackData; JSValueRef result; @autoreleasepool { - [context beginCallbackWithData:&callbackData thisValue:thisObject argumentCount:argumentCount arguments:arguments]; + [context beginCallbackWithData:&callbackData calleeValue:function thisValue:thisObject argumentCount:argumentCount arguments:arguments]; result = impl->call(context, thisObject, argumentCount, arguments, exception); if (context.exception) *exception = valueInternalValue(context.exception); @@ -491,7 +474,7 @@ static JSValueRef objCCallbackFunctionCallAsFunction(JSContextRef callerContext, static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerContext, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { - JSC::APIEntryShim entryShim(toJS(callerContext)); + JSC::JSLockHolder locker(toJS(callerContext)); ObjCCallbackFunction* callback = static_cast(toJS(constructor)); ObjCCallbackFunctionImpl* impl = callback->impl(); @@ -500,7 +483,7 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont CallbackData callbackData; JSValueRef result; @autoreleasepool { - [context beginCallbackWithData:&callbackData thisValue:nil argumentCount:argumentCount arguments:arguments]; + [context beginCallbackWithData:&callbackData calleeValue:constructor thisValue:nil argumentCount:argumentCount arguments:arguments]; result = impl->call(context, NULL, argumentCount, arguments, exception); if (context.exception) *exception = valueInternalValue(context.exception); @@ -512,7 +495,7 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont return 0; if (!JSValueIsObject(contextRef, result)) { - *exception = toRef(JSC::createTypeError(toJS(contextRef), "Objective-C blocks called as constructors must return an object.")); + *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("Objective-C blocks called as constructors must return an object."))); return 0; } return (JSObjectRef)result; @@ -520,8 +503,8 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ObjCCallbackFunction) }; -ObjCCallbackFunction::ObjCCallbackFunction(JSC::VM&, JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback functionCallback, JSObjectCallAsConstructorCallback constructCallback, PassOwnPtr impl) - : Base(globalObject, globalObject->objcCallbackFunctionStructure()) +ObjCCallbackFunction::ObjCCallbackFunction(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback functionCallback, JSObjectCallAsConstructorCallback constructCallback, PassOwnPtr impl) + : Base(vm, globalObject->objcCallbackFunctionStructure()) , m_functionCallback(functionCallback) , m_constructCallback(constructCallback) , m_impl(impl) @@ -537,7 +520,9 @@ ObjCCallbackFunction* ObjCCallbackFunction::create(JSC::VM& vm, JSC::JSGlobalObj void ObjCCallbackFunction::destroy(JSCell* cell) { - static_cast(cell)->ObjCCallbackFunction::~ObjCCallbackFunction(); + ObjCCallbackFunction& function = *jsCast(cell); + function.impl()->destroy(*Heap::heap(cell)); + function.~ObjCCallbackFunction(); } @@ -576,7 +561,7 @@ JSValueRef ObjCCallbackFunctionImpl::call(JSContext *context, JSObjectRef thisOb RELEASE_ASSERT(!thisObject); target = [m_instanceClass alloc]; if (!target || ![target isKindOfClass:m_instanceClass]) { - *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method")); + *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("self type check failed for Objective-C instance method"))); return JSValueMakeUndefined(contextRef); } [m_invocation setTarget:target]; @@ -586,7 +571,7 @@ JSValueRef ObjCCallbackFunctionImpl::call(JSContext *context, JSObjectRef thisOb case CallbackInstanceMethod: { target = tryUnwrapObjcObject(contextRef, thisObject); if (!target || ![target isKindOfClass:m_instanceClass]) { - *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method")); + *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("self type check failed for Objective-C instance method"))); return JSValueMakeUndefined(contextRef); } [m_invocation setTarget:target]; @@ -646,6 +631,9 @@ inline bool skipNumber(const char*& position) static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, const char* signatureWithObjcClasses) { + if (!signatureWithObjcClasses) + return nil; + const char* position = signatureWithObjcClasses; OwnPtr result = adoptPtr(parseObjCType(position)); @@ -684,8 +672,8 @@ static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvoc } JSC::ExecState* exec = toJS([context JSGlobalContextRef]); - JSC::APIEntryShim shim(exec); - OwnPtr impl = adoptPtr(new JSC::ObjCCallbackFunctionImpl(context, invocation, type, instanceClass, arguments.release(), result.release())); + JSC::JSLockHolder locker(exec); + OwnPtr impl = adoptPtr(new JSC::ObjCCallbackFunctionImpl(invocation, type, instanceClass, arguments.release(), result.release())); return toRef(JSC::ObjCCallbackFunction::create(exec->vm(), exec->lexicalGlobalObject(), impl->name(), impl.release())); } @@ -725,7 +713,7 @@ JSObjectRef objCCallbackFunctionForBlock(JSContext *context, id target) id tryUnwrapConstructor(JSObjectRef object) { - if (!toJS(object)->inherits(&JSC::ObjCCallbackFunction::s_info)) + if (!toJS(object)->inherits(JSC::ObjCCallbackFunction::info())) return nil; JSC::ObjCCallbackFunctionImpl* impl = static_cast(toJS(object))->impl(); if (!impl->isConstructible())