+struct ptrData {
+ apr_pool_t *pool_;
+ void *value_;
+ sig::Type type_;
+
+ void *operator new(size_t size) {
+ apr_pool_t *pool;
+ apr_pool_create(&pool, NULL);
+ void *data(apr_palloc(pool, size));
+ reinterpret_cast<ptrData *>(data)->pool_ = pool;
+ return data;;
+ }
+
+ ptrData(void *value) :
+ value_(value)
+ {
+ }
+
+ virtual ~ptrData() {
+ }
+};
+
+struct ffiData : ptrData {
+ sig::Signature signature_;
+ ffi_cif cif_;
+
+ ffiData(const char *type, void (*value)()) :
+ ptrData(reinterpret_cast<void *>(value))
+ {
+ sig::Parse(pool_, &signature_, type);
+ sig::sig_ffi_cif(pool_, &sig::ObjectiveC, &signature_, &cif_);
+ }
+};
+
+struct ffoData : ffiData {
+ JSContextRef context_;
+ JSObjectRef function_;
+
+ ffoData(const char *type) :
+ ffiData(type, NULL)
+ {
+ }
+};
+
+struct selData : ptrData {
+ selData(SEL value) :
+ ptrData(value)
+ {
+ }
+
+ SEL GetValue() const {
+ return reinterpret_cast<SEL>(value_);
+ }
+};
+
+struct jocData : ptrData {
+ bool transient_;
+
+ jocData(id value, bool transient) :
+ ptrData(value)
+ {
+ }
+
+ virtual ~jocData() {
+ if (!transient_)
+ [GetValue() release];
+ }
+
+ id GetValue() const {
+ return reinterpret_cast<id>(value_);
+ }
+};
+
+JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient = true) {
+ if (!transient)
+ object = [object retain];
+ jocData *data(new jocData(object, transient));
+ return JSObjectMake(context, Instance_, data);
+}
+
+const char *CYPoolCString(apr_pool_t *pool, NSString *value) {
+ if (pool == NULL)
+ return [value UTF8String];
+ else {
+ size_t size([value maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1);
+ char *string(new(pool) char[size]);
+ if (![value getCString:string maxLength:size encoding:NSUTF8StringEncoding])
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"[NSString getCString:maxLength:encoding:] == NO" userInfo:nil];
+ return string;
+ }
+}
+
+JSValueRef CYCastJSValue(JSContextRef context, bool value) {
+ return JSValueMakeBoolean(context, value);
+}
+
+JSValueRef CYCastJSValue(JSContextRef context, double value) {
+ return JSValueMakeNumber(context, value);
+}
+
+#define CYCastJSValue_(Type_) \
+ JSValueRef CYCastJSValue(JSContextRef context, Type_ value) { \
+ return JSValueMakeNumber(context, static_cast<double>(value)); \
+ }
+
+CYCastJSValue_(int)
+CYCastJSValue_(unsigned int)
+CYCastJSValue_(long int)
+CYCastJSValue_(long unsigned int)
+CYCastJSValue_(long long int)
+CYCastJSValue_(long long unsigned int)
+
+JSValueRef CYJSUndefined(JSContextRef context) {
+ return JSValueMakeUndefined(context);