inline bool IsConstructCall() const;
inline Local<Value> Data() const;
private:
+ static const int kDataIndex = 0;
+ static const int kCalleeIndex = -1;
+ static const int kHolderIndex = -2;
+
friend class ImplementationUtilities;
- inline Arguments(Local<Value> data,
- Local<Object> holder,
- Local<Function> callee,
- bool is_construct_call,
- void** values, int length);
- Local<Value> data_;
- Local<Object> holder_;
- Local<Function> 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_;
};
}
-Arguments::Arguments(v8::Local<v8::Value> data,
- v8::Local<v8::Object> holder,
- v8::Local<v8::Function> 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<Value> Arguments::operator[](int i) const {
Local<Function> Arguments::Callee() const {
- return callee_;
+ return Local<Function>(reinterpret_cast<Function*>(
+ &implicit_args_[kCalleeIndex]));
}
Local<Object> Arguments::Holder() const {
- return holder_;
+ return Local<Object>(reinterpret_cast<Object*>(
+ &implicit_args_[kHolderIndex]));
}
Local<Value> Arguments::Data() const {
- return data_;
+ return Local<Value>(reinterpret_cast<Value*>(&implicit_args_[kDataIndex]));
}
#define V8_APIUTILS_H_
namespace v8 {
-
class ImplementationUtilities {
public:
static v8::Handle<v8::Primitive> Undefined();
return that->names_;
}
- static v8::Arguments NewArguments(Local<Value> data,
- Local<Object> holder,
- Local<Function> 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
values_[1] = holder;
values_[0] = data;
}
+
+ inline CustomArguments() {
+#ifdef DEBUG
+ for (size_t i = 0; i < ARRAY_SIZE(values_); i++) {
+ values_[i] = reinterpret_cast<Object*>(kZapValue);
+ }
+#endif
+ }
+
void IterateInstance(ObjectVisitor* v);
Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
private:
Object* data_obj = call_data->data();
Object* result;
- Handle<Object> data_handle(data_obj);
- v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
- ASSERT(raw_holder->IsJSObject());
- v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
- Handle<JSObject> holder_handle(JSObject::cast(raw_holder));
- v8::Local<v8::Object> 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<void**>(&args[0] - 1),
- args.length() - 1);
+ custom.end(),
+ &args[0] - 1,
+ args.length() - 1,
+ is_construct);
v8::Handle<v8::Value> value;
{
Handle<JSFunction> function = args.at<JSFunction>(args_length);
Object* callback_obj = args[args_length + 1];
- Handle<Object> data_handle = args.at<Object>(args_length + 2);
+ Handle<Object> data = args.at<Object>(args_length + 2);
Handle<JSObject> checked_holder = args.at<JSObject>(args_length + 3);
#ifdef DEBUG
VerifyTypeCheck(checked_holder, function);
#endif
- v8::Local<v8::Object> holder = v8::Utils::ToLocal(checked_holder);
- v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
- v8::InvocationCallback callback =
- v8::ToCData<v8::InvocationCallback>(callback_obj);
- v8::Local<v8::Value> 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<void**>(&args[0] - 1),
- args_length - 1);
+ custom.end(),
+ &args[0] - 1,
+ args_length - 1,
+ is_construct);
HandleScope scope;
Object* result;
#ifdef ENABLE_LOGGING_AND_PROFILING
state.set_external_callback(v8::ToCData<Address>(callback_obj));
#endif
+ v8::InvocationCallback callback =
+ v8::ToCData<v8::InvocationCallback>(callback_obj);
+
value = callback(new_args);
}
if (value.IsEmpty()) {
v8::ToCData<v8::InvocationCallback>(callback_obj);
// Get the data for the call and perform the callback.
- Object* data_obj = call_data->data();
Object* result;
- { HandleScope scope;
- v8::Local<v8::Object> self =
- v8::Utils::ToLocal(Handle<JSObject>::cast(args.receiver()));
- Handle<Object> data_handle(data_obj);
- v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
- Handle<JSFunction> callee_handle(constructor);
- v8::Local<v8::Function> 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<void**>(&args[0] - 1),
- args.length() - 1);
+ custom.end(),
+ &args[0] - 1,
+ args.length() - 1,
+ is_construct_call);
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.