Commit b3d793e4 authored by jochen's avatar jochen Committed by Commit bot

[api] Introduce ReturnValue::Get

This is a convenience API that an embedder can use to do final checks on
the return value. Note that this creates a new handle and thus defeats
the performance optimization done for ReturnValue - an embedder should
only use this in non-performance critical code paths.

BUG=
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/1875263003

Cr-Commit-Position: refs/heads/master@{#35409}
parent 0f0d3494
......@@ -330,6 +330,8 @@ class Local {
template <class F1, class F2, class F3>
friend class PersistentValueMapBase;
template<class F1, class F2> friend class PersistentValueVector;
template <class F>
friend class ReturnValue;
explicit V8_INLINE Local(T* that) : val_(that) {}
V8_INLINE static Local<T> New(Isolate* isolate, T* that);
......@@ -3127,12 +3129,17 @@ class ReturnValue {
V8_INLINE void SetUndefined();
V8_INLINE void SetEmptyString();
// Convenience getter for Isolate
V8_INLINE Isolate* GetIsolate();
V8_INLINE Isolate* GetIsolate() const;
// Pointer setter: Uncompilable to prevent inadvertent misuse.
template <typename S>
V8_INLINE void Set(S* whatever);
// Getter. Creates a new Local<> so it comes with a certain performance
// hit. If the ReturnValue was not yet set, this will return the undefined
// value.
V8_INLINE Local<Value> Get() const;
private:
template<class F> friend class ReturnValue;
template<class F> friend class FunctionCallbackInfo;
......@@ -7334,6 +7341,7 @@ class Internals {
kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset + kApiInt64Size +
kApiPointerSize;
static const int kUndefinedValueRootIndex = 4;
static const int kTheHoleValueRootIndex = 5;
static const int kNullValueRootIndex = 6;
static const int kTrueValueRootIndex = 7;
static const int kFalseValueRootIndex = 8;
......@@ -7813,14 +7821,22 @@ void ReturnValue<T>::SetEmptyString() {
*value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex);
}
template<typename T>
Isolate* ReturnValue<T>::GetIsolate() {
template <typename T>
Isolate* ReturnValue<T>::GetIsolate() const {
// Isolate is always the pointer below the default value on the stack.
return *reinterpret_cast<Isolate**>(&value_[-2]);
}
template<typename T>
template<typename S>
template <typename T>
Local<Value> ReturnValue<T>::Get() const {
typedef internal::Internals I;
if (*value_ == *I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex))
return Local<Value>(*Undefined(GetIsolate()));
return Local<Value>::New(GetIsolate(), reinterpret_cast<Value*>(value_));
}
template <typename T>
template <typename S>
void ReturnValue<T>::Set(S* whatever) {
// Uncompilable to prevent inadvertent misuse.
TYPE_CHECK(S*, Primitive);
......
......@@ -549,6 +549,7 @@ class Heap {
STATIC_ASSERT(kUndefinedValueRootIndex ==
Internals::kUndefinedValueRootIndex);
STATIC_ASSERT(kTheHoleValueRootIndex == Internals::kTheHoleValueRootIndex);
STATIC_ASSERT(kNullValueRootIndex == Internals::kNullValueRootIndex);
STATIC_ASSERT(kTrueValueRootIndex == Internals::kTrueValueRootIndex);
STATIC_ASSERT(kFalseValueRootIndex == Internals::kFalseValueRootIndex);
......
......@@ -18,6 +18,12 @@ static void CheckReturnValue(const T& t, i::Address callback) {
CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
// Verify reset
bool is_runtime = (*o)->IsTheHole();
if (is_runtime) {
CHECK(rv.Get()->IsUndefined());
} else {
i::Handle<i::Object> v = v8::Utils::OpenHandle(*rv.Get());
CHECK_EQ(*v, *o);
}
rv.Set(true);
CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined());
rv.Set(v8::Local<v8::Object>());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment