]> git.saurik.com Git - cycript.git/commitdiff
Finished factoring out multi-context support and made CYSadTry/Catch for the simple...
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 5 Nov 2009 02:31:02 +0000 (02:31 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 5 Nov 2009 02:31:02 +0000 (02:31 +0000)
Library.cpp
ObjectiveC/Library.mm
cycript.hpp

index 7a873687ba400708f3bf901d1b885a6dcf7601e3..78f0fd0eaf1086e8f7f2648e8d1e1634e44eb358 100644 (file)
@@ -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<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);
@@ -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<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);
@@ -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_;
 }
index 548a2b2268de699d5e24850a3e7e6dc7fe95da77..63da8cb3b85da956521ea1ebf145751ccc05b7fd 100644 (file)
     } \
 }
 
+#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<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);
@@ -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<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")
@@ -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) {
index a39585a1c9da456f16489a07f7a0360ee1a85879..24ed1cd3d6b485f0f99d1537c82b8c26c429de8b 100644 (file)
@@ -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);