Skip to content

Commit

Permalink
Allow PseudoHandle casting and easier assignment.
Browse files Browse the repository at this point in the history
Summary:
`PinnedHermesValue` can now be assigned to from a `PseudoHandle`,
so this allows assignment into registers and such without having
to remember to invalidate the `PseudoHandle` afterwards.

Add `vmcast` and `dyn_vmcast` static functions to `PseudoHandle`
which are analogous to `Handle`.
The use of the latter does require invalidating the initial handle,
so it doesn't really work for assignment in the condition of an `if`
statement directly, but is sufficient for most other use cases.

Reviewed By: tmikov

Differential Revision: D19746814

fbshipit-source-id: 84ed028279c0924b630fad37db728dfa79ca9b96
  • Loading branch information
avp authored and facebook-github-bot committed May 7, 2020
1 parent d7a38bb commit 6f5bcfd
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
17 changes: 17 additions & 0 deletions include/hermes/VM/Handle-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,28 @@

#include "hermes/VM/Handle.h"

#include "hermes/VM/Casting.h"
#include "hermes/VM/HandleRootOwner.h"

namespace hermes {
namespace vm {

template <typename T>
template <typename U>
inline PseudoHandle<T> PseudoHandle<T>::vmcast(PseudoHandle<U> &&other) {
auto result = PseudoHandle<T>::create(hermes::vm::vmcast<T>(other.get()));
other.invalidate();
return result;
}

template <typename T>
template <typename U>
inline PseudoHandle<T> PseudoHandle<T>::dyn_vmcast(PseudoHandle<U> &&other) {
auto result = PseudoHandle<T>::create(hermes::vm::dyn_vmcast<T>(other.get()));
other.invalidate();
return result;
}

/// Allocate a new handle in the current GCScope
inline HandleBase::HandleBase(HandleRootOwner *runtime, HermesValue value)
: handle_(runtime->newHandle(value)) {
Expand Down
6 changes: 6 additions & 0 deletions include/hermes/VM/Handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ class PseudoHandle {
static PseudoHandle<T> create(value_type value) {
return PseudoHandle<T>(value);
}

template <typename U>
static inline PseudoHandle vmcast(PseudoHandle<U> &&other);

template <typename U>
static inline PseudoHandle dyn_vmcast(PseudoHandle<U> &&other);
};

/// A HermesValue in the current GCScope which is trackable by the GC and will
Expand Down
8 changes: 8 additions & 0 deletions include/hermes/VM/HermesValue-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define HERMES_VM_HERMESVALUE_INLINE_H

#include "hermes/Support/SlowAssert.h"
#include "hermes/VM/Handle.h"
#include "hermes/VM/HermesValue.h"

#include "hermes/VM/GC.h"
Expand All @@ -21,6 +22,13 @@ void HermesValue::setInGC(HermesValue hv, GC *gc) {
assert(gc->inGC());
}

template <typename T>
inline PinnedHermesValue &PinnedHermesValue::operator=(PseudoHandle<T> &&hv) {
setNoBarrier(hv.getHermesValue());
hv.invalidate();
return *this;
}

template <typename NeedsBarriers>
inline void GCHermesValue::set(HermesValue hv, GC *gc) {
HERMES_SLOW_ASSERT(
Expand Down
4 changes: 4 additions & 0 deletions include/hermes/VM/HermesValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ namespace hermes {
namespace vm {

class StringPrimitive;
template <typename T>
class PseudoHandle;

template <typename T>
class PseudoHandle;
Expand Down Expand Up @@ -508,6 +510,8 @@ class PinnedHermesValue : public HermesValue {
setNoBarrier(hv);
return *this;
}
template <typename T>
inline PinnedHermesValue &operator=(PseudoHandle<T> &&hv);
} HERMES_ATTRIBUTE_WARN_UNUSED_VARIABLES;

// All HermesValues stored in heap object should be of this
Expand Down

0 comments on commit 6f5bcfd

Please sign in to comment.