Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index a24be6eab0e63e31be8c4be7f999d07e3d245216..2d52b66fd3c2b9692aa28fd3fc2e9d473715891b 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -4011,7 +4011,8 @@ THREADED_TEST(Vector) { |
THREADED_TEST(FunctionCall) { |
LocalContext context; |
- v8::HandleScope scope(context->GetIsolate()); |
+ v8::Isolate* isolate = context->GetIsolate(); |
+ v8::HandleScope scope(isolate); |
CompileRun( |
"function Foo() {" |
" var result = [];" |
@@ -4019,9 +4020,20 @@ THREADED_TEST(FunctionCall) { |
" result.push(arguments[i]);" |
" }" |
" return result;" |
+ "}" |
+ "function ReturnThisSloppy() {" |
+ " return this;" |
+ "}" |
+ "function ReturnThisStrict() {" |
+ " 'use strict';" |
+ " return this;" |
"}"); |
Local<Function> Foo = |
Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); |
+ Local<Function> ReturnThisSloppy = |
+ Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisSloppy"))); |
+ Local<Function> ReturnThisStrict = |
+ Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisStrict"))); |
v8::Handle<Value>* args0 = NULL; |
Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->Call(Foo, 0, args0)); |
@@ -4058,6 +4070,31 @@ THREADED_TEST(FunctionCall) { |
CHECK_EQ(8.8, a4->Get(v8::Integer::New(1))->NumberValue()); |
CHECK_EQ(9.9, a4->Get(v8::Integer::New(2))->NumberValue()); |
CHECK_EQ(10.11, a4->Get(v8::Integer::New(3))->NumberValue()); |
+ |
+ Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL); |
+ CHECK(r1->StrictEquals(context->Global())); |
+ Local<v8::Value> r2 = ReturnThisSloppy->Call(v8::Null(isolate), 0, NULL); |
+ CHECK(r2->StrictEquals(context->Global())); |
+ Local<v8::Value> r3 = ReturnThisSloppy->Call(v8_num(42), 0, NULL); |
+ CHECK(r3->IsNumberObject()); |
+ CHECK_EQ(42.0, r3.As<v8::NumberObject>()->ValueOf()); |
+ Local<v8::Value> r4 = ReturnThisSloppy->Call(v8_str("hello"), 0, NULL); |
+ CHECK(r4->IsStringObject()); |
+ CHECK(r4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); |
+ Local<v8::Value> r5 = ReturnThisSloppy->Call(v8::True(isolate), 0, NULL); |
+ CHECK(r5->IsBooleanObject()); |
+ CHECK(r5.As<v8::BooleanObject>()->ValueOf()); |
+ |
+ Local<v8::Value> r6 = ReturnThisStrict->Call(v8::Undefined(isolate), 0, NULL); |
+ CHECK(r6->IsUndefined()); |
+ Local<v8::Value> r7 = ReturnThisStrict->Call(v8::Null(isolate), 0, NULL); |
+ CHECK(r7->IsNull()); |
+ Local<v8::Value> r8 = ReturnThisStrict->Call(v8_num(42), 0, NULL); |
+ CHECK(r8->StrictEquals(v8_num(42))); |
+ Local<v8::Value> r9 = ReturnThisStrict->Call(v8_str("hello"), 0, NULL); |
+ CHECK(r9->StrictEquals(v8_str("hello"))); |
+ Local<v8::Value> r10 = ReturnThisStrict->Call(v8::True(isolate), 0, NULL); |
+ CHECK(r10->StrictEquals(v8::True(isolate))); |
} |
@@ -10176,6 +10213,10 @@ static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) { |
args.GetReturnValue().Set(args[0]); |
} |
+static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ args.GetReturnValue().Set(args.This()); |
+} |
+ |
// Test that a call handler can be set for objects which will allow |
// non-function objects created through the API to be called as |
@@ -10289,6 +10330,81 @@ THREADED_TEST(CallAsFunction) { |
CHECK_EQ("23", *exception_value2); |
try_catch.Reset(); |
} |
+ |
+ { v8::Isolate* isolate = context->GetIsolate(); |
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); |
+ Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
+ instance_template->SetCallAsFunctionHandler(ReturnThis); |
+ Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
+ |
+ Local<v8::Value> a1 = |
+ instance->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
+ CHECK(a1->StrictEquals(instance)); |
+ Local<v8::Value> a2 = |
+ instance->CallAsFunction(v8::Null(isolate), 0, NULL); |
+ CHECK(a2->StrictEquals(instance)); |
+ Local<v8::Value> a3 = |
+ instance->CallAsFunction(v8_num(42), 0, NULL); |
+ CHECK(a3->StrictEquals(instance)); |
+ Local<v8::Value> a4 = |
+ instance->CallAsFunction(v8_str("hello"), 0, NULL); |
+ CHECK(a4->StrictEquals(instance)); |
+ Local<v8::Value> a5 = |
+ instance->CallAsFunction(v8::True(isolate), 0, NULL); |
+ CHECK(a5->StrictEquals(instance)); |
+ } |
+ |
+ { v8::Isolate* isolate = context->GetIsolate(); |
+ CompileRun( |
+ "function ReturnThisSloppy() {" |
+ " return this;" |
+ "}" |
+ "function ReturnThisStrict() {" |
+ " 'use strict';" |
+ " return this;" |
+ "}"); |
+ Local<Function> ReturnThisSloppy = |
+ Local<Function>::Cast( |
+ context->Global()->Get(v8_str("ReturnThisSloppy"))); |
+ Local<Function> ReturnThisStrict = |
+ Local<Function>::Cast( |
+ context->Global()->Get(v8_str("ReturnThisStrict"))); |
+ |
+ Local<v8::Value> a1 = |
+ ReturnThisSloppy->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
+ CHECK(a1->StrictEquals(context->Global())); |
+ Local<v8::Value> a2 = |
+ ReturnThisSloppy->CallAsFunction(v8::Null(isolate), 0, NULL); |
+ CHECK(a2->StrictEquals(context->Global())); |
+ Local<v8::Value> a3 = |
+ ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); |
+ CHECK(a3->IsNumberObject()); |
+ CHECK_EQ(42.0, a3.As<v8::NumberObject>()->ValueOf()); |
+ Local<v8::Value> a4 = |
+ ReturnThisSloppy->CallAsFunction(v8_str("hello"), 0, NULL); |
+ CHECK(a4->IsStringObject()); |
+ CHECK(a4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); |
+ Local<v8::Value> a5 = |
+ ReturnThisSloppy->CallAsFunction(v8::True(isolate), 0, NULL); |
+ CHECK(a5->IsBooleanObject()); |
+ CHECK(a5.As<v8::BooleanObject>()->ValueOf()); |
+ |
+ Local<v8::Value> a6 = |
+ ReturnThisStrict->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
+ CHECK(a6->IsUndefined()); |
+ Local<v8::Value> a7 = |
+ ReturnThisStrict->CallAsFunction(v8::Null(isolate), 0, NULL); |
+ CHECK(a7->IsNull()); |
+ Local<v8::Value> a8 = |
+ ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); |
+ CHECK(a8->StrictEquals(v8_num(42))); |
+ Local<v8::Value> a9 = |
+ ReturnThisStrict->CallAsFunction(v8_str("hello"), 0, NULL); |
+ CHECK(a9->StrictEquals(v8_str("hello"))); |
+ Local<v8::Value> a10 = |
+ ReturnThisStrict->CallAsFunction(v8::True(isolate), 0, NULL); |
+ CHECK(a10->StrictEquals(v8::True(isolate))); |
+ } |
} |