Deshim VirtualExecutor in folly
[hiphop-php.git] / hphp / hhbbc / type-system-detail.h
blob7fad29955beac599996d3f1e027e174d6e930b90
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef HHBBC_TYPE_SYSTEM_DETAIL_H
18 #error "type-system-detail.h should only be included by type-system-bits.h"
19 #endif
21 #include <boost/preprocessor/cat.hpp>
22 #include <boost/preprocessor/seq/cat.hpp>
23 #include <boost/preprocessor/seq/fold_left.hpp>
24 #include <boost/preprocessor/seq/for_each.hpp>
25 #include <boost/preprocessor/seq/pop_back.hpp>
26 #include <boost/preprocessor/seq/seq.hpp>
27 #include <boost/preprocessor/seq/transform.hpp>
28 #include <boost/preprocessor/tuple/elem.hpp>
29 #include <boost/preprocessor/variadic/to_seq.hpp>
30 #include <boost/preprocessor/variadic/to_tuple.hpp>
33 * This file is responsible for taking the various type declaration
34 * macros declared in type-system-bits.h and using them to create all
35 * the appropriate trep bits. It's split into a separate file because
36 * the details are ugly.
38 * Besides the treps themselves, it also declares the
39 * HHBBC_TYPE_PREDEFINED macro which can be used to expand to all
40 * predefined types.
43 //////////////////////////////////////////////////////////////////////
45 // These are all internal macros. They cannot be undefined afterward
46 // this because they're used in the expansion of
47 // HHBBC_TYPE_PREDEFINED.
49 #define HHBBC_COUNTED_OR_UNCOUNTEDSTATIC_ELEMS(Name, X) \
50 X(S##Name) \
52 #define HHBBC_COUNTED_OR_UNCOUNTEDCOUNTED_ELEMS(Name, X) \
53 X(C##Name) \
55 #define HHBBC_COUNTED_OR_UNCOUNTEDELEMS(Name, X) \
56 HHBBC_COUNTED_OR_UNCOUNTEDSTATIC_ELEMS(Name, X) \
57 HHBBC_COUNTED_OR_UNCOUNTEDCOUNTED_ELEMS(Name, X) \
59 #define HHBBC_COUNTED_OR_UNCOUNTEDUNIONS(Name, X) \
60 X(Name, BS##Name|BC##Name) \
62 #define HHBBC_ARRAY_STATIC_ELEMS(Name, X, ...) \
63 X(S##Name##E) \
64 X(S##Name##N) \
66 #define HHBBC_ARRAY_COUNTED_ELEMS(Name, X, ...) \
67 X(C##Name##E) \
68 X(C##Name##N) \
70 #define HHBBC_ARRAY_ELEMS(Name, X) \
71 HHBBC_ARRAY_STATIC_ELEMS(Name, X) \
72 HHBBC_ARRAY_COUNTED_ELEMS(Name, X) \
74 #define HHBBC_ARRAY_UNIONS(Name, X, ...) \
75 X(S##Name, BS##Name##E|BS##Name##N) \
76 X(C##Name, BC##Name##E|BC##Name##N) \
77 X(Name##E, BS##Name##E|BC##Name##E) \
78 X(Name##N, BS##Name##N|BC##Name##N) \
79 X(Name, B##Name##E|B##Name##N) \
81 #define HHBBC_ADD_PREFIX_SUFFIX(_, Data, Elem) \
82 BOOST_PP_CAT( \
83 BOOST_PP_CAT( \
84 BOOST_PP_TUPLE_ELEM(0, Data),Elem),BOOST_PP_TUPLE_ELEM(1, Data)) \
86 #define HHBBC_JOIN_WITH_UNION(_, Prev, X) Prev|X
88 #define BUILD_UNION_EXPR(Seq) \
89 BOOST_PP_SEQ_FOLD_LEFT( \
90 HHBBC_JOIN_WITH_UNION, \
91 BOOST_PP_SEQ_HEAD(Seq), BOOST_PP_SEQ_TAIL(Seq))
93 #define HHBBC_TRANSFORM_ARRAY_LIST(Prefix, Suffix, ...) \
94 BUILD_UNION_EXPR(BOOST_PP_SEQ_TRANSFORM( \
95 HHBBC_ADD_PREFIX_SUFFIX, \
96 BOOST_PP_VARIADIC_TO_TUPLE(Prefix, Suffix), \
97 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))) \
99 #define HHBBC_ARRAY_UNION_ELEMS(Name, X, ...) \
100 X(S##Name##E, HHBBC_TRANSFORM_ARRAY_LIST(BS, E, __VA_ARGS__)) \
101 X(C##Name##E, HHBBC_TRANSFORM_ARRAY_LIST(BC, E, __VA_ARGS__)) \
102 X(S##Name##N, HHBBC_TRANSFORM_ARRAY_LIST(BS, N, __VA_ARGS__)) \
103 X(C##Name##N, HHBBC_TRANSFORM_ARRAY_LIST(BC, N, __VA_ARGS__)) \
105 #define HHBBC_NAME_TO_UNION_FRAGMENT(Name) B##Name |
107 #define HHBBC_UNCOUNTED_TYPES \
108 HHBBC_TYPE_DECL_SINGLE_UNCOUNTED_NO_OPT(HHBBC_NAME_TO_UNION_FRAGMENT) \
109 HHBBC_TYPE_DECL_SINGLE_UNCOUNTED(HHBBC_NAME_TO_UNION_FRAGMENT) \
110 HHBBC_TYPE_DECL_COUNTED_OR_UNCOUNTED( \
111 HHBBC_COUNTED_OR_UNCOUNTEDSTATIC_ELEMS, \
112 HHBBC_NAME_TO_UNION_FRAGMENT) \
113 HHBBC_TYPE_DECL_ARRAY( \
114 HHBBC_ARRAY_STATIC_ELEMS, \
115 HHBBC_NAME_TO_UNION_FRAGMENT) \
116 HHBBC_TYPE_DECL_ARRAY_UNION( \
117 HHBBC_ARRAY_STATIC_ELEMS, \
118 HHBBC_NAME_TO_UNION_FRAGMENT) \
121 #define HHBBC_COUNTED_TYPES \
122 HHBBC_TYPE_DECL_SINGLE_COUNTED_NO_OPT(HHBBC_NAME_TO_UNION_FRAGMENT) \
123 HHBBC_TYPE_DECL_SINGLE_COUNTED(HHBBC_NAME_TO_UNION_FRAGMENT) \
124 HHBBC_TYPE_DECL_COUNTED_OR_UNCOUNTED( \
125 HHBBC_COUNTED_OR_UNCOUNTEDCOUNTED_ELEMS, \
126 HHBBC_NAME_TO_UNION_FRAGMENT) \
127 HHBBC_TYPE_DECL_ARRAY( \
128 HHBBC_ARRAY_COUNTED_ELEMS, \
129 HHBBC_NAME_TO_UNION_FRAGMENT) \
130 HHBBC_TYPE_DECL_ARRAY_UNION( \
131 HHBBC_ARRAY_COUNTED_ELEMS, \
132 HHBBC_NAME_TO_UNION_FRAGMENT) \
135 #define HHBBC_TYPE_SINGLE_OPT(X) \
136 HHBBC_TYPE_DECL_SINGLE_UNCOUNTED(X) \
137 HHBBC_TYPE_DECL_SINGLE_COUNTED(X) \
138 HHBBC_TYPE_DECL_COUNTED_OR_UNCOUNTED(HHBBC_COUNTED_OR_UNCOUNTEDELEMS, X) \
139 HHBBC_TYPE_DECL_ARRAY(HHBBC_ARRAY_ELEMS, X) \
141 #define HHBBC_TYPE_SINGLE(X) \
142 HHBBC_TYPE_DECL_SINGLE_UNCOUNTED_NO_OPT(X) \
143 HHBBC_TYPE_DECL_SINGLE_COUNTED_NO_OPT(X) \
144 HHBBC_TYPE_SINGLE_OPT(X) \
146 #define HHBBC_TYPE_UNION_OPT(X) \
147 HHBBC_TYPE_DECL_COUNTED_OR_UNCOUNTED(HHBBC_COUNTED_OR_UNCOUNTEDUNIONS, X) \
148 HHBBC_TYPE_DECL_ARRAY(HHBBC_ARRAY_UNIONS, X) \
149 HHBBC_TYPE_DECL_ARRAY_UNION(HHBBC_ARRAY_UNION_ELEMS, X) \
150 HHBBC_TYPE_DECL_ARRAY_UNION(HHBBC_ARRAY_UNIONS, X) \
151 HHBBC_TYPE_DECL_UNION(X) \
153 #define HHBBC_CELL_TYPES \
154 HHBBC_TYPE_SINGLE(HHBBC_NAME_TO_UNION_FRAGMENT) \
157 #define HHBBC_TYPE_UNION(X) \
158 HHBBC_TYPE_UNION_OPT(X) \
159 HHBBC_TYPE_DECL_UNION_NO_OPT(X) \
160 X(Unc, HHBBC_UNCOUNTED_TYPES) \
161 X(InitUnc, BUnc - BUninit) \
162 X(Counted, HHBBC_COUNTED_TYPES) \
163 X(Cell, HHBBC_CELL_TYPES) \
164 X(NonNull, BCell - BNull) \
165 X(InitCell, BCell - BUninit) \
167 #define HHBBC_MAKE_NAME_OPT(Name, ...) (Opt##Name)
168 #define HHBBC_CALL_X_WITH_NAME(_, X, Name) X(Name)
170 //////////////////////////////////////////////////////////////////////
172 // These is meant to be used outside this file to expand to all
173 // predefined types:
175 #define HHBBC_TYPE_PREDEFINED(X) \
176 X(Bottom) \
177 HHBBC_TYPE_SINGLE(X) \
178 HHBBC_TYPE_UNION(X) \
179 BOOST_PP_SEQ_FOR_EACH( \
180 HHBBC_CALL_X_WITH_NAME, \
181 X, \
182 HHBBC_TYPE_SINGLE_OPT(HHBBC_MAKE_NAME_OPT)) \
183 BOOST_PP_SEQ_FOR_EACH( \
184 HHBBC_CALL_X_WITH_NAME, \
185 X, \
186 HHBBC_TYPE_UNION_OPT(HHBBC_MAKE_NAME_OPT)) \
187 X(Top) \
189 //////////////////////////////////////////////////////////////////////
191 namespace HPHP::HHBBC {
193 //////////////////////////////////////////////////////////////////////
195 namespace detail {
197 // This is just an enumeration of all non-union types. It's used to
198 // automatically generate a bit index for each such type in the trep.
199 enum class single_types {
200 #define X(Name) Name,
201 HHBBC_TYPE_SINGLE(X)
202 #undef X
208 //////////////////////////////////////////////////////////////////////
210 constexpr const size_t kTRepBitsStored = 48;
212 static_assert((size_t)detail::single_types::Max <= kTRepBitsStored);
214 enum trep : uint64_t {
215 BBottom = 0,
217 // First the non-union types. They each get a specific bit index.
218 #define X(Name) B##Name = 1ULL << (int64_t)detail::single_types::Name,
219 HHBBC_TYPE_SINGLE(X)
220 #undef X
222 // Then the union types. These are just combinations of the above
223 // non-union types.
224 #define X(Name, Bits) B##Name = (Bits),
225 HHBBC_TYPE_UNION(X)
226 #undef X
228 // The non-union types which can be made optional. This is just the
229 // type with BInitNull added.
230 #define X(Name) BOpt##Name = B##Name | BInitNull,
231 HHBBC_TYPE_SINGLE_OPT(X)
232 #undef X
234 // Finally the same, except for union types.
235 #define X(Name, ...) BOpt##Name = B##Name | BInitNull,
236 HHBBC_TYPE_UNION_OPT(X)
237 #undef X
239 BTop = (1ULL << kTRepBitsStored) - 1,
242 //////////////////////////////////////////////////////////////////////