Basic JIT support for Records
[hiphop-php.git] / hphp / runtime / vm / unit-util.h
blobad1d92da3b346672e8ca4a01a260fbe17c87df09
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/array-iterator.h"
23 #include "hphp/runtime/base/static-string-table.h"
24 #include "hphp/runtime/base/type-string.h"
25 #include "hphp/runtime/base/type-structure.h"
27 namespace HPHP {
29 //////////////////////////////////////////////////////////////////////
32 * Returns true if the class or function name is normalized wrt namespaces.
34 inline bool isNSNormalized(const StringData* name) {
35 return name->data()[0] != '\\';
39 * Returns true if the class or function name needs to be normalized.
41 inline bool needsNSNormalization(const StringData* name) {
42 auto const data = name->data();
43 return name->size() >= 2 && data[0] == '\\' && data[1] != '\\';
47 * Returns true if the string is not of the form "Class::Method".
49 inline bool notClassMethodPair(const StringData* name) {
50 return strstr(name->data(), "::") == nullptr;
53 const char kInOutSuffix[] = "$inout";
54 inline bool needsStripInOut(const StringData* name) {
55 return
56 name->size() > sizeof(kInOutSuffix) &&
57 !strcmp(name->data() + name->size() - strlen(kInOutSuffix), kInOutSuffix);
61 * Normalizes a given class or function name removing the leading '\'.
62 * Leaves the name unchanged if more than one '\' is leading.
63 * So '\name' becomes 'name' but '\\name' stays '\\name'.
65 inline const StringData* normalizeNS(const StringData* name) {
66 if (needsNSNormalization(name)) {
67 assertx(name->size() != 0);
68 auto const size = static_cast<size_t>(name->size() - 1);
69 auto const piece = folly::StringPiece{name->data() + 1, size};
70 return makeStaticString(piece);
72 return name;
75 inline String normalizeNS(const String& name) {
76 if (needsNSNormalization(name.get())) {
77 return String(name.data() + 1, name.size() - 1, CopyString);
79 return name;
82 inline const StringData* stripInOutSuffix(const StringData* name) {
83 if (UNLIKELY(needsStripInOut(name))) {
84 assertx(name->size() > sizeof(kInOutSuffix));
85 auto const s = name->data();
86 size_t len = name->size() - sizeof(kInOutSuffix);
87 for (; s[len] != '$'; --len) assertx(len != 0);
88 return makeStaticString(folly::StringPiece(name->data(), len));
90 return name;
93 inline StringData* stripInOutSuffix(StringData* name) {
94 return const_cast<StringData*>(
95 stripInOutSuffix((const StringData*)name)
99 inline String stripInOutSuffix(String& s) {
100 return String(stripInOutSuffix(s.get()));
103 inline std::string mangleInOutFuncName(const char* name,
104 std::vector<uint32_t> params) {
105 return folly::sformat("{}${}$inout", name, folly::join(";", params));
108 inline std::string mangleInOutFuncName(const std::string& name,
109 std::vector<uint32_t> params) {
110 return mangleInOutFuncName(name.data(), std::move(params));
113 inline String mangleInOutFuncName(const StringData* name,
114 std::vector<uint32_t> params) {
115 return String(makeStaticString(
116 mangleInOutFuncName(name->data(), std::move(params))
120 inline std::string mangleReifiedGenericsName(const ArrayData* tsList) {
121 std::vector<std::string> l;
122 IterateV(
123 tsList,
124 [&](TypedValue v) {
125 assertx(isArrayLikeType(v.m_type));
126 auto str =
127 TypeStructure::toStringForDisplay(ArrNR(v.m_data.parr)).toCppString();
128 str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
129 l.emplace_back(str);
132 return folly::sformat("<{}>", folly::join(",", l));
135 inline StringData* mangleReifiedName(
136 const StringData* name,
137 const StringData* tsName
139 return makeStaticString(folly::sformat("$${}$${}", name, tsName));
142 inline bool isReifiedName(const StringData* name) {
143 // Length larger than $$name$$<type>
144 return name->size() > 7 &&
145 name->data()[0] == '$' &&
146 name->data()[1] == '$' &&
147 folly::qfind(name->slice(), folly::StringPiece("$$<"))
148 != std::string::npos;
151 inline folly::StringPiece stripClsOrFnNameFromReifiedName(
152 const folly::StringPiece name
154 auto i = name.find("$$<");
155 if (i == std::string::npos) raise_error("Not a reified name");
156 return name.subpiece(i + 2, name.size() - i - 2);
159 inline StringData* stripClsOrFnNameFromReifiedName(const StringData* name) {
160 return makeStaticString(stripClsOrFnNameFromReifiedName(name->slice()));
163 inline folly::StringPiece stripTypeFromReifiedName(
164 const folly::StringPiece name
166 auto i = name.find("$$<");
167 if (i == std::string::npos || i < 2) raise_error("Not a reified name");
168 // Remove the initial $$
169 return name.subpiece(2, i - 2);
172 inline StringData* stripTypeFromReifiedName(const StringData* name) {
173 return makeStaticString(stripTypeFromReifiedName(name->slice()));
176 //////////////////////////////////////////////////////////////////////
179 #endif