]> git.saurik.com Git - cycript.git/blob - sig/copy.cpp
Support casting any pointer to a function type.
[cycript.git] / sig / copy.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2013 Jay Freeman (saurik)
3 */
4
5 /* GNU General Public License, Version 3 {{{ */
6 /*
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.
11 *
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.
16 *
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/>.
19 **/
20 /* }}} */
21
22 #ifndef _GNU_SOURCE
23 #define _GNU_SOURCE
24 #endif
25
26 #include "Pooling.hpp"
27 #include "sig/parse.hpp"
28
29 #ifdef HAVE_FFI_FFI_H
30 #include <ffi/ffi.h>
31 #else
32 #include <ffi.h>
33 #endif
34
35 namespace sig {
36
37 void Copy(CYPool &pool, Element &lhs, Element &rhs) {
38 lhs.name = pool.strdup(rhs.name);
39 if (rhs.type == NULL)
40 lhs.type = NULL;
41 else {
42 lhs.type = new(pool) Type;
43 Copy(pool, *lhs.type, *rhs.type);
44 }
45 lhs.offset = rhs.offset;
46 }
47
48 void Copy(CYPool &pool, Signature &lhs, Signature &rhs) {
49 size_t count(rhs.count);
50 lhs.count = count;
51 lhs.elements = new(pool) Element[count];
52 for (size_t index(0); index != count; ++index)
53 Copy(pool, lhs.elements[index], rhs.elements[index]);
54 }
55
56 void Copy(CYPool &pool, Type &lhs, Type &rhs) {
57 lhs.primitive = rhs.primitive;
58 lhs.name = pool.strdup(rhs.name);
59 lhs.flags = rhs.flags;
60
61 if (rhs.primitive == '\0' || sig::IsAggregate(rhs.primitive))
62 Copy(pool, lhs.data.signature, rhs.data.signature);
63 else {
64 sig::Type *&lht(lhs.data.data.type);
65 sig::Type *&rht(rhs.data.data.type);
66
67 if (rht == NULL)
68 lht = NULL;
69 else {
70 lht = new(pool) Type;
71 Copy(pool, *lht, *rht);
72 }
73
74 lhs.data.data.size = rhs.data.data.size;
75 }
76 }
77
78 void Copy(CYPool &pool, ffi_type &lhs, ffi_type &rhs) {
79 lhs.size = rhs.size;
80 lhs.alignment = rhs.alignment;
81 lhs.type = rhs.type;
82 if (rhs.elements == NULL)
83 lhs.elements = NULL;
84 else {
85 size_t count(0);
86 while (rhs.elements[count] != NULL)
87 ++count;
88
89 lhs.elements = new(pool) ffi_type *[count + 1];
90 lhs.elements[count] = NULL;
91
92 for (size_t index(0); index != count; ++index) {
93 // XXX: if these are libffi native then you can just take them
94 ffi_type *ffi(new(pool) ffi_type);
95 lhs.elements[index] = ffi;
96 sig::Copy(pool, *ffi, *rhs.elements[index]);
97 }
98 }
99 }
100
101 }