]> git.saurik.com Git - cycript.git/blame_incremental - Decode.cpp
Do not use corrupt struct to store type reference.
[cycript.git] / Decode.cpp
... / ...
CommitLineData
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
3*/
4
5/* GNU Affero General Public License, Version 3 {{{ */
6/*
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
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>.
19**/
20/* }}} */
21
22#include <sstream>
23
24#include "Decode.hpp"
25#include "Replace.hpp"
26
27namespace sig {
28
29template <>
30CYTypedIdentifier *Primitive<bool>::Decode(CYPool &pool) const {
31 return $ CYTypedIdentifier($ CYTypeVariable("bool"));
32}
33
34template <>
35CYTypedIdentifier *Primitive<char>::Decode(CYPool &pool) const {
36 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeNeutral));
37}
38
39template <>
40CYTypedIdentifier *Primitive<double>::Decode(CYPool &pool) const {
41 return $ CYTypedIdentifier($ CYTypeVariable("double"));
42}
43
44template <>
45CYTypedIdentifier *Primitive<float>::Decode(CYPool &pool) const {
46 return $ CYTypedIdentifier($ CYTypeVariable("float"));
47}
48
49template <>
50CYTypedIdentifier *Primitive<signed char>::Decode(CYPool &pool) const {
51 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeSigned));
52}
53
54template <>
55CYTypedIdentifier *Primitive<signed int>::Decode(CYPool &pool) const {
56 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 1));
57}
58
59#ifdef __SIZEOF_INT128__
60template <>
61CYTypedIdentifier *Primitive<signed __int128>::Decode(CYPool &pool) const {
62 return $ CYTypedIdentifier($ CYTypeInt128(CYTypeSigned));
63}
64#endif
65
66template <>
67CYTypedIdentifier *Primitive<signed long int>::Decode(CYPool &pool) const {
68 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 2));
69}
70
71template <>
72CYTypedIdentifier *Primitive<signed long long int>::Decode(CYPool &pool) const {
73 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 3));
74}
75
76template <>
77CYTypedIdentifier *Primitive<signed short int>::Decode(CYPool &pool) const {
78 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 0));
79}
80
81template <>
82CYTypedIdentifier *Primitive<unsigned char>::Decode(CYPool &pool) const {
83 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeUnsigned));
84}
85
86template <>
87CYTypedIdentifier *Primitive<unsigned int>::Decode(CYPool &pool) const {
88 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 1));
89}
90
91#ifdef __SIZEOF_INT128__
92template <>
93CYTypedIdentifier *Primitive<unsigned __int128>::Decode(CYPool &pool) const {
94 return $ CYTypedIdentifier($ CYTypeInt128(CYTypeUnsigned));
95}
96#endif
97
98template <>
99CYTypedIdentifier *Primitive<unsigned long int>::Decode(CYPool &pool) const {
100 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 2));
101}
102
103template <>
104CYTypedIdentifier *Primitive<unsigned long long int>::Decode(CYPool &pool) const {
105 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 3));
106}
107
108template <>
109CYTypedIdentifier *Primitive<unsigned short int>::Decode(CYPool &pool) const {
110 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 0));
111}
112
113CYTypedIdentifier *Void::Decode(CYPool &pool) const {
114 return $ CYTypedIdentifier($ CYTypeVoid());
115}
116
117CYTypedIdentifier *Unknown::Decode(CYPool &pool) const {
118 return $ CYTypedIdentifier($ CYTypeError());
119}
120
121CYTypedIdentifier *String::Decode(CYPool &pool) const {
122 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeNeutral), $ CYTypePointerTo());
123}
124
125#ifdef CY_OBJECTIVEC
126CYTypedIdentifier *Meta::Decode(CYPool &pool) const {
127 return $ CYTypedIdentifier($ CYTypeVariable("Class"));
128}
129
130CYTypedIdentifier *Selector::Decode(CYPool &pool) const {
131 return $ CYTypedIdentifier($ CYTypeVariable("SEL"));
132}
133#endif
134
135CYTypedIdentifier *Bits::Decode(CYPool &pool) const {
136 _assert(false);
137}
138
139CYTypedIdentifier *Pointer::Decode(CYPool &pool) const {
140 return CYDecodeType(pool, &type)->Modify($ CYTypePointerTo());
141}
142
143CYTypedIdentifier *Array::Decode(CYPool &pool) const {
144 return CYDecodeType(pool, &type)->Modify($ CYTypeArrayOf($D(size)));
145}
146
147#ifdef CY_OBJECTIVEC
148CYTypedIdentifier *Object::Decode(CYPool &pool) const {
149 if (name == NULL)
150 return $ CYTypedIdentifier($ CYTypeVariable("id"));
151 else
152 return $ CYTypedIdentifier($ CYTypeVariable(name), $ CYTypePointerTo());
153}
154#endif
155
156CYTypedIdentifier *Enum::Decode(CYPool &pool) const {
157 CYEnumConstant *values(NULL);
158 for (size_t i(count); i != 0; --i)
159 values = $ CYEnumConstant($I(pool.strdup(constants[i - 1].name)), $D(constants[i - 1].value), values);
160 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
161 CYTypedIdentifier *typed(type.Decode(pool));
162 _assert(typed->modifier_ == NULL);
163 return $ CYTypedIdentifier($ CYTypeEnum(identifier, typed->specifier_, values));
164}
165
166CYTypedIdentifier *Aggregate::Decode(CYPool &pool) const {
167 _assert(!overlap);
168
169 if (signature.count == _not(size_t)) {
170 _assert(name != NULL);
171 return $ CYTypedIdentifier($ CYTypeReference(CYTypeReferenceStruct, $I($pool.strdup(name))));
172 }
173
174 CYTypeStructField *fields(NULL);
175 for (size_t i(signature.count); i != 0; --i) {
176 sig::Element &element(signature.elements[i - 1]);
177 CYTypedIdentifier *typed(CYDecodeType(pool, element.type));
178 if (element.name != NULL)
179 typed->identifier_ = $I(element.name);
180 fields = $ CYTypeStructField(typed, fields);
181 }
182 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
183 return $ CYTypedIdentifier($ CYTypeStruct(identifier, $ CYStructTail(fields)));
184}
185
186CYTypedIdentifier *Callable::Decode(CYPool &pool) const {
187 _assert(signature.count != 0);
188 CYTypedParameter *parameters(NULL);
189 for (size_t i(signature.count - 1); i != 0; --i)
190 parameters = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), parameters);
191 return Modify(pool, CYDecodeType(pool, signature.elements[0].type), parameters);
192}
193
194CYTypedIdentifier *Function::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
195 return result->Modify($ CYTypeFunctionWith(variadic, parameters));
196}
197
198#ifdef CY_OBJECTIVEC
199CYTypedIdentifier *Block::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
200 return result->Modify($ CYTypeBlockWith(parameters));
201}
202
203CYTypedIdentifier *Block::Decode(CYPool &pool) const {
204 if (signature.count == 0)
205 return $ CYTypedIdentifier($ CYTypeVariable("NSBlock"), $ CYTypePointerTo());
206 return Callable::Decode(pool);
207}
208#endif
209
210}
211
212CYTypedIdentifier *CYDecodeType(CYPool &pool, struct sig::Type *type) {
213 CYTypedIdentifier *typed(type->Decode(pool));
214 if ((type->flags & JOC_TYPE_CONST) != 0) {
215 if (dynamic_cast<sig::String *>(type) != NULL)
216 typed->modifier_ = $ CYTypeConstant(typed->modifier_);
217 else
218 typed = typed->Modify($ CYTypeConstant());
219 }
220 return typed;
221}