+struct CYData {
+ apr_pool_t *pool_;
+
+ virtual ~CYData() {
+ }
+
+ void *operator new(size_t size) {
+ apr_pool_t *pool;
+ apr_pool_create(&pool, NULL);
+ void *data(apr_palloc(pool, size));
+ reinterpret_cast<CYData *>(data)->pool_ = pool;
+ return data;;
+ }
+
+ static void Finalize(JSObjectRef object) {
+ CYData *data(reinterpret_cast<CYData *>(JSObjectGetPrivate(object)));
+ data->~CYData();
+ apr_pool_destroy(data->pool_);
+ }
+};
+
+struct Pointer_privateData :
+ CYData
+{
+ void *value_;
+ sig::Type type_;
+
+ Pointer_privateData(void *value) :
+ value_(value)
+ {
+ }
+};
+
+struct Functor_privateData : Pointer_privateData {
+ sig::Signature signature_;
+ ffi_cif cif_;
+
+ Functor_privateData(const char *type, void (*value)()) :
+ Pointer_privateData(reinterpret_cast<void *>(value))
+ {
+ sig::Parse(pool_, &signature_, type);
+ sig::sig_ffi_cif(pool_, &sig::ObjectiveC, &signature_, &cif_);
+ }
+};
+
+struct ffoData : Functor_privateData {
+ JSContextRef context_;
+ JSObjectRef function_;
+
+ ffoData(const char *type) :
+ Functor_privateData(type, NULL)
+ {
+ }
+};
+
+struct Selector_privateData : Pointer_privateData {
+ Selector_privateData(SEL value) :
+ Pointer_privateData(value)
+ {
+ }
+
+ SEL GetValue() const {
+ return reinterpret_cast<SEL>(value_);
+ }
+};
+
+struct Instance_privateData : Pointer_privateData {
+ bool transient_;
+
+ Instance_privateData(id value, bool transient) :
+ Pointer_privateData(value)
+ {
+ }
+
+ virtual ~Instance_privateData() {
+ if (!transient_)
+ [GetValue() release];
+ }
+
+ id GetValue() const {
+ return reinterpret_cast<id>(value_);
+ }
+};
+
+struct Struct_privateData : CYData {
+};
+
+JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
+ if (!transient)
+ object = [object retain];
+ Instance_privateData *data(new Instance_privateData(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);