From 15befa5438e3f0e1c2ef3692a5801ad1bcb90b4c Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 25 Aug 2011 11:15:02 +1000 Subject: Update v8 Change-Id: I576fb2215345aa6599cfb75c6a27544260b2c145 Reviewed-on: http://codereview.qt.nokia.com/3536 Reviewed-by: Qt Sanity Bot Reviewed-by: Aaron Kennedy --- src/3rdparty/v8 | 2 +- ...shing-and-comparison-methods-to-v8-String.patch | 2 +- .../v8/0002-Add-a-bit-field-3-to-Map.patch | 2 +- ...back-mode-for-named-property-interceptors.patch | 2 +- ...0004-Generalize-external-object-resources.patch | 2 +- .../v8/0005-Introduce-a-QML-compilation-mode.patch | 2 +- ...6-Allow-access-to-the-calling-script-data.patch | 2 +- src/declarative/v8/0007-Fix-warnings.patch | 2 +- .../0008-Add-custom-object-compare-callback.patch | 2 +- ...unction-method-to-the-Object-class-in-the.patch | 286 +++++++++++++++ ...allAsConstructor-method-for-Object-in-the.patch | 397 +++++++++++++++++++++ ...-Add-new-v8-api-to-check-if-a-value-is-an.patch | 63 ++++ ...d-IsCallable-method-for-Object-in-the-API.patch | 116 ++++++ .../0013-Remove-execute-flag-from-v8-debug.h.patch | 15 + ...unction-method-to-the-Object-class-in-the.patch | 286 --------------- ...allAsConstructor-method-for-Object-in-the.patch | 397 --------------------- ...-Add-new-v8-api-to-check-if-a-value-is-an.patch | 63 ---- 17 files changed, 886 insertions(+), 755 deletions(-) create mode 100644 src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch create mode 100644 src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch create mode 100644 src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch create mode 100644 src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch create mode 100644 src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch delete mode 100644 src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch delete mode 100644 src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch delete mode 100644 src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch (limited to 'src') diff --git a/src/3rdparty/v8 b/src/3rdparty/v8 index 472c04c9e7..dc2cad4f8f 160000 --- a/src/3rdparty/v8 +++ b/src/3rdparty/v8 @@ -1 +1 @@ -Subproject commit 472c04c9e7a64e8734c76d2cf97a7cc5b773b788 +Subproject commit dc2cad4f8fc88c52fcea09b8d0262d35cd32dc44 diff --git a/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch b/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch index 4596202944..1fb3b90733 100644 --- a/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch +++ b/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch @@ -1,7 +1,7 @@ From e13ce09287a56c920d5ffdc5d4662d49f1838f16 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 23 May 2011 15:47:20 +1000 -Subject: [PATCH 1/8] Add hashing and comparison methods to v8::String +Subject: [PATCH 01/13] Add hashing and comparison methods to v8::String This allows us to more rapidly search for a v8::String inside a hash of QStrings. diff --git a/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch b/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch index cb578c0f96..daf8b35570 100644 --- a/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch +++ b/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch @@ -1,7 +1,7 @@ From 7c9cfff80b7864d5687432d424074e51712c4a07 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 23 May 2011 15:55:26 +1000 -Subject: [PATCH 2/8] Add a bit field 3 to Map +Subject: [PATCH 02/13] Add a bit field 3 to Map Bit field 3 will be used to add QML specific map flags. --- diff --git a/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch index daa2250a25..1c81b2af9d 100644 --- a/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch +++ b/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch @@ -1,7 +1,7 @@ From ae8688b53d67044f2c9b0cce25fc282b078610c1 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 23 May 2011 16:21:02 +1000 -Subject: [PATCH 3/8] Add a "fallback" mode for named property interceptors +Subject: [PATCH 03/13] Add a "fallback" mode for named property interceptors By default interceptors are called before the normal property resolution on objects. When an interceptor is installed as a diff --git a/src/declarative/v8/0004-Generalize-external-object-resources.patch b/src/declarative/v8/0004-Generalize-external-object-resources.patch index 56e5e371fd..6b85666cf0 100644 --- a/src/declarative/v8/0004-Generalize-external-object-resources.patch +++ b/src/declarative/v8/0004-Generalize-external-object-resources.patch @@ -1,7 +1,7 @@ From 4827116b12c50f6662794017c5a662b5dbb2da0b Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 23 May 2011 16:55:35 +1000 -Subject: [PATCH 4/8] Generalize external object resources +Subject: [PATCH 04/13] Generalize external object resources V8 was already able to manage and finalize an external string resource. This change generalizes that mechanism to handle a diff --git a/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch b/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch index 7ec10e9448..2dfd3d9699 100644 --- a/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch +++ b/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch @@ -1,7 +1,7 @@ From fd7d475e298e5b63cd6383c78cc900635c82aa38 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 23 May 2011 18:26:19 +1000 -Subject: [PATCH 5/8] Introduce a QML compilation mode +Subject: [PATCH 05/13] Introduce a QML compilation mode In QML mode, there is a second global object - known as the QML global object. During property resolution, if a property is not diff --git a/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch b/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch index 7af81c3f69..b9c44654cd 100644 --- a/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch +++ b/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch @@ -1,7 +1,7 @@ From f890f0d1a1e5bd62711815489c87755a4f382436 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 25 May 2011 10:36:13 +1000 -Subject: [PATCH 6/8] Allow access to the calling script data +Subject: [PATCH 06/13] Allow access to the calling script data --- include/v8.h | 1 + diff --git a/src/declarative/v8/0007-Fix-warnings.patch b/src/declarative/v8/0007-Fix-warnings.patch index 2efc8331aa..60fb24c138 100644 --- a/src/declarative/v8/0007-Fix-warnings.patch +++ b/src/declarative/v8/0007-Fix-warnings.patch @@ -1,7 +1,7 @@ From dac5d9db84cf20564621c679937ca7b9c6a8e880 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 27 May 2011 13:04:15 +1000 -Subject: [PATCH 7/8] Fix warnings +Subject: [PATCH 07/13] Fix warnings --- include/v8.h | 16 ++++++++-------- diff --git a/src/declarative/v8/0008-Add-custom-object-compare-callback.patch b/src/declarative/v8/0008-Add-custom-object-compare-callback.patch index 659cf4c167..fdb0895f06 100644 --- a/src/declarative/v8/0008-Add-custom-object-compare-callback.patch +++ b/src/declarative/v8/0008-Add-custom-object-compare-callback.patch @@ -1,7 +1,7 @@ From bec11b8b7f89d135e7d9a823ac4fe98c70d017cf Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 27 Jun 2011 14:57:28 +1000 -Subject: [PATCH 8/8] Add custom object compare callback +Subject: [PATCH 08/13] Add custom object compare callback A global custom object comparison callback can be set with: V8::SetUserObjectComparisonCallbackFunction() diff --git a/src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch b/src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch new file mode 100644 index 0000000000..89ec7b96bc --- /dev/null +++ b/src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch @@ -0,0 +1,286 @@ +From 4183b973ed3bd603784c798dfa63ba48f6b68003 Mon Sep 17 00:00:00 2001 +From: ager@chromium.org +Date: Wed, 4 May 2011 13:03:08 +0000 +Subject: [PATCH 09/13] Add CallAsFunction method to the Object class in the API + +Patch by Peter Varga. + +BUG=v8:1336 +TEST=cctest/test-api/CallAsFunction + +Review URL: http://codereview.chromium.org/6883045 + +git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7781 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 +--- + include/v8.h | 8 +++ + src/api.cc | 31 +++++++++++ + src/execution.cc | 24 ++++++++ + src/execution.h | 2 + + test/cctest/test-api.cc | 135 ++++++++++++++++++++++++++++++++++------------- + 5 files changed, 163 insertions(+), 37 deletions(-) + +diff --git a/include/v8.h b/include/v8.h +index d5d6972..8a8e1cd 100644 +--- a/include/v8.h ++++ b/include/v8.h +@@ -1757,6 +1757,14 @@ class Object : public Value { + V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType(); + V8EXPORT int GetIndexedPropertiesExternalArrayDataLength(); + ++ /** ++ * Call an Object as a function if a callback is set by the ++ * ObjectTemplate::SetCallAsFunctionHandler method. ++ */ ++ V8EXPORT Local CallAsFunction(Handle recv, ++ int argc, ++ Handle argv[]); ++ + V8EXPORT static Local New(); + static inline Object* Cast(Value* obj); + private: +diff --git a/src/api.cc b/src/api.cc +index 2436031..e412e51 100644 +--- a/src/api.cc ++++ b/src/api.cc +@@ -3259,6 +3259,37 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() { + } + + ++Local Object::CallAsFunction(v8::Handle recv, int argc, ++ v8::Handle argv[]) { ++ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ++ ON_BAILOUT(isolate, "v8::Object::CallAsFunction()", ++ return Local()); ++ LOG_API(isolate, "Object::CallAsFunction"); ++ ENTER_V8(isolate); ++ HandleScope scope; ++ i::Handle obj = Utils::OpenHandle(this); ++ i::Handle recv_obj = Utils::OpenHandle(*recv); ++ STATIC_ASSERT(sizeof(v8::Handle) == sizeof(i::Object**)); ++ i::Object*** args = reinterpret_cast(argv); ++ i::Handle fun = i::Handle(); ++ if (obj->IsJSFunction()) { ++ fun = i::Handle::cast(obj); ++ } else { ++ EXCEPTION_PREAMBLE(isolate); ++ i::Handle delegate = ++ i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception); ++ EXCEPTION_BAILOUT_CHECK(isolate, Local()); ++ fun = i::Handle::cast(delegate); ++ recv_obj = obj; ++ } ++ EXCEPTION_PREAMBLE(isolate); ++ i::Handle returned = ++ i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception); ++ EXCEPTION_BAILOUT_CHECK(isolate, Local()); ++ return scope.Close(Utils::ToLocal(returned)); ++} ++ ++ + Local Function::NewInstance() const { + return NewInstance(0, NULL); + } +diff --git a/src/execution.cc b/src/execution.cc +index 1632076..894d741 100644 +--- a/src/execution.cc ++++ b/src/execution.cc +@@ -254,6 +254,30 @@ Handle Execution::GetFunctionDelegate(Handle object) { + } + + ++Handle Execution::TryGetFunctionDelegate(Handle object, ++ bool* has_pending_exception) { ++ ASSERT(!object->IsJSFunction()); ++ Isolate* isolate = Isolate::Current(); ++ ++ // Objects created through the API can have an instance-call handler ++ // that should be used when calling the object as a function. ++ if (object->IsHeapObject() && ++ HeapObject::cast(*object)->map()->has_instance_call_handler()) { ++ return Handle( ++ isolate->global_context()->call_as_function_delegate()); ++ } ++ ++ // If the Object doesn't have an instance-call handler we should ++ // throw a non-callable exception. ++ i::Handle error_obj = isolate->factory()->NewTypeError( ++ "called_non_callable", i::HandleVector(&object, 1)); ++ isolate->Throw(*error_obj); ++ *has_pending_exception = true; ++ ++ return isolate->factory()->undefined_value(); ++} ++ ++ + Handle Execution::GetConstructorDelegate(Handle object) { + ASSERT(!object->IsJSFunction()); + Isolate* isolate = Isolate::Current(); +diff --git a/src/execution.h b/src/execution.h +index a476eb4..0a0be51 100644 +--- a/src/execution.h ++++ b/src/execution.h +@@ -144,6 +144,8 @@ class Execution : public AllStatic { + // Get a function delegate (or undefined) for the given non-function + // object. Used for support calling objects as functions. + static Handle GetFunctionDelegate(Handle object); ++ static Handle TryGetFunctionDelegate(Handle object, ++ bool* has_pending_exception); + + // Get a function delegate (or undefined) for the given non-function + // object. Used for support calling objects as constructors. +diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc +index d7621d1..693d51e 100644 +--- a/test/cctest/test-api.cc ++++ b/test/cctest/test-api.cc +@@ -6962,50 +6962,111 @@ THREADED_TEST(CallAsFunction) { + v8::HandleScope scope; + LocalContext context; + +- Local t = v8::FunctionTemplate::New(); +- Local instance_template = t->InstanceTemplate(); +- instance_template->SetCallAsFunctionHandler(call_as_function); +- Local instance = t->GetFunction()->NewInstance(); +- context->Global()->Set(v8_str("obj"), instance); +- v8::TryCatch try_catch; +- Local value; +- CHECK(!try_catch.HasCaught()); ++ { Local t = v8::FunctionTemplate::New(); ++ Local instance_template = t->InstanceTemplate(); ++ instance_template->SetCallAsFunctionHandler(call_as_function); ++ Local instance = t->GetFunction()->NewInstance(); ++ context->Global()->Set(v8_str("obj"), instance); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); + +- value = CompileRun("obj(42)"); +- CHECK(!try_catch.HasCaught()); +- CHECK_EQ(42, value->Int32Value()); ++ value = CompileRun("obj(42)"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(42, value->Int32Value()); + +- value = CompileRun("(function(o){return o(49)})(obj)"); +- CHECK(!try_catch.HasCaught()); +- CHECK_EQ(49, value->Int32Value()); ++ value = CompileRun("(function(o){return o(49)})(obj)"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(49, value->Int32Value()); + +- // test special case of call as function +- value = CompileRun("[obj]['0'](45)"); +- CHECK(!try_catch.HasCaught()); +- CHECK_EQ(45, value->Int32Value()); ++ // test special case of call as function ++ value = CompileRun("[obj]['0'](45)"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(45, value->Int32Value()); + +- value = CompileRun("obj.call = Function.prototype.call;" +- "obj.call(null, 87)"); +- CHECK(!try_catch.HasCaught()); +- CHECK_EQ(87, value->Int32Value()); ++ value = CompileRun("obj.call = Function.prototype.call;" ++ "obj.call(null, 87)"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(87, value->Int32Value()); + +- // Regression tests for bug #1116356: Calling call through call/apply +- // must work for non-function receivers. +- const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; +- value = CompileRun(apply_99); +- CHECK(!try_catch.HasCaught()); +- CHECK_EQ(99, value->Int32Value()); ++ // Regression tests for bug #1116356: Calling call through call/apply ++ // must work for non-function receivers. ++ const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; ++ value = CompileRun(apply_99); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(99, value->Int32Value()); + +- const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; +- value = CompileRun(call_17); +- CHECK(!try_catch.HasCaught()); +- CHECK_EQ(17, value->Int32Value()); ++ const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; ++ value = CompileRun(call_17); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(17, value->Int32Value()); + +- // Check that the call-as-function handler can be called through +- // new. +- 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 ++ // new. ++ 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 args[] = { v8_num(28) }; ++ value = instance->CallAsFunction(instance, 1, args); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(28, value->Int32Value()); ++ } ++ ++ { Local t = v8::FunctionTemplate::New(); ++ Local instance_template = t->InstanceTemplate(); ++ Local instance = t->GetFunction()->NewInstance(); ++ context->Global()->Set(v8_str("obj2"), instance); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); ++ ++ // Call an object without call-as-function handler through the JS ++ value = CompileRun("obj2(28)"); ++ CHECK(value.IsEmpty()); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value1(try_catch.Exception()); ++ CHECK_EQ(*exception_value1, ++ "TypeError: Property 'obj2' of object " ++ "# is not a function"); ++ try_catch.Reset(); ++ ++ // Call an object without call-as-function handler through the API ++ value = CompileRun("obj2(28)"); ++ v8::Handle args[] = { v8_num(28) }; ++ value = instance->CallAsFunction(instance, 1, args); ++ CHECK(value.IsEmpty()); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value2(try_catch.Exception()); ++ CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function"); ++ try_catch.Reset(); ++ } ++ ++ { Local t = v8::FunctionTemplate::New(); ++ Local instance_template = t->InstanceTemplate(); ++ instance_template->SetCallAsFunctionHandler(ThrowValue); ++ Local instance = t->GetFunction()->NewInstance(); ++ context->Global()->Set(v8_str("obj3"), instance); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); ++ ++ // Catch the exception which is thrown by call-as-function handler ++ value = CompileRun("obj3(22)"); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value1(try_catch.Exception()); ++ CHECK_EQ(*exception_value1, "22"); ++ try_catch.Reset(); ++ ++ v8::Handle args[] = { v8_num(23) }; ++ value = instance->CallAsFunction(instance, 1, args); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value2(try_catch.Exception()); ++ CHECK_EQ(*exception_value2, "23"); ++ try_catch.Reset(); ++ } + } + + +-- +1.7.2.3 + diff --git a/src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch b/src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch new file mode 100644 index 0000000000..09c2d4af1a --- /dev/null +++ b/src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch @@ -0,0 +1,397 @@ +From 3d6d4249878f7960eac4c9c94e0f2529f9a58c4a Mon Sep 17 00:00:00 2001 +From: ager@chromium.org +Date: Fri, 6 May 2011 11:07:52 +0000 +Subject: [PATCH 10/13] Implement CallAsConstructor method for Object in the API + +Patch by Peter Varga. + +BUG=v8:1348 +TEST=cctest/test-api/ConstructorForObject + +Review URL: http://codereview.chromium.org/6902108 + +git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 +--- + include/v8.h | 8 ++ + src/api.cc | 41 +++++++++- + src/execution.cc | 28 +++++++ + src/execution.h | 2 + + test/cctest/test-api.cc | 205 +++++++++++++++++++++++++++++++++++++++++++++-- + 5 files changed, 276 insertions(+), 8 deletions(-) + +diff --git a/include/v8.h b/include/v8.h +index 8a8e1cd..84462b5 100644 +--- a/include/v8.h ++++ b/include/v8.h +@@ -1765,6 +1765,14 @@ class Object : public Value { + int argc, + Handle argv[]); + ++ /** ++ * Call an Object as a consturctor if a callback is set by the ++ * ObjectTemplate::SetCallAsFunctionHandler method. ++ * Note: This method behaves like the Function::NewInstance method. ++ */ ++ V8EXPORT Local CallAsConstructor(int argc, ++ Handle argv[]); ++ + V8EXPORT static Local New(); + static inline Object* Cast(Value* obj); + private: +diff --git a/src/api.cc b/src/api.cc +index e412e51..1a585d6 100644 +--- a/src/api.cc ++++ b/src/api.cc +@@ -3266,7 +3266,7 @@ Local Object::CallAsFunction(v8::Handle recv, int argc, + return Local()); + LOG_API(isolate, "Object::CallAsFunction"); + ENTER_V8(isolate); +- HandleScope scope; ++ i::HandleScope scope(isolate); + i::Handle obj = Utils::OpenHandle(this); + i::Handle recv_obj = Utils::OpenHandle(*recv); + STATIC_ASSERT(sizeof(v8::Handle) == sizeof(i::Object**)); +@@ -3286,7 +3286,44 @@ Local Object::CallAsFunction(v8::Handle recv, int argc, + i::Handle returned = + i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception); + EXCEPTION_BAILOUT_CHECK(isolate, Local()); +- return scope.Close(Utils::ToLocal(returned)); ++ return Utils::ToLocal(scope.CloseAndEscape(returned)); ++} ++ ++ ++Local Object::CallAsConstructor(int argc, ++ v8::Handle argv[]) { ++ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ++ ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()", ++ return Local()); ++ LOG_API(isolate, "Object::CallAsConstructor"); ++ ENTER_V8(isolate); ++ i::HandleScope scope(isolate); ++ i::Handle obj = Utils::OpenHandle(this); ++ STATIC_ASSERT(sizeof(v8::Handle) == sizeof(i::Object**)); ++ i::Object*** args = reinterpret_cast(argv); ++ if (obj->IsJSFunction()) { ++ i::Handle fun = i::Handle::cast(obj); ++ EXCEPTION_PREAMBLE(isolate); ++ i::Handle returned = ++ i::Execution::New(fun, argc, args, &has_pending_exception); ++ EXCEPTION_BAILOUT_CHECK(isolate, Local()); ++ return Utils::ToLocal(scope.CloseAndEscape( ++ i::Handle::cast(returned))); ++ } ++ EXCEPTION_PREAMBLE(isolate); ++ i::Handle delegate = ++ i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception); ++ EXCEPTION_BAILOUT_CHECK(isolate, Local()); ++ if (!delegate->IsUndefined()) { ++ i::Handle fun = i::Handle::cast(delegate); ++ EXCEPTION_PREAMBLE(isolate); ++ i::Handle returned = ++ i::Execution::Call(fun, obj, argc, args, &has_pending_exception); ++ EXCEPTION_BAILOUT_CHECK(isolate, Local()); ++ ASSERT(!delegate->IsUndefined()); ++ return Utils::ToLocal(scope.CloseAndEscape(returned)); ++ } ++ return Local(); + } + + +diff --git a/src/execution.cc b/src/execution.cc +index 894d741..afb352c 100644 +--- a/src/execution.cc ++++ b/src/execution.cc +@@ -297,6 +297,34 @@ Handle Execution::GetConstructorDelegate(Handle object) { + } + + ++Handle Execution::TryGetConstructorDelegate( ++ Handle object, ++ bool* has_pending_exception) { ++ ASSERT(!object->IsJSFunction()); ++ Isolate* isolate = Isolate::Current(); ++ ++ // If you return a function from here, it will be called when an ++ // attempt is made to call the given object as a constructor. ++ ++ // Objects created through the API can have an instance-call handler ++ // that should be used when calling the object as a function. ++ if (object->IsHeapObject() && ++ HeapObject::cast(*object)->map()->has_instance_call_handler()) { ++ return Handle( ++ isolate->global_context()->call_as_constructor_delegate()); ++ } ++ ++ // If the Object doesn't have an instance-call handler we should ++ // throw a non-callable exception. ++ i::Handle error_obj = isolate->factory()->NewTypeError( ++ "called_non_callable", i::HandleVector(&object, 1)); ++ isolate->Throw(*error_obj); ++ *has_pending_exception = true; ++ ++ return isolate->factory()->undefined_value(); ++} ++ ++ + bool StackGuard::IsStackOverflow() { + ExecutionAccess access(isolate_); + return (thread_local_.jslimit_ != kInterruptLimit && +diff --git a/src/execution.h b/src/execution.h +index 0a0be51..ec2a195 100644 +--- a/src/execution.h ++++ b/src/execution.h +@@ -150,6 +150,8 @@ class Execution : public AllStatic { + // Get a function delegate (or undefined) for the given non-function + // object. Used for support calling objects as constructors. + static Handle GetConstructorDelegate(Handle object); ++ static Handle TryGetConstructorDelegate(Handle object, ++ bool* has_pending_exception); + }; + + +diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc +index 693d51e..1334f63 100644 +--- a/test/cctest/test-api.cc ++++ b/test/cctest/test-api.cc +@@ -6746,6 +6746,200 @@ THREADED_TEST(Constructor) { + CHECK(value->BooleanValue()); + } + ++ ++static Handle ConstructorCallback(const Arguments& args) { ++ ApiTestFuzzer::Fuzz(); ++ Local This; ++ ++ if (args.IsConstructCall()) { ++ Local Holder = args.Holder(); ++ This = Object::New(); ++ Local proto = Holder->GetPrototype(); ++ if (proto->IsObject()) { ++ This->SetPrototype(proto); ++ } ++ } else { ++ This = args.This(); ++ } ++ ++ This->Set(v8_str("a"), args[0]); ++ return This; ++} ++ ++ ++static Handle FakeConstructorCallback(const Arguments& args) { ++ ApiTestFuzzer::Fuzz(); ++ return args[0]; ++} ++ ++ ++THREADED_TEST(ConstructorForObject) { ++ v8::HandleScope handle_scope; ++ LocalContext context; ++ ++ { Local instance_template = ObjectTemplate::New(); ++ instance_template->SetCallAsFunctionHandler(ConstructorCallback); ++ Local instance = instance_template->NewInstance(); ++ context->Global()->Set(v8_str("obj"), instance); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); ++ ++ // Call the Object's constructor with a 32-bit signed integer. ++ value = CompileRun("(function() { var o = new obj(28); return o.a; })()"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsInt32()); ++ CHECK_EQ(28, value->Int32Value()); ++ ++ Local args1[] = { v8_num(28) }; ++ Local value_obj1 = instance->CallAsConstructor(1, args1); ++ CHECK(value_obj1->IsObject()); ++ Local object1 = Local::Cast(value_obj1); ++ value = object1->Get(v8_str("a")); ++ CHECK(value->IsInt32()); ++ CHECK(!try_catch.HasCaught()); ++ CHECK_EQ(28, value->Int32Value()); ++ ++ // Call the Object's constructor with a String. ++ value = CompileRun( ++ "(function() { var o = new obj('tipli'); return o.a; })()"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsString()); ++ String::AsciiValue string_value1(value->ToString()); ++ CHECK_EQ("tipli", *string_value1); ++ ++ Local args2[] = { v8_str("tipli") }; ++ Local value_obj2 = instance->CallAsConstructor(1, args2); ++ CHECK(value_obj2->IsObject()); ++ Local object2 = Local::Cast(value_obj2); ++ value = object2->Get(v8_str("a")); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsString()); ++ String::AsciiValue string_value2(value->ToString()); ++ CHECK_EQ("tipli", *string_value2); ++ ++ // Call the Object's constructor with a Boolean. ++ value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsBoolean()); ++ CHECK_EQ(true, value->BooleanValue()); ++ ++ Handle args3[] = { v8::Boolean::New(true) }; ++ Local value_obj3 = instance->CallAsConstructor(1, args3); ++ CHECK(value_obj3->IsObject()); ++ Local object3 = Local::Cast(value_obj3); ++ value = object3->Get(v8_str("a")); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsBoolean()); ++ CHECK_EQ(true, value->BooleanValue()); ++ ++ // Call the Object's constructor with undefined. ++ Handle args4[] = { v8::Undefined() }; ++ Local value_obj4 = instance->CallAsConstructor(1, args4); ++ CHECK(value_obj4->IsObject()); ++ Local object4 = Local::Cast(value_obj4); ++ value = object4->Get(v8_str("a")); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsUndefined()); ++ ++ // Call the Object's constructor with null. ++ Handle args5[] = { v8::Null() }; ++ Local value_obj5 = instance->CallAsConstructor(1, args5); ++ CHECK(value_obj5->IsObject()); ++ Local object5 = Local::Cast(value_obj5); ++ value = object5->Get(v8_str("a")); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsNull()); ++ } ++ ++ // Check exception handling when there is no constructor set for the Object. ++ { Local instance_template = ObjectTemplate::New(); ++ Local instance = instance_template->NewInstance(); ++ context->Global()->Set(v8_str("obj2"), instance); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); ++ ++ value = CompileRun("new obj2(28)"); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value1(try_catch.Exception()); ++ CHECK_EQ("TypeError: object is not a function", *exception_value1); ++ try_catch.Reset(); ++ ++ Local args[] = { v8_num(29) }; ++ value = instance->CallAsConstructor(1, args); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value2(try_catch.Exception()); ++ CHECK_EQ("TypeError: # is not a function", *exception_value2); ++ try_catch.Reset(); ++ } ++ ++ // Check the case when constructor throws exception. ++ { Local instance_template = ObjectTemplate::New(); ++ instance_template->SetCallAsFunctionHandler(ThrowValue); ++ Local instance = instance_template->NewInstance(); ++ context->Global()->Set(v8_str("obj3"), instance); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); ++ ++ value = CompileRun("new obj3(22)"); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value1(try_catch.Exception()); ++ CHECK_EQ("22", *exception_value1); ++ try_catch.Reset(); ++ ++ Local args[] = { v8_num(23) }; ++ value = instance->CallAsConstructor(1, args); ++ CHECK(try_catch.HasCaught()); ++ String::AsciiValue exception_value2(try_catch.Exception()); ++ CHECK_EQ("23", *exception_value2); ++ try_catch.Reset(); ++ } ++ ++ // Check whether constructor returns with an object or non-object. ++ { Local function_template = ++ FunctionTemplate::New(FakeConstructorCallback); ++ Local function = function_template->GetFunction(); ++ Local instance1 = function; ++ context->Global()->Set(v8_str("obj4"), instance1); ++ v8::TryCatch try_catch; ++ Local value; ++ CHECK(!try_catch.HasCaught()); ++ ++ CHECK(instance1->IsObject()); ++ CHECK(instance1->IsFunction()); ++ ++ value = CompileRun("new obj4(28)"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsObject()); ++ ++ Local args1[] = { v8_num(28) }; ++ value = instance1->CallAsConstructor(1, args1); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(value->IsObject()); ++ ++ Local instance_template = ObjectTemplate::New(); ++ instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); ++ Local instance2 = instance_template->NewInstance(); ++ context->Global()->Set(v8_str("obj5"), instance2); ++ CHECK(!try_catch.HasCaught()); ++ ++ CHECK(instance2->IsObject()); ++ CHECK(!instance2->IsFunction()); ++ ++ value = CompileRun("new obj5(28)"); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(!value->IsObject()); ++ ++ Local args2[] = { v8_num(28) }; ++ value = instance2->CallAsConstructor(1, args2); ++ CHECK(!try_catch.HasCaught()); ++ CHECK(!value->IsObject()); ++ } ++} ++ ++ + THREADED_TEST(FunctionDescriptorException) { + v8::HandleScope handle_scope; + LocalContext context; +@@ -7028,9 +7222,8 @@ THREADED_TEST(CallAsFunction) { + CHECK(value.IsEmpty()); + CHECK(try_catch.HasCaught()); + String::AsciiValue exception_value1(try_catch.Exception()); +- CHECK_EQ(*exception_value1, +- "TypeError: Property 'obj2' of object " +- "# is not a function"); ++ CHECK_EQ("TypeError: Property 'obj2' of object # is not a function", ++ *exception_value1); + try_catch.Reset(); + + // Call an object without call-as-function handler through the API +@@ -7040,7 +7233,7 @@ THREADED_TEST(CallAsFunction) { + CHECK(value.IsEmpty()); + CHECK(try_catch.HasCaught()); + String::AsciiValue exception_value2(try_catch.Exception()); +- CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function"); ++ CHECK_EQ("TypeError: [object Object] is not a function", *exception_value2); + try_catch.Reset(); + } + +@@ -7057,14 +7250,14 @@ THREADED_TEST(CallAsFunction) { + value = CompileRun("obj3(22)"); + CHECK(try_catch.HasCaught()); + String::AsciiValue exception_value1(try_catch.Exception()); +- CHECK_EQ(*exception_value1, "22"); ++ CHECK_EQ("22", *exception_value1); + try_catch.Reset(); + + v8::Handle args[] = { v8_num(23) }; + value = instance->CallAsFunction(instance, 1, args); + CHECK(try_catch.HasCaught()); + String::AsciiValue exception_value2(try_catch.Exception()); +- CHECK_EQ(*exception_value2, "23"); ++ CHECK_EQ("23", *exception_value2); + try_catch.Reset(); + } + } +-- +1.7.2.3 + diff --git a/src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch b/src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch new file mode 100644 index 0000000000..f4a15bf97a --- /dev/null +++ b/src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch @@ -0,0 +1,63 @@ +From f22d0312faeb93ced8747d9aae8c6d77e11b4aba Mon Sep 17 00:00:00 2001 +From: Jedrzej Nowacki +Date: Tue, 7 Dec 2010 11:56:42 +0100 +Subject: [PATCH 11/13] QtScript/V8: Add new v8 api to check if a value is an error. + +New function v8::Value::IsError was created. + +This API is experimental and added only for the purposes of our +research. +--- + include/v8.h | 5 +++++ + src/api.cc | 6 ++++++ + src/heap.h | 1 + + 3 files changed, 12 insertions(+), 0 deletions(-) + +diff --git a/include/v8.h b/include/v8.h +index 84462b5..08b0ec2 100644 +--- a/include/v8.h ++++ b/include/v8.h +@@ -937,6 +937,11 @@ class Value : public Data { + */ + V8EXPORT bool IsRegExp() const; + ++ /** ++ * Returns true if this value is an Error. ++ */ ++ V8EXPORT bool IsError() const; ++ + V8EXPORT Local ToBoolean() const; + V8EXPORT Local ToNumber() const; + V8EXPORT Local ToString() const; +diff --git a/src/api.cc b/src/api.cc +index 1a585d6..bd435eb 100644 +--- a/src/api.cc ++++ b/src/api.cc +@@ -2108,6 +2108,12 @@ bool Value::IsRegExp() const { + return obj->IsJSRegExp(); + } + ++bool Value::IsError() const { ++ if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsError()")) return false; ++ i::Handle obj = Utils::OpenHandle(this); ++ return obj->HasSpecificClassOf(HEAP->Error_symbol()); ++} ++ + + Local Value::ToString() const { + i::Handle obj = Utils::OpenHandle(this); +diff --git a/src/heap.h b/src/heap.h +index 8cbf378..db90bb9 100644 +--- a/src/heap.h ++++ b/src/heap.h +@@ -169,6 +169,7 @@ inline Heap* _inline_get_heap_(); + V(string_symbol, "string") \ + V(String_symbol, "String") \ + V(Date_symbol, "Date") \ ++ V(Error_symbol, "Error") \ + V(this_symbol, "this") \ + V(to_string_symbol, "toString") \ + V(char_at_symbol, "CharAt") \ +-- +1.7.2.3 + diff --git a/src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch b/src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch new file mode 100644 index 0000000000..e4c46b0cbf --- /dev/null +++ b/src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch @@ -0,0 +1,116 @@ +From 472c04c9e7a64e8734c76d2cf97a7cc5b773b788 Mon Sep 17 00:00:00 2001 +From: ager@chromium.org +Date: Mon, 9 May 2011 15:24:48 +0000 +Subject: [PATCH 12/13] 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: https://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(+), 0 deletions(-) + +diff --git a/include/v8.h b/include/v8.h +index 08b0ec2..4194d4a 100644 +--- a/include/v8.h ++++ b/include/v8.h +@@ -1763,6 +1763,13 @@ class Object : public Value { + 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 bd435eb..a5a637f 100644 +--- a/src/api.cc ++++ b/src/api.cc +@@ -3265,6 +3265,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 1334f63..45db5a1 100644 +--- a/test/cctest/test-api.cc ++++ b/test/cctest/test-api.cc +@@ -7263,6 +7263,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(); + } +-- +1.7.2.3 + diff --git a/src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch b/src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch new file mode 100644 index 0000000000..0a769921cd --- /dev/null +++ b/src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch @@ -0,0 +1,15 @@ +From dc2cad4f8fc88c52fcea09b8d0262d35cd32dc44 Mon Sep 17 00:00:00 2001 +From: Aaron Kennedy +Date: Thu, 25 Aug 2011 11:09:58 +1000 +Subject: [PATCH 13/13] Remove execute flag from v8-debug.h + +--- + 0 files changed, 0 insertions(+), 0 deletions(-) + mode change 100755 => 100644 include/v8-debug.h + +diff --git a/include/v8-debug.h b/include/v8-debug.h +old mode 100755 +new mode 100644 +-- +1.7.2.3 + diff --git a/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch b/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch deleted file mode 100644 index 6cd9294d31..0000000000 --- a/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 5719ba59309e85f3ca47da6b64df66e710f3016f Mon Sep 17 00:00:00 2001 -From: "ager@chromium.org" -Date: Wed, 4 May 2011 13:03:08 +0000 -Subject: [PATCH] Add CallAsFunction method to the Object class in the API - -Patch by Peter Varga. - -BUG=v8:1336 -TEST=cctest/test-api/CallAsFunction - -Review URL: http://codereview.chromium.org/6883045 - -git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7781 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 ---- - include/v8.h | 8 +++ - src/api.cc | 31 +++++++++++ - src/execution.cc | 24 ++++++++ - src/execution.h | 2 + - test/cctest/test-api.cc | 135 ++++++++++++++++++++++++++++++++++------------- - 5 files changed, 163 insertions(+), 37 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 4dcbf28..78ee7e6 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -1606,6 +1606,14 @@ class Object : public Value { - V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType(); - V8EXPORT int GetIndexedPropertiesExternalArrayDataLength(); - -+ /** -+ * Call an Object as a function if a callback is set by the -+ * ObjectTemplate::SetCallAsFunctionHandler method. -+ */ -+ V8EXPORT Local CallAsFunction(Handle recv, -+ int argc, -+ Handle argv[]); -+ - V8EXPORT static Local New(); - static inline Object* Cast(Value* obj); - private: -diff --git a/src/api.cc b/src/api.cc -index 792e488..c72857d 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -3255,6 +3255,37 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() { - } - - -+Local Object::CallAsFunction(v8::Handle recv, int argc, -+ v8::Handle argv[]) { -+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); -+ ON_BAILOUT(isolate, "v8::Object::CallAsFunction()", -+ return Local()); -+ LOG_API(isolate, "Object::CallAsFunction"); -+ ENTER_V8(isolate); -+ HandleScope scope; -+ i::Handle obj = Utils::OpenHandle(this); -+ i::Handle recv_obj = Utils::OpenHandle(*recv); -+ STATIC_ASSERT(sizeof(v8::Handle) == sizeof(i::Object**)); -+ i::Object*** args = reinterpret_cast(argv); -+ i::Handle fun = i::Handle(); -+ if (obj->IsJSFunction()) { -+ fun = i::Handle::cast(obj); -+ } else { -+ EXCEPTION_PREAMBLE(isolate); -+ i::Handle delegate = -+ i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception); -+ EXCEPTION_BAILOUT_CHECK(isolate, Local()); -+ fun = i::Handle::cast(delegate); -+ recv_obj = obj; -+ } -+ EXCEPTION_PREAMBLE(isolate); -+ i::Handle returned = -+ i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception); -+ EXCEPTION_BAILOUT_CHECK(isolate, Local()); -+ return scope.Close(Utils::ToLocal(returned)); -+} -+ -+ - Local Function::NewInstance() const { - return NewInstance(0, NULL); - } -diff --git a/src/execution.cc b/src/execution.cc -index eb26438..850dec5 100644 ---- a/src/execution.cc -+++ b/src/execution.cc -@@ -234,6 +234,30 @@ Handle Execution::GetFunctionDelegate(Handle object) { - } - - -+Handle Execution::TryGetFunctionDelegate(Handle object, -+ bool* has_pending_exception) { -+ ASSERT(!object->IsJSFunction()); -+ Isolate* isolate = Isolate::Current(); -+ -+ // Objects created through the API can have an instance-call handler -+ // that should be used when calling the object as a function. -+ if (object->IsHeapObject() && -+ HeapObject::cast(*object)->map()->has_instance_call_handler()) { -+ return Handle( -+ isolate->global_context()->call_as_function_delegate()); -+ } -+ -+ // If the Object doesn't have an instance-call handler we should -+ // throw a non-callable exception. -+ i::Handle error_obj = isolate->factory()->NewTypeError( -+ "called_non_callable", i::HandleVector(&object, 1)); -+ isolate->Throw(*error_obj); -+ *has_pending_exception = true; -+ -+ return isolate->factory()->undefined_value(); -+} -+ -+ - Handle Execution::GetConstructorDelegate(Handle object) { - ASSERT(!object->IsJSFunction()); - Isolate* isolate = Isolate::Current(); -diff --git a/src/execution.h b/src/execution.h -index d4b80d2..e89d6ba 100644 ---- a/src/execution.h -+++ b/src/execution.h -@@ -138,6 +138,8 @@ class Execution : public AllStatic { - // Get a function delegate (or undefined) for the given non-function - // object. Used for support calling objects as functions. - static Handle GetFunctionDelegate(Handle object); -+ static Handle TryGetFunctionDelegate(Handle object, -+ bool* has_pending_exception); - - // Get a function delegate (or undefined) for the given non-function - // object. Used for support calling objects as constructors. -diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc -index e2a7fb1..c6affe5 100644 ---- a/test/cctest/test-api.cc -+++ b/test/cctest/test-api.cc -@@ -6962,50 +6962,111 @@ THREADED_TEST(CallAsFunction) { - v8::HandleScope scope; - LocalContext context; - -- Local t = v8::FunctionTemplate::New(); -- Local instance_template = t->InstanceTemplate(); -- instance_template->SetCallAsFunctionHandler(call_as_function); -- Local instance = t->GetFunction()->NewInstance(); -- context->Global()->Set(v8_str("obj"), instance); -- v8::TryCatch try_catch; -- Local value; -- CHECK(!try_catch.HasCaught()); -+ { Local t = v8::FunctionTemplate::New(); -+ Local instance_template = t->InstanceTemplate(); -+ instance_template->SetCallAsFunctionHandler(call_as_function); -+ Local instance = t->GetFunction()->NewInstance(); -+ context->Global()->Set(v8_str("obj"), instance); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); - -- value = CompileRun("obj(42)"); -- CHECK(!try_catch.HasCaught()); -- CHECK_EQ(42, value->Int32Value()); -+ value = CompileRun("obj(42)"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(42, value->Int32Value()); - -- value = CompileRun("(function(o){return o(49)})(obj)"); -- CHECK(!try_catch.HasCaught()); -- CHECK_EQ(49, value->Int32Value()); -+ value = CompileRun("(function(o){return o(49)})(obj)"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(49, value->Int32Value()); - -- // test special case of call as function -- value = CompileRun("[obj]['0'](45)"); -- CHECK(!try_catch.HasCaught()); -- CHECK_EQ(45, value->Int32Value()); -+ // test special case of call as function -+ value = CompileRun("[obj]['0'](45)"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(45, value->Int32Value()); - -- value = CompileRun("obj.call = Function.prototype.call;" -- "obj.call(null, 87)"); -- CHECK(!try_catch.HasCaught()); -- CHECK_EQ(87, value->Int32Value()); -+ value = CompileRun("obj.call = Function.prototype.call;" -+ "obj.call(null, 87)"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(87, value->Int32Value()); - -- // Regression tests for bug #1116356: Calling call through call/apply -- // must work for non-function receivers. -- const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; -- value = CompileRun(apply_99); -- CHECK(!try_catch.HasCaught()); -- CHECK_EQ(99, value->Int32Value()); -+ // Regression tests for bug #1116356: Calling call through call/apply -+ // must work for non-function receivers. -+ const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; -+ value = CompileRun(apply_99); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(99, value->Int32Value()); - -- const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; -- value = CompileRun(call_17); -- CHECK(!try_catch.HasCaught()); -- CHECK_EQ(17, value->Int32Value()); -+ const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; -+ value = CompileRun(call_17); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(17, value->Int32Value()); - -- // Check that the call-as-function handler can be called through -- // new. -- 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 -+ // new. -+ 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 args[] = { v8_num(28) }; -+ value = instance->CallAsFunction(instance, 1, args); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(28, value->Int32Value()); -+ } -+ -+ { Local t = v8::FunctionTemplate::New(); -+ Local instance_template = t->InstanceTemplate(); -+ Local instance = t->GetFunction()->NewInstance(); -+ context->Global()->Set(v8_str("obj2"), instance); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); -+ -+ // Call an object without call-as-function handler through the JS -+ value = CompileRun("obj2(28)"); -+ CHECK(value.IsEmpty()); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value1(try_catch.Exception()); -+ CHECK_EQ(*exception_value1, -+ "TypeError: Property 'obj2' of object " -+ "# is not a function"); -+ try_catch.Reset(); -+ -+ // Call an object without call-as-function handler through the API -+ value = CompileRun("obj2(28)"); -+ v8::Handle args[] = { v8_num(28) }; -+ value = instance->CallAsFunction(instance, 1, args); -+ CHECK(value.IsEmpty()); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value2(try_catch.Exception()); -+ CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function"); -+ try_catch.Reset(); -+ } -+ -+ { Local t = v8::FunctionTemplate::New(); -+ Local instance_template = t->InstanceTemplate(); -+ instance_template->SetCallAsFunctionHandler(ThrowValue); -+ Local instance = t->GetFunction()->NewInstance(); -+ context->Global()->Set(v8_str("obj3"), instance); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); -+ -+ // Catch the exception which is thrown by call-as-function handler -+ value = CompileRun("obj3(22)"); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value1(try_catch.Exception()); -+ CHECK_EQ(*exception_value1, "22"); -+ try_catch.Reset(); -+ -+ v8::Handle args[] = { v8_num(23) }; -+ value = instance->CallAsFunction(instance, 1, args); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value2(try_catch.Exception()); -+ CHECK_EQ(*exception_value2, "23"); -+ try_catch.Reset(); -+ } - } - - --- -1.7.5.4 - diff --git a/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch b/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch deleted file mode 100644 index 7d90f0dfbd..0000000000 --- a/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch +++ /dev/null @@ -1,397 +0,0 @@ -From fd2cc52576e8c89f3dffc2b4b5a9cc9c48a96f32 Mon Sep 17 00:00:00 2001 -From: "ager@chromium.org" -Date: Fri, 6 May 2011 11:07:52 +0000 -Subject: [PATCH] Implement CallAsConstructor method for Object in the API - -Patch by Peter Varga. - -BUG=v8:1348 -TEST=cctest/test-api/ConstructorForObject - -Review URL: http://codereview.chromium.org/6902108 - -git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 ---- - include/v8.h | 8 ++ - src/api.cc | 41 +++++++++- - src/execution.cc | 28 +++++++ - src/execution.h | 2 + - test/cctest/test-api.cc | 205 +++++++++++++++++++++++++++++++++++++++++++++-- - 5 files changed, 276 insertions(+), 8 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 4921823..5fc8059 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -1614,6 +1614,14 @@ class Object : public Value { - int argc, - Handle argv[]); - -+ /** -+ * Call an Object as a consturctor if a callback is set by the -+ * ObjectTemplate::SetCallAsFunctionHandler method. -+ * Note: This method behaves like the Function::NewInstance method. -+ */ -+ V8EXPORT Local CallAsConstructor(int argc, -+ Handle argv[]); -+ - V8EXPORT static Local New(); - static inline Object* Cast(Value* obj); - private: -diff --git a/src/api.cc b/src/api.cc -index c5c66a7..9194641 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -3262,7 +3262,7 @@ Local Object::CallAsFunction(v8::Handle recv, int argc, - return Local()); - LOG_API(isolate, "Object::CallAsFunction"); - ENTER_V8(isolate); -- HandleScope scope; -+ i::HandleScope scope(isolate); - i::Handle obj = Utils::OpenHandle(this); - i::Handle recv_obj = Utils::OpenHandle(*recv); - STATIC_ASSERT(sizeof(v8::Handle) == sizeof(i::Object**)); -@@ -3282,7 +3282,44 @@ Local Object::CallAsFunction(v8::Handle recv, int argc, - i::Handle returned = - i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception); - EXCEPTION_BAILOUT_CHECK(isolate, Local()); -- return scope.Close(Utils::ToLocal(returned)); -+ return Utils::ToLocal(scope.CloseAndEscape(returned)); -+} -+ -+ -+Local Object::CallAsConstructor(int argc, -+ v8::Handle argv[]) { -+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); -+ ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()", -+ return Local()); -+ LOG_API(isolate, "Object::CallAsConstructor"); -+ ENTER_V8(isolate); -+ i::HandleScope scope(isolate); -+ i::Handle obj = Utils::OpenHandle(this); -+ STATIC_ASSERT(sizeof(v8::Handle) == sizeof(i::Object**)); -+ i::Object*** args = reinterpret_cast(argv); -+ if (obj->IsJSFunction()) { -+ i::Handle fun = i::Handle::cast(obj); -+ EXCEPTION_PREAMBLE(isolate); -+ i::Handle returned = -+ i::Execution::New(fun, argc, args, &has_pending_exception); -+ EXCEPTION_BAILOUT_CHECK(isolate, Local()); -+ return Utils::ToLocal(scope.CloseAndEscape( -+ i::Handle::cast(returned))); -+ } -+ EXCEPTION_PREAMBLE(isolate); -+ i::Handle delegate = -+ i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception); -+ EXCEPTION_BAILOUT_CHECK(isolate, Local()); -+ if (!delegate->IsUndefined()) { -+ i::Handle fun = i::Handle::cast(delegate); -+ EXCEPTION_PREAMBLE(isolate); -+ i::Handle returned = -+ i::Execution::Call(fun, obj, argc, args, &has_pending_exception); -+ EXCEPTION_BAILOUT_CHECK(isolate, Local()); -+ ASSERT(!delegate->IsUndefined()); -+ return Utils::ToLocal(scope.CloseAndEscape(returned)); -+ } -+ return Local(); - } - - -diff --git a/src/execution.cc b/src/execution.cc -index 4ab3e78..db74492 100644 ---- a/src/execution.cc -+++ b/src/execution.cc -@@ -277,6 +277,34 @@ Handle Execution::GetConstructorDelegate(Handle object) { - } - - -+Handle Execution::TryGetConstructorDelegate( -+ Handle object, -+ bool* has_pending_exception) { -+ ASSERT(!object->IsJSFunction()); -+ Isolate* isolate = Isolate::Current(); -+ -+ // If you return a function from here, it will be called when an -+ // attempt is made to call the given object as a constructor. -+ -+ // Objects created through the API can have an instance-call handler -+ // that should be used when calling the object as a function. -+ if (object->IsHeapObject() && -+ HeapObject::cast(*object)->map()->has_instance_call_handler()) { -+ return Handle( -+ isolate->global_context()->call_as_constructor_delegate()); -+ } -+ -+ // If the Object doesn't have an instance-call handler we should -+ // throw a non-callable exception. -+ i::Handle error_obj = isolate->factory()->NewTypeError( -+ "called_non_callable", i::HandleVector(&object, 1)); -+ isolate->Throw(*error_obj); -+ *has_pending_exception = true; -+ -+ return isolate->factory()->undefined_value(); -+} -+ -+ - bool StackGuard::IsStackOverflow() { - ExecutionAccess access(isolate_); - return (thread_local_.jslimit_ != kInterruptLimit && -diff --git a/src/execution.h b/src/execution.h -index 74189a2..7b6a48c 100644 ---- a/src/execution.h -+++ b/src/execution.h -@@ -146,6 +146,8 @@ class Execution : public AllStatic { - // Get a function delegate (or undefined) for the given non-function - // object. Used for support calling objects as constructors. - static Handle GetConstructorDelegate(Handle object); -+ static Handle TryGetConstructorDelegate(Handle object, -+ bool* has_pending_exception); - }; - - -diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc -index 1bcc232..f48d5b4 100644 ---- a/test/cctest/test-api.cc -+++ b/test/cctest/test-api.cc -@@ -6747,6 +6747,200 @@ THREADED_TEST(Constructor) { - CHECK(value->BooleanValue()); - } - -+ -+static Handle ConstructorCallback(const Arguments& args) { -+ ApiTestFuzzer::Fuzz(); -+ Local This; -+ -+ if (args.IsConstructCall()) { -+ Local Holder = args.Holder(); -+ This = Object::New(); -+ Local proto = Holder->GetPrototype(); -+ if (proto->IsObject()) { -+ This->SetPrototype(proto); -+ } -+ } else { -+ This = args.This(); -+ } -+ -+ This->Set(v8_str("a"), args[0]); -+ return This; -+} -+ -+ -+static Handle FakeConstructorCallback(const Arguments& args) { -+ ApiTestFuzzer::Fuzz(); -+ return args[0]; -+} -+ -+ -+THREADED_TEST(ConstructorForObject) { -+ v8::HandleScope handle_scope; -+ LocalContext context; -+ -+ { Local instance_template = ObjectTemplate::New(); -+ instance_template->SetCallAsFunctionHandler(ConstructorCallback); -+ Local instance = instance_template->NewInstance(); -+ context->Global()->Set(v8_str("obj"), instance); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); -+ -+ // Call the Object's constructor with a 32-bit signed integer. -+ value = CompileRun("(function() { var o = new obj(28); return o.a; })()"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsInt32()); -+ CHECK_EQ(28, value->Int32Value()); -+ -+ Local args1[] = { v8_num(28) }; -+ Local value_obj1 = instance->CallAsConstructor(1, args1); -+ CHECK(value_obj1->IsObject()); -+ Local object1 = Local::Cast(value_obj1); -+ value = object1->Get(v8_str("a")); -+ CHECK(value->IsInt32()); -+ CHECK(!try_catch.HasCaught()); -+ CHECK_EQ(28, value->Int32Value()); -+ -+ // Call the Object's constructor with a String. -+ value = CompileRun( -+ "(function() { var o = new obj('tipli'); return o.a; })()"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsString()); -+ String::AsciiValue string_value1(value->ToString()); -+ CHECK_EQ("tipli", *string_value1); -+ -+ Local args2[] = { v8_str("tipli") }; -+ Local value_obj2 = instance->CallAsConstructor(1, args2); -+ CHECK(value_obj2->IsObject()); -+ Local object2 = Local::Cast(value_obj2); -+ value = object2->Get(v8_str("a")); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsString()); -+ String::AsciiValue string_value2(value->ToString()); -+ CHECK_EQ("tipli", *string_value2); -+ -+ // Call the Object's constructor with a Boolean. -+ value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsBoolean()); -+ CHECK_EQ(true, value->BooleanValue()); -+ -+ Handle args3[] = { v8::Boolean::New(true) }; -+ Local value_obj3 = instance->CallAsConstructor(1, args3); -+ CHECK(value_obj3->IsObject()); -+ Local object3 = Local::Cast(value_obj3); -+ value = object3->Get(v8_str("a")); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsBoolean()); -+ CHECK_EQ(true, value->BooleanValue()); -+ -+ // Call the Object's constructor with undefined. -+ Handle args4[] = { v8::Undefined() }; -+ Local value_obj4 = instance->CallAsConstructor(1, args4); -+ CHECK(value_obj4->IsObject()); -+ Local object4 = Local::Cast(value_obj4); -+ value = object4->Get(v8_str("a")); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsUndefined()); -+ -+ // Call the Object's constructor with null. -+ Handle args5[] = { v8::Null() }; -+ Local value_obj5 = instance->CallAsConstructor(1, args5); -+ CHECK(value_obj5->IsObject()); -+ Local object5 = Local::Cast(value_obj5); -+ value = object5->Get(v8_str("a")); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsNull()); -+ } -+ -+ // Check exception handling when there is no constructor set for the Object. -+ { Local instance_template = ObjectTemplate::New(); -+ Local instance = instance_template->NewInstance(); -+ context->Global()->Set(v8_str("obj2"), instance); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); -+ -+ value = CompileRun("new obj2(28)"); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value1(try_catch.Exception()); -+ CHECK_EQ("TypeError: object is not a function", *exception_value1); -+ try_catch.Reset(); -+ -+ Local args[] = { v8_num(29) }; -+ value = instance->CallAsConstructor(1, args); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value2(try_catch.Exception()); -+ CHECK_EQ("TypeError: # is not a function", *exception_value2); -+ try_catch.Reset(); -+ } -+ -+ // Check the case when constructor throws exception. -+ { Local instance_template = ObjectTemplate::New(); -+ instance_template->SetCallAsFunctionHandler(ThrowValue); -+ Local instance = instance_template->NewInstance(); -+ context->Global()->Set(v8_str("obj3"), instance); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); -+ -+ value = CompileRun("new obj3(22)"); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value1(try_catch.Exception()); -+ CHECK_EQ("22", *exception_value1); -+ try_catch.Reset(); -+ -+ Local args[] = { v8_num(23) }; -+ value = instance->CallAsConstructor(1, args); -+ CHECK(try_catch.HasCaught()); -+ String::AsciiValue exception_value2(try_catch.Exception()); -+ CHECK_EQ("23", *exception_value2); -+ try_catch.Reset(); -+ } -+ -+ // Check whether constructor returns with an object or non-object. -+ { Local function_template = -+ FunctionTemplate::New(FakeConstructorCallback); -+ Local function = function_template->GetFunction(); -+ Local instance1 = function; -+ context->Global()->Set(v8_str("obj4"), instance1); -+ v8::TryCatch try_catch; -+ Local value; -+ CHECK(!try_catch.HasCaught()); -+ -+ CHECK(instance1->IsObject()); -+ CHECK(instance1->IsFunction()); -+ -+ value = CompileRun("new obj4(28)"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsObject()); -+ -+ Local args1[] = { v8_num(28) }; -+ value = instance1->CallAsConstructor(1, args1); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(value->IsObject()); -+ -+ Local instance_template = ObjectTemplate::New(); -+ instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); -+ Local instance2 = instance_template->NewInstance(); -+ context->Global()->Set(v8_str("obj5"), instance2); -+ CHECK(!try_catch.HasCaught()); -+ -+ CHECK(instance2->IsObject()); -+ CHECK(!instance2->IsFunction()); -+ -+ value = CompileRun("new obj5(28)"); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(!value->IsObject()); -+ -+ Local args2[] = { v8_num(28) }; -+ value = instance2->CallAsConstructor(1, args2); -+ CHECK(!try_catch.HasCaught()); -+ CHECK(!value->IsObject()); -+ } -+} -+ -+ - THREADED_TEST(FunctionDescriptorException) { - v8::HandleScope handle_scope; - LocalContext context; -@@ -7029,9 +7223,8 @@ THREADED_TEST(CallAsFunction) { - CHECK(value.IsEmpty()); - CHECK(try_catch.HasCaught()); - String::AsciiValue exception_value1(try_catch.Exception()); -- CHECK_EQ(*exception_value1, -- "TypeError: Property 'obj2' of object " -- "# is not a function"); -+ CHECK_EQ("TypeError: Property 'obj2' of object # is not a function", -+ *exception_value1); - try_catch.Reset(); - - // Call an object without call-as-function handler through the API -@@ -7041,7 +7234,7 @@ THREADED_TEST(CallAsFunction) { - CHECK(value.IsEmpty()); - CHECK(try_catch.HasCaught()); - String::AsciiValue exception_value2(try_catch.Exception()); -- CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function"); -+ CHECK_EQ("TypeError: [object Object] is not a function", *exception_value2); - try_catch.Reset(); - } - -@@ -7058,14 +7251,14 @@ THREADED_TEST(CallAsFunction) { - value = CompileRun("obj3(22)"); - CHECK(try_catch.HasCaught()); - String::AsciiValue exception_value1(try_catch.Exception()); -- CHECK_EQ(*exception_value1, "22"); -+ CHECK_EQ("22", *exception_value1); - try_catch.Reset(); - - v8::Handle args[] = { v8_num(23) }; - value = instance->CallAsFunction(instance, 1, args); - CHECK(try_catch.HasCaught()); - String::AsciiValue exception_value2(try_catch.Exception()); -- CHECK_EQ(*exception_value2, "23"); -+ CHECK_EQ("23", *exception_value2); - try_catch.Reset(); - } - } --- -1.7.5.4 - diff --git a/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch b/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch deleted file mode 100644 index 0558ce19f6..0000000000 --- a/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 859c452847317efe1131e337fcd51514de616ea2 Mon Sep 17 00:00:00 2001 -From: Jedrzej Nowacki -Date: Tue, 7 Dec 2010 11:56:42 +0100 -Subject: [PATCH] QtScript/V8: Add new v8 api to check if a value is an error. - -New function v8::Value::IsError was created. - -This API is experimental and added only for the purposes of our -research. ---- - include/v8.h | 5 +++++ - src/api.cc | 6 ++++++ - src/heap.h | 1 + - 3 files changed, 12 insertions(+), 0 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 303cb7a..f992cb2 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -937,6 +937,11 @@ class Value : public Data { - */ - V8EXPORT bool IsRegExp() const; - -+ /** -+ * Returns true if this value is an Error. -+ */ -+ V8EXPORT bool IsError() const; -+ - V8EXPORT Local ToBoolean() const; - V8EXPORT Local ToNumber() const; - V8EXPORT Local ToString() const; -diff --git a/src/api.cc b/src/api.cc -index fd4a76b..5ada246 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -2108,6 +2108,12 @@ bool Value::IsRegExp() const { - return obj->IsJSRegExp(); - } - -+bool Value::IsError() const { -+ if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsError()")) return false; -+ i::Handle obj = Utils::OpenHandle(this); -+ return obj->HasSpecificClassOf(HEAP->Error_symbol()); -+} -+ - - Local Value::ToString() const { - i::Handle obj = Utils::OpenHandle(this); -diff --git a/src/heap.h b/src/heap.h -index 8cbf378..db90bb9 100644 ---- a/src/heap.h -+++ b/src/heap.h -@@ -169,6 +169,7 @@ inline Heap* _inline_get_heap_(); - V(string_symbol, "string") \ - V(String_symbol, "String") \ - V(Date_symbol, "Date") \ -+ V(Error_symbol, "Error") \ - V(this_symbol, "this") \ - V(to_string_symbol, "toString") \ - V(char_at_symbol, "CharAt") \ --- -1.7.4.15.g7811d - -- cgit v1.2.3