]> git.saurik.com Git - cycript.git/blobdiff - sig/parse.cpp
new operator must return JSObject even for errors.
[cycript.git] / sig / parse.cpp
index 8eb081873e1a7d16ee9ea88f1c8813e650ad42a5..20fa5a2474536ca4d0a3af83c29a8169e64e395d 100644 (file)
@@ -91,7 +91,10 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
   parse:
     switch (next) {
         case '?': type = new(pool) Unknown(); break;
+
+#ifdef CY_OBJECTIVEC
         case '#': type = new(pool) Meta(); break;
+#endif
 
         case '(':
             type = new(pool) Aggregate(true);
@@ -99,6 +102,8 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
         goto aggregate;
 
         case '*': type = new(pool) String(); break;
+
+#ifdef CY_OBJECTIVEC
         case ':': type = new(pool) Selector(); break;
 
         case '@': {
@@ -113,10 +118,9 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
                     name = NULL;
                 else {
                     const char *quote = strchr(*encoding + 1, '"');
-                    if (quote == NULL) {
-                        printf("unterminated specific id type {%s}\n", *encoding - 10);
-                        _assert(false);
-                    } else if (!named || quote[1] == eos || quote[1] == '"') {
+                    if (quote == NULL)
+                        CYThrow("unterminated specific id type {%s}", *encoding - 10);
+                    else if (!named || quote[1] == eos || quote[1] == '"') {
                         name = pool.strmemdup(*encoding + 1, quote - *encoding - 1);
                         *encoding = quote + 1;
                     } else {
@@ -128,6 +132,7 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
             }
 
         } break;
+#endif
 
         case 'B': type = new(pool) Primitive<bool>(); break;
         case 'C': type = new(pool) Primitive<unsigned char>(); break;
@@ -139,10 +144,8 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
         case '[': {
             size_t size(strtoul(*encoding, (char **) encoding, 10));
             type = new(pool) Array(*Parse_(pool, encoding, eos, false, callback), size);
-            if (**encoding != ']') {
-                printf("']' != \"%s\"\n", *encoding);
-                _assert(false);
-            }
+            if (**encoding != ']')
+                CYThrow("']' != \"%s\"", *encoding);
             ++*encoding;
         } break;
 
@@ -151,10 +154,12 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
                 _assert(false); // XXX: why is this here?!?
             else {
                 type = Parse_(pool, encoding, eos, named, callback);
+#ifdef CY_OBJECTIVEC
                 Aggregate *aggregate(dynamic_cast<Aggregate *>(type));
                 if (aggregate != NULL && strcmp(aggregate->name, "_objc_class") == 0)
                     type = new(pool) Meta();
                 else
+#endif
                     type = new(pool) Pointer(*type);
             }
         break;
@@ -172,6 +177,11 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
         case 's': type = new(pool) Primitive<short>(); break;
         case 'v': type = new(pool) Void(); break;
 
+#ifdef __SIZEOF_INT128__
+        case 't': type = new(pool) Primitive<signed __int128>(); break;
+        case 'T': type = new(pool) Primitive<unsigned __int128>(); break;
+#endif
+
         case '{':
             type = new(pool) Aggregate(false);
             next = '}';
@@ -182,16 +192,22 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
 
             char end = next;
             const char *begin = *encoding;
-            do next = *(*encoding)++;
-            while (
-                next != '=' &&
-                next != '}'
-            );
+            do switch (next = *(*encoding)++) {
+                case '\0':
+                    _assert(false);
+                case '}':
+                    // XXX: this is actually a type reference
+                    aggregate->signature.count = _not(size_t);
+                    next = '='; // this is a "break". I'm sorry
+            } while (next != '=');
+
             size_t length = *encoding - begin - 1;
             if (strncmp(begin, "?", length) != 0)
                 aggregate->name = (char *) pool.strmemdup(begin, length);
 
-            if (next == '=')
+            if (aggregate->signature.count == _not(size_t))
+                aggregate->signature.elements = NULL;
+            else
                 Parse_(pool, &aggregate->signature, encoding, end, callback);
 
             // XXX: this is a hack to support trivial unions
@@ -217,8 +233,7 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback
         break;
 
         default:
-            printf("invalid type character: '%c' {%s}\n", next, *encoding - 10);
-            _assert(false);
+            CYThrow("invalid type character: '%c' {%s}", next, *encoding - 10);
     }
 
     type->flags = flags;
@@ -274,6 +289,13 @@ const char *Primitive<signed int>::Encode(CYPool &pool) const {
     return "i";
 }
 
+#ifdef __SIZEOF_INT128__
+template <>
+const char *Primitive<signed __int128>::Encode(CYPool &pool) const {
+    return "t";
+}
+#endif
+
 template <>
 const char *Primitive<signed long int>::Encode(CYPool &pool) const {
     return "l";
@@ -299,6 +321,13 @@ const char *Primitive<unsigned int>::Encode(CYPool &pool) const {
     return "I";
 }
 
+#ifdef __SIZEOF_INT128__
+template <>
+const char *Primitive<unsigned __int128>::Encode(CYPool &pool) const {
+    return "T";
+}
+#endif
+
 template <>
 const char *Primitive<unsigned long int>::Encode(CYPool &pool) const {
     return "L";
@@ -326,6 +355,7 @@ const char *String::Encode(CYPool &pool) const {
     return "*";
 }
 
+#ifdef CY_OBJECTIVEC
 const char *Meta::Encode(CYPool &pool) const {
     return "#";
 }
@@ -333,6 +363,7 @@ const char *Meta::Encode(CYPool &pool) const {
 const char *Selector::Encode(CYPool &pool) const {
     return ":";
 }
+#endif
 
 const char *Bits::Encode(CYPool &pool) const {
     return pool.strcat("b", pool.itoa(size), NULL);
@@ -346,21 +377,34 @@ const char *Array::Encode(CYPool &pool) const {
     return pool.strcat("[", pool.itoa(size), type.Encode(pool), "]", NULL);
 }
 
+#ifdef CY_OBJECTIVEC
 const char *Object::Encode(CYPool &pool) const {
     return name == NULL ? "@" : pool.strcat("@\"", name, "\"", NULL);
 }
+#endif
+
+const char *Enum::Encode(CYPool &pool) const {
+    return type.Encode(pool);
+}
 
 const char *Aggregate::Encode(CYPool &pool) const {
-    return pool.strcat(overlap ? "(" : "{", name == NULL ? "?" : name, "=", Unparse(pool, &signature), overlap ? ")" : "}", NULL);
+    bool reference(signature.count == _not(size_t));
+    return pool.strcat(overlap ? "(" : "{",
+        name == NULL ? "?" : name,
+        reference ? "" : "=",
+        reference ? "" : Unparse(pool, &signature),
+    overlap ? ")" : "}", NULL);
 }
 
 const char *Function::Encode(CYPool &pool) const {
     return "?";
 }
 
+#ifdef CY_OBJECTIVEC
 const char *Block::Encode(CYPool &pool) const {
     return "@?";
 }
+#endif
 
 const char *Unparse(CYPool &pool, const struct Type *type) {
     const char *base(type->Encode(pool));