Refactoring of v8:Arguments similary we did with v8::AccessorInfo (http://codereview...
authorserya@chromium.org <serya@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 1 Nov 2010 10:51:44 +0000 (10:51 +0000)
committerserya@chromium.org <serya@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 1 Nov 2010 10:51:44 +0000 (10:51 +0000)
Review URL: http://codereview.chromium.org/4117010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5746 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/apiutils.h
src/arguments.h
src/builtins.cc

index 89502cb..c7e4552 100644 (file)
@@ -1790,18 +1790,19 @@ class Arguments {
   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_;
 };
 
 
@@ -3470,14 +3471,13 @@ void Persistent<T>::ClearWeak() {
 }
 
 
-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 {
@@ -3487,7 +3487,8 @@ Local<Value> Arguments::operator[](int i) const {
 
 
 Local<Function> Arguments::Callee() const {
-  return callee_;
+  return Local<Function>(reinterpret_cast<Function*>(
+      &implicit_args_[kCalleeIndex]));
 }
 
 
@@ -3497,12 +3498,13 @@ Local<Object> Arguments::This() const {
 
 
 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]));
 }
 
 
index 8c791eb..1313dda 100644 (file)
@@ -29,7 +29,6 @@
 #define V8_APIUTILS_H_
 
 namespace v8 {
-
 class ImplementationUtilities {
  public:
   static v8::Handle<v8::Primitive> Undefined();
@@ -45,12 +44,21 @@ class ImplementationUtilities {
     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
index c17f4cf..d51c9e4 100644 (file)
@@ -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<Object*>(kZapValue);
+    }
+#endif
+  }
+
   void IterateInstance(ObjectVisitor* v);
   Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
  private:
index 52d5530..aede302 100644 (file)
@@ -1014,20 +1014,18 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
     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;
     {
@@ -1089,26 +1087,22 @@ BUILTIN(FastHandleApiCall) {
 
   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;
@@ -1119,6 +1113,9 @@ BUILTIN(FastHandleApiCall) {
 #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()) {
@@ -1161,23 +1158,20 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
       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.