]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - API/ObjCCallbackFunction.mm
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / API / ObjCCallbackFunction.mm
index e0bd2d7336636fd035b0da2deb0c0a6e3f3271d0..c62b7319dafa6ce050cf43cc7ebc58cf8675bc7f 100644 (file)
@@ -30,7 +30,7 @@
 
 #import "APICallbackFunction.h"
 #import "APICast.h"
 
 #import "APICallbackFunction.h"
 #import "APICast.h"
-#import "APIShims.h"
+#import "DelayedReleaseScope.h"
 #import "Error.h"
 #import "JSCJSValueInlines.h"
 #import "JSCell.h"
 #import "Error.h"
 #import "JSCJSValueInlines.h"
 #import "JSCell.h"
@@ -128,7 +128,7 @@ private:
             return;
         }
 
             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;
     }
 
     Class m_class;
@@ -395,9 +395,8 @@ namespace JSC {
 
 class ObjCCallbackFunctionImpl {
 public:
 
 class ObjCCallbackFunctionImpl {
 public:
-    ObjCCallbackFunctionImpl(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr<CallbackArgument> arguments, PassOwnPtr<CallbackResult> result)
-        : m_context(context)
-        , m_type(type)
+    ObjCCallbackFunctionImpl(NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr<CallbackArgument> arguments, PassOwnPtr<CallbackResult> result)
+        : m_type(type)
         , m_instanceClass([instanceClass retain])
         , m_invocation(invocation)
         , m_arguments(arguments)
         , m_instanceClass([instanceClass retain])
         , m_invocation(invocation)
         , m_arguments(arguments)
@@ -406,28 +405,17 @@ public:
         ASSERT((type != CallbackInstanceMethod && type != CallbackInitMethod) || instanceClass);
     }
 
         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)
         // -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);
 
         [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;
     id wrappedBlock()
     {
         return m_type == CallbackBlock ? [m_invocation target] : nil;
@@ -453,7 +441,6 @@ public:
     String name();
 
 private:
     String name();
 
 private:
-    WeakContextRef m_context;
     CallbackType m_type;
     Class m_instanceClass;
     RetainPtr<NSInvocation> m_invocation;
     CallbackType m_type;
     Class m_instanceClass;
     RetainPtr<NSInvocation> 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.
     // (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<ObjCCallbackFunction*>(toJS(function));
     ObjCCallbackFunctionImpl* impl = callback->impl();
 
     ObjCCallbackFunction* callback = static_cast<ObjCCallbackFunction*>(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 {
 
     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);
         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)
 {
 
 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<ObjCCallbackFunction*>(toJS(constructor));
     ObjCCallbackFunctionImpl* impl = callback->impl();
 
     ObjCCallbackFunction* callback = static_cast<ObjCCallbackFunction*>(toJS(constructor));
     ObjCCallbackFunctionImpl* impl = callback->impl();
@@ -500,7 +483,7 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont
     CallbackData callbackData;
     JSValueRef result;
     @autoreleasepool {
     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);
         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)) {
         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;
         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) };
 
 
 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<ObjCCallbackFunctionImpl> impl)
-    : Base(globalObject, globalObject->objcCallbackFunctionStructure())
+ObjCCallbackFunction::ObjCCallbackFunction(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback functionCallback, JSObjectCallAsConstructorCallback constructCallback, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
+    : Base(vm, globalObject->objcCallbackFunctionStructure())
     , m_functionCallback(functionCallback)
     , m_constructCallback(constructCallback)
     , m_impl(impl)
     , 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)
 {
 
 void ObjCCallbackFunction::destroy(JSCell* cell)
 {
-    static_cast<ObjCCallbackFunction*>(cell)->ObjCCallbackFunction::~ObjCCallbackFunction();
+    ObjCCallbackFunction& function = *jsCast<ObjCCallbackFunction*>(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]) {
         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];
             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]) {
     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];
             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)
 {
 
 static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, const char* signatureWithObjcClasses)
 {
+    if (!signatureWithObjcClasses)
+        return nil;
+
     const char* position = signatureWithObjcClasses;
 
     OwnPtr<CallbackResult> result = adoptPtr(parseObjCType<ResultTypeDelegate>(position));
     const char* position = signatureWithObjcClasses;
 
     OwnPtr<CallbackResult> result = adoptPtr(parseObjCType<ResultTypeDelegate>(position));
@@ -684,8 +672,8 @@ static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvoc
     }
 
     JSC::ExecState* exec = toJS([context JSGlobalContextRef]);
     }
 
     JSC::ExecState* exec = toJS([context JSGlobalContextRef]);
-    JSC::APIEntryShim shim(exec);
-    OwnPtr<JSC::ObjCCallbackFunctionImpl> impl = adoptPtr(new JSC::ObjCCallbackFunctionImpl(context, invocation, type, instanceClass, arguments.release(), result.release()));
+    JSC::JSLockHolder locker(exec);
+    OwnPtr<JSC::ObjCCallbackFunctionImpl> 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()));
 }
 
     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)
 {
 
 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<JSC::ObjCCallbackFunction*>(toJS(object))->impl();
     if (!impl->isConstructible())
         return nil;
     JSC::ObjCCallbackFunctionImpl* impl = static_cast<JSC::ObjCCallbackFunction*>(toJS(object))->impl();
     if (!impl->isConstructible())