#import "APICallbackFunction.h"
#import "APICast.h"
-#import "APIShims.h"
+#import "DelayedReleaseScope.h"
#import "Error.h"
#import "JSCJSValueInlines.h"
#import "JSCell.h"
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 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)
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;
String name();
private:
- WeakContextRef m_context;
CallbackType m_type;
Class m_instanceClass;
RetainPtr<NSInvocation> m_invocation;
// (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();
- 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);
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();
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);
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;
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)
void ObjCCallbackFunction::destroy(JSCell* cell)
{
- static_cast<ObjCCallbackFunction*>(cell)->ObjCCallbackFunction::~ObjCCallbackFunction();
+ ObjCCallbackFunction& function = *jsCast<ObjCCallbackFunction*>(cell);
+ function.impl()->destroy(*Heap::heap(cell));
+ function.~ObjCCallbackFunction();
}
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];
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];
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));
}
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()));
}
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())