From b64ab4dac5a76da209ff3cb12aa8bf83c6142607 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 5 Nov 2009 02:31:02 +0000 Subject: [PATCH] Finished factoring out multi-context support and made CYSadTry/Catch for the simple conversion catches I had. --- Library.cpp | 63 +++++++++++++++++++++++++++---------------- ObjectiveC/Library.mm | 48 +++++++++++++++++---------------- cycript.hpp | 2 +- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/Library.cpp b/Library.cpp index 7a87368..78f0fd0 100644 --- a/Library.cpp +++ b/Library.cpp @@ -127,7 +127,7 @@ JSStringRef CYCopyJSString(JSStringRef value) { } 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); } @@ -260,7 +260,7 @@ void CYStringify(std::ostringstream &str, const char *data, size_t size) { 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: @@ -300,8 +300,7 @@ bool CYIsKey(CYUTF8String value) { } /* }}} */ -static JSGlobalContextRef Context_; - +static JSClassRef Context_; static JSClassRef Functor_; static JSClassRef Global_; static JSClassRef Pointer_; @@ -399,6 +398,17 @@ void Structor_(apr_pool_t *pool, sig::Type *&type) { JSClassRef Type_privateData::Class_; +struct Context : + CYData +{ + JSGlobalContextRef context_; + + Context(JSGlobalContextRef context) : + context_(context) + { + } +}; + struct Pointer : CYOwned { @@ -511,7 +521,7 @@ JSObjectRef CYCastJSObject(JSContextRef context, JSValueRef value) { 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); @@ -1282,10 +1292,11 @@ static JSValueRef CYValue_callAsFunction_toCYON(JSContextRef context, JSObjectRe static JSValueRef Pointer_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { Pointer *internal(reinterpret_cast(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); @@ -1433,6 +1444,11 @@ void CYInitialize() { JSClassDefinition definition; + definition = kJSClassDefinitionEmpty; + definition.className = "Context"; + definition.finalize = &CYFinalize; + Context_ = JSClassCreate(&definition); + definition = kJSClassDefinitionEmpty; definition.className = "Functor"; definition.staticFunctions = cy::Functor::StaticFunctions; @@ -1515,10 +1531,10 @@ JSValueRef CYJSError::CastJSValue(JSContextRef context) const { 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 { @@ -1527,9 +1543,9 @@ 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) { @@ -1558,23 +1574,22 @@ CYJSError::CYJSError(JSContextRef context, const char *format, ...) { 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(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); @@ -1632,10 +1647,12 @@ void CYSetupContext(JSGlobalContextRef context) { 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_; } diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 548a2b2..63da8cb 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -97,6 +97,14 @@ } \ } +#define CYSadTry { \ + @try +#define CYSadCatch \ + @catch (NSException *error ) { \ + throw CYJSError(context, CYCastJSValue(context, error)); \ + } \ +} + #ifndef __APPLE__ #define class_getSuperclass GSObjCSuper #define class_getInstanceVariable GSCGetInstanceVariableDefinition @@ -287,17 +295,19 @@ Type_privateData *Selector_privateData::GetType() const { 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 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); @@ -312,9 +322,7 @@ JSValueRef CYGetClassPrototype(JSContextRef context, id self) { JSObjectRef object(JSObjectMake(context, _class, NULL)); JSObjectSetPrototype(context, object, prototype); - - JSValueProtect(context, object); - value = object; + CYSetProperty(context, cy, name, object); return object; } @@ -1312,15 +1320,13 @@ static SEL CYCastSEL(JSContextRef context, JSValueRef value) { return CYCastPointer(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") @@ -1330,13 +1336,11 @@ JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) 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: @@ -1352,9 +1356,7 @@ static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Ty } 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) { diff --git a/cycript.hpp b/cycript.hpp index a39585a..24ed1cd 100644 --- a/cycript.hpp +++ b/cycript.hpp @@ -126,7 +126,7 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception, sig::Signature *signature, ffi_cif *cif, void (*function)()); bool CYIsCallable(JSContextRef context, JSValueRef value); -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[]); const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef object); -- 2.47.2