]> git.saurik.com Git - cycript.git/blobdiff - sig/types.hpp
Move x.type() to typeid(x) and implement variadic.
[cycript.git] / sig / types.hpp
index 117c7df5dd407bc1ac73802566d2e55ce2ecfcf9..f0530466c8a01d5c4e364cc36bdfb286a282daf7 100644 (file)
 /* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2013  Jay Freeman (saurik)
+ * Copyright (C) 2009-2015  Jay Freeman (saurik)
 */
 
-/* GNU General Public License, Version 3 {{{ */
+/* GNU Affero General Public License, Version 3 {{{ */
 /*
- * Cycript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 3 of the License,
- * or (at your option) any later version.
- *
- * Cycript is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Cycript.  If not, see <http://www.gnu.org/licenses/>.
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **/
 /* }}} */
 
 #ifndef SIG_TYPES_H
 #define SIG_TYPES_H
 
+#include <cstdlib>
+#include <stdint.h>
+
+#include <JavaScriptCore/JSBase.h>
+
+#ifdef HAVE_FFI_FFI_H
+#include <ffi/ffi.h>
+#else
+#include <ffi.h>
+#endif
+
 #include "Standard.hpp"
 
+class CYPool;
+struct CYTypedIdentifier;
+struct CYTypedParameter;
+
 namespace sig {
 
-enum Primitive {
-    typename_P = '#',
-    union_P = '(',
-    string_P = '*',
-    selector_P = ':',
-    block_P = '?',
-    object_P = 'W',
-    boolean_P = 'B',
-    uchar_P = 'C',
-    uint_P = 'I',
-    ulong_P = 'L',
-    ulonglong_P = 'Q',
-    ushort_P = 'S',
-    array_P = '[',
-    pointer_P = '^',
-    bit_P = 'b',
-    char_P = 'c',
-    double_P = 'd',
-    float_P = 'f',
-    int_P = 'i',
-    long_P = 'l',
-    longlong_P = 'q',
-    short_P = 's',
-    void_P = 'v',
-    struct_P = '{'
+#define JOC_TYPE_INOUT  (1 << 0)
+#define JOC_TYPE_IN     (1 << 1)
+#define JOC_TYPE_BYCOPY (1 << 2)
+#define JOC_TYPE_OUT    (1 << 3)
+#define JOC_TYPE_BYREF  (1 << 4)
+#define JOC_TYPE_CONST  (1 << 5)
+#define JOC_TYPE_ONEWAY (1 << 6)
+
+struct Type {
+    uint8_t flags;
+
+    Type() :
+        flags(0)
+    {
+    }
+
+    virtual Type *Copy(CYPool &pool, const char *name = NULL) const = 0;
+    virtual const char *GetName() const;
+
+    virtual const char *Encode(CYPool &pool) const = 0;
+    virtual CYTypedIdentifier *Decode(CYPool &pool) const = 0;
+
+    virtual ffi_type *GetFFI(CYPool &pool) const = 0;
+    virtual void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const = 0;
+    virtual JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize = false, JSObjectRef owner = NULL) const = 0;
+};
+
+template <typename Type_>
+struct Primitive :
+    Type
+{
+    Primitive *Copy(CYPool &pool, const char *name) const {
+        return new(pool) Primitive();
+    }
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
 };
 
 struct Element {
-    char *name;
-    struct Type *type;
+    const char *name;
+    Type *type;
     size_t offset;
 };
 
 struct Signature {
-    struct Element *elements;
+    Element *elements;
     size_t count;
 };
 
-#define JOC_TYPE_INOUT  (1 << 0)
-#define JOC_TYPE_IN     (1 << 1)
-#define JOC_TYPE_BYCOPY (1 << 2)
-#define JOC_TYPE_OUT    (1 << 3)
-#define JOC_TYPE_BYREF  (1 << 4)
-#define JOC_TYPE_CONST  (1 << 5)
-#define JOC_TYPE_ONEWAY (1 << 6)
+struct Void :
+    Type
+{
+    Void *Copy(CYPool &pool, const char *name = NULL) const override;
 
-struct Type {
-    enum Primitive primitive;
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Unknown :
+    Type
+{
+    Unknown *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct String :
+    Type
+{
+    String *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Meta :
+    Type
+{
+    Meta *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Selector :
+    Type
+{
+    Selector *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Bits :
+    Type
+{
+    size_t size;
+
+    Bits(size_t size) :
+        size(size)
+    {
+    }
+
+    Bits *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Pointer :
+    Type
+{
+    Type &type;
+
+    Pointer(Type &type) :
+        type(type)
+    {
+    }
+
+    Pointer *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Array :
+    Type
+{
+    Type &type;
+    size_t size;
+
+    Array(Type &type, size_t size = _not(size_t)) :
+        type(type),
+        size(size)
+    {
+    }
+
+    Array *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Object :
+    Type
+{
     const char *name;
-    uint8_t flags;
 
-    union {
-        struct {
-            struct Type *type;
-            size_t size;
-        } data;
+    Object(const char *name = NULL) :
+        name(name)
+    {
+    }
+
+    Object *Copy(CYPool &pool, const char *name = NULL) const override;
+    const char *GetName() const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
 
-        struct Signature signature;
-    } data;
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
 };
 
-struct Type *joc_parse_type(char **name, char eos, bool variable, bool signature);
-void joc_parse_signature(struct Signature *signature, char **name, char eos, bool variable);
+struct Aggregate :
+    Type
+{
+    bool overlap;
+    const char *name;
+    Signature signature;
 
-_finline bool IsAggregate(Primitive primitive) {
-    return primitive == struct_P || primitive == union_P;
-}
+    Aggregate(bool overlap, const char *name = NULL) :
+        overlap(overlap),
+        name(name)
+    {
+    }
+
+    Aggregate *Copy(CYPool &pool, const char *name = NULL) const override;
+    const char *GetName() const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Callable :
+    Type
+{
+    Signature signature;
+
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+    virtual CYTypedIdentifier *Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const = 0;
+};
+
+struct Function :
+    Callable
+{
+    bool variadic;
+
+    Function(bool variadic) :
+        variadic(variadic)
+    {
+    }
+
+    Function *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+struct Block :
+    Callable
+{
+    Block *Copy(CYPool &pool, const char *name = NULL) const override;
+
+    const char *Encode(CYPool &pool) const override;
+    CYTypedIdentifier *Decode(CYPool &pool) const override;
+    CYTypedIdentifier *Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const override;
+
+    ffi_type *GetFFI(CYPool &pool) const override;
+    void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
+    JSValueRef FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const override;
+};
+
+Type *joc_parse_type(char **name, char eos, bool variable, bool signature);
+void joc_parse_signature(Signature *signature, char **name, char eos, bool variable);
 
 }