Commit 3f027300 authored by verwaest's avatar verwaest Committed by Commit bot

Simplify the interface of PropertyCallbackArguments

Use internal handles as API, and move boilerplate code into the call wrappers.
BUG=

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

Cr-Commit-Position: refs/heads/master@{#34684}
parent d30af81e
...@@ -4,82 +4,28 @@ ...@@ -4,82 +4,28 @@
#include "src/api-arguments.h" #include "src/api-arguments.h"
#include "src/api.h"
#include "src/vm-state-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
template <typename T> Handle<Object> FunctionCallbackArguments::Call(FunctionCallback f) {
template <typename V>
v8::Local<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
// Check the ReturnValue.
Object** handle = &this->begin()[kReturnValueOffset];
// Nothing was set, return empty handle as per previous behaviour.
if ((*handle)->IsTheHole()) return v8::Local<V>();
return Utils::Convert<Object, V>(Handle<Object>(handle));
}
v8::Local<v8::Value> FunctionCallbackArguments::Call(FunctionCallback f) {
Isolate* isolate = this->isolate(); Isolate* isolate = this->isolate();
VMState<EXTERNAL> state(isolate); VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
FunctionCallbackInfo<v8::Value> info(begin(), argv_, argc_, FunctionCallbackInfo<v8::Value> info(begin(), argv_, argc_,
is_construct_call_); is_construct_call_);
f(info); f(info);
return GetReturnValue<v8::Value>(isolate); return GetReturnValue<Object>(isolate);
} }
#define WRITE_CALL_0(Function, ReturnValue) \ Handle<JSObject> PropertyCallbackArguments::Call(
v8::Local<ReturnValue> PropertyCallbackArguments::Call(Function f) { \ IndexedPropertyEnumeratorCallback f) {
Isolate* isolate = this->isolate(); \ Isolate* isolate = this->isolate();
VMState<EXTERNAL> state(isolate); \ VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \ ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
PropertyCallbackInfo<ReturnValue> info(begin()); \ PropertyCallbackInfo<v8::Array> info(begin());
f(info); \ f(info);
return GetReturnValue<ReturnValue>(isolate); \ return GetReturnValue<JSObject>(isolate);
} }
#define WRITE_CALL_1(Function, ReturnValue, Arg1) \
v8::Local<ReturnValue> PropertyCallbackArguments::Call(Function f, \
Arg1 arg1) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ReturnValue> info(begin()); \
f(arg1, info); \
return GetReturnValue<ReturnValue>(isolate); \
}
#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2) \
v8::Local<ReturnValue> PropertyCallbackArguments::Call( \
Function f, Arg1 arg1, Arg2 arg2) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ReturnValue> info(begin()); \
f(arg1, arg2, info); \
return GetReturnValue<ReturnValue>(isolate); \
}
#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \
void PropertyCallbackArguments::Call(Function f, Arg1 arg1, Arg2 arg2) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ReturnValue> info(begin()); \
f(arg1, arg2, info); \
}
FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2)
FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID)
#undef WRITE_CALL_0
#undef WRITE_CALL_1
#undef WRITE_CALL_2
#undef WRITE_CALL_2_VOID
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -5,37 +5,14 @@ ...@@ -5,37 +5,14 @@
#ifndef V8_API_ARGUMENTS_H_ #ifndef V8_API_ARGUMENTS_H_
#define V8_API_ARGUMENTS_H_ #define V8_API_ARGUMENTS_H_
#include "src/api.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/tracing/trace-event.h" #include "src/tracing/trace-event.h"
#include "src/vm-state-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// For each type of callback, we have a list of arguments
// They are used to generate the Call() functions below
// These aren't included in the list as they have duplicate signatures
// F(GenericNamedPropertyEnumeratorCallback, ...)
// F(GenericNamedPropertyGetterCallback, ...)
#define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
F(IndexedPropertyEnumeratorCallback, v8::Array)
#define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
F(AccessorNameGetterCallback, v8::Value, v8::Local<v8::Name>) \
F(GenericNamedPropertyQueryCallback, v8::Integer, v8::Local<v8::Name>) \
F(GenericNamedPropertyDeleterCallback, v8::Boolean, v8::Local<v8::Name>) \
F(IndexedPropertyGetterCallback, v8::Value, uint32_t) \
F(IndexedPropertyQueryCallback, v8::Integer, uint32_t) \
F(IndexedPropertyDeleterCallback, v8::Boolean, uint32_t)
#define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \
F(GenericNamedPropertySetterCallback, v8::Value, v8::Local<v8::Name>, \
v8::Local<v8::Value>) \
F(IndexedPropertySetterCallback, v8::Value, uint32_t, v8::Local<v8::Value>)
#define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
F(AccessorNameSetterCallback, void, v8::Local<v8::Name>, v8::Local<v8::Value>)
// Custom arguments replicate a small segment of stack that can be // Custom arguments replicate a small segment of stack that can be
// accessed through an Arguments object the same way the actual stack // accessed through an Arguments object the same way the actual stack
// can. // can.
...@@ -68,13 +45,25 @@ class CustomArguments : public CustomArgumentsBase<T::kArgsLength> { ...@@ -68,13 +45,25 @@ class CustomArguments : public CustomArgumentsBase<T::kArgsLength> {
explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {} explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
template <typename V> template <typename V>
v8::Local<V> GetReturnValue(Isolate* isolate); Handle<V> GetReturnValue(Isolate* isolate);
inline Isolate* isolate() { inline Isolate* isolate() {
return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]); return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]);
} }
}; };
template <typename T>
template <typename V>
Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
// Check the ReturnValue.
Object** handle = &this->begin()[kReturnValueOffset];
// Nothing was set, return empty handle as per previous behaviour.
if ((*handle)->IsTheHole()) return Handle<V>();
Handle<V> result = Handle<V>::cast(Handle<Object>(handle));
result->VerifyApiCallResultType();
return result;
}
class PropertyCallbackArguments class PropertyCallbackArguments
: public CustomArguments<PropertyCallbackInfo<Value> > { : public CustomArguments<PropertyCallbackInfo<Value> > {
public: public:
...@@ -117,27 +106,91 @@ class PropertyCallbackArguments ...@@ -117,27 +106,91 @@ class PropertyCallbackArguments
* and used if it's been set to anything inside the callback. * and used if it's been set to anything inside the callback.
* New style callbacks always use the return value. * New style callbacks always use the return value.
*/ */
#define WRITE_CALL_0(Function, ReturnValue) \ Handle<JSObject> Call(IndexedPropertyEnumeratorCallback f);
v8::Local<ReturnValue> Call(Function f);
#define FOR_EACH_CALLBACK_TABLE_MAPPING_1_NAME(F) \
F(AccessorNameGetterCallback, "get", v8::Value, Object) \
F(GenericNamedPropertyQueryCallback, "has", v8::Integer, Object) \
F(GenericNamedPropertyDeleterCallback, "delete", v8::Boolean, Object)
#define WRITE_CALL_1_NAME(Function, type, ApiReturn, InternalReturn) \
Handle<InternalReturn> Call(Function f, Handle<Name> name) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ApiReturn> info(begin()); \
LOG(isolate, \
ApiNamedPropertyAccess("interceptor-named-" type, holder(), *name)); \
f(v8::Utils::ToLocal(name), info); \
return GetReturnValue<InternalReturn>(isolate); \
}
#define WRITE_CALL_1(Function, ReturnValue, Arg1) \ FOR_EACH_CALLBACK_TABLE_MAPPING_1_NAME(WRITE_CALL_1_NAME)
v8::Local<ReturnValue> Call(Function f, Arg1 arg1);
#undef FOR_EACH_CALLBACK_TABLE_MAPPING_1_NAME
#undef WRITE_CALL_1_NAME
#define FOR_EACH_CALLBACK_TABLE_MAPPING_1_INDEX(F) \
F(IndexedPropertyGetterCallback, "get", v8::Value, Object) \
F(IndexedPropertyQueryCallback, "has", v8::Integer, Object) \
F(IndexedPropertyDeleterCallback, "delete", v8::Boolean, Object)
#define WRITE_CALL_1_INDEX(Function, type, ApiReturn, InternalReturn) \
Handle<InternalReturn> Call(Function f, uint32_t index) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ApiReturn> info(begin()); \
LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-" type, \
holder(), index)); \
f(index, info); \
return GetReturnValue<InternalReturn>(isolate); \
}
#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2) \ FOR_EACH_CALLBACK_TABLE_MAPPING_1_INDEX(WRITE_CALL_1_INDEX)
v8::Local<ReturnValue> Call(Function f, Arg1 arg1, Arg2 arg2);
#undef FOR_EACH_CALLBACK_TABLE_MAPPING_1_INDEX
#undef WRITE_CALL_1_INDEX
Handle<Object> Call(GenericNamedPropertySetterCallback f, Handle<Name> name,
Handle<Object> value) {
Isolate* isolate = this->isolate();
VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
PropertyCallbackInfo<v8::Value> info(begin());
LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-set", holder(), *name));
f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
return GetReturnValue<Object>(isolate);
}
#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \ Handle<Object> Call(IndexedPropertySetterCallback f, uint32_t index,
void Call(Function f, Arg1 arg1, Arg2 arg2); Handle<Object> value) {
Isolate* isolate = this->isolate();
VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
PropertyCallbackInfo<v8::Value> info(begin());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-set", holder(), index));
f(index, v8::Utils::ToLocal(value), info);
return GetReturnValue<Object>(isolate);
}
FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0) void Call(AccessorNameSetterCallback f, Handle<Name> name,
FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1) Handle<Object> value) {
FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2) Isolate* isolate = this->isolate();
FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID) VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
PropertyCallbackInfo<void> info(begin());
LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-set", holder(), *name));
f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
}
#undef WRITE_CALL_0 private:
#undef WRITE_CALL_1 inline JSObject* holder() {
#undef WRITE_CALL_2 return JSObject::cast(this->begin()[T::kHolderIndex]);
#undef WRITE_CALL_2_VOID }
}; };
class FunctionCallbackArguments class FunctionCallbackArguments
...@@ -187,7 +240,7 @@ class FunctionCallbackArguments ...@@ -187,7 +240,7 @@ class FunctionCallbackArguments
* and used if it's been set to anything inside the callback. * and used if it's been set to anything inside the callback.
* New style callbacks always use the return value. * New style callbacks always use the return value.
*/ */
v8::Local<v8::Value> Call(FunctionCallback f); Handle<Object> Call(FunctionCallback f);
private: private:
internal::Object** argv_; internal::Object** argv_;
......
...@@ -3970,14 +3970,8 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( ...@@ -3970,14 +3970,8 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
args.length() - 1, args.length() - 1,
is_construct); is_construct);
v8::Local<v8::Value> value = custom.Call(callback); Handle<Object> result = custom.Call(callback);
Handle<Object> result; if (result.is_null()) result = isolate->factory()->undefined_value();
if (value.IsEmpty()) {
result = isolate->factory()->undefined_value();
} else {
result = v8::Utils::OpenHandle(*value);
result->VerifyApiCallResultType();
}
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!is_construct || result->IsJSObject()) { if (!is_construct || result->IsJSObject()) {
...@@ -4144,8 +4138,6 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function, ...@@ -4144,8 +4138,6 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
Isolate* isolate, bool is_construct_call, Isolate* isolate, bool is_construct_call,
BuiltinArguments<BuiltinExtraArguments::kNone> args) { BuiltinArguments<BuiltinExtraArguments::kNone> args) {
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
// Get the object called. // Get the object called.
...@@ -4180,12 +4172,11 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( ...@@ -4180,12 +4172,11 @@ MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
&args[0] - 1, &args[0] - 1,
args.length() - 1, args.length() - 1,
is_construct_call); is_construct_call);
v8::Local<v8::Value> value = custom.Call(callback); Handle<Object> result_handle = custom.Call(callback);
if (value.IsEmpty()) { if (result_handle.is_null()) {
result = heap->undefined_value(); result = isolate->heap()->undefined_value();
} else { } else {
result = *reinterpret_cast<Object**>(*value); result = *result_handle;
result->VerifyApiCallResultType();
} }
} }
// Check for exceptions and return result. // Check for exceptions and return result.
......
...@@ -2761,12 +2761,11 @@ RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) { ...@@ -2761,12 +2761,11 @@ RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) {
FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address); FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address);
DCHECK(fun != NULL); DCHECK(fun != NULL);
LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
Object::ShouldThrow should_throw = Object::ShouldThrow should_throw =
is_sloppy(language_mode) ? Object::DONT_THROW : Object::THROW_ON_ERROR; is_sloppy(language_mode) ? Object::DONT_THROW : Object::THROW_ON_ERROR;
PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver, PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
*holder, should_throw); *holder, should_throw);
custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); custom_args.Call(fun, name, value);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *value; return *value;
} }
...@@ -2796,19 +2795,15 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptorOnly) { ...@@ -2796,19 +2795,15 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptorOnly) {
v8::GenericNamedPropertyGetterCallback getter = v8::GenericNamedPropertyGetterCallback getter =
v8::ToCData<v8::GenericNamedPropertyGetterCallback>( v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
interceptor->getter()); interceptor->getter());
LOG(isolate, ApiNamedPropertyAccess("interceptor-named-get", *holder, *name)); Handle<Object> result = arguments.Call(getter, name);
v8::Local<v8::Value> result =
arguments.Call(getter, v8::Utils::ToLocal(name));
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
Handle<Object> result_internal; Handle<Object> result_internal;
if (result.IsEmpty()) { if (result.is_null()) {
return isolate->heap()->no_interceptor_result_sentinel(); return isolate->heap()->no_interceptor_result_sentinel();
} }
result_internal = v8::Utils::OpenHandle(*result); return *result;
result_internal->VerifyApiCallResultType();
return *result_internal;
} }
...@@ -2886,31 +2881,24 @@ RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { ...@@ -2886,31 +2881,24 @@ RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) {
uint32_t index = args.smi_at(1); uint32_t index = args.smi_at(1);
InterceptorInfo* interceptor = receiver->GetIndexedInterceptor(); InterceptorInfo* interceptor = receiver->GetIndexedInterceptor();
v8::Local<v8::Value> result;
PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
*receiver, Object::DONT_THROW); *receiver, Object::DONT_THROW);
v8::IndexedPropertyGetterCallback getter = v8::IndexedPropertyGetterCallback getter =
v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
LOG(isolate, Handle<Object> result = arguments.Call(getter, index);
ApiIndexedPropertyAccess("interceptor-indexed-get", *receiver, index));
result = arguments.Call(getter, index);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
Handle<Object> result_internal; if (result.is_null()) {
if (result.IsEmpty()) {
LookupIterator it(isolate, receiver, index, receiver); LookupIterator it(isolate, receiver, index, receiver);
DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
it.Next(); it.Next();
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result_internal, ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
Object::GetProperty(&it)); Object::GetProperty(&it));
} else {
result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
} }
return *result_internal; return *result;
} }
......
...@@ -1056,18 +1056,13 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { ...@@ -1056,18 +1056,13 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); v8::ToCData<v8::AccessorNameGetterCallback>(info->getter());
if (call_fun == nullptr) return isolate->factory()->undefined_value(); if (call_fun == nullptr) return isolate->factory()->undefined_value();
LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name));
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
Object::DONT_THROW); Object::DONT_THROW);
v8::Local<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(name)); Handle<Object> result = args.Call(call_fun, name);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) { if (result.is_null()) return ReadAbsentProperty(isolate, receiver, name);
return ReadAbsentProperty(isolate, receiver, name);
}
Handle<Object> return_value = v8::Utils::OpenHandle(*result);
return_value->VerifyApiCallResultType();
// Rebox handle before return. // Rebox handle before return.
return handle(*return_value, isolate); return handle(*result, isolate);
} }
// Regular accessor. // Regular accessor.
...@@ -1131,10 +1126,9 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it, ...@@ -1131,10 +1126,9 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
// have a setter. // have a setter.
if (call_fun == nullptr) return Just(true); if (call_fun == nullptr) return Just(true);
LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
should_throw); should_throw);
args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); args.Call(call_fun, name, value);
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
return Just(true); return Just(true);
} }
...@@ -4072,7 +4066,7 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, ...@@ -4072,7 +4066,7 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
if (interceptor->setter()->IsUndefined()) return Just(false); if (interceptor->setter()->IsUndefined()) return Just(false);
Handle<JSObject> holder = it->GetHolder<JSObject>(); Handle<JSObject> holder = it->GetHolder<JSObject>();
v8::Local<v8::Value> result; bool result;
PropertyCallbackArguments args(isolate, interceptor->data(), PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder, should_throw); *it->GetReceiver(), *holder, should_throw);
...@@ -4080,9 +4074,9 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, ...@@ -4080,9 +4074,9 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
uint32_t index = it->index(); uint32_t index = it->index();
v8::IndexedPropertySetterCallback setter = v8::IndexedPropertySetterCallback setter =
v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
LOG(isolate, // TODO(neis): In the future, we may want to actually return the
ApiIndexedPropertyAccess("interceptor-indexed-set", *holder, index)); // interceptor's result, which then should be a boolean.
result = args.Call(setter, index, v8::Utils::ToLocal(value)); result = !args.Call(setter, index, value).is_null();
} else { } else {
Handle<Name> name = it->name(); Handle<Name> name = it->name();
DCHECK(!name->IsPrivate()); DCHECK(!name->IsPrivate());
...@@ -4094,21 +4088,11 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, ...@@ -4094,21 +4088,11 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
v8::GenericNamedPropertySetterCallback setter = v8::GenericNamedPropertySetterCallback setter =
v8::ToCData<v8::GenericNamedPropertySetterCallback>( v8::ToCData<v8::GenericNamedPropertySetterCallback>(
interceptor->setter()); interceptor->setter());
LOG(it->isolate(), result = !args.Call(setter, name, value).is_null();
ApiNamedPropertyAccess("interceptor-named-set", *holder, *name));
result =
args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
} }
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
if (result.IsEmpty()) return Just(false); return Just(result);
#ifdef DEBUG
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
#endif
return Just(true);
// TODO(neis): In the future, we may want to actually return the interceptor's
// result, which then should be a boolean.
} }
...@@ -5421,13 +5405,11 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( ...@@ -5421,13 +5405,11 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
*it->GetReceiver(), *holder, *it->GetReceiver(), *holder,
Object::DONT_THROW); Object::DONT_THROW);
if (!interceptor->query()->IsUndefined()) { if (!interceptor->query()->IsUndefined()) {
v8::Local<v8::Integer> result; Handle<Object> result;
if (it->IsElement()) { if (it->IsElement()) {
uint32_t index = it->index(); uint32_t index = it->index();
v8::IndexedPropertyQueryCallback query = v8::IndexedPropertyQueryCallback query =
v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-has", *holder, index));
result = args.Call(query, index); result = args.Call(query, index);
} else { } else {
Handle<Name> name = it->name(); Handle<Name> name = it->name();
...@@ -5435,25 +5417,20 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( ...@@ -5435,25 +5417,20 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
v8::GenericNamedPropertyQueryCallback query = v8::GenericNamedPropertyQueryCallback query =
v8::ToCData<v8::GenericNamedPropertyQueryCallback>( v8::ToCData<v8::GenericNamedPropertyQueryCallback>(
interceptor->query()); interceptor->query());
LOG(isolate, result = args.Call(query, name);
ApiNamedPropertyAccess("interceptor-named-has", *holder, *name));
result = args.Call(query, v8::Utils::ToLocal(name));
} }
if (!result.IsEmpty()) { if (!result.is_null()) {
DCHECK(result->IsInt32()); int32_t value;
return Just(static_cast<PropertyAttributes>( CHECK(result->ToInt32(&value));
result->Int32Value(reinterpret_cast<v8::Isolate*>(isolate) return Just(static_cast<PropertyAttributes>(value));
->GetCurrentContext()).FromJust()));
} }
} else if (!interceptor->getter()->IsUndefined()) { } else if (!interceptor->getter()->IsUndefined()) {
// TODO(verwaest): Use GetPropertyWithInterceptor? // TODO(verwaest): Use GetPropertyWithInterceptor?
v8::Local<v8::Value> result; Handle<Object> result;
if (it->IsElement()) { if (it->IsElement()) {
uint32_t index = it->index(); uint32_t index = it->index();
v8::IndexedPropertyGetterCallback getter = v8::IndexedPropertyGetterCallback getter =
v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-get-has",
*holder, index));
result = args.Call(getter, index); result = args.Call(getter, index);
} else { } else {
Handle<Name> name = it->name(); Handle<Name> name = it->name();
...@@ -5461,11 +5438,9 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( ...@@ -5461,11 +5438,9 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
v8::GenericNamedPropertyGetterCallback getter = v8::GenericNamedPropertyGetterCallback getter =
v8::ToCData<v8::GenericNamedPropertyGetterCallback>( v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
interceptor->getter()); interceptor->getter());
LOG(isolate, result = args.Call(getter, name);
ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name));
result = args.Call(getter, v8::Utils::ToLocal(name));
} }
if (!result.IsEmpty()) return Just(DONT_ENUM); if (!result.is_null()) return Just(DONT_ENUM);
} }
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
...@@ -6077,13 +6052,11 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it, ...@@ -6077,13 +6052,11 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
PropertyCallbackArguments args(isolate, interceptor->data(), PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder, should_throw); *it->GetReceiver(), *holder, should_throw);
v8::Local<v8::Boolean> result; Handle<Object> result;
if (it->IsElement()) { if (it->IsElement()) {
uint32_t index = it->index(); uint32_t index = it->index();
v8::IndexedPropertyDeleterCallback deleter = v8::IndexedPropertyDeleterCallback deleter =
v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-delete", *holder, index));
result = args.Call(deleter, index); result = args.Call(deleter, index);
} else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) { } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) {
return Nothing<bool>(); return Nothing<bool>();
...@@ -6093,19 +6066,15 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it, ...@@ -6093,19 +6066,15 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
v8::GenericNamedPropertyDeleterCallback deleter = v8::GenericNamedPropertyDeleterCallback deleter =
v8::ToCData<v8::GenericNamedPropertyDeleterCallback>( v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
interceptor->deleter()); interceptor->deleter());
LOG(isolate, result = args.Call(deleter, name);
ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name));
result = args.Call(deleter, v8::Utils::ToLocal(name));
} }
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
if (result.IsEmpty()) return Nothing<bool>(); if (result.is_null()) return Nothing<bool>();
DCHECK(result->IsBoolean()); DCHECK(result->IsBoolean());
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
// Rebox CustomArguments::kReturnValueOffset before returning. // Rebox CustomArguments::kReturnValueOffset before returning.
return Just(result_internal->BooleanValue()); return Just(result->IsTrue());
} }
...@@ -8506,7 +8475,7 @@ static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate, ...@@ -8506,7 +8475,7 @@ static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate,
} }
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
*object, Object::DONT_THROW); *object, Object::DONT_THROW);
v8::Local<v8::Object> result; Handle<JSObject> result;
if (!interceptor->enumerator()->IsUndefined()) { if (!interceptor->enumerator()->IsUndefined()) {
Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator()); Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
const char* log_tag = type == kIndexed ? "interceptor-indexed-enum" const char* log_tag = type == kIndexed ? "interceptor-indexed-enum"
...@@ -8515,18 +8484,13 @@ static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate, ...@@ -8515,18 +8484,13 @@ static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate,
result = args.Call(enum_fun); result = args.Call(enum_fun);
} }
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
if (result.IsEmpty()) return Just(true); if (result.is_null()) return Just(true);
DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || DCHECK(result->IsJSArray() || result->HasSloppyArgumentsElements());
(v8::Utils::OpenHandle(*result)->IsJSObject() &&
Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))
->HasSloppyArgumentsElements()));
// The accumulator takes care of string/symbol filtering. // The accumulator takes care of string/symbol filtering.
if (type == kIndexed) { if (type == kIndexed) {
accumulator->AddElementKeysFromInterceptor( accumulator->AddElementKeysFromInterceptor(result);
Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)));
} else { } else {
accumulator->AddKeys(Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)), accumulator->AddKeys(result, DO_NOT_CONVERT);
DO_NOT_CONVERT);
} }
return Just(true); return Just(true);
} }
...@@ -16321,7 +16285,7 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, ...@@ -16321,7 +16285,7 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
} }
Handle<JSObject> holder = it->GetHolder<JSObject>(); Handle<JSObject> holder = it->GetHolder<JSObject>();
v8::Local<v8::Value> result; Handle<Object> result;
PropertyCallbackArguments args(isolate, interceptor->data(), PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder, *it->GetReceiver(), *holder,
Object::DONT_THROW); Object::DONT_THROW);
...@@ -16330,8 +16294,6 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, ...@@ -16330,8 +16294,6 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
uint32_t index = it->index(); uint32_t index = it->index();
v8::IndexedPropertyGetterCallback getter = v8::IndexedPropertyGetterCallback getter =
v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-get", *holder, index));
result = args.Call(getter, index); result = args.Call(getter, index);
} else { } else {
Handle<Name> name = it->name(); Handle<Name> name = it->name();
...@@ -16344,18 +16306,14 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, ...@@ -16344,18 +16306,14 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
v8::GenericNamedPropertyGetterCallback getter = v8::GenericNamedPropertyGetterCallback getter =
v8::ToCData<v8::GenericNamedPropertyGetterCallback>( v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
interceptor->getter()); interceptor->getter());
LOG(isolate, result = args.Call(getter, name);
ApiNamedPropertyAccess("interceptor-named-get", *holder, *name));
result = args.Call(getter, v8::Utils::ToLocal(name));
} }
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) return isolate->factory()->undefined_value(); if (result.is_null()) return isolate->factory()->undefined_value();
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
*done = true; *done = true;
// Rebox handle before return // Rebox handle before return
return handle(*result_internal, isolate); return handle(*result, isolate);
} }
......
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