]>
git.saurik.com Git - cycript.git/blob - sig/ffi_type.cpp
96f39bbbfaaa564a3575e308a8b7bd5e1893f4df
   1 /* Cycript - Optimizing JavaScript Compiler/Runtime 
   2  * Copyright (C) 2009-2013  Jay Freeman (saurik) 
   5 /* GNU General Public License, Version 3 {{{ */ 
   7  * Cycript is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU General Public License as published 
   9  * by the Free Software Foundation, either version 3 of the License, 
  10  * or (at your option) any later version. 
  12  * Cycript is distributed in the hope that it will be useful, but 
  13  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU General Public License for more details. 
  17  * You should have received a copy of the GNU General Public License 
  18  * along with Cycript.  If not, see <http://www.gnu.org/licenses/>. 
  24 #include "sig/ffi_type.hpp" 
  25 #include "sig/types.hpp" 
  27 #define ffi_type_slonglong ffi_type_sint64 
  28 #define ffi_type_ulonglong ffi_type_uint64 
  34     ffi_type 
*(*sig_ffi_type
)(CYPool 
&, struct Type 
*), 
  35     struct Signature 
*signature
, 
  40     _assert(signature
->count 
>= skip
); 
  41     for (size_t index 
= skip
; index 
!= signature
->count
; ++index
) 
  42         types
[index 
- skip 
+ offset
] = (*sig_ffi_type
)(pool
, signature
->elements
[index
].type
); 
  45 ffi_type 
*ObjectiveC(CYPool 
&pool
, struct Type 
*type
) { 
  46     switch (type
->primitive
) { 
  47         case typename_P
: return &ffi_type_pointer
; 
  50             /* XXX: we can totally make this work */ 
  54         case string_P
: return &ffi_type_pointer
; 
  55         case selector_P
: return &ffi_type_pointer
; 
  56         case block_P
: return &ffi_type_pointer
; 
  57         case object_P
: return &ffi_type_pointer
; 
  58         case boolean_P
: return &ffi_type_uchar
; 
  59         case uchar_P
: return &ffi_type_uchar
; 
  60         case uint_P
: return &ffi_type_uint
; 
  61         case ulong_P
: return &ffi_type_ulong
; 
  62         case ulonglong_P
: return &ffi_type_ulonglong
; 
  63         case ushort_P
: return &ffi_type_ushort
; 
  66             // XXX: this is really lame 
  67             ffi_type 
*aggregate(new(pool
) ffi_type()); 
  69             aggregate
->alignment 
= 0; 
  70             aggregate
->type 
= FFI_TYPE_STRUCT
; 
  72             ffi_type 
*element(ObjectiveC(pool
, type
->data
.data
.type
)); 
  73             size_t size(type
->data
.data
.size
); 
  75             aggregate
->elements 
= new(pool
) ffi_type 
*[size 
+ 1]; 
  76             for (size_t i(0); i 
!= size
; ++i
) 
  77                 aggregate
->elements
[i
] = element
; 
  78             aggregate
->elements
[size
] = NULL
; 
  83         case pointer_P
: return &ffi_type_pointer
; 
  86             /* XXX: we can totally make this work */ 
  90         case char_P
: return &ffi_type_schar
; 
  91         case double_P
: return &ffi_type_double
; 
  92         case float_P
: return &ffi_type_float
; 
  93         case int_P
: return &ffi_type_sint
; 
  94         case long_P
: return &ffi_type_slong
; 
  95         case longlong_P
: return &ffi_type_slonglong
; 
  96         case short_P
: return &ffi_type_sshort
; 
  98         case void_P
: return &ffi_type_void
; 
 101             ffi_type 
*aggregate(new(pool
) ffi_type()); 
 103             aggregate
->alignment 
= 0; 
 104             aggregate
->type 
= FFI_TYPE_STRUCT
; 
 106             aggregate
->elements 
= new(pool
) ffi_type 
*[type
->data
.signature
.count 
+ 1]; 
 107             sig_ffi_types(pool
, &ObjectiveC
, &type
->data
.signature
, aggregate
->elements
); 
 108             aggregate
->elements
[type
->data
.signature
.count
] = NULL
; 
 119 ffi_type 
*Java(CYPool 
&pool
, struct Type 
*type
) { 
 120     switch (type
->primitive
) { 
 121         case typename_P
: return &ffi_type_pointer
; 
 122         case union_P
: _assert(false); break; 
 123         case string_P
: return &ffi_type_pointer
; 
 124         case selector_P
: return &ffi_type_pointer
; 
 125         case block_P
: return &ffi_type_pointer
; 
 126         case object_P
: return &ffi_type_pointer
; 
 127         case boolean_P
: return &ffi_type_uchar
; 
 128         case uchar_P
: return &ffi_type_uchar
; 
 129         case uint_P
: return &ffi_type_uint
; 
 130         case ulong_P
: return &ffi_type_ulong
; 
 131         case ulonglong_P
: return &ffi_type_ulonglong
; 
 132         case ushort_P
: return &ffi_type_ushort
; 
 133         case array_P
: return &ffi_type_pointer
; 
 134         case pointer_P
: return &ffi_type_pointer
; 
 135         case bit_P
: _assert(false); break; 
 136         case char_P
: return &ffi_type_schar
; 
 137         case double_P
: return &ffi_type_double
; 
 138         case float_P
: return &ffi_type_double
; 
 139         case int_P
: return &ffi_type_sint
; 
 140         case long_P
: return &ffi_type_slong
; 
 141         case longlong_P
: return &ffi_type_slonglong
; 
 142         case short_P
: return &ffi_type_sshort
; 
 143         case void_P
: return &ffi_type_void
; 
 144         case struct_P
: return &ffi_type_pointer
; 
 154     ffi_type 
*(*sig_ffi_type
)(CYPool 
&, struct Type 
*), 
 155     struct Signature 
*signature
, 
 162         types 
= new(pool
) ffi_type 
*[signature
->count 
- 1]; 
 163     ffi_type 
*type 
= (*sig_ffi_type
)(pool
, signature
->elements
[0].type
); 
 164     sig_ffi_types(pool
, sig_ffi_type
, signature
, types
, 1 + skip
, offset
); 
 165     ffi_status status 
= ffi_prep_cif(cif
, FFI_DEFAULT_ABI
, signature
->count 
- 1 - skip 
+ offset
, type
, types
); 
 166     _assert(status 
== FFI_OK
);