Add sub-controls for Hack array compat runtime checks
[hiphop-php.git] / hphp / runtime / base / repo-auth-type-codec.cpp
blob43c3e57915a741de6f385a07ba388c642be019dd
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 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 +----------------------------------------------------------------------+
16 #include "hphp/runtime/base/repo-auth-type-codec.h"
18 #include "hphp/runtime/vm/unit.h"
19 #include "hphp/runtime/vm/repo.h"
20 #include "hphp/runtime/vm/repo-global-data.h"
22 namespace HPHP {
24 //////////////////////////////////////////////////////////////////////
26 namespace {
28 template <class LookupStr, class LookupArrayType>
29 RepoAuthType decodeRATImpl(const unsigned char*& pc, LookupStr lookupStr,
30 LookupArrayType lookupArrayType) {
31 using T = RepoAuthType::Tag;
32 auto const rawTag = *pc++;
33 bool const highBitSet = rawTag & kRATArrayDataBit;
34 auto const tag = static_cast<T>(rawTag & ~kRATArrayDataBit);
35 switch (tag) {
36 case T::Uninit:
37 case T::InitNull:
38 case T::Null:
39 case T::Int:
40 case T::OptInt:
41 case T::Dbl:
42 case T::OptDbl:
43 case T::Res:
44 case T::OptRes:
45 case T::Bool:
46 case T::OptBool:
47 case T::SStr:
48 case T::OptSStr:
49 case T::Str:
50 case T::OptStr:
51 case T::Obj:
52 case T::OptObj:
53 case T::UncArrKey:
54 case T::ArrKey:
55 case T::OptUncArrKey:
56 case T::OptArrKey:
57 case T::InitUnc:
58 case T::Unc:
59 case T::InitCell:
60 case T::Cell:
61 case T::Ref:
62 case T::InitGen:
63 case T::Gen:
64 assert(!highBitSet);
65 return RepoAuthType{tag};
67 case T::SArr:
68 case T::OptSArr:
69 case T::Arr:
70 case T::OptArr:
71 case T::SVArr:
72 case T::OptSVArr:
73 case T::VArr:
74 case T::OptVArr:
75 case T::SDArr:
76 case T::OptSDArr:
77 case T::DArr:
78 case T::OptDArr:
79 case T::SVec:
80 case T::OptSVec:
81 case T::Vec:
82 case T::OptVec:
83 case T::SDict:
84 case T::OptSDict:
85 case T::Dict:
86 case T::OptDict:
87 case T::SKeyset:
88 case T::OptSKeyset:
89 case T::Keyset:
90 case T::OptKeyset:
91 if (highBitSet) {
92 uint32_t id;
93 std::memcpy(&id, pc, sizeof id);
94 pc += sizeof id;
95 auto const arr = lookupArrayType(id);
96 return RepoAuthType{tag, arr};
98 return RepoAuthType{tag};
100 case T::ExactObj:
101 case T::SubObj:
102 case T::OptExactObj:
103 case T::OptSubObj:
104 assert(!highBitSet);
106 uint32_t id;
107 std::memcpy(&id, pc, sizeof id);
108 pc += sizeof id;
109 const StringData* const clsName = lookupStr(id);
110 return RepoAuthType{tag, clsName};
113 not_reached();
118 RepoAuthType decodeRAT(const Unit* unit, const unsigned char*& pc) {
119 return decodeRATImpl(
121 [&](uint32_t id) { return unit->lookupLitstrId(id); },
122 [&](uint32_t id) { return unit->lookupArrayTypeId(id); }
126 RepoAuthType decodeRAT(const UnitEmitter& ue, const unsigned char*& pc) {
127 return decodeRATImpl(
129 [&](uint32_t id) { return ue.lookupLitstr(id); },
130 [&](uint32_t id) { return ue.lookupArrayType(id); }
134 void encodeRAT(UnitEmitter& ue, RepoAuthType rat) {
135 using T = RepoAuthType::Tag;
136 switch (rat.tag()) {
137 case T::Uninit:
138 case T::InitNull:
139 case T::Null:
140 case T::Int:
141 case T::OptInt:
142 case T::Dbl:
143 case T::OptDbl:
144 case T::Res:
145 case T::OptRes:
146 case T::Bool:
147 case T::OptBool:
148 case T::SStr:
149 case T::OptSStr:
150 case T::Str:
151 case T::OptStr:
152 case T::Obj:
153 case T::OptObj:
154 case T::UncArrKey:
155 case T::ArrKey:
156 case T::OptUncArrKey:
157 case T::OptArrKey:
158 case T::InitUnc:
159 case T::Unc:
160 case T::InitCell:
161 case T::Cell:
162 case T::Ref:
163 case T::InitGen:
164 case T::Gen:
165 ue.emitByte(static_cast<uint8_t>(rat.tag()));
166 break;
168 case T::SArr:
169 case T::OptSArr:
170 case T::Arr:
171 case T::OptArr:
172 case T::SVArr:
173 case T::OptSVArr:
174 case T::VArr:
175 case T::OptVArr:
176 case T::SDArr:
177 case T::OptSDArr:
178 case T::DArr:
179 case T::OptDArr:
180 case T::SVec:
181 case T::OptSVec:
182 case T::Vec:
183 case T::OptVec:
184 case T::SDict:
185 case T::OptSDict:
186 case T::Dict:
187 case T::OptDict:
188 case T::SKeyset:
189 case T::OptSKeyset:
190 case T::Keyset:
191 case T::OptKeyset:
193 auto tagByte = static_cast<uint8_t>(rat.tag());
194 if (rat.hasArrData()) tagByte |= kRATArrayDataBit;
195 ue.emitByte(tagByte);
196 if (rat.hasArrData()) {
197 ue.emitInt32(rat.arrayId());
199 break;
202 case T::ExactObj:
203 case T::SubObj:
204 case T::OptExactObj:
205 case T::OptSubObj:
206 ue.emitByte(static_cast<uint8_t>(rat.tag()));
207 ue.emitInt32(ue.mergeLitstr(rat.clsName()));
208 break;
212 //////////////////////////////////////////////////////////////////////