-/* 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)
#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 *rename = 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 *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 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;
+
+ Object(const char *name = NULL) :
+ name(name)
+ {
+ }
+
+ 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 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 *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);
}