Reviewers: Michael Starzinger,
Description:
Function::Call API should allow v8::Value as a receiver
Since the primitive values can be a receiver of strict mode functions in
ECMA262 5.1th, v8::Function::Call should take v8::Value as a receiver
instead of v8::Object.
BUG=v8:2915
Please review this at https://chromiumcodereview.appspot.com/24920003/
SVN Base: git://github.com/v8/v8.git@master
Affected files (+41, -4 lines):
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
5f9286e5f8503ea58ad098378942e5ba5f3e0f49..2aeafce5ff79d114964047f398f32227244c05d0
100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2485,7 +2485,7 @@ class V8_EXPORT Function : public Object {
Local<Object> NewInstance() const;
Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
- Local<Value> Call(Handle<Object> recv, int argc, Handle<Value> argv[]);
+ Local<Value> Call(Handle<Value> recv, int argc, Handle<Value> argv[]);
void SetName(Handle<String> name);
Handle<Value> GetName() const;
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
01aa2ceb4be49be70af7d17da565902853ba75bf..a4416535a1cceb6eaf5c9859863b4fbf372774d6
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -4053,7 +4053,7 @@ Local<v8::Object> Function::NewInstance(int argc,
}
-Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
+Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
v8::Handle<v8::Value> argv[]) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
@@ -4070,7 +4070,7 @@ Local<v8::Value>
Function::Call(v8::Handle<v8::Object> recv, int argc,
i::Handle<i::Object>* args =
reinterpret_cast<i::Handle<i::Object>*>(argv);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned = i::Execution::Call(
- isolate, fun, recv_obj, argc, args, &has_pending_exception);
+ isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
raw_result = *returned;
}
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
4dc773b414cce7a99b0e3076fb4a86da7620dc0c..eaa745c43c6a9d8726c4be8fd992f5f7157a6be6
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -4013,7 +4013,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 = [];"
@@ -4021,9 +4022,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));
@@ -4060,6 +4072,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)));
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.