2 +----------------------------------------------------------------------+
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 incl_HPHP_VM_UNIT_UTIL_H_
18 #define incl_HPHP_VM_UNIT_UTIL_H_
20 #include <folly/Range.h>
22 #include "hphp/runtime/base/static-string-table.h"
23 #include "hphp/runtime/base/type-string.h"
24 #include "hphp/runtime/base/type-structure.h"
28 //////////////////////////////////////////////////////////////////////
31 * Returns true if the class or function name is normalized wrt namespaces.
33 inline bool isNSNormalized(const StringData
* name
) {
34 return name
->data()[0] != '\\';
38 * Returns true if the class or function name needs to be normalized.
40 inline bool needsNSNormalization(const StringData
* name
) {
41 auto const data
= name
->data();
42 return name
->size() >= 2 && data
[0] == '\\' && data
[1] != '\\';
46 * Returns true if the string is not of the form "Class::Method".
48 inline bool notClassMethodPair(const StringData
* name
) {
49 return strstr(name
->data(), "::") == nullptr;
52 const char kInOutSuffix
[] = "$inout";
53 inline bool needsStripInOut(const StringData
* name
) {
54 auto const sz
= name
->size();
56 !memcmp(name
->data() + sz
- 6, kInOutSuffix
, 6) &&
57 folly::qfind(name
->slice().subpiece(0, sz
- 6), folly::StringPiece("$")) !=
62 * Normalizes a given class or function name removing the leading '\'.
63 * Leaves the name unchanged if more than one '\' is leading.
64 * So '\name' becomes 'name' but '\\name' stays '\\name'.
66 inline const StringData
* normalizeNS(const StringData
* name
) {
67 if (needsNSNormalization(name
)) {
68 assertx(name
->size() != 0);
69 auto const size
= static_cast<size_t>(name
->size() - 1);
70 auto const piece
= folly::StringPiece
{name
->data() + 1, size
};
71 return makeStaticString(piece
);
76 inline String
normalizeNS(const String
& name
) {
77 if (needsNSNormalization(name
.get())) {
78 return String(name
.data() + 1, name
.size() - 1, CopyString
);
83 inline const StringData
* stripInOutSuffix(const StringData
* name
) {
84 if (UNLIKELY(needsStripInOut(name
))) {
85 assertx(name
->size() > sizeof(kInOutSuffix
));
86 auto const s
= name
->data();
87 size_t len
= name
->size() - sizeof(kInOutSuffix
);
88 for (; s
[len
] != '$'; --len
) assertx(len
!= 0);
89 return makeStaticString(folly::StringPiece(name
->data(), len
));
94 inline StringData
* stripInOutSuffix(StringData
* name
) {
95 return const_cast<StringData
*>(
96 stripInOutSuffix((const StringData
*)name
)
100 inline String
stripInOutSuffix(String
& s
) {
101 return String(stripInOutSuffix(s
.get()));
104 inline std::string
mangleInOutFuncName(const char* name
,
105 std::vector
<uint32_t> params
) {
106 return folly::sformat("{}${}$inout", name
, folly::join(";", params
));
109 inline std::string
mangleInOutFuncName(const std::string
& name
,
110 std::vector
<uint32_t> params
) {
111 return mangleInOutFuncName(name
.data(), std::move(params
));
114 inline String
mangleInOutFuncName(const StringData
* name
,
115 std::vector
<uint32_t> params
) {
116 return String(makeStaticString(
117 mangleInOutFuncName(name
->data(), std::move(params
))
121 std::string
mangleReifiedGenericsName(const ArrayData
* tsList
);
123 inline bool isReifiedName(const StringData
* name
) {
124 // Length larger than $$name$$<type>
125 return name
->size() > 7 &&
126 name
->data()[0] == '$' &&
127 name
->data()[1] == '$' &&
128 folly::qfind(name
->slice(), folly::StringPiece("$$<"))
129 != std::string::npos
;
132 inline bool isMangledReifiedGenericInClosure(const StringData
* name
) {
133 // mangled name is of the form
134 // __captured$reifiedgeneric$class$ or __captured$reifiedgeneric$function$
135 // so it must be longer than 32 characters
136 return name
->size() > 32 &&
137 folly::qfind(name
->slice(),
138 folly::StringPiece("__captured$reifiedgeneric$"))
139 != std::string::npos
;
142 inline folly::StringPiece
stripClsOrFnNameFromReifiedName(
143 const folly::StringPiece name
145 auto i
= name
.find("$$<");
146 if (i
== std::string::npos
) raise_error("Not a reified name");
147 return name
.subpiece(i
+ 2, name
.size() - i
- 2);
150 inline StringData
* stripClsOrFnNameFromReifiedName(const StringData
* name
) {
151 return makeStaticString(stripClsOrFnNameFromReifiedName(name
->slice()));
154 inline folly::StringPiece
stripTypeFromReifiedName(
155 const folly::StringPiece name
157 auto i
= name
.find("$$<");
158 if (i
== std::string::npos
|| i
< 2) raise_error("Not a reified name");
159 // Remove the initial $$
160 return name
.subpiece(2, i
- 2);
163 inline StringData
* stripTypeFromReifiedName(const StringData
* name
) {
164 return makeStaticString(stripTypeFromReifiedName(name
->slice()));
167 //////////////////////////////////////////////////////////////////////