/* 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/>.
**/
/* }}} */
#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 {
- function_P = '\0',
- 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 *rename = 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 {
const char *name;
- struct Type *type;
+ 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 *rename = 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 *rename = 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 *rename = 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 *rename = 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 *rename = 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 *rename = 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 *rename = 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 *rename = 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)
+ {
+ }
- struct Signature signature;
- } data;
+ Object *Copy(CYPool &pool, const char *rename = 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 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;
+
+ Aggregate(bool overlap, const char *name = NULL) :
+ overlap(overlap),
+ name(name)
+ {
+ }
-_finline bool IsAggregate(Primitive primitive) {
- return primitive == struct_P || primitive == union_P;
-}
+ Aggregate *Copy(CYPool &pool, const char *rename = 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 *rename = 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 *rename = 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);
}