]>
git.saurik.com Git - cycript.git/blob - Decode.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2015 Jay Freeman (saurik)
5 /* GNU Affero General Public License, Version 3 {{{ */
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.
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.
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/>.
25 #include "Replace.hpp"
27 CYTypedIdentifier
*Decode_(CYPool
&pool
, struct sig::Type
*type
) {
28 switch (type
->primitive
) {
29 case sig::unknown_P
: return $
CYTypedIdentifier($
CYTypeError());
31 case sig::function_P
: {
32 _assert(type
->data
.signature
.count
!= 0);
33 CYTypedParameter
*parameter(NULL
);
34 for (size_t i(type
->data
.signature
.count
- 1); i
!= 0; --i
)
35 parameter
= $
CYTypedParameter(Decode(pool
, type
->data
.signature
.elements
[i
].type
), parameter
);
36 return Decode(pool
, type
->data
.signature
.elements
[0].type
)->Modify($
CYTypeFunctionWith(parameter
));
39 case sig::typename_P
: return $
CYTypedIdentifier($
CYTypeVariable("Class"));
40 case sig::union_P
: _assert(false); break;
41 case sig::string_P
: return $
CYTypedIdentifier($
CYTypeVariable("char"), $
CYTypePointerTo());
42 case sig::selector_P
: return $
CYTypedIdentifier($
CYTypeVariable("SEL"));
45 if (type
->data
.signature
.count
== 0)
46 return $
CYTypedIdentifier($
CYTypeVariable("NSBlock"), $
CYTypePointerTo());
48 CYTypedParameter
*parameter(NULL
);
49 for (size_t i(type
->data
.signature
.count
- 1); i
!= 0; --i
)
50 parameter
= $
CYTypedParameter(Decode(pool
, type
->data
.signature
.elements
[i
].type
), parameter
);
51 return Decode(pool
, type
->data
.signature
.elements
[0].type
)->Modify($
CYTypeBlockWith(parameter
));
56 if (type
->name
== NULL
)
57 return $
CYTypedIdentifier($
CYTypeVariable("id"));
59 return $
CYTypedIdentifier($
CYTypeVariable(type
->name
), $
CYTypePointerTo());
62 case sig::boolean_P
: return $
CYTypedIdentifier($
CYTypeVariable("bool"));
63 case sig::uchar_P
: return $
CYTypedIdentifier($
CYTypeUnsigned($
CYTypeVariable("char")));
64 case sig::uint_P
: return $
CYTypedIdentifier($
CYTypeUnsigned($
CYTypeVariable("int")));
65 case sig::ulong_P
: return $
CYTypedIdentifier($
CYTypeUnsigned($
CYTypeLong($
CYTypeVariable("int"))));
66 case sig::ulonglong_P
: return $
CYTypedIdentifier($
CYTypeUnsigned($
CYTypeLong($
CYTypeLong($
CYTypeVariable("int")))));
67 case sig::ushort_P
: return $
CYTypedIdentifier($
CYTypeUnsigned($
CYTypeShort($
CYTypeVariable("int"))));
68 case sig::array_P
: return Decode(pool
, type
->data
.data
.type
)->Modify($
CYTypeArrayOf($
D(type
->data
.data
.size
)));
70 case sig::pointer_P
: {
71 CYTypedIdentifier
*typed
;
72 if (type
->data
.data
.type
== NULL
)
73 typed
= $
CYTypedIdentifier($
CYTypeVoid());
75 typed
= Decode(pool
, type
->data
.data
.type
);
76 return typed
->Modify($
CYTypePointerTo());
79 case sig::bit_P
: _assert(false); break;
80 case sig::schar_P
: return $
CYTypedIdentifier($
CYTypeSigned($
CYTypeVariable("char")));
81 case sig::double_P
: return $
CYTypedIdentifier($
CYTypeVariable("double"));
82 case sig::float_P
: return $
CYTypedIdentifier($
CYTypeVariable("float"));
83 case sig::int_P
: return $
CYTypedIdentifier($
CYTypeVariable("int"));
84 case sig::long_P
: return $
CYTypedIdentifier($
CYTypeLong($
CYTypeVariable("int")));
85 case sig::longlong_P
: return $
CYTypedIdentifier($
CYTypeLong($
CYTypeLong($
CYTypeVariable("int"))));
86 case sig::short_P
: return $
CYTypedIdentifier($
CYTypeShort($
CYTypeVariable("int")));
88 case sig::void_P
: return $
CYTypedIdentifier($
CYTypeVoid());
89 case sig::char_P
: return $
CYTypedIdentifier($
CYTypeVariable("char"));
92 CYTypeStructField
*fields(NULL
);
93 for (size_t i(type
->data
.signature
.count
); i
!= 0; --i
) {
94 sig::Element
&element(type
->data
.signature
.elements
[i
- 1]);
95 CYTypedIdentifier
*typed(Decode(pool
, element
.type
));
96 if (element
.name
!= NULL
)
97 typed
->identifier_
= $
I(element
.name
);
98 fields
= $
CYTypeStructField(typed
, fields
);
100 CYIdentifier
*name(type
->name
== NULL
? NULL
: $
I(type
->name
));
101 return $
CYTypedIdentifier($
CYTypeStruct(name
, $
CYStructTail(fields
)));
109 CYTypedIdentifier
*Decode(CYPool
&pool
, struct sig::Type
*type
) {
110 CYTypedIdentifier
*typed(Decode_(pool
, type
));
111 if ((type
->flags
& JOC_TYPE_CONST
) != 0) {
112 if (type
->primitive
== sig::string_P
)
113 typed
->modifier_
= $
CYTypeConstant(typed
->modifier_
);
115 typed
= typed
->Modify($
CYTypeConstant());