]> git.saurik.com Git - cycript.git/blame - sig/copy.cpp
Avoid infinite recursion while CYONifying objects.
[cycript.git] / sig / copy.cpp
CommitLineData
b3378a02 1/* Cycript - Optimizing JavaScript Compiler/Runtime
c15969fd 2 * Copyright (C) 2009-2013 Jay Freeman (saurik)
3c1c3635
JF
3*/
4
c15969fd 5/* GNU General Public License, Version 3 {{{ */
3c1c3635 6/*
c15969fd
JF
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.
3c1c3635 11 *
c15969fd
JF
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.
3c1c3635 16 *
c15969fd 17 * You should have received a copy of the GNU General Public License
b3378a02
JF
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
19**/
3c1c3635
JF
20/* }}} */
21
22#ifndef _GNU_SOURCE
23#define _GNU_SOURCE
24#endif
25
3c1c3635
JF
26#include "Pooling.hpp"
27#include "sig/parse.hpp"
b128dfee
DWT
28
29#ifdef HAVE_FFI_FFI_H
30#include <ffi/ffi.h>
31#else
3c1c3635 32#include <ffi.h>
b128dfee 33#endif
3c1c3635
JF
34
35namespace sig {
36
84aef9a7 37void Copy(CYPool &pool, Element &lhs, const Element &rhs) {
b799113b 38 lhs.name = pool.strdup(rhs.name);
3c1c3635
JF
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
84aef9a7 48void Copy(CYPool &pool, Signature &lhs, const Signature &rhs) {
3c1c3635
JF
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
84aef9a7 56void Copy(CYPool &pool, Type &lhs, const Type &rhs) {
3c1c3635 57 lhs.primitive = rhs.primitive;
b799113b 58 lhs.name = pool.strdup(rhs.name);
3c1c3635
JF
59 lhs.flags = rhs.flags;
60
3fe16be7 61 if (sig::IsFunctional(rhs.primitive) || sig::IsAggregate(rhs.primitive))
3c1c3635
JF
62 Copy(pool, lhs.data.signature, rhs.data.signature);
63 else {
64 sig::Type *&lht(lhs.data.data.type);
84aef9a7 65 sig::Type *const &rht(rhs.data.data.type);
3c1c3635
JF
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
b799113b 78void Copy(CYPool &pool, ffi_type &lhs, ffi_type &rhs) {
3c1c3635
JF
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}