]> 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 0ffb56a385ddf4340d26b140ba93a98b144eebc9..f0530466c8a01d5c4e364cc36bdfb286a282daf7 100644 (file)
@@ -1,85 +1,45 @@
-/* Cycript - Remote Execution Server and Disassembler
- * Copyright (C) 2009  Jay Freeman (saurik)
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2015  Jay Freeman (saurik)
 */
 
-/* Modified BSD License {{{ */
+/* GNU Affero General Public License, Version 3 {{{ */
 /*
- *        Redistribution and use in source and binary
- * forms, with or without modification, are permitted
- * provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer in the documentation
- *    and/or other materials provided with the
- *    distribution.
- * 3. The name of the author may not be used to endorse
- *    or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ * 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 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 "minimal/stdlib.h"
+#include <cstdlib>
+#include <stdint.h>
 
-namespace sig {
+#include <JavaScriptCore/JSBase.h>
 
-enum Primitive {
-    typename_P = '#',
-    union_P = '(',
-    string_P = '*',
-    selector_P = ':',
-    object_P = '@',
-    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 = '{'
-};
+#ifdef HAVE_FFI_FFI_H
+#include <ffi/ffi.h>
+#else
+#include <ffi.h>
+#endif
 
-struct Element {
-    char *name;
-    struct Type *type;
-    size_t offset;
-};
+#include "Standard.hpp"
 
-struct Signature {
-    struct Element *elements;
-    size_t count;
-};
+class CYPool;
+struct CYTypedIdentifier;
+struct CYTypedParameter;
+
+namespace sig {
 
 #define JOC_TYPE_INOUT  (1 << 0)
 #define JOC_TYPE_IN     (1 << 1)
@@ -90,26 +50,268 @@ struct Signature {
 #define JOC_TYPE_ONEWAY (1 << 6)
 
 struct Type {
-    enum Primitive primitive;
-    char *name;
     uint8_t flags;
 
-    union {
-        struct {
-            struct Type *type;
-            size_t size;
-        } data;
+    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;
 
-        struct Signature signature;
-    } data;
+    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;
 };
 
-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);
+template <typename Type_>
+struct Primitive :
+    Type
+{
+    Primitive *Copy(CYPool &pool, const char *name) const {
+        return new(pool) Primitive();
+    }
 
-_finline bool IsAggregate(Primitive primitive) {
-    return primitive == struct_P || primitive == union_P;
-}
+    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 {
+    const char *name;
+    Type *type;
+    size_t offset;
+};
+
+struct Signature {
+    Element *elements;
+    size_t count;
+};
+
+struct Void :
+    Type
+{
+    Void *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 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;
+
+    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;
+
+    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 Aggregate :
+    Type
+{
+    bool overlap;
+    const char *name;
+    Signature signature;
+
+    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);
 
 }