Simplify ClassGetTS interpreter implementation
[hiphop-php.git] / hphp / runtime / vm / unit-util.h
blobbdb1378908536cbee880792251c322855a4487c9
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 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"
26 namespace HPHP {
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();
55 return sz > 6 &&
56 !memcmp(name->data() + sz - 6, kInOutSuffix, 6) &&
57 folly::qfind(name->slice().subpiece(0, sz - 6), folly::StringPiece("$")) !=
58 std::string::npos;
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);
73 return name;
76 inline String normalizeNS(const String& name) {
77 if (needsNSNormalization(name.get())) {
78 return String(name.data() + 1, name.size() - 1, CopyString);
80 return name;
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));
91 return name;
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 //////////////////////////////////////////////////////////////////////
170 #endif