]> git.saurik.com Git - cycript.git/blob - sig/copy.cpp
Reorganize grammar and add more labelled sections.
[cycript.git] / sig / copy.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2010 Jay Freeman (saurik)
3 */
4
5 /* GNU Lesser General Public License, Version 3 {{{ */
6 /*
7 * Cycript is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * Cycript is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser 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 <apr_strings.h>
27 #include "Pooling.hpp"
28 #include "sig/parse.hpp"
29
30 #ifdef HAVE_FFI_FFI_H
31 #include <ffi/ffi.h>
32 #else
33 #include <ffi.h>
34 #endif
35
36 namespace sig {
37
38 void Copy(apr_pool_t *pool, Element &lhs, Element &rhs) {
39 lhs.name = apr_pstrdup(pool, rhs.name);
40 if (rhs.type == NULL)
41 lhs.type = NULL;
42 else {
43 lhs.type = new(pool) Type;
44 Copy(pool, *lhs.type, *rhs.type);
45 }
46 lhs.offset = rhs.offset;
47 }
48
49 void Copy(apr_pool_t *pool, Signature &lhs, Signature &rhs) {
50 size_t count(rhs.count);
51 lhs.count = count;
52 lhs.elements = new(pool) Element[count];
53 for (size_t index(0); index != count; ++index)
54 Copy(pool, lhs.elements[index], rhs.elements[index]);
55 }
56
57 void Copy(apr_pool_t *pool, Type &lhs, Type &rhs) {
58 lhs.primitive = rhs.primitive;
59 lhs.name = apr_pstrdup(pool, rhs.name);
60 lhs.flags = rhs.flags;
61
62 if (sig::IsAggregate(rhs.primitive))
63 Copy(pool, lhs.data.signature, rhs.data.signature);
64 else {
65 sig::Type *&lht(lhs.data.data.type);
66 sig::Type *&rht(rhs.data.data.type);
67
68 if (rht == NULL)
69 lht = NULL;
70 else {
71 lht = new(pool) Type;
72 Copy(pool, *lht, *rht);
73 }
74
75 lhs.data.data.size = rhs.data.data.size;
76 }
77 }
78
79 void Copy(apr_pool_t *pool, ffi_type &lhs, ffi_type &rhs) {
80 lhs.size = rhs.size;
81 lhs.alignment = rhs.alignment;
82 lhs.type = rhs.type;
83 if (rhs.elements == NULL)
84 lhs.elements = NULL;
85 else {
86 size_t count(0);
87 while (rhs.elements[count] != NULL)
88 ++count;
89
90 lhs.elements = new(pool) ffi_type *[count + 1];
91 lhs.elements[count] = NULL;
92
93 for (size_t index(0); index != count; ++index) {
94 // XXX: if these are libffi native then you can just take them
95 ffi_type *ffi(new(pool) ffi_type);
96 lhs.elements[index] = ffi;
97 sig::Copy(pool, *ffi, *rhs.elements[index]);
98 }
99 }
100 }
101
102 }