]> git.saurik.com Git - cycript.git/blame - Decode.cpp
Avoid guessing when converting Functor to Pointer.
[cycript.git] / Decode.cpp
CommitLineData
7341eedb
JF
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
9a39f705
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
9a39f705 6/*
f95d2598
JF
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9a39f705 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
9a39f705
JF
19**/
20/* }}} */
21
22#include <sstream>
23
24#include "Decode.hpp"
25#include "Replace.hpp"
26
0559abf8
JF
27namespace sig {
28
29template <>
5b4dabb2
JF
30CYType *Primitive<bool>::Decode(CYPool &pool) const {
31 return $ CYType($ CYTypeVariable("bool"));
0559abf8
JF
32}
33
34template <>
5b4dabb2
JF
35CYType *Primitive<char>::Decode(CYPool &pool) const {
36 return $ CYType($ CYTypeCharacter(CYTypeNeutral));
0559abf8
JF
37}
38
39template <>
5b4dabb2 40CYType *Primitive<double>::Decode(CYPool &pool) const {
1e8d8047 41 return $ CYType($ CYTypeFloating(1));
0559abf8
JF
42}
43
44template <>
5b4dabb2 45CYType *Primitive<float>::Decode(CYPool &pool) const {
1e8d8047
JF
46 return $ CYType($ CYTypeFloating(0));
47}
48
49template <>
50CYType *Primitive<long double>::Decode(CYPool &pool) const {
51 return $ CYType($ CYTypeFloating(2));
0559abf8
JF
52}
53
54template <>
5b4dabb2
JF
55CYType *Primitive<signed char>::Decode(CYPool &pool) const {
56 return $ CYType($ CYTypeCharacter(CYTypeSigned));
0559abf8
JF
57}
58
59template <>
5b4dabb2
JF
60CYType *Primitive<signed int>::Decode(CYPool &pool) const {
61 return $ CYType($ CYTypeIntegral(CYTypeSigned, 1));
0559abf8
JF
62}
63
24ffc58c
JF
64#ifdef __SIZEOF_INT128__
65template <>
5b4dabb2
JF
66CYType *Primitive<signed __int128>::Decode(CYPool &pool) const {
67 return $ CYType($ CYTypeInt128(CYTypeSigned));
24ffc58c
JF
68}
69#endif
70
0559abf8 71template <>
5b4dabb2
JF
72CYType *Primitive<signed long int>::Decode(CYPool &pool) const {
73 return $ CYType($ CYTypeIntegral(CYTypeSigned, 2));
0559abf8
JF
74}
75
76template <>
5b4dabb2
JF
77CYType *Primitive<signed long long int>::Decode(CYPool &pool) const {
78 return $ CYType($ CYTypeIntegral(CYTypeSigned, 3));
0559abf8
JF
79}
80
81template <>
5b4dabb2
JF
82CYType *Primitive<signed short int>::Decode(CYPool &pool) const {
83 return $ CYType($ CYTypeIntegral(CYTypeSigned, 0));
0559abf8
JF
84}
85
86template <>
5b4dabb2
JF
87CYType *Primitive<unsigned char>::Decode(CYPool &pool) const {
88 return $ CYType($ CYTypeCharacter(CYTypeUnsigned));
0559abf8
JF
89}
90
91template <>
5b4dabb2
JF
92CYType *Primitive<unsigned int>::Decode(CYPool &pool) const {
93 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 1));
0559abf8
JF
94}
95
24ffc58c
JF
96#ifdef __SIZEOF_INT128__
97template <>
5b4dabb2
JF
98CYType *Primitive<unsigned __int128>::Decode(CYPool &pool) const {
99 return $ CYType($ CYTypeInt128(CYTypeUnsigned));
24ffc58c
JF
100}
101#endif
102
0559abf8 103template <>
5b4dabb2
JF
104CYType *Primitive<unsigned long int>::Decode(CYPool &pool) const {
105 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 2));
0559abf8
JF
106}
107
108template <>
5b4dabb2
JF
109CYType *Primitive<unsigned long long int>::Decode(CYPool &pool) const {
110 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 3));
0559abf8
JF
111}
112
113template <>
5b4dabb2
JF
114CYType *Primitive<unsigned short int>::Decode(CYPool &pool) const {
115 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 0));
0559abf8
JF
116}
117
5b4dabb2
JF
118CYType *Void::Decode(CYPool &pool) const {
119 return $ CYType($ CYTypeVoid());
0559abf8
JF
120}
121
5b4dabb2
JF
122CYType *Unknown::Decode(CYPool &pool) const {
123 return $ CYType($ CYTypeError());
0559abf8
JF
124}
125
5b4dabb2
JF
126CYType *String::Decode(CYPool &pool) const {
127 return $ CYType($ CYTypeCharacter(CYTypeNeutral), $ CYTypePointerTo());
0559abf8 128}
9a39f705 129
e2ce853b 130#ifdef CY_OBJECTIVEC
5b4dabb2
JF
131CYType *Meta::Decode(CYPool &pool) const {
132 return $ CYType($ CYTypeVariable("Class"));
0559abf8
JF
133}
134
5b4dabb2
JF
135CYType *Selector::Decode(CYPool &pool) const {
136 return $ CYType($ CYTypeVariable("SEL"));
0559abf8 137}
e2ce853b 138#endif
0559abf8 139
5b4dabb2 140CYType *Bits::Decode(CYPool &pool) const {
9a39f705 141 _assert(false);
9a39f705
JF
142}
143
5b4dabb2 144CYType *Pointer::Decode(CYPool &pool) const {
0559abf8
JF
145 return CYDecodeType(pool, &type)->Modify($ CYTypePointerTo());
146}
147
5b4dabb2 148CYType *Array::Decode(CYPool &pool) const {
0559abf8
JF
149 return CYDecodeType(pool, &type)->Modify($ CYTypeArrayOf($D(size)));
150}
151
e2ce853b 152#ifdef CY_OBJECTIVEC
5b4dabb2 153CYType *Object::Decode(CYPool &pool) const {
0559abf8 154 if (name == NULL)
5b4dabb2 155 return $ CYType($ CYTypeVariable("id"));
0559abf8 156 else
5b4dabb2 157 return $ CYType($ CYTypeVariable(name), $ CYTypePointerTo());
0559abf8 158}
e2ce853b 159#endif
0559abf8 160
5b4dabb2 161CYType *Enum::Decode(CYPool &pool) const {
aaa29c28
JF
162 CYEnumConstant *values(NULL);
163 for (size_t i(count); i != 0; --i)
164 values = $ CYEnumConstant($I(pool.strdup(constants[i - 1].name)), $D(constants[i - 1].value), values);
165 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
5b4dabb2 166 CYType *typed(type.Decode(pool));
aaa29c28 167 _assert(typed->modifier_ == NULL);
5b4dabb2 168 return $ CYType($ CYTypeEnum(identifier, typed->specifier_, values));
aaa29c28
JF
169}
170
5b4dabb2 171CYType *Aggregate::Decode(CYPool &pool) const {
0559abf8
JF
172 _assert(!overlap);
173
1fdd7c7a
JF
174 if (signature.count == _not(size_t)) {
175 _assert(name != NULL);
5b4dabb2 176 return $ CYType($ CYTypeReference(CYTypeReferenceStruct, $I($pool.strdup(name))));
1fdd7c7a
JF
177 }
178
0559abf8
JF
179 CYTypeStructField *fields(NULL);
180 for (size_t i(signature.count); i != 0; --i) {
181 sig::Element &element(signature.elements[i - 1]);
5b4dabb2 182 fields = $ CYTypeStructField(CYDecodeType(pool, element.type), element.name == NULL ? NULL : $I(element.name), fields);
0559abf8
JF
183 }
184 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
5b4dabb2 185 return $ CYType($ CYTypeStruct(identifier, $ CYStructTail(fields)));
0559abf8
JF
186}
187
5b4dabb2 188CYType *Callable::Decode(CYPool &pool) const {
0559abf8 189 _assert(signature.count != 0);
574d4720 190 CYTypedParameter *parameters(NULL);
0559abf8 191 for (size_t i(signature.count - 1); i != 0; --i)
5b4dabb2 192 parameters = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), NULL, parameters);
574d4720
JF
193 return Modify(pool, CYDecodeType(pool, signature.elements[0].type), parameters);
194}
195
5b4dabb2 196CYType *Function::Modify(CYPool &pool, CYType *result, CYTypedParameter *parameters) const {
574d4720
JF
197 return result->Modify($ CYTypeFunctionWith(variadic, parameters));
198}
199
e2ce853b 200#ifdef CY_OBJECTIVEC
5b4dabb2 201CYType *Block::Modify(CYPool &pool, CYType *result, CYTypedParameter *parameters) const {
574d4720 202 return result->Modify($ CYTypeBlockWith(parameters));
0559abf8
JF
203}
204
5b4dabb2 205CYType *Block::Decode(CYPool &pool) const {
0559abf8 206 if (signature.count == 0)
5b4dabb2 207 return $ CYType($ CYTypeVariable("NSBlock"), $ CYTypePointerTo());
574d4720 208 return Callable::Decode(pool);
0559abf8 209}
e2ce853b 210#endif
0559abf8
JF
211
212}
213
5b4dabb2
JF
214CYType *CYDecodeType(CYPool &pool, struct sig::Type *type) {
215 CYType *typed(type->Decode(pool));
02873b72 216 if ((type->flags & JOC_TYPE_CONST) != 0) {
0559abf8 217 if (dynamic_cast<sig::String *>(type) != NULL)
02873b72
JF
218 typed->modifier_ = $ CYTypeConstant(typed->modifier_);
219 else
220 typed = typed->Modify($ CYTypeConstant());
221 }
9a39f705
JF
222 return typed;
223}