Skip to content

Commit d8a9898

Browse files
tmikovfacebook-github-bot
authored andcommitted
Convenience improvements to MutableHandle
Summary: - Make it copyable. It is extremely annoying otherwise. - Add castAndSetHermesValue() Differential Revision: D76012422
1 parent 881096e commit d8a9898

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

include/hermes/VM/Handle.h

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ class PinnedValue : private PinnedHermesValue {
283283
/// This is the base object factoring out common code from the type-specific
284284
/// versions.
285285
class HandleBase {
286+
template <typename U>
287+
friend class MutableHandle;
286288
#ifndef NDEBUG
287289
/// In debug mode we store the GCScope that created us so we can update its
288290
/// active handle count in our destructor.
@@ -544,9 +546,6 @@ static_assert(
544546
/// explicit as possible by using this class.
545547
template <typename T>
546548
class MutableHandle : public Handle<T> {
547-
MutableHandle(const MutableHandle &) = delete;
548-
void operator=(const MutableHandle &) = delete;
549-
550549
/// Alias a MutableHandle with a non-movable HermesValue without any checks.
551550
explicit MutableHandle(PinnedHermesValue *valueAddr, bool dummy)
552551
: Handle<T>(valueAddr, dummy) {}
@@ -564,6 +563,16 @@ class MutableHandle : public Handle<T> {
564563
/// type.
565564
/* implicit */ MutableHandle(const PinnedValue<T> &pv) : Handle<T>(pv) {}
566565

566+
/// Copy constructor.
567+
MutableHandle(const MutableHandle &sc) : Handle<T>(sc) {}
568+
569+
/// Copy constructor from MutableHandle<U> where U is compatible with T.
570+
template <
571+
typename U,
572+
typename =
573+
typename std::enable_if<IsHermesValueConvertible<T, U>::value>::type>
574+
MutableHandle(const MutableHandle<U> &sc) : Handle<T>(sc) {}
575+
567576
/// A move constructor.
568577
MutableHandle(MutableHandle &&sc) : Handle<T>(std::move(sc)) {}
569578

@@ -591,6 +600,19 @@ class MutableHandle : public Handle<T> {
591600
*HandleBase::handleRef() = HermesValueTraits<T>::encode(value);
592601
}
593602

603+
/// Assign the HermesValue \p val to this MutableHandle, asserting that it
604+
/// has type U which is compatible with T. This allows assigning a HermesValue
605+
/// with a known type to the PinnedValue without having to extract a
606+
/// pointer/symbol from it only to then re-encode it.
607+
template <
608+
typename U,
609+
typename =
610+
typename std::enable_if<IsHermesValueConvertible<U, T>::value>::type>
611+
void castAndSetHermesValue(HermesValue val) {
612+
HermesValueCast<U>::assertValid(val);
613+
*HandleBase::handleRef() = val;
614+
}
615+
594616
/// Create a MutableHandle from a pinned HermesValue and assert that the value
595617
/// has the correct type.
596618
static MutableHandle<T> vmcast(PinnedHermesValue *valueAddr) {
@@ -613,6 +635,19 @@ class MutableHandle : public Handle<T> {
613635
// register before we've read it if we used this method on it.
614636
return MutableHandle<T>(valueAddr, true);
615637
}
638+
639+
/// A version of \c aliasForOutput() that takes a \c MutableHandle<U>.
640+
template <
641+
typename U,
642+
typename =
643+
typename std::enable_if<IsHermesValueConvertible<T, U>::value>::type>
644+
static MutableHandle aliasForOutput(MutableHandle<U> &other) {
645+
return MutableHandle(other.handleRef(), true);
646+
}
647+
648+
PinnedHermesValue *unsafeGetPinnedHermesValue() {
649+
return HandleBase::handleRef();
650+
}
616651
} HERMES_ATTRIBUTE_WARN_UNUSED_VARIABLES;
617652

618653
static_assert(

0 commit comments

Comments
 (0)