Skip to content

Commit e5ace24

Browse files
authored
Merge pull request #5424 from cloudflare/jasnell/tech-debt-jsvalue-stuff
2 parents 5402d95 + 5b6fded commit e5ace24

File tree

2 files changed

+133
-11
lines changed

2 files changed

+133
-11
lines changed

src/workerd/jsg/jsvalue.c++

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,88 @@ JsValue JsObject::getPrototype(Lock& js) {
171171
return JsValue(inner->GetPrototypeV2());
172172
}
173173

174+
kj::String JsSymbol::description(Lock& js) const {
175+
auto desc = inner->Description(js.v8Isolate);
176+
if (desc.IsEmpty() || desc->IsUndefined()) {
177+
return kj::String();
178+
}
179+
return kj::str(desc);
180+
}
181+
182+
void JsSet::add(Lock& js, const JsValue& value) {
183+
check(inner->Add(js.v8Context(), value.inner));
184+
}
185+
186+
bool JsSet::has(Lock& js, const JsValue& value) const {
187+
return check(inner->Has(js.v8Context(), value.inner));
188+
}
189+
190+
bool JsSet::delete_(Lock& js, const JsValue& value) {
191+
return check(inner->Delete(js.v8Context(), value.inner));
192+
}
193+
194+
void JsSet::addAll(Lock& js, kj::ArrayPtr<const JsValue> values) {
195+
for (const JsValue& value: values) {
196+
check(inner->Add(js.v8Context(), value.inner));
197+
}
198+
}
199+
200+
void JsSet::clear() {
201+
inner->Clear();
202+
}
203+
204+
size_t JsSet::size() const {
205+
return inner->Size();
206+
}
207+
208+
JsSet::operator JsArray() const {
209+
return JsArray(inner->AsArray());
210+
}
211+
212+
kj::Maybe<int32_t> JsInt32::value(Lock& js) const {
213+
KJ_ASSERT(!inner.IsEmpty());
214+
int32_t value;
215+
// The Int32Value(...) operation can fail with a JS exception, in which case
216+
// we return kj::none and the error should be allowed to propagate.
217+
if (inner->Int32Value(js.v8Context()).To(&value)) {
218+
return value;
219+
}
220+
return kj::none;
221+
}
222+
223+
kj::Maybe<uint32_t> JsUint32::value(Lock& js) const {
224+
KJ_ASSERT(!inner.IsEmpty());
225+
uint32_t value;
226+
// The Uint32Value(...) operation can fail with a JS exception, in which case
227+
// we return kj::none and the error should be allowed to propagate.
228+
if (inner->Uint32Value(js.v8Context()).To(&value)) {
229+
return value;
230+
}
231+
return kj::none;
232+
};
233+
234+
kj::Maybe<int64_t> JsBigInt::toInt64(Lock& js) const {
235+
KJ_ASSERT(!inner.IsEmpty());
236+
bool lossless = false;
237+
int64_t value = inner->Int64Value(&lossless);
238+
if (!lossless) {
239+
js.v8Isolate->ThrowException(js.rangeError("BigInt value does not fit in int64_t"));
240+
return kj::none;
241+
}
242+
return value;
243+
}
244+
245+
kj::Maybe<uint64_t> JsBigInt::toUint64(Lock& js) const {
246+
KJ_ASSERT(!inner.IsEmpty());
247+
bool lossless = false;
248+
uint64_t value = inner->Uint64Value(&lossless);
249+
if (!lossless) {
250+
js.v8Isolate->ThrowException(js.rangeError("BigInt value does not fit in uint64_t"));
251+
return kj::none;
252+
}
253+
return value;
254+
}
255+
174256
kj::Maybe<double> JsNumber::value(Lock& js) const {
175257
KJ_ASSERT(!inner.IsEmpty());
176258
double value;

src/workerd/jsg/jsvalue.h

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -334,19 +334,59 @@ class JsProxy final: public JsBase<v8::Proxy, JsProxy> {
334334
using JsBase<v8::Proxy, JsProxy>::JsBase;
335335
};
336336

337-
#define V(Name) \
338-
class Js##Name final: public JsBase<v8::Name, Js##Name> { \
339-
public: \
340-
using JsBase<v8::Name, Js##Name>::JsBase; \
341-
};
337+
class JsSymbol final: public JsBase<v8::Symbol, JsSymbol> {
338+
public:
339+
kj::String description(Lock& js) const KJ_WARN_UNUSED_RESULT;
342340

343-
V(Symbol)
344-
V(BigInt)
345-
V(Int32)
346-
V(Uint32)
347-
V(Set)
341+
using JsBase<v8::Symbol, JsSymbol>::JsBase;
342+
};
348343

349-
#undef V
344+
class JsSet final: public JsBase<v8::Set, JsSet> {
345+
public:
346+
void add(Lock& js, const JsValue& value);
347+
bool has(Lock& js, const JsValue& value) const;
348+
bool delete_(Lock& js, const JsValue& value);
349+
void clear();
350+
size_t size() const;
351+
352+
template <IsJsValue... Args>
353+
void addAll(Lock& js, Args... args) {
354+
(check(inner->Add(js.v8Context(), args.inner)), ...);
355+
}
356+
357+
void addAll(Lock& js, kj::ArrayPtr<const JsValue> values);
358+
359+
operator JsArray() const;
360+
361+
using JsBase<v8::Set, JsSet>::JsBase;
362+
};
363+
364+
class JsBigInt final: public JsBase<v8::BigInt, JsBigInt> {
365+
public:
366+
// If the BigInt value does not fit in int64_t, returns kj::none
367+
// and schedules an exception on the isolate.
368+
kj::Maybe<int64_t> toInt64(Lock& js) const KJ_WARN_UNUSED_RESULT;
369+
370+
// If the BigInt value does not fit in int64_t, returns kj::none
371+
// and schedules an exception on the isolate.
372+
kj::Maybe<uint64_t> toUint64(Lock& js) const KJ_WARN_UNUSED_RESULT;
373+
374+
using JsBase<v8::BigInt, JsBigInt>::JsBase;
375+
};
376+
377+
class JsInt32 final: public JsBase<v8::Int32, JsInt32> {
378+
public:
379+
kj::Maybe<int32_t> value(Lock& js) const KJ_WARN_UNUSED_RESULT;
380+
381+
using JsBase<v8::Int32, JsInt32>::JsBase;
382+
};
383+
384+
class JsUint32 final: public JsBase<v8::Uint32, JsUint32> {
385+
public:
386+
kj::Maybe<uint32_t> value(Lock& js) const KJ_WARN_UNUSED_RESULT;
387+
388+
using JsBase<v8::Uint32, JsUint32>::JsBase;
389+
};
350390

351391
class JsNumber final: public JsBase<v8::Number, JsNumber> {
352392
public:

0 commit comments

Comments
 (0)