| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 result = v8_compile("(new obj()).m")->Run(); | 816 result = v8_compile("(new obj()).m")->Run(); |
| 817 CHECK_EQ(239, result->Int32Value()); | 817 CHECK_EQ(239, result->Int32Value()); |
| 818 } | 818 } |
| 819 } | 819 } |
| 820 | 820 |
| 821 | 821 |
| 822 static void* expected_ptr; | 822 static void* expected_ptr; |
| 823 static v8::Handle<v8::Value> callback(const v8::Arguments& args) { | 823 static v8::Handle<v8::Value> callback(const v8::Arguments& args) { |
| 824 void* ptr = v8::External::Unwrap(args.Data()); | 824 void* ptr = v8::External::Unwrap(args.Data()); |
| 825 CHECK_EQ(expected_ptr, ptr); | 825 CHECK_EQ(expected_ptr, ptr); |
| 826 return v8::Boolean::New(true); | 826 return v8::True(); |
| 827 } | 827 } |
| 828 | 828 |
| 829 | 829 |
| 830 static void TestExternalPointerWrapping() { | 830 static void TestExternalPointerWrapping() { |
| 831 v8::HandleScope scope; | 831 v8::HandleScope scope; |
| 832 LocalContext env; | 832 LocalContext env; |
| 833 | 833 |
| 834 v8::Handle<v8::Value> data = v8::External::Wrap(expected_ptr); | 834 v8::Handle<v8::Value> data = v8::External::Wrap(expected_ptr); |
| 835 | 835 |
| 836 v8::Handle<v8::Object> obj = v8::Object::New(); | 836 v8::Handle<v8::Object> obj = v8::Object::New(); |
| (...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2616 } | 2616 } |
| 2617 | 2617 |
| 2618 | 2618 |
| 2619 v8::Handle<Value> ThrowFromC(const v8::Arguments& args) { | 2619 v8::Handle<Value> ThrowFromC(const v8::Arguments& args) { |
| 2620 ApiTestFuzzer::Fuzz(); | 2620 ApiTestFuzzer::Fuzz(); |
| 2621 return v8::ThrowException(v8_str("konto")); | 2621 return v8::ThrowException(v8_str("konto")); |
| 2622 } | 2622 } |
| 2623 | 2623 |
| 2624 | 2624 |
| 2625 v8::Handle<Value> CCatcher(const v8::Arguments& args) { | 2625 v8::Handle<Value> CCatcher(const v8::Arguments& args) { |
| 2626 if (args.Length() < 1) return v8::Boolean::New(false); | 2626 if (args.Length() < 1) return v8::False(); |
| 2627 v8::HandleScope scope; | 2627 v8::HandleScope scope; |
| 2628 v8::TryCatch try_catch; | 2628 v8::TryCatch try_catch; |
| 2629 Local<Value> result = v8::Script::Compile(args[0]->ToString())->Run(); | 2629 Local<Value> result = v8::Script::Compile(args[0]->ToString())->Run(); |
| 2630 CHECK(!try_catch.HasCaught() || result.IsEmpty()); | 2630 CHECK(!try_catch.HasCaught() || result.IsEmpty()); |
| 2631 return v8::Boolean::New(try_catch.HasCaught()); | 2631 return v8::Boolean::New(try_catch.HasCaught()); |
| 2632 } | 2632 } |
| 2633 | 2633 |
| 2634 | 2634 |
| 2635 THREADED_TEST(APICatch) { | 2635 THREADED_TEST(APICatch) { |
| 2636 v8::HandleScope scope; | 2636 v8::HandleScope scope; |
| (...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4233 "}\n" | 4233 "}\n" |
| 4234 "\"PASS\"", | 4234 "\"PASS\"", |
| 4235 "PASS"); | 4235 "PASS"); |
| 4236 } | 4236 } |
| 4237 | 4237 |
| 4238 | 4238 |
| 4239 template <typename T> static void USE(T) { } | 4239 template <typename T> static void USE(T) { } |
| 4240 | 4240 |
| 4241 | 4241 |
| 4242 // This test is not intended to be run, just type checked. | 4242 // This test is not intended to be run, just type checked. |
| 4243 static void PersistentHandles() { | 4243 static inline void PersistentHandles() { |
| 4244 USE(PersistentHandles); | 4244 USE(PersistentHandles); |
| 4245 Local<String> str = v8_str("foo"); | 4245 Local<String> str = v8_str("foo"); |
| 4246 v8::Persistent<String> p_str = v8::Persistent<String>::New(str); | 4246 v8::Persistent<String> p_str = v8::Persistent<String>::New(str); |
| 4247 USE(p_str); | 4247 USE(p_str); |
| 4248 Local<Script> scr = Script::Compile(v8_str("")); | 4248 Local<Script> scr = Script::Compile(v8_str("")); |
| 4249 v8::Persistent<Script> p_scr = v8::Persistent<Script>::New(scr); | 4249 v8::Persistent<Script> p_scr = v8::Persistent<Script>::New(scr); |
| 4250 USE(p_scr); | 4250 USE(p_scr); |
| 4251 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 4251 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
| 4252 v8::Persistent<ObjectTemplate> p_templ = | 4252 v8::Persistent<ObjectTemplate> p_templ = |
| 4253 v8::Persistent<ObjectTemplate>::New(templ); | 4253 v8::Persistent<ObjectTemplate>::New(templ); |
| (...skipping 3049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7303 CHECK(value->IsString()); | 7303 CHECK(value->IsString()); |
| 7304 String::AsciiValue string_value2(value->ToString()); | 7304 String::AsciiValue string_value2(value->ToString()); |
| 7305 CHECK_EQ("tipli", *string_value2); | 7305 CHECK_EQ("tipli", *string_value2); |
| 7306 | 7306 |
| 7307 // Call the Object's constructor with a Boolean. | 7307 // Call the Object's constructor with a Boolean. |
| 7308 value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); | 7308 value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); |
| 7309 CHECK(!try_catch.HasCaught()); | 7309 CHECK(!try_catch.HasCaught()); |
| 7310 CHECK(value->IsBoolean()); | 7310 CHECK(value->IsBoolean()); |
| 7311 CHECK_EQ(true, value->BooleanValue()); | 7311 CHECK_EQ(true, value->BooleanValue()); |
| 7312 | 7312 |
| 7313 Handle<Value> args3[] = { v8::Boolean::New(true) }; | 7313 Handle<Value> args3[] = { v8::True() }; |
| 7314 Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); | 7314 Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); |
| 7315 CHECK(value_obj3->IsObject()); | 7315 CHECK(value_obj3->IsObject()); |
| 7316 Local<Object> object3 = Local<Object>::Cast(value_obj3); | 7316 Local<Object> object3 = Local<Object>::Cast(value_obj3); |
| 7317 value = object3->Get(v8_str("a")); | 7317 value = object3->Get(v8_str("a")); |
| 7318 CHECK(!try_catch.HasCaught()); | 7318 CHECK(!try_catch.HasCaught()); |
| 7319 CHECK(value->IsBoolean()); | 7319 CHECK(value->IsBoolean()); |
| 7320 CHECK_EQ(true, value->BooleanValue()); | 7320 CHECK_EQ(true, value->BooleanValue()); |
| 7321 | 7321 |
| 7322 // Call the Object's constructor with undefined. | 7322 // Call the Object's constructor with undefined. |
| 7323 Handle<Value> args4[] = { v8::Undefined() }; | 7323 Handle<Value> args4[] = { v8::Undefined() }; |
| (...skipping 2250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9574 CHECK_EQ(3, value->Int32Value()); | 9574 CHECK_EQ(3, value->Int32Value()); |
| 9575 | 9575 |
| 9576 // Check 'i' is cannot be shadowed or changed. | 9576 // Check 'i' is cannot be shadowed or changed. |
| 9577 value = v8_compile("o.i = 3; o.i")->Run(); | 9577 value = v8_compile("o.i = 3; o.i")->Run(); |
| 9578 CHECK_EQ(42, value->Int32Value()); | 9578 CHECK_EQ(42, value->Int32Value()); |
| 9579 } | 9579 } |
| 9580 | 9580 |
| 9581 | 9581 |
| 9582 static v8::Handle<Value> IsConstructHandler(const v8::Arguments& args) { | 9582 static v8::Handle<Value> IsConstructHandler(const v8::Arguments& args) { |
| 9583 ApiTestFuzzer::Fuzz(); | 9583 ApiTestFuzzer::Fuzz(); |
| 9584 if (args.IsConstructCall()) { | 9584 return v8::Boolean::New(args.IsConstructCall()); |
| 9585 return v8::Boolean::New(true); | |
| 9586 } | |
| 9587 return v8::Boolean::New(false); | |
| 9588 } | 9585 } |
| 9589 | 9586 |
| 9590 | 9587 |
| 9591 THREADED_TEST(IsConstructCall) { | 9588 THREADED_TEST(IsConstructCall) { |
| 9592 v8::HandleScope scope; | 9589 v8::HandleScope scope; |
| 9593 | 9590 |
| 9594 // Function template with call handler. | 9591 // Function template with call handler. |
| 9595 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 9592 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 9596 templ->SetCallHandler(IsConstructHandler); | 9593 templ->SetCallHandler(IsConstructHandler); |
| 9597 | 9594 |
| (...skipping 2207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11805 CHECK_EQ(28, result->Int32Value()); | 11802 CHECK_EQ(28, result->Int32Value()); |
| 11806 | 11803 |
| 11807 result = CompileRun("var sum = 0;" | 11804 result = CompileRun("var sum = 0;" |
| 11808 "for (var i = 0; i < 8; i++) {" | 11805 "for (var i = 0; i < 8; i++) {" |
| 11809 " sum += pixels[i];" | 11806 " sum += pixels[i];" |
| 11810 "}" | 11807 "}" |
| 11811 "sum;"); | 11808 "sum;"); |
| 11812 CHECK_EQ(28, result->Int32Value()); | 11809 CHECK_EQ(28, result->Int32Value()); |
| 11813 | 11810 |
| 11814 i::Handle<i::Smi> value(i::Smi::FromInt(2)); | 11811 i::Handle<i::Smi> value(i::Smi::FromInt(2)); |
| 11815 i::SetElement(jsobj, 1, value, i::kNonStrictMode); | 11812 i::Handle<i::Object> no_failure; |
| 11813 no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode); |
| 11814 ASSERT(!no_failure.is_null()); |
| 11815 i::USE(no_failure); |
| 11816 CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); | 11816 CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); |
| 11817 *value.location() = i::Smi::FromInt(256); | 11817 *value.location() = i::Smi::FromInt(256); |
| 11818 i::SetElement(jsobj, 1, value, i::kNonStrictMode); | 11818 no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode); |
| 11819 ASSERT(!no_failure.is_null()); |
| 11820 i::USE(no_failure); |
| 11819 CHECK_EQ(255, | 11821 CHECK_EQ(255, |
| 11820 i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); | 11822 i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); |
| 11821 *value.location() = i::Smi::FromInt(-1); | 11823 *value.location() = i::Smi::FromInt(-1); |
| 11822 i::SetElement(jsobj, 1, value, i::kNonStrictMode); | 11824 no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode); |
| 11825 ASSERT(!no_failure.is_null()); |
| 11826 i::USE(no_failure); |
| 11823 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); | 11827 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); |
| 11824 | 11828 |
| 11825 result = CompileRun("for (var i = 0; i < 8; i++) {" | 11829 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 11826 " pixels[i] = (i * 65) - 109;" | 11830 " pixels[i] = (i * 65) - 109;" |
| 11827 "}" | 11831 "}" |
| 11828 "pixels[1] + pixels[6];"); | 11832 "pixels[1] + pixels[6];"); |
| 11829 CHECK_EQ(255, result->Int32Value()); | 11833 CHECK_EQ(255, result->Int32Value()); |
| 11830 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0)->ToObjectChecked())->value()); | 11834 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(0)->ToObjectChecked())->value()); |
| 11831 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); | 11835 CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value()); |
| 11832 CHECK_EQ(21, | 11836 CHECK_EQ(21, |
| (...skipping 2631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14464 } | 14468 } |
| 14465 | 14469 |
| 14466 | 14470 |
| 14467 TEST(RegExp) { | 14471 TEST(RegExp) { |
| 14468 v8::HandleScope scope; | 14472 v8::HandleScope scope; |
| 14469 LocalContext context; | 14473 LocalContext context; |
| 14470 | 14474 |
| 14471 v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone); | 14475 v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone); |
| 14472 CHECK(re->IsRegExp()); | 14476 CHECK(re->IsRegExp()); |
| 14473 CHECK(re->GetSource()->Equals(v8_str("foo"))); | 14477 CHECK(re->GetSource()->Equals(v8_str("foo"))); |
| 14474 CHECK_EQ(re->GetFlags(), v8::RegExp::kNone); | 14478 CHECK_EQ(v8::RegExp::kNone, re->GetFlags()); |
| 14475 | 14479 |
| 14476 re = v8::RegExp::New(v8_str("bar"), | 14480 re = v8::RegExp::New(v8_str("bar"), |
| 14477 static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | | 14481 static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | |
| 14478 v8::RegExp::kGlobal)); | 14482 v8::RegExp::kGlobal)); |
| 14479 CHECK(re->IsRegExp()); | 14483 CHECK(re->IsRegExp()); |
| 14480 CHECK(re->GetSource()->Equals(v8_str("bar"))); | 14484 CHECK(re->GetSource()->Equals(v8_str("bar"))); |
| 14481 CHECK_EQ(static_cast<int>(re->GetFlags()), | 14485 CHECK_EQ(v8::RegExp::kIgnoreCase | v8::RegExp::kGlobal, |
| 14482 v8::RegExp::kIgnoreCase | v8::RegExp::kGlobal); | 14486 static_cast<int>(re->GetFlags())); |
| 14483 | 14487 |
| 14484 re = v8::RegExp::New(v8_str("baz"), | 14488 re = v8::RegExp::New(v8_str("baz"), |
| 14485 static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | | 14489 static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | |
| 14486 v8::RegExp::kMultiline)); | 14490 v8::RegExp::kMultiline)); |
| 14487 CHECK(re->IsRegExp()); | 14491 CHECK(re->IsRegExp()); |
| 14488 CHECK(re->GetSource()->Equals(v8_str("baz"))); | 14492 CHECK(re->GetSource()->Equals(v8_str("baz"))); |
| 14489 CHECK_EQ(static_cast<int>(re->GetFlags()), | 14493 CHECK_EQ(v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline, |
| 14490 v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline); | 14494 static_cast<int>(re->GetFlags())); |
| 14491 | 14495 |
| 14492 re = CompileRun("/quux/").As<v8::RegExp>(); | 14496 re = CompileRun("/quux/").As<v8::RegExp>(); |
| 14493 CHECK(re->IsRegExp()); | 14497 CHECK(re->IsRegExp()); |
| 14494 CHECK(re->GetSource()->Equals(v8_str("quux"))); | 14498 CHECK(re->GetSource()->Equals(v8_str("quux"))); |
| 14495 CHECK_EQ(re->GetFlags(), v8::RegExp::kNone); | 14499 CHECK_EQ(v8::RegExp::kNone, re->GetFlags()); |
| 14496 | 14500 |
| 14497 re = CompileRun("/quux/gm").As<v8::RegExp>(); | 14501 re = CompileRun("/quux/gm").As<v8::RegExp>(); |
| 14498 CHECK(re->IsRegExp()); | 14502 CHECK(re->IsRegExp()); |
| 14499 CHECK(re->GetSource()->Equals(v8_str("quux"))); | 14503 CHECK(re->GetSource()->Equals(v8_str("quux"))); |
| 14500 CHECK_EQ(static_cast<int>(re->GetFlags()), | 14504 CHECK_EQ(v8::RegExp::kGlobal | v8::RegExp::kMultiline, |
| 14501 v8::RegExp::kGlobal | v8::RegExp::kMultiline); | 14505 static_cast<int>(re->GetFlags())); |
| 14502 | 14506 |
| 14503 // Override the RegExp constructor and check the API constructor | 14507 // Override the RegExp constructor and check the API constructor |
| 14504 // still works. | 14508 // still works. |
| 14505 CompileRun("RegExp = function() {}"); | 14509 CompileRun("RegExp = function() {}"); |
| 14506 | 14510 |
| 14507 re = v8::RegExp::New(v8_str("foobar"), v8::RegExp::kNone); | 14511 re = v8::RegExp::New(v8_str("foobar"), v8::RegExp::kNone); |
| 14508 CHECK(re->IsRegExp()); | 14512 CHECK(re->IsRegExp()); |
| 14509 CHECK(re->GetSource()->Equals(v8_str("foobar"))); | 14513 CHECK(re->GetSource()->Equals(v8_str("foobar"))); |
| 14510 CHECK_EQ(re->GetFlags(), v8::RegExp::kNone); | 14514 CHECK_EQ(v8::RegExp::kNone, re->GetFlags()); |
| 14511 | 14515 |
| 14512 re = v8::RegExp::New(v8_str("foobarbaz"), | 14516 re = v8::RegExp::New(v8_str("foobarbaz"), |
| 14513 static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | | 14517 static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | |
| 14514 v8::RegExp::kMultiline)); | 14518 v8::RegExp::kMultiline)); |
| 14515 CHECK(re->IsRegExp()); | 14519 CHECK(re->IsRegExp()); |
| 14516 CHECK(re->GetSource()->Equals(v8_str("foobarbaz"))); | 14520 CHECK(re->GetSource()->Equals(v8_str("foobarbaz"))); |
| 14517 CHECK_EQ(static_cast<int>(re->GetFlags()), | 14521 CHECK_EQ(v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline, |
| 14518 v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline); | 14522 static_cast<int>(re->GetFlags())); |
| 14519 | 14523 |
| 14520 context->Global()->Set(v8_str("re"), re); | 14524 context->Global()->Set(v8_str("re"), re); |
| 14521 ExpectTrue("re.test('FoobarbaZ')"); | 14525 ExpectTrue("re.test('FoobarbaZ')"); |
| 14522 | 14526 |
| 14523 // RegExps are objects on which you can set properties. | 14527 // RegExps are objects on which you can set properties. |
| 14524 re->Set(v8_str("property"), v8::Integer::New(32)); | 14528 re->Set(v8_str("property"), v8::Integer::New(32)); |
| 14525 v8::Handle<v8::Value> value = CompileRun("re.property"); | 14529 v8::Handle<v8::Value> value = CompileRun("re.property"); |
| 14526 ASSERT_EQ(32, value->Int32Value()); | 14530 ASSERT_EQ(32, value->Int32Value()); |
| 14527 | 14531 |
| 14528 v8::TryCatch try_catch; | 14532 v8::TryCatch try_catch; |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15058 | 15062 |
| 15059 Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); | 15063 Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); |
| 15060 CHECK(result5->Equals( | 15064 CHECK(result5->Equals( |
| 15061 object_with_hidden->GetPrototype()->ToObject()->GetPrototype())); | 15065 object_with_hidden->GetPrototype()->ToObject()->GetPrototype())); |
| 15062 | 15066 |
| 15063 Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); | 15067 Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); |
| 15064 CHECK(result6->Equals(Undefined())); | 15068 CHECK(result6->Equals(Undefined())); |
| 15065 | 15069 |
| 15066 context.Dispose(); | 15070 context.Dispose(); |
| 15067 } | 15071 } |
| 15072 |
| 15073 |
| 15074 static void TestReceiver(Local<Value> expected_result, |
| 15075 Local<Value> expected_receiver, |
| 15076 const char* code) { |
| 15077 Local<Value> result = CompileRun(code); |
| 15078 CHECK(result->IsObject()); |
| 15079 CHECK(expected_receiver->Equals(result->ToObject()->Get(1))); |
| 15080 CHECK(expected_result->Equals(result->ToObject()->Get(0))); |
| 15081 } |
| 15082 |
| 15083 |
| 15084 THREADED_TEST(ForeignFunctionReceiver) { |
| 15085 HandleScope scope; |
| 15086 |
| 15087 // Create two contexts with different "id" properties ('i' and 'o'). |
| 15088 // Call a function both from its own context and from a the foreign |
| 15089 // context, and see what "this" is bound to (returning both "this" |
| 15090 // and "this.id" for comparison). |
| 15091 |
| 15092 Persistent<Context> foreign_context = v8::Context::New(); |
| 15093 foreign_context->Enter(); |
| 15094 Local<Value> foreign_function = |
| 15095 CompileRun("function func() { return { 0: this.id, " |
| 15096 " 1: this, " |
| 15097 " toString: function() { " |
| 15098 " return this[0];" |
| 15099 " }" |
| 15100 " };" |
| 15101 "}" |
| 15102 "var id = 'i';" |
| 15103 "func;"); |
| 15104 CHECK(foreign_function->IsFunction()); |
| 15105 foreign_context->Exit(); |
| 15106 |
| 15107 LocalContext context; |
| 15108 |
| 15109 Local<String> password = v8_str("Password"); |
| 15110 // Don't get hit by security checks when accessing foreign_context's |
| 15111 // global receiver (aka. global proxy). |
| 15112 context->SetSecurityToken(password); |
| 15113 foreign_context->SetSecurityToken(password); |
| 15114 |
| 15115 Local<String> i = v8_str("i"); |
| 15116 Local<String> o = v8_str("o"); |
| 15117 Local<String> id = v8_str("id"); |
| 15118 |
| 15119 CompileRun("function ownfunc() { return { 0: this.id, " |
| 15120 " 1: this, " |
| 15121 " toString: function() { " |
| 15122 " return this[0];" |
| 15123 " }" |
| 15124 " };" |
| 15125 "}" |
| 15126 "var id = 'o';" |
| 15127 "ownfunc"); |
| 15128 context->Global()->Set(v8_str("func"), foreign_function); |
| 15129 |
| 15130 // Sanity check the contexts. |
| 15131 CHECK(i->Equals(foreign_context->Global()->Get(id))); |
| 15132 CHECK(o->Equals(context->Global()->Get(id))); |
| 15133 |
| 15134 // Checking local function's receiver. |
| 15135 // Calling function using its call/apply methods. |
| 15136 TestReceiver(o, context->Global(), "ownfunc.call()"); |
| 15137 TestReceiver(o, context->Global(), "ownfunc.apply()"); |
| 15138 // Making calls through built-in functions. |
| 15139 TestReceiver(o, context->Global(), "[1].map(ownfunc)[0]"); |
| 15140 CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/,ownfunc)[1]"))); |
| 15141 CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/g,ownfunc)[1]"))); |
| 15142 CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/g,ownfunc)[3]"))); |
| 15143 // Calling with environment record as base. |
| 15144 TestReceiver(o, context->Global(), "ownfunc()"); |
| 15145 // Calling with no base. |
| 15146 TestReceiver(o, context->Global(), "(1,ownfunc)()"); |
| 15147 |
| 15148 // Checking foreign function return value. |
| 15149 // Calling function using its call/apply methods. |
| 15150 TestReceiver(i, foreign_context->Global(), "func.call()"); |
| 15151 TestReceiver(i, foreign_context->Global(), "func.apply()"); |
| 15152 // Calling function using another context's call/apply methods. |
| 15153 TestReceiver(i, foreign_context->Global(), |
| 15154 "Function.prototype.call.call(func)"); |
| 15155 TestReceiver(i, foreign_context->Global(), |
| 15156 "Function.prototype.call.apply(func)"); |
| 15157 TestReceiver(i, foreign_context->Global(), |
| 15158 "Function.prototype.apply.call(func)"); |
| 15159 TestReceiver(i, foreign_context->Global(), |
| 15160 "Function.prototype.apply.apply(func)"); |
| 15161 // Making calls through built-in functions. |
| 15162 TestReceiver(i, foreign_context->Global(), "[1].map(func)[0]"); |
| 15163 // ToString(func()) is func()[0], i.e., the returned this.id. |
| 15164 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/,func)[1]"))); |
| 15165 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[1]"))); |
| 15166 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
| 15167 |
| 15168 // TODO(1547): Make the following also return "i". |
| 15169 // Calling with environment record as base. |
| 15170 TestReceiver(o, context->Global(), "func()"); |
| 15171 // Calling with no base. |
| 15172 TestReceiver(o, context->Global(), "(1,func)()"); |
| 15173 |
| 15174 foreign_context.Dispose(); |
| 15175 } |
| OLD | NEW |