CFLog(kCFLogLevelNotice, CFSTR("_trace():%u"), __LINE__); \
} while (false)
+#define CYPoolTry { \
+ id _saved(nil); \
+ NSAutoreleasePool *_pool([[NSAutoreleasePool alloc] init]); \
+ @try
+#define CYPoolCatch(value) \
+ @catch (NSException *error) { \
+ _saved = [error retain]; \
+ @throw; \
+ return value; \
+ } @finally { \
+ [_pool release]; \
+ if (_saved != nil) \
+ [_saved autorelease]; \
+ } \
+}
+
static JSGlobalContextRef Context_;
static JSObjectRef System_;
}
};
-JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient = true) {
+JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
if (!transient)
object = [object retain];
jocData *data(new jocData(object, transient));
@interface NSObject (Cycript)
- (bool) cy$isUndefined;
- (NSString *) cy$toJSON;
-- (JSValueRef) cy$JSValueInContext:(JSContextRef)context;
+- (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient;
@end
@interface NSString (Cycript)
return [self description];
}
-- (JSValueRef) cy$JSValueInContext:(JSContextRef)context {
- return CYMakeInstance(context, self);
+- (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient {
+ return CYMakeInstance(context, self, transient);
}
@end
return @"undefined";
}
-- (JSValueRef) cy$JSValueInContext:(JSContextRef)context {
+- (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient {
return CYJSUndefined(context);
}
return [self class] != NSCFBoolean_ ? [self stringValue] : [self boolValue] ? @"true" : @"false";
}
-- (JSValueRef) cy$JSValueInContext:(JSContextRef)context {
+- (JSValueRef) cy$JSValueInContext:(JSContextRef)context transient:(bool)transient {
return [self class] != NSCFBoolean_ ? CYCastJSValue(context, [self doubleValue]) : CYCastJSValue(context, [self boolValue]);
}
return Context_;
}
+#define CYTry \
+ @try
#define CYCatch \
@catch (id error) { \
NSLog(@"e:%@", error); \
return CYCastJSValue(context, CYJSString(value));
}
-JSValueRef CYCastJSValue(JSContextRef context, id value) {
- return value == nil ? CYJSNull(context) : [value cy$JSValueInContext:context];
+JSValueRef CYCastJSValue(JSContextRef context, id value, bool transient = true) {
+ return value == nil ? CYJSNull(context) : [value cy$JSValueInContext:context transient:transient];
}
JSObjectRef CYCastJSObject(JSContextRef context, JSValueRef value) {
}
void CYThrow(JSContextRef context, id error, JSValueRef *exception) {
+ if (exception == NULL)
+ throw error;
*exception = CYCastJSValue(context, error);
}
@end
-CFStringRef CYCopyJSONString(JSContextRef context, JSValueRef value) { _pooled
- id object(CYCastNSObject(NULL, context, value));
- return reinterpret_cast<CFStringRef>([(object == nil ? @"null" : [object cy$toJSON]) retain]);
+CFStringRef CYCopyJSONString(JSContextRef context, JSValueRef value, JSValueRef *exception) {
+ CYTry {
+ CYPoolTry {
+ id object(CYCastNSObject(NULL, context, value));
+ return reinterpret_cast<CFStringRef>([(object == nil ? @"null" : [object cy$toJSON]) retain]);
+ } CYPoolCatch(NULL)
+ } CYCatch
}
-const char *CYPoolJSONString(apr_pool_t *pool, JSContextRef context, JSValueRef value) {
- NSString *json((NSString *) CYCopyJSONString(context, value));
- const char *string(CYPoolCString(pool, json));
- [json release];
- return string;
+const char *CYPoolJSONString(apr_pool_t *pool, JSContextRef context, JSValueRef value, JSValueRef *exception) {
+ if (NSString *json = (NSString *) CYCopyJSONString(context, value, exception)) {
+ const char *string(CYPoolCString(pool, json));
+ [json release];
+ return string;
+ } else return NULL;
}
static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1));
CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8"));
- CFStringRef json(CYCopyJSONString(CYGetJSContext(), result));
+ CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL));
CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL));
CFRelease(json);
}
static JSValueRef Instance_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
- @try {
+ CYTry {
CYPool pool;
NSString *name(CYCastNSString(pool, property));
NSLog(@"get:%@", name);
}
static bool Instance_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) {
- @try {
+ CYTry {
CYPool pool;
NSString *name(CYCastNSString(pool, property));
NSLog(@"set:%@", name);
}
static bool Instance_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
- @try {
+ CYTry {
CYPool pool;
NSString *name(CYCastNSString(pool, property));
NSLog(@"delete:%@", name);
}
static JSObjectRef Instance_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
jocData *data(reinterpret_cast<jocData *>(JSObjectGetPrivate(object)));
- return CYMakeInstance(context, [data->GetValue() alloc]);
+ return CYMakeInstance(context, [data->GetValue() alloc], true);
} CYCatch
}
break;
case sig::typename_P:
- value = CYMakeInstance(context, *reinterpret_cast<Class *>(data));
+ value = CYMakeInstance(context, *reinterpret_cast<Class *>(data), true);
break;
case sig::selector_P:
}
static JSValueRef CYCallFunction(JSContextRef context, size_t count, const JSValueRef *arguments, JSValueRef *exception, sig::Signature *signature, ffi_cif *cif, void (*function)()) {
- @try {
+ CYTry {
if (count != signature->count - 1)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to ffi function" userInfo:nil];
}
void Closure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
- NSLog(@"Closure()");
ffoData *data(reinterpret_cast<ffoData *>(arg));
JSContextRef context(data->context_);
}
static JSValueRef Global_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
- @try {
+ CYTry {
CYPool pool;
NSString *name(CYCastNSString(pool, property));
if (Class _class = NSClassFromString(name))
- return CYMakeInstance(context, _class);
+ return CYMakeInstance(context, _class, true);
if (NSMutableArray *entry = [Bridge_ objectForKey:name])
switch ([[entry objectAtIndex:0] intValue]) {
case 0:
}
static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
NSLog(@"%s", CYCastCString(context, arguments[0]));
return CYJSUndefined(context);
} CYCatch
}
static JSValueRef CYApplicationMain(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
CYPool pool;
NSString *name(CYCastNSObject(pool, context, arguments[0]));
int argc(*_NSGetArgc());
CYPool pool;
- @try {
+ CYTry {
if (count < 2)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"too few arguments to objc_msgSend" userInfo:nil];
Class _class(object_getClass(self));
if (Method method = class_getInstanceMethod(_class, _cmd))
type = method_getTypeEncoding(method);
- else { _pooled
- NSMethodSignature *method([self methodSignatureForSelector:_cmd]);
- if (method == nil)
- @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"unrecognized selector %s sent to object %p", sel_getName(_cmd), self] userInfo:nil];
- type = CYPoolCString(pool, [method _typeString]);
+ else {
+ CYPoolTry {
+ NSMethodSignature *method([self methodSignatureForSelector:_cmd]);
+ if (method == nil)
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"unrecognized selector %s sent to object %p", sel_getName(_cmd), self] userInfo:nil];
+ type = CYPoolCString(pool, [method _typeString]);
+ } CYPoolCatch(NULL)
}
} CYCatch
}
JSObjectRef Selector_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
if (count != 1)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Selector constructor" userInfo:nil];
const char *name(CYCastCString(context, arguments[0]));
}
JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
if (count != 2)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Functor constructor" userInfo:nil];
const char *type(CYCastCString(context, arguments[1]));
return Function_;
}
-static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { _pooled
- @try {
+static JSValueRef Instance_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+ CYTry {
jocData *data(reinterpret_cast<jocData *>(JSObjectGetPrivate(_this)));
- return CYCastJSValue(context, CYJSString([data->GetValue() description]));
+ NSString *description; CYPoolTry {
+ description = [data->GetValue() description];
+ } CYPoolCatch(NULL)
+ return CYCastJSValue(context, CYJSString(description));
} CYCatch
}
static JSValueRef Selector_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
selData *data(reinterpret_cast<selData *>(JSObjectGetPrivate(_this)));
return CYCastJSValue(context, sel_getName(data->GetValue()));
} CYCatch
}
static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- @try {
+ CYTry {
if (count != 2)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Selector.type" userInfo:nil];
CYPool pool;