]> git.saurik.com Git - cycript.git/blobdiff - ObjectiveC/Library.mm
Use the base JavaScript CYONifier for CYJSArray.
[cycript.git] / ObjectiveC / Library.mm
index 973909930d5ab67544eff4c3b1c84a6dcc637917..f5fdb28a872a3ce07e7706e4d110394372427f3e 100644 (file)
@@ -296,9 +296,9 @@ JSValueRef CYGetClassPrototype(JSContextRef context, id self) {
     JSValueRef prototype;
 
     if (self == NSArray_)
-        prototype = CYGetCachedObject(context, CYJSString("Array_prototype"));
+        prototype = CYGetCachedObject(context, CYJSString("ArrayInstance_prototype"));
     else if (self == NSDictionary_)
-        prototype = CYGetCachedObject(context, CYJSString("Object_prototype"));
+        prototype = CYGetCachedObject(context, CYJSString("ObjectInstance_prototype"));
     else if (self == NSString_)
         prototype = CYGetCachedObject(context, CYJSString("StringInstance_prototype"));
     else
@@ -394,6 +394,7 @@ JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
 @end
 
 @protocol Cycript
+- (id) cy$box;
 - (JSValueRef) cy$JSValueInContext:(JSContextRef)context;
 @end
 
@@ -679,6 +680,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
 /* Bridge: NSArray {{{ */
 @implementation NSArray (Cycript)
 
+- (id) cy$box {
+    return [[self mutableCopy] autorelease];
+}
+
 - (NSString *) cy$toCYON {
     NSMutableString *json([[[NSMutableString alloc] init] autorelease]);
     [json appendString:@"@["];
@@ -779,6 +784,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
 /* Bridge: NSDictionary {{{ */
 @implementation NSDictionary (Cycript)
 
+- (id) cy$box {
+    return [[self mutableCopy] autorelease];
+}
+
 - (NSString *) cy$toCYON {
     NSMutableString *json([[[NSMutableString alloc] init] autorelease]);
     [json appendString:@"@{"];
@@ -951,6 +960,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
 /* Bridge: NSObject {{{ */
 @implementation NSObject (Cycript)
 
+- (id) cy$box {
+    return self;
+}
+
 - (JSValueRef) cy$JSValueInContext:(JSContextRef)context { CYObjectiveTry_(context) {
     return NULL;
 } CYObjectiveCatch }
@@ -1012,6 +1025,10 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
 /* Bridge: NSString {{{ */
 @implementation NSString (Cycript)
 
+- (id) cy$box {
+    return [[self copy] autorelease];
+}
+
 - (JSType) cy$JSType {
     return kJSTypeString;
 }
@@ -1214,6 +1231,11 @@ JSValueRef CYCastJSValue(JSContextRef context, NSObject *value) { CYPoolTry {
 
 @implementation CYJSArray
 
+- (NSString *) cy$toCYON {
+    CYPool pool;
+    return [NSString stringWithUTF8String:CYPoolCCYON(pool, context_, object_)];
+}
+
 - (id) initWithJSObject:(JSObjectRef)object inContext:(JSContextRef)context { CYObjectiveTry {
     if ((self = [super init]) != nil) {
         object_ = object;
@@ -1821,6 +1843,16 @@ static bool Instance_hasInstance(JSContextRef context, JSObjectRef constructor,
     return false;
 } CYCatch }
 
+static JSValueRef Instance_box_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+    if (count == 0)
+        throw CYJSError(context, "incorrect number of arguments to Instance");
+    CYPool pool;
+    id value(CYCastNSObject(pool, context, arguments[0]));
+    if (value == nil)
+        value = [NSNull null];
+    return CYCastJSValue(context, [value cy$box]);
+} CYCatch }
+
 static bool Internal_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) {
     Internal *internal(reinterpret_cast<Internal *>(JSObjectGetPrivate(object)));
     CYPool pool;
@@ -2064,6 +2096,26 @@ JSValueRef CYSendMessage(apr_pool_t *pool, JSContextRef context, id self, Class
     sig::Signature signature;
     sig::Parse(pool, &signature, type, &Structor_);
 
+    size_t used(count + 3);
+    if (used > signature.count) {
+        sig::Element *elements(new (pool) sig::Element[used]);
+        memcpy(elements, signature.elements, used * sizeof(sig::Element));
+
+        for (size_t index(signature.count); index != used; ++index) {
+            sig::Element *element(&elements[index]);
+            element->name = NULL;
+            element->offset = _not(size_t);
+
+            sig::Type *type(new (pool) sig::Type);
+            memset(type, 0, sizeof(*type));
+            type->primitive = sig::object_P;
+            element->type = type;
+        }
+
+        signature.elements = elements;
+        signature.count = used;
+    }
+
     ffi_cif cif;
     sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif);
 
@@ -2538,15 +2590,26 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry {
     JSObjectRef Instance(JSObjectMakeConstructor(context, Instance_, &Instance_new));
     JSObjectRef Message(JSObjectMakeConstructor(context, Message_, NULL));
     JSObjectRef Selector(JSObjectMakeConstructor(context, Selector_, &Selector_new));
-    JSObjectRef StringInstance(JSObjectMakeConstructor(context, Instance_, NULL));
     JSObjectRef Super(JSObjectMakeConstructor(context, Super_, &Super_new));
 
     JSObjectRef Instance_prototype(CYCastJSObject(context, CYGetProperty(context, Instance, prototype_s)));
     CYSetProperty(context, cy, CYJSString("Instance_prototype"), Instance_prototype);
 
+    JSObjectRef ArrayInstance(JSObjectMakeConstructor(context, Instance_, NULL));
+    JSObjectRef ArrayInstance_prototype(CYCastJSObject(context, CYGetProperty(context, ArrayInstance, prototype_s)));
+    CYSetProperty(context, cy, CYJSString("ArrayInstance_prototype"), ArrayInstance_prototype);
+    JSObjectRef Array_prototype(CYGetCachedObject(context, CYJSString("Array_prototype")));
+    JSObjectSetPrototype(context, ArrayInstance_prototype, Array_prototype);
+
+    JSObjectRef ObjectInstance(JSObjectMakeConstructor(context, Instance_, NULL));
+    JSObjectRef ObjectInstance_prototype(CYCastJSObject(context, CYGetProperty(context, ObjectInstance, prototype_s)));
+    CYSetProperty(context, cy, CYJSString("ObjectInstance_prototype"), ObjectInstance_prototype);
+    JSObjectRef Object_prototype(CYGetCachedObject(context, CYJSString("Object_prototype")));
+    JSObjectSetPrototype(context, ObjectInstance_prototype, Object_prototype);
+
+    JSObjectRef StringInstance(JSObjectMakeConstructor(context, Instance_, NULL));
     JSObjectRef StringInstance_prototype(CYCastJSObject(context, CYGetProperty(context, StringInstance, prototype_s)));
     CYSetProperty(context, cy, CYJSString("StringInstance_prototype"), StringInstance_prototype);
-
     JSObjectRef String_prototype(CYGetCachedObject(context, CYJSString("String_prototype")));
     JSObjectSetPrototype(context, StringInstance_prototype, String_prototype);
 
@@ -2554,6 +2617,9 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry {
     CYSetProperty(context, cycript, CYJSString("Selector"), Selector);
     CYSetProperty(context, cycript, CYJSString("Super"), Super);
 
+    JSObjectRef box(JSObjectMakeFunctionWithCallback(context, CYJSString("box"), &Instance_box_callAsFunction));
+    CYSetProperty(context, Instance, CYJSString("box"), box);
+
 #if defined(__APPLE__) && defined(__arm__) && 0
     CYSetProperty(context, all, CYJSString("objc_registerClassPair"), &objc_registerClassPair_, kJSPropertyAttributeDontEnum);
 #endif