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 { ...@@ -330,6 +330,8 @@ class Local {
template <class F1, class F2, class F3> template <class F1, class F2, class F3>
friend class PersistentValueMapBase; friend class PersistentValueMapBase;
template<class F1, class F2> friend class PersistentValueVector; template<class F1, class F2> friend class PersistentValueVector;
template <class F>
friend class ReturnValue;
explicit V8_INLINE Local(T* that) : val_(that) {} explicit V8_INLINE Local(T* that) : val_(that) {}
V8_INLINE static Local<T> New(Isolate* isolate, T* that); V8_INLINE static Local<T> New(Isolate* isolate, T* that);
...@@ -3127,12 +3129,17 @@ class ReturnValue { ...@@ -3127,12 +3129,17 @@ class ReturnValue {
V8_INLINE void SetUndefined(); V8_INLINE void SetUndefined();
V8_INLINE void SetEmptyString(); V8_INLINE void SetEmptyString();
// Convenience getter for Isolate // Convenience getter for Isolate
V8_INLINE Isolate* GetIsolate(); V8_INLINE Isolate* GetIsolate() const;
// Pointer setter: Uncompilable to prevent inadvertent misuse. // Pointer setter: Uncompilable to prevent inadvertent misuse.
template <typename S> template <typename S>
V8_INLINE void Set(S* whatever); 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: private:
template<class F> friend class ReturnValue; template<class F> friend class ReturnValue;
template<class F> friend class FunctionCallbackInfo; template<class F> friend class FunctionCallbackInfo;
...@@ -7334,6 +7341,7 @@ class Internals { ...@@ -7334,6 +7341,7 @@ class Internals {
kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset + kApiInt64Size + kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset + kApiInt64Size +
kApiPointerSize; kApiPointerSize;
static const int kUndefinedValueRootIndex = 4; static const int kUndefinedValueRootIndex = 4;
static const int kTheHoleValueRootIndex = 5;
static const int kNullValueRootIndex = 6; static const int kNullValueRootIndex = 6;
static const int kTrueValueRootIndex = 7; static const int kTrueValueRootIndex = 7;
static const int kFalseValueRootIndex = 8; static const int kFalseValueRootIndex = 8;
...@@ -7813,14 +7821,22 @@ void ReturnValue<T>::SetEmptyString() { ...@@ -7813,14 +7821,22 @@ void ReturnValue<T>::SetEmptyString() {
*value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); *value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex);
} }
template<typename T> template <typename T>
Isolate* ReturnValue<T>::GetIsolate() { Isolate* ReturnValue<T>::GetIsolate() const {
// Isolate is always the pointer below the default value on the stack. // Isolate is always the pointer below the default value on the stack.
return *reinterpret_cast<Isolate**>(&value_[-2]); return *reinterpret_cast<Isolate**>(&value_[-2]);
} }
template<typename T> template <typename T>
template<typename S> 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) { void ReturnValue<T>::Set(S* whatever) {
// Uncompilable to prevent inadvertent misuse. // Uncompilable to prevent inadvertent misuse.
TYPE_CHECK(S*, Primitive); TYPE_CHECK(S*, Primitive);
......
...@@ -549,6 +549,7 @@ class Heap { ...@@ -549,6 +549,7 @@ class Heap {
STATIC_ASSERT(kUndefinedValueRootIndex == STATIC_ASSERT(kUndefinedValueRootIndex ==
Internals::kUndefinedValueRootIndex); Internals::kUndefinedValueRootIndex);
STATIC_ASSERT(kTheHoleValueRootIndex == Internals::kTheHoleValueRootIndex);
STATIC_ASSERT(kNullValueRootIndex == Internals::kNullValueRootIndex); STATIC_ASSERT(kNullValueRootIndex == Internals::kNullValueRootIndex);
STATIC_ASSERT(kTrueValueRootIndex == Internals::kTrueValueRootIndex); STATIC_ASSERT(kTrueValueRootIndex == Internals::kTrueValueRootIndex);
STATIC_ASSERT(kFalseValueRootIndex == Internals::kFalseValueRootIndex); STATIC_ASSERT(kFalseValueRootIndex == Internals::kFalseValueRootIndex);
......
...@@ -18,6 +18,12 @@ static void CheckReturnValue(const T& t, i::Address callback) { ...@@ -18,6 +18,12 @@ static void CheckReturnValue(const T& t, i::Address callback) {
CHECK((*o)->IsTheHole() || (*o)->IsUndefined()); CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
// Verify reset // Verify reset
bool is_runtime = (*o)->IsTheHole(); 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); rv.Set(true);
CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined()); CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined());
rv.Set(v8::Local<v8::Object>()); 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