}
JSStringRef CYCopyJSString(CYUTF8String value) {
- // XXX: this is very wrong
+ // XXX: this is very wrong; it needs to convert to UTF16 and then create from there
return CYCopyJSString(value.data);
}
break;
default:
- // this test is designed to be "awewsome", generating neither warnings nor incorrect results
+ // this test is designed to be "awesome", generating neither warnings nor incorrect results
if (*value < 0x20 || *value >= 0x7f)
str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(uint8_t(*value));
else simple:
}
/* }}} */
-static JSGlobalContextRef Context_;
-
+static JSClassRef Context_;
static JSClassRef Functor_;
static JSClassRef Global_;
static JSClassRef Pointer_;
JSClassRef Type_privateData::Class_;
+struct Context :
+ CYData
+{
+ JSGlobalContextRef context_;
+
+ Context(JSGlobalContextRef context) :
+ context_(context)
+ {
+ }
+};
+
struct Pointer :
CYOwned
{
return object;
}
-JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, JSValueRef arguments[]) {
+JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, const JSValueRef arguments[]) {
JSValueRef exception(NULL);
JSValueRef value(JSObjectCallAsFunction(context, function, _this, count, arguments, &exception));
CYThrow(context, exception);
static JSValueRef Pointer_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
Pointer *internal(reinterpret_cast<Pointer *>(JSObjectGetPrivate(_this)));
- if (internal->length_ != _not(size_t))
- // XXX: maybe dynamically look up Array.toCYON?
- return Array_callAsFunction_toCYON(context, object, _this, count, arguments, exception);
- else {
+ if (internal->length_ != _not(size_t)) {
+ JSObjectRef Array(CYGetCachedObject(context, Array_s));
+ JSObjectRef toCYON(CYCastJSObject(context, CYGetProperty(context, Array, toCYON_s)));
+ return CYCallAsFunction(context, toCYON, _this, count, arguments);
+ } else {
char string[32];
sprintf(string, "%p", internal->value_);
return CYCastJSValue(context, string);
JSClassDefinition definition;
+ definition = kJSClassDefinitionEmpty;
+ definition.className = "Context";
+ definition.finalize = &CYFinalize;
+ Context_ = JSClassCreate(&definition);
+
definition = kJSClassDefinitionEmpty;
definition.className = "Functor";
definition.staticFunctions = cy::Functor::StaticFunctions;
void CYThrow(const char *format, ...) {
va_list args;
- va_start (args, format);
+ va_start(args, format);
throw CYPoolError(format, args);
// XXX: does this matter? :(
- va_end (args);
+ va_end(args);
}
const char *CYPoolError::PoolCString(apr_pool_t *pool) const {
CYPoolError::CYPoolError(const char *format, ...) {
va_list args;
- va_start (args, format);
+ va_start(args, format);
message_ = apr_pvsprintf(pool_, format, args);
- va_end (args);
+ va_end(args);
}
CYPoolError::CYPoolError(const char *format, va_list args) {
CYPool pool;
va_list args;
- va_start (args, format);
+ va_start(args, format);
const char *message(apr_pvsprintf(pool, format, args));
- va_end (args);
+ va_end(args);
value_ = CYCastJSError(context, message);
}
JSGlobalContextRef CYGetJSContext(JSContextRef context) {
- // XXX: do something better
- return Context_;
+ return reinterpret_cast<Context *>(JSObjectGetPrivate(CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s))))->context_;
}
void CYSetupContext(JSGlobalContextRef context) {
JSObjectRef global(CYGetGlobalObject(context));
- JSObjectRef cy(JSObjectMake(context, NULL, NULL));
- CYSetProperty(context, global, cy_s, cy);
+ JSObjectRef cy(JSObjectMake(context, Context_, new Context(context)));
+ CYSetProperty(context, global, cy_s, cy, kJSPropertyAttributeDontEnum);
JSObjectRef Array(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))));
CYSetProperty(context, cy, CYJSString("Array"), Array);
JSGlobalContextRef CYGetJSContext() {
CYInitialize();
- if (Context_ == NULL) {
- Context_ = JSGlobalContextCreate(Global_);
- CYSetupContext(Context_);
+ static JSGlobalContextRef context_;
+
+ if (context_ == NULL) {
+ context_ = JSGlobalContextCreate(Global_);
+ CYSetupContext(context_);
}
- return Context_;
+ return context_;
}
} \
}
+#define CYSadTry { \
+ @try
+#define CYSadCatch \
+ @catch (NSException *error ) { \
+ throw CYJSError(context, CYCastJSValue(context, error)); \
+ } \
+}
+
#ifndef __APPLE__
#define class_getSuperclass GSObjCSuper
#define class_getInstanceVariable GSCGetInstanceVariableDefinition
return Selector_type;
}
-// XXX: trick this out with associated objects!
JSValueRef CYGetClassPrototype(JSContextRef context, id self) {
if (self == nil)
return CYGetCachedObject(context, CYJSString("Instance_prototype"));
- // XXX: I need to think through multi-context
- typedef std::map<id, JSValueRef> CacheMap;
- static CacheMap cache_;
+ JSObjectRef global(CYGetGlobalObject(context));
+ JSObjectRef cy(CYCastJSObject(context, CYGetProperty(context, global, cy_s)));
+
+ char label[32];
+ sprintf(label, "i%p", self);
+ CYJSString name(label);
- JSValueRef &value(cache_[self]);
- if (value != NULL)
+ JSValueRef value(CYGetProperty(context, cy, name));
+ if (!JSValueIsUndefined(context, value))
return value;
JSClassRef _class(NULL);
JSObjectRef object(JSObjectMake(context, _class, NULL));
JSObjectSetPrototype(context, object, prototype);
-
- JSValueProtect(context, object);
- value = object;
+ CYSetProperty(context, cy, name, object);
return object;
}
return CYCastPointer<SEL>(context, value);
}
-void *CYObjectiveC_ExecuteStart(JSContextRef context) {
- // XXX: deal with exceptions!
+void *CYObjectiveC_ExecuteStart(JSContextRef context) { CYSadTry {
return (void *) [[NSAutoreleasePool alloc] init];
-}
+} CYSadCatch }
-void CYObjectiveC_ExecuteEnd(JSContextRef context, void *handle) {
- // XXX: deal with exceptions!
+void CYObjectiveC_ExecuteEnd(JSContextRef context, void *handle) { CYSadTry {
return [(NSAutoreleasePool *) handle release];
-}
+} CYSadCatch }
JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) { CYPoolTry {
if (name == "nil")
return NULL;
} CYPoolCatch(NULL) return /*XXX*/ NULL; }
-static void CYObjectiveC_CallFunction(JSContextRef context, ffi_cif *cif, void (*function)(), uint8_t *value, void **values) { @try {
+static void CYObjectiveC_CallFunction(JSContextRef context, ffi_cif *cif, void (*function)(), uint8_t *value, void **values) { CYSadTry {
ffi_call(cif, function, value, values);
-} @catch (NSException *error ) {
- throw CYJSError(context, CYCastJSValue(context, error));
-} }
+} CYSadCatch }
-static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) { @try {
+static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) { CYSadTry {
switch (type->primitive) {
case sig::object_P:
case sig::typename_P:
}
return true;
-} @catch (NSException *error ) {
- throw CYJSError(context, CYCastJSValue(context, error));
-} }
+} CYSadCatch }
static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) { CYPoolTry {
switch (type->primitive) {