// // JSCocoaFFIClosure.m // JSCocoa // // Created by Patrick Geiller on 29/07/08. // Copyright 2008 __MyCompanyName__. All rights reserved. // #import "JSCocoaFFIClosure.h" #import "JSCocoaController.h" #include // for mmap() @implementation JSCocoaFFIClosure // // Common closure function, calling back closure object // void closure_function(ffi_cif* cif, void* resp, void** args, void* userdata) { [(id)userdata calledByClosureWithArgs:args returnValue:resp]; } - (id)init { self = [super init]; argTypes = NULL; encodings = NULL; jsFunction = NULL; return self; } // // Cleanup : called by dealloc and finalize // - (void)cleanUp { if (encodings) [encodings release]; if (argTypes) free(argTypes); if (jsFunction) { JSValueUnprotect(ctx, jsFunction); [JSCocoaController downJSValueProtectCount]; } #if !TARGET_OS_IPHONE if (munmap(closure, sizeof(closure)) == -1) NSLog(@"ffi closure munmap failed"); #endif } - (void)dealloc { // NSLog(@"deallocing closure %p IMP=%p", self, closure); [self cleanUp]; [super dealloc]; } - (void)finalize { [self cleanUp]; [super finalize]; } - (void*)functionPointer { #if !TARGET_OS_IPHONE return closure; #else return NULL; #endif } // // Bind a js function to closure. We'll jsValueProtect that function from GC. // - (IMP)setJSFunction:(JSValueRef)fn inContext:(JSContextRef)context argumentEncodings:(NSMutableArray*)argumentEncodings objC:(BOOL)objC { #if !TARGET_OS_IPHONE if ([argumentEncodings count] == 0) return NULL; encodings = argumentEncodings; [encodings retain]; isObjC = objC; unsigned int i, argumentCount = (unsigned int)([argumentEncodings count]-1); argTypes = malloc(sizeof(ffi_type*)*argumentCount); for (i=0; i 0 && size < paddedSize && paddedSize == 4) { v = *(long*)returnValue; v = CFSwapInt32(v); *(long*)returnValue = v; } #endif } if (effectiveArgumentCount) free(args); if (exception) { @throw [NSException exceptionWithName:@"JSCocoa exception" reason:[[JSCocoaController controllerFromContext:ctx] formatJSException:exception] userInfo:nil]; } } @end