Reviewers: ,

Description:
Add Call method to the Object class in the API

Patch by Peter Varga.

BUG=v8:1336
TEST=cctest/test-api/CallAsFunction


Please review this at http://codereview.chromium.org/6883045/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M include/v8.h
  M src/api.cc
  M test/cctest/test-api.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index d15d024dc3ce11164f9b28eb026f8fa2c74e93d7..2c31d8e18cd7bc881470a4c8dc37ec4ccf0966a0 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1685,6 +1685,10 @@ class Object : public Value {
   V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
   V8EXPORT int GetIndexedPropertiesExternalArrayDataLength();

+  V8EXPORT Local<Value> Call(Handle<Object> recv,
+                             int argc,
+                             Handle<Value> argv[]);
+
   V8EXPORT static Local<Object> New();
   static inline Object* Cast(Value* obj);
  private:
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 1a521748211bcb72be2c434189b96d0c103dcf79..4a1e22c654e34f8465ebffe4910a46c68e25f457 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -3182,6 +3182,38 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
 }


+Local<v8::Value> Object::Call(v8::Handle<v8::Object> recv, int argc,
+                                v8::Handle<v8::Value> argv[]) {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::Call()", return Local<v8::Value>());
+  LOG_API(isolate, "Object::Call");
+  ENTER_V8(isolate);
+  i::Object* raw_result = NULL;
+  {
+    i::HandleScope scope(isolate);
+    i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+    i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
+    STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+    i::Object*** args = reinterpret_cast<i::Object***>(argv);
+    i::Handle<i::JSFunction> fun;
+    if (obj->IsJSFunction()) {
+      fun = i::Handle<i::JSFunction>::cast(obj);
+    } else {
+      fun = i::Handle<i::JSFunction>::cast(
+              i::Execution::GetFunctionDelegate(obj));
+      recv_obj = obj;
+    }
+    EXCEPTION_PREAMBLE(isolate);
+    i::Handle<i::Object> returned =
+ i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
+    raw_result = *returned;
+  }
+  i::Handle<i::Object> result(raw_result);
+  return Utils::ToLocal(result);
+}
+
+
 Local<v8::Object> Function::NewInstance() const {
   return NewInstance(0, NULL);
 }
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 28a9be159937b9f1399efa6f7de5e9734751ba55..7167bba63a103e3ea209a7a8b61b3745baf7bbfa 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -7006,6 +7006,13 @@ THREADED_TEST(CallAsFunction) {
   value = CompileRun("new obj(43)");
   CHECK(!try_catch.HasCaught());
   CHECK_EQ(-43, value->Int32Value());
+
+  // Check that the call-as-function handler can be called through
+  // the API.
+  v8::Handle<Value> args1[] = { v8_num(28) };
+  value = instance->Call(instance, 1, args1);
+  CHECK(!try_catch.HasCaught());
+  CHECK_EQ(28, value->Int32Value());
 }




--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to