Skip to content

Commit 93e2668

Browse files
Jake ChampionJakeChampion
authored andcommitted
extract cache-override namespace into its own files
1 parent c3b431f commit 93e2668

File tree

3 files changed

+416
-343
lines changed

3 files changed

+416
-343
lines changed
Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
// TODO: remove these once the warnings are fixed
2+
#pragma clang diagnostic push
3+
#pragma clang diagnostic ignored "-Winvalid-offsetof"
4+
#include "js/experimental/TypedData.h" // used in "js/Conversions.h"
5+
#pragma clang diagnostic pop
6+
7+
#include "js/Conversions.h"
8+
9+
#include "cache-override.h"
10+
#include "host_call.h"
11+
#include "js-compute-builtins.h"
12+
13+
namespace builtins {
14+
15+
CacheOverride::CacheOverrideMode CacheOverride::mode(JSObject *self) {
16+
return (CacheOverride::CacheOverrideMode)JS::GetReservedSlot(self, Slots::Mode).toInt32();
17+
}
18+
19+
void CacheOverride::set_mode(JSObject *self, CacheOverride::CacheOverrideMode mode) {
20+
JS::SetReservedSlot(self, CacheOverride::Slots::Mode, JS::Int32Value((int32_t)mode));
21+
}
22+
23+
JS::Value CacheOverride::ttl(JSObject *self) {
24+
if (CacheOverride::mode(self) != CacheOverride::CacheOverrideMode::Override)
25+
return JS::UndefinedValue();
26+
return JS::GetReservedSlot(self, Slots::TTL);
27+
}
28+
29+
void CacheOverride::set_ttl(JSObject *self, uint32_t ttl) {
30+
MOZ_RELEASE_ASSERT(mode(self) == CacheOverride::CacheOverrideMode::Override);
31+
JS::SetReservedSlot(self, CacheOverride::Slots::TTL, JS::Int32Value((int32_t)ttl));
32+
}
33+
34+
JS::Value CacheOverride::swr(JSObject *self) {
35+
if (CacheOverride::mode(self) != CacheOverride::CacheOverrideMode::Override)
36+
return JS::UndefinedValue();
37+
return JS::GetReservedSlot(self, Slots::SWR);
38+
}
39+
40+
void CacheOverride::set_swr(JSObject *self, uint32_t swr) {
41+
MOZ_RELEASE_ASSERT(CacheOverride::mode(self) == CacheOverride::CacheOverrideMode::Override);
42+
JS::SetReservedSlot(self, CacheOverride::Slots::SWR, JS::Int32Value((int32_t)swr));
43+
}
44+
45+
JS::Value CacheOverride::surrogate_key(JSObject *self) {
46+
if (CacheOverride::mode(self) != CacheOverride::CacheOverrideMode::Override)
47+
return JS::UndefinedValue();
48+
return JS::GetReservedSlot(self, Slots::SurrogateKey);
49+
}
50+
51+
void CacheOverride::set_surrogate_key(JSObject *self, JSString *key) {
52+
MOZ_RELEASE_ASSERT(CacheOverride::mode(self) == CacheOverride::CacheOverrideMode::Override);
53+
JS::SetReservedSlot(self, CacheOverride::Slots::SurrogateKey, JS::StringValue(key));
54+
}
55+
56+
JS::Value CacheOverride::pci(JSObject *self) {
57+
if (CacheOverride::mode(self) != CacheOverride::CacheOverrideMode::Override)
58+
return JS::UndefinedValue();
59+
return JS::GetReservedSlot(self, Slots::PCI);
60+
}
61+
62+
void CacheOverride::set_pci(JSObject *self, bool pci) {
63+
MOZ_RELEASE_ASSERT(CacheOverride::mode(self) == CacheOverride::CacheOverrideMode::Override);
64+
JS::SetReservedSlot(self, CacheOverride::Slots::PCI, JS::BooleanValue(pci));
65+
}
66+
67+
uint32_t CacheOverride::abi_tag(JSObject *self) {
68+
switch (CacheOverride::mode(self)) {
69+
case CacheOverride::CacheOverrideMode::None:
70+
return (uint32_t)CacheOverrideTag::None;
71+
case CacheOverride::CacheOverrideMode::Pass:
72+
return (uint32_t)CacheOverrideTag::Pass;
73+
default:;
74+
}
75+
76+
uint32_t tag = 0;
77+
if (!ttl(self).isUndefined())
78+
tag |= (uint32_t)CacheOverrideTag::TTL;
79+
if (!swr(self).isUndefined())
80+
tag |= (uint32_t)CacheOverrideTag::SWR;
81+
if (!pci(self).isUndefined())
82+
tag |= (uint32_t)CacheOverrideTag::PCI;
83+
84+
return tag;
85+
}
86+
87+
bool CacheOverride::mode_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval) {
88+
const char *mode_chars;
89+
switch (CacheOverride::mode(self)) {
90+
case CacheOverride::CacheOverrideMode::None:
91+
mode_chars = "none";
92+
break;
93+
case CacheOverride::CacheOverrideMode::Pass:
94+
mode_chars = "pass";
95+
break;
96+
case CacheOverride::CacheOverrideMode::Override:
97+
mode_chars = "override";
98+
break;
99+
}
100+
101+
JS::RootedString mode_str(cx, JS_NewStringCopyZ(cx, mode_chars));
102+
if (!mode_str)
103+
return false;
104+
105+
rval.setString(mode_str);
106+
return true;
107+
}
108+
109+
bool CacheOverride::ensure_override(JSContext *cx, JS::HandleObject self, const char *field) {
110+
if (CacheOverride::mode(self) == CacheOverride::CacheOverrideMode::Override)
111+
return true;
112+
113+
JS_ReportErrorUTF8(cx,
114+
"Can't set %s on CacheOverride object whose mode "
115+
"isn't \"override\"",
116+
field);
117+
return false;
118+
}
119+
120+
bool CacheOverride::mode_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
121+
JS::MutableHandleValue rval) {
122+
size_t mode_len;
123+
JS::UniqueChars mode_chars = encode(cx, val, &mode_len);
124+
if (!mode_chars)
125+
return false;
126+
127+
CacheOverride::CacheOverrideMode mode;
128+
if (!strcmp(mode_chars.get(), "none")) {
129+
mode = CacheOverride::CacheOverrideMode::None;
130+
} else if (!strcmp(mode_chars.get(), "pass")) {
131+
mode = CacheOverride::CacheOverrideMode::Pass;
132+
} else if (!strcmp(mode_chars.get(), "override")) {
133+
mode = CacheOverride::CacheOverrideMode::Override;
134+
} else {
135+
JS_ReportErrorUTF8(cx,
136+
"'mode' has to be \"none\", \"pass\", or \"override\", "
137+
"but got %s",
138+
mode_chars.get());
139+
return false;
140+
}
141+
142+
CacheOverride::set_mode(self, mode);
143+
return true;
144+
}
145+
146+
bool CacheOverride::ttl_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval) {
147+
rval.set(CacheOverride::ttl(self));
148+
return true;
149+
}
150+
151+
bool CacheOverride::ttl_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
152+
JS::MutableHandleValue rval) {
153+
if (!CacheOverride::ensure_override(cx, self, "a TTL"))
154+
return false;
155+
156+
if (val.isUndefined()) {
157+
JS::SetReservedSlot(self, CacheOverride::Slots::TTL, val);
158+
} else {
159+
int32_t ttl;
160+
if (!JS::ToInt32(cx, val, &ttl))
161+
return false;
162+
163+
CacheOverride::set_ttl(self, ttl);
164+
}
165+
rval.set(CacheOverride::ttl(self));
166+
return true;
167+
}
168+
169+
bool CacheOverride::swr_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval) {
170+
rval.set(CacheOverride::swr(self));
171+
return true;
172+
}
173+
174+
bool CacheOverride::swr_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
175+
JS::MutableHandleValue rval) {
176+
if (!CacheOverride::ensure_override(cx, self, "SWR"))
177+
return false;
178+
179+
if (val.isUndefined()) {
180+
JS::SetReservedSlot(self, CacheOverride::Slots::SWR, val);
181+
} else {
182+
int32_t swr;
183+
if (!JS::ToInt32(cx, val, &swr))
184+
return false;
185+
186+
CacheOverride::set_swr(self, swr);
187+
}
188+
rval.set(CacheOverride::swr(self));
189+
return true;
190+
}
191+
192+
bool CacheOverride::surrogate_key_get(JSContext *cx, JS::HandleObject self,
193+
JS::MutableHandleValue rval) {
194+
rval.set(CacheOverride::surrogate_key(self));
195+
return true;
196+
}
197+
198+
bool CacheOverride::surrogate_key_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
199+
JS::MutableHandleValue rval) {
200+
if (!CacheOverride::ensure_override(cx, self, "a surrogate key"))
201+
return false;
202+
203+
if (val.isUndefined()) {
204+
JS::SetReservedSlot(self, CacheOverride::Slots::SurrogateKey, val);
205+
} else {
206+
JS::RootedString surrogate_key(cx, JS::ToString(cx, val));
207+
if (!surrogate_key)
208+
return false;
209+
210+
CacheOverride::set_surrogate_key(self, surrogate_key);
211+
}
212+
rval.set(CacheOverride::surrogate_key(self));
213+
return true;
214+
}
215+
216+
bool CacheOverride::pci_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval) {
217+
rval.set(CacheOverride::pci(self));
218+
return true;
219+
}
220+
221+
bool CacheOverride::pci_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
222+
JS::MutableHandleValue rval) {
223+
if (!CacheOverride::ensure_override(cx, self, "PCI"))
224+
return false;
225+
226+
if (val.isUndefined()) {
227+
JS::SetReservedSlot(self, CacheOverride::Slots::PCI, val);
228+
} else {
229+
bool pci = JS::ToBoolean(val);
230+
CacheOverride::set_pci(self, pci);
231+
}
232+
rval.set(CacheOverride::pci(self));
233+
return true;
234+
}
235+
236+
template <auto accessor_fn>
237+
bool CacheOverride::accessor_get(JSContext *cx, unsigned argc, JS::Value *vp) {
238+
METHOD_HEADER(0)
239+
return accessor_fn(cx, self, args.rval());
240+
}
241+
242+
template <auto accessor_fn>
243+
bool CacheOverride::accessor_set(JSContext *cx, unsigned argc, JS::Value *vp) {
244+
METHOD_HEADER(1)
245+
return accessor_fn(cx, self, args[0], args.rval());
246+
}
247+
248+
const JSFunctionSpec CacheOverride::methods[] = {JS_FS_END};
249+
250+
const JSPropertySpec CacheOverride::properties[] = {
251+
JS_PSGS("mode", accessor_get<mode_get>, accessor_set<mode_set>, JSPROP_ENUMERATE),
252+
JS_PSGS("ttl", accessor_get<ttl_get>, accessor_set<ttl_set>, JSPROP_ENUMERATE),
253+
JS_PSGS("swr", accessor_get<swr_get>, accessor_set<swr_set>, JSPROP_ENUMERATE),
254+
JS_PSGS("surrogateKey", accessor_get<surrogate_key_get>, accessor_set<surrogate_key_set>,
255+
JSPROP_ENUMERATE),
256+
JS_PSGS("pci", accessor_get<pci_get>, accessor_set<pci_set>, JSPROP_ENUMERATE),
257+
JS_STRING_SYM_PS(toStringTag, "CacheOverride", JSPROP_READONLY),
258+
JS_PS_END};
259+
260+
bool CacheOverride::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
261+
CTOR_HEADER("CacheOverride", 1);
262+
263+
JS::RootedObject self(cx, JS_NewObjectForConstructor(cx, &class_, args));
264+
265+
JS::RootedValue val(cx);
266+
if (!mode_set(cx, self, args[0], &val))
267+
return false;
268+
269+
if (CacheOverride::mode(self) == CacheOverride::CacheOverrideMode::Override) {
270+
if (!args.get(1).isObject()) {
271+
JS_ReportErrorUTF8(cx, "Creating a CacheOverride object with mode \"override\" requires "
272+
"an init object for the override parameters as the second argument");
273+
return false;
274+
}
275+
276+
JS::RootedObject override_init(cx, &args[1].toObject());
277+
278+
if (!JS_GetProperty(cx, override_init, "ttl", &val) || !ttl_set(cx, self, val, &val)) {
279+
return false;
280+
}
281+
282+
if (!JS_GetProperty(cx, override_init, "swr", &val) || !swr_set(cx, self, val, &val)) {
283+
return false;
284+
}
285+
286+
if (!JS_GetProperty(cx, override_init, "surrogateKey", &val) ||
287+
!surrogate_key_set(cx, self, val, &val)) {
288+
return false;
289+
}
290+
291+
if (!JS_GetProperty(cx, override_init, "pci", &val) || !pci_set(cx, self, val, &val)) {
292+
return false;
293+
}
294+
}
295+
296+
args.rval().setObject(*self);
297+
return true;
298+
}
299+
300+
/**
301+
* Clone a CacheOverride instance by copying all its reserved slots.
302+
*
303+
* This works because CacheOverride slots only contain primitive values.
304+
*/
305+
JSObject *CacheOverride::clone(JSContext *cx, JS::HandleObject self) {
306+
MOZ_ASSERT(is_instance(self));
307+
JS::RootedObject result(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
308+
if (!result) {
309+
return nullptr;
310+
}
311+
312+
for (size_t i = 0; i < Slots::Count; i++) {
313+
JS::Value val = JS::GetReservedSlot(self, i);
314+
MOZ_ASSERT(!val.isObject());
315+
JS::SetReservedSlot(result, i, val);
316+
}
317+
318+
return result;
319+
}
320+
321+
bool CacheOverride::init_class(JSContext *cx, JS::HandleObject global) {
322+
return BuiltinImpl<CacheOverride>::init_class_impl(cx, global);
323+
}
324+
325+
} // namespace builtins

0 commit comments

Comments
 (0)