From 8033be880e2163d30a4099867f06493562e483b8 Mon Sep 17 00:00:00 2001 From: "ager@chromium.org" Date: Mon, 9 May 2011 15:24:48 +0000 Subject: [PATCH] Add IsCallable method for Object in the API Patch by Peter Varga. BUG=none TEST=cctest/test-api/CallableObject Review URL: http://codereview.chromium.org/6964005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7828 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 7 +++++++ src/api.cc | 11 +++++++++++ test/cctest/test-api.cc | 43 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/include/v8.h b/include/v8.h index 5fc805960..457633a6e 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1606,6 +1606,13 @@ class Object : public Value { V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType(); V8EXPORT int GetIndexedPropertiesExternalArrayDataLength(); + /** + * Checks whether a callback is set by the + * ObjectTemplate::SetCallAsFunctionHandler method. + * When an Object is callable this method returns true. + */ + V8EXPORT bool IsCallable(); + /** * Call an Object as a function if a callback is set by the * ObjectTemplate::SetCallAsFunctionHandler method. diff --git a/src/api.cc b/src/api.cc index fee0daf1e..a6dfc26cf 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3255,6 +3255,17 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() { } +bool v8::Object::IsCallable() { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false); + ENTER_V8(isolate); + i::HandleScope scope(isolate); + i::Handle obj = Utils::OpenHandle(this); + if (obj->IsJSFunction()) return true; + return i::Execution::GetFunctionDelegate(obj)->IsJSFunction(); +} + + Local Object::CallAsFunction(v8::Handle recv, int argc, v8::Handle argv[]) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index ab94085a9..4a0e595b6 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -7264,6 +7264,49 @@ THREADED_TEST(CallAsFunction) { } +// Check whether a non-function object is callable. +THREADED_TEST(CallableObject) { + v8::HandleScope scope; + LocalContext context; + + { Local instance_template = ObjectTemplate::New(); + instance_template->SetCallAsFunctionHandler(call_as_function); + Local instance = instance_template->NewInstance(); + v8::TryCatch try_catch; + + CHECK(instance->IsCallable()); + CHECK(!try_catch.HasCaught()); + } + + { Local instance_template = ObjectTemplate::New(); + Local instance = instance_template->NewInstance(); + v8::TryCatch try_catch; + + CHECK(!instance->IsCallable()); + CHECK(!try_catch.HasCaught()); + } + + { Local function_template = + FunctionTemplate::New(call_as_function); + Local function = function_template->GetFunction(); + Local instance = function; + v8::TryCatch try_catch; + + CHECK(instance->IsCallable()); + CHECK(!try_catch.HasCaught()); + } + + { Local function_template = FunctionTemplate::New(); + Local function = function_template->GetFunction(); + Local instance = function; + v8::TryCatch try_catch; + + CHECK(instance->IsCallable()); + CHECK(!try_catch.HasCaught()); + } +} + + static int CountHandles() { return v8::HandleScope::NumberOfHandles(); } -- 2.34.1