diff --git a/include/v8.h b/include/v8.h index 89502cb915..c7e4552b4d 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1790,18 +1790,19 @@ class Arguments { inline bool IsConstructCall() const; inline Local Data() const; private: + static const int kDataIndex = 0; + static const int kCalleeIndex = -1; + static const int kHolderIndex = -2; + friend class ImplementationUtilities; - inline Arguments(Local data, - Local holder, - Local callee, - bool is_construct_call, - void** values, int length); - Local data_; - Local holder_; - Local callee_; - bool is_construct_call_; - void** values_; + inline Arguments(internal::Object** implicit_args, + internal::Object** values, + int length, + bool is_construct_call); + internal::Object** implicit_args_; + internal::Object** values_; int length_; + bool is_construct_call_; }; @@ -3470,14 +3471,13 @@ void Persistent::ClearWeak() { } -Arguments::Arguments(v8::Local data, - v8::Local holder, - v8::Local callee, - bool is_construct_call, - void** values, int length) - : data_(data), holder_(holder), callee_(callee), - is_construct_call_(is_construct_call), - values_(values), length_(length) { } +Arguments::Arguments(internal::Object** implicit_args, + internal::Object** values, int length, + bool is_construct_call) + : implicit_args_(implicit_args), + values_(values), + length_(length), + is_construct_call_(is_construct_call) { } Local Arguments::operator[](int i) const { @@ -3487,7 +3487,8 @@ Local Arguments::operator[](int i) const { Local Arguments::Callee() const { - return callee_; + return Local(reinterpret_cast( + &implicit_args_[kCalleeIndex])); } @@ -3497,12 +3498,13 @@ Local Arguments::This() const { Local Arguments::Holder() const { - return holder_; + return Local(reinterpret_cast( + &implicit_args_[kHolderIndex])); } Local Arguments::Data() const { - return data_; + return Local(reinterpret_cast(&implicit_args_[kDataIndex])); } diff --git a/src/apiutils.h b/src/apiutils.h index 8c791ebdd5..1313ddaabe 100644 --- a/src/apiutils.h +++ b/src/apiutils.h @@ -29,7 +29,6 @@ #define V8_APIUTILS_H_ namespace v8 { - class ImplementationUtilities { public: static v8::Handle Undefined(); @@ -45,12 +44,21 @@ class ImplementationUtilities { return that->names_; } - static v8::Arguments NewArguments(Local data, - Local holder, - Local callee, - bool is_construct_call, - void** argv, int argc) { - return v8::Arguments(data, holder, callee, is_construct_call, argv, argc); + // Packs additional parameters for the NewArguments function. |implicit_args| + // is a pointer to the last element of 3-elements array controlled by GC. + static void PrepareArgumentsData(internal::Object** implicit_args, + internal::Object* data, + internal::JSFunction* callee, + internal::Object* holder) { + implicit_args[v8::Arguments::kDataIndex] = data; + implicit_args[v8::Arguments::kCalleeIndex] = callee; + implicit_args[v8::Arguments::kHolderIndex] = holder; + } + + static v8::Arguments NewArguments(internal::Object** implicit_args, + internal::Object** argv, int argc, + bool is_construct_call) { + return v8::Arguments(implicit_args, argv, argc, is_construct_call); } // Introduce an alias for the handle scope data to allow non-friends diff --git a/src/arguments.h b/src/arguments.h index c17f4cf80b..d51c9e4cb1 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -84,6 +84,15 @@ class CustomArguments : public Relocatable { values_[1] = holder; values_[0] = data; } + + inline CustomArguments() { +#ifdef DEBUG + for (size_t i = 0; i < ARRAY_SIZE(values_); i++) { + values_[i] = reinterpret_cast(kZapValue); + } +#endif + } + void IterateInstance(ObjectVisitor* v); Object** end() { return values_ + ARRAY_SIZE(values_) - 1; } private: diff --git a/src/builtins.cc b/src/builtins.cc index 52d5530cec..aede302035 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -1014,20 +1014,18 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper( Object* data_obj = call_data->data(); Object* result; - Handle data_handle(data_obj); - v8::Local data = v8::Utils::ToLocal(data_handle); - ASSERT(raw_holder->IsJSObject()); - v8::Local callee = v8::Utils::ToLocal(function); - Handle holder_handle(JSObject::cast(raw_holder)); - v8::Local holder = v8::Utils::ToLocal(holder_handle); LOG(ApiObjectAccess("call", JSObject::cast(*args.receiver()))); + ASSERT(raw_holder->IsJSObject()); + + CustomArguments custom; + v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), + data_obj, *function, raw_holder); + v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( - data, - holder, - callee, - is_construct, - reinterpret_cast(&args[0] - 1), - args.length() - 1); + custom.end(), + &args[0] - 1, + args.length() - 1, + is_construct); v8::Handle value; { @@ -1089,26 +1087,22 @@ BUILTIN(FastHandleApiCall) { Handle function = args.at(args_length); Object* callback_obj = args[args_length + 1]; - Handle data_handle = args.at(args_length + 2); + Handle data = args.at(args_length + 2); Handle checked_holder = args.at(args_length + 3); #ifdef DEBUG VerifyTypeCheck(checked_holder, function); #endif - v8::Local holder = v8::Utils::ToLocal(checked_holder); - v8::Local callee = v8::Utils::ToLocal(function); - v8::InvocationCallback callback = - v8::ToCData(callback_obj); - v8::Local data = v8::Utils::ToLocal(data_handle); + CustomArguments custom; + v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), + *data, *function, *checked_holder); v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( - data, - holder, - callee, - is_construct, - reinterpret_cast(&args[0] - 1), - args_length - 1); + custom.end(), + &args[0] - 1, + args_length - 1, + is_construct); HandleScope scope; Object* result; @@ -1119,6 +1113,9 @@ BUILTIN(FastHandleApiCall) { #ifdef ENABLE_LOGGING_AND_PROFILING state.set_external_callback(v8::ToCData
(callback_obj)); #endif + v8::InvocationCallback callback = + v8::ToCData(callback_obj); + value = callback(new_args); } if (value.IsEmpty()) { @@ -1161,23 +1158,20 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor( v8::ToCData(callback_obj); // Get the data for the call and perform the callback. - Object* data_obj = call_data->data(); Object* result; - { HandleScope scope; - v8::Local self = - v8::Utils::ToLocal(Handle::cast(args.receiver())); - Handle data_handle(data_obj); - v8::Local data = v8::Utils::ToLocal(data_handle); - Handle callee_handle(constructor); - v8::Local callee = v8::Utils::ToLocal(callee_handle); - LOG(ApiObjectAccess("call non-function", JSObject::cast(*args.receiver()))); + { + HandleScope scope; + + LOG(ApiObjectAccess("call non-function", obj)); + + CustomArguments custom; + v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), + call_data->data(), constructor, obj); v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( - data, - self, - callee, - is_construct_call, - reinterpret_cast(&args[0] - 1), - args.length() - 1); + custom.end(), + &args[0] - 1, + args.length() - 1, + is_construct_call); v8::Handle value; { // Leaving JavaScript.