| 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 12 matching lines...) Expand all Loading... |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include <limits.h> | 28 #include <limits.h> |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 | 31 |
| 32 #include "api.h" | 32 #include "api.h" |
| 33 #include "isolate.h" |
| 33 #include "compilation-cache.h" | 34 #include "compilation-cache.h" |
| 34 #include "execution.h" | 35 #include "execution.h" |
| 35 #include "snapshot.h" | 36 #include "snapshot.h" |
| 36 #include "platform.h" | 37 #include "platform.h" |
| 37 #include "utils.h" | 38 #include "utils.h" |
| 38 #include "cctest.h" | 39 #include "cctest.h" |
| 39 #include "parser.h" | 40 #include "parser.h" |
| 40 #include "unicode-inl.h" | 41 #include "unicode-inl.h" |
| 41 | 42 |
| 42 static const bool kLogThreading = false; | 43 static const bool kLogThreading = false; |
| (...skipping 3889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3932 | 3933 |
| 3933 | 3934 |
| 3934 ExpectBoolean("undetectable===null", false); | 3935 ExpectBoolean("undetectable===null", false); |
| 3935 ExpectBoolean("null===undetectable", false); | 3936 ExpectBoolean("null===undetectable", false); |
| 3936 ExpectBoolean("undetectable===undefined", false); | 3937 ExpectBoolean("undetectable===undefined", false); |
| 3937 ExpectBoolean("undefined===undetectable", false); | 3938 ExpectBoolean("undefined===undetectable", false); |
| 3938 ExpectBoolean("undetectable===undetectable", true); | 3939 ExpectBoolean("undetectable===undetectable", true); |
| 3939 } | 3940 } |
| 3940 | 3941 |
| 3941 | 3942 |
| 3943 TEST(UndetectableOptimized) { |
| 3944 i::FLAG_allow_natives_syntax = true; |
| 3945 v8::HandleScope scope; |
| 3946 LocalContext env; |
| 3947 |
| 3948 Local<String> obj = String::NewUndetectable("foo"); |
| 3949 env->Global()->Set(v8_str("undetectable"), obj); |
| 3950 env->Global()->Set(v8_str("detectable"), v8_str("bar")); |
| 3951 |
| 3952 ExpectString( |
| 3953 "function testBranch() {" |
| 3954 " if (!%_IsUndetectableObject(undetectable)) throw 1;" |
| 3955 " if (%_IsUndetectableObject(detectable)) throw 2;" |
| 3956 "}\n" |
| 3957 "function testBool() {" |
| 3958 " var b1 = !%_IsUndetectableObject(undetectable);" |
| 3959 " var b2 = %_IsUndetectableObject(detectable);" |
| 3960 " if (b1) throw 3;" |
| 3961 " if (b2) throw 4;" |
| 3962 " return b1 == b2;" |
| 3963 "}\n" |
| 3964 "%OptimizeFunctionOnNextCall(testBranch);" |
| 3965 "%OptimizeFunctionOnNextCall(testBool);" |
| 3966 "for (var i = 0; i < 10; i++) {" |
| 3967 " testBranch();" |
| 3968 " testBool();" |
| 3969 "}\n" |
| 3970 "\"PASS\"", |
| 3971 "PASS"); |
| 3972 } |
| 3973 |
| 3974 |
| 3942 template <typename T> static void USE(T) { } | 3975 template <typename T> static void USE(T) { } |
| 3943 | 3976 |
| 3944 | 3977 |
| 3945 // This test is not intended to be run, just type checked. | 3978 // This test is not intended to be run, just type checked. |
| 3946 static void PersistentHandles() { | 3979 static void PersistentHandles() { |
| 3947 USE(PersistentHandles); | 3980 USE(PersistentHandles); |
| 3948 Local<String> str = v8_str("foo"); | 3981 Local<String> str = v8_str("foo"); |
| 3949 v8::Persistent<String> p_str = v8::Persistent<String>::New(str); | 3982 v8::Persistent<String> p_str = v8::Persistent<String>::New(str); |
| 3950 USE(p_str); | 3983 USE(p_str); |
| 3951 Local<Script> scr = Script::Compile(v8_str("")); | 3984 Local<Script> scr = Script::Compile(v8_str("")); |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4392 "}" | 4425 "}" |
| 4393 "gc();" | 4426 "gc();" |
| 4394 "4"; | 4427 "4"; |
| 4395 v8::Handle<Value> result = CompileRun(code); | 4428 v8::Handle<Value> result = CompileRun(code); |
| 4396 CHECK_EQ(4.0, result->NumberValue()); | 4429 CHECK_EQ(4.0, result->NumberValue()); |
| 4397 delete whammy; | 4430 delete whammy; |
| 4398 context.Dispose(); | 4431 context.Dispose(); |
| 4399 } | 4432 } |
| 4400 | 4433 |
| 4401 | 4434 |
| 4402 static bool in_scavenge = false; | 4435 static void DisposeAndSetFlag(v8::Persistent<v8::Value> obj, void* data) { |
| 4403 static int last = -1; | |
| 4404 | |
| 4405 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { | |
| 4406 CHECK_EQ(-1, last); | |
| 4407 last = 0; | |
| 4408 obj.Dispose(); | 4436 obj.Dispose(); |
| 4409 obj.Clear(); | 4437 obj.Clear(); |
| 4410 in_scavenge = true; | |
| 4411 HEAP->PerformScavenge(); | |
| 4412 in_scavenge = false; | |
| 4413 *(reinterpret_cast<bool*>(data)) = true; | 4438 *(reinterpret_cast<bool*>(data)) = true; |
| 4414 } | 4439 } |
| 4415 | 4440 |
| 4416 static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, | |
| 4417 void* data) { | |
| 4418 CHECK_EQ(0, last); | |
| 4419 last = 1; | |
| 4420 *(reinterpret_cast<bool*>(data)) = in_scavenge; | |
| 4421 obj.Dispose(); | |
| 4422 obj.Clear(); | |
| 4423 } | |
| 4424 | 4441 |
| 4425 THREADED_TEST(NoWeakRefCallbacksInScavenge) { | 4442 THREADED_TEST(IndependentWeakHandle) { |
| 4426 // Test verifies that scavenge cannot invoke WeakReferenceCallbacks. | |
| 4427 // Calling callbacks from scavenges is unsafe as objects held by those | |
| 4428 // handlers might have become strongly reachable, but scavenge doesn't | |
| 4429 // check that. | |
| 4430 v8::Persistent<Context> context = Context::New(); | 4443 v8::Persistent<Context> context = Context::New(); |
| 4431 Context::Scope context_scope(context); | 4444 Context::Scope context_scope(context); |
| 4432 | 4445 |
| 4433 v8::Persistent<v8::Object> object_a; | 4446 v8::Persistent<v8::Object> object_a; |
| 4434 v8::Persistent<v8::Object> object_b; | |
| 4435 | 4447 |
| 4436 { | 4448 { |
| 4437 v8::HandleScope handle_scope; | 4449 v8::HandleScope handle_scope; |
| 4438 object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); | |
| 4439 object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); | 4450 object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 4440 } | 4451 } |
| 4441 | 4452 |
| 4442 bool object_a_disposed = false; | 4453 bool object_a_disposed = false; |
| 4443 object_a.MakeWeak(&object_a_disposed, &ForceScavenge); | 4454 object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag); |
| 4444 bool released_in_scavenge = false; | 4455 object_a.MarkIndependent(); |
| 4445 object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); | 4456 HEAP->PerformScavenge(); |
| 4457 CHECK(object_a_disposed); |
| 4458 } |
| 4446 | 4459 |
| 4447 while (!object_a_disposed) { | 4460 |
| 4448 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 4461 static void InvokeScavenge() { |
| 4462 HEAP->PerformScavenge(); |
| 4463 } |
| 4464 |
| 4465 |
| 4466 static void InvokeMarkSweep() { |
| 4467 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 4468 } |
| 4469 |
| 4470 |
| 4471 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
| 4472 obj.Dispose(); |
| 4473 obj.Clear(); |
| 4474 *(reinterpret_cast<bool*>(data)) = true; |
| 4475 InvokeScavenge(); |
| 4476 } |
| 4477 |
| 4478 |
| 4479 static void ForceMarkSweep(v8::Persistent<v8::Value> obj, void* data) { |
| 4480 obj.Dispose(); |
| 4481 obj.Clear(); |
| 4482 *(reinterpret_cast<bool*>(data)) = true; |
| 4483 InvokeMarkSweep(); |
| 4484 } |
| 4485 |
| 4486 |
| 4487 THREADED_TEST(GCFromWeakCallbacks) { |
| 4488 v8::Persistent<Context> context = Context::New(); |
| 4489 Context::Scope context_scope(context); |
| 4490 |
| 4491 static const int kNumberOfGCTypes = 2; |
| 4492 v8::WeakReferenceCallback gc_forcing_callback[kNumberOfGCTypes] = |
| 4493 {&ForceScavenge, &ForceMarkSweep}; |
| 4494 |
| 4495 typedef void (*GCInvoker)(); |
| 4496 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; |
| 4497 |
| 4498 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { |
| 4499 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { |
| 4500 v8::Persistent<v8::Object> object; |
| 4501 { |
| 4502 v8::HandleScope handle_scope; |
| 4503 object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 4504 } |
| 4505 bool disposed = false; |
| 4506 object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]); |
| 4507 object.MarkIndependent(); |
| 4508 invoke_gc[outer_gc](); |
| 4509 CHECK(disposed); |
| 4510 } |
| 4449 } | 4511 } |
| 4450 CHECK(!released_in_scavenge); | 4512 } |
| 4513 |
| 4514 |
| 4515 static void RevivingCallback(v8::Persistent<v8::Value> obj, void* data) { |
| 4516 obj.ClearWeak(); |
| 4517 *(reinterpret_cast<bool*>(data)) = true; |
| 4518 } |
| 4519 |
| 4520 |
| 4521 THREADED_TEST(IndependentHandleRevival) { |
| 4522 v8::Persistent<Context> context = Context::New(); |
| 4523 Context::Scope context_scope(context); |
| 4524 |
| 4525 v8::Persistent<v8::Object> object; |
| 4526 { |
| 4527 v8::HandleScope handle_scope; |
| 4528 object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 4529 object->Set(v8_str("x"), v8::Integer::New(1)); |
| 4530 v8::Local<String> y_str = v8_str("y"); |
| 4531 object->Set(y_str, y_str); |
| 4532 } |
| 4533 bool revived = false; |
| 4534 object.MakeWeak(&revived, &RevivingCallback); |
| 4535 object.MarkIndependent(); |
| 4536 HEAP->PerformScavenge(); |
| 4537 CHECK(revived); |
| 4538 HEAP->CollectAllGarbage(true); |
| 4539 { |
| 4540 v8::HandleScope handle_scope; |
| 4541 v8::Local<String> y_str = v8_str("y"); |
| 4542 CHECK_EQ(v8::Integer::New(1), object->Get(v8_str("x"))); |
| 4543 CHECK(object->Get(y_str)->Equals(y_str)); |
| 4544 } |
| 4451 } | 4545 } |
| 4452 | 4546 |
| 4453 | 4547 |
| 4454 v8::Handle<Function> args_fun; | 4548 v8::Handle<Function> args_fun; |
| 4455 | 4549 |
| 4456 | 4550 |
| 4457 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { | 4551 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { |
| 4458 ApiTestFuzzer::Fuzz(); | 4552 ApiTestFuzzer::Fuzz(); |
| 4459 CHECK_EQ(args_fun, args.Callee()); | 4553 CHECK_EQ(args_fun, args.Callee()); |
| 4460 CHECK_EQ(3, args.Length()); | 4554 CHECK_EQ(3, args.Length()); |
| (...skipping 2278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6739 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 6833 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 6740 templ->SetClassName(v8_str("Fun")); | 6834 templ->SetClassName(v8_str("Fun")); |
| 6741 Local<Function> cons = templ->GetFunction(); | 6835 Local<Function> cons = templ->GetFunction(); |
| 6742 context->Global()->Set(v8_str("Fun"), cons); | 6836 context->Global()->Set(v8_str("Fun"), cons); |
| 6743 Local<v8::Object> inst = cons->NewInstance(); | 6837 Local<v8::Object> inst = cons->NewInstance(); |
| 6744 i::Handle<i::JSObject> obj = v8::Utils::OpenHandle(*inst); | 6838 i::Handle<i::JSObject> obj = v8::Utils::OpenHandle(*inst); |
| 6745 Local<Value> value = CompileRun("(new Fun()).constructor === Fun"); | 6839 Local<Value> value = CompileRun("(new Fun()).constructor === Fun"); |
| 6746 CHECK(value->BooleanValue()); | 6840 CHECK(value->BooleanValue()); |
| 6747 } | 6841 } |
| 6748 | 6842 |
| 6843 |
| 6844 static Handle<Value> ConstructorCallback(const Arguments& args) { |
| 6845 ApiTestFuzzer::Fuzz(); |
| 6846 Local<Object> This; |
| 6847 |
| 6848 if (args.IsConstructCall()) { |
| 6849 Local<Object> Holder = args.Holder(); |
| 6850 This = Object::New(); |
| 6851 Local<Value> proto = Holder->GetPrototype(); |
| 6852 if (proto->IsObject()) { |
| 6853 This->SetPrototype(proto); |
| 6854 } |
| 6855 } else { |
| 6856 This = args.This(); |
| 6857 } |
| 6858 |
| 6859 This->Set(v8_str("a"), args[0]); |
| 6860 return This; |
| 6861 } |
| 6862 |
| 6863 |
| 6864 static Handle<Value> FakeConstructorCallback(const Arguments& args) { |
| 6865 ApiTestFuzzer::Fuzz(); |
| 6866 return args[0]; |
| 6867 } |
| 6868 |
| 6869 |
| 6870 THREADED_TEST(ConstructorForObject) { |
| 6871 v8::HandleScope handle_scope; |
| 6872 LocalContext context; |
| 6873 |
| 6874 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); |
| 6875 instance_template->SetCallAsFunctionHandler(ConstructorCallback); |
| 6876 Local<Object> instance = instance_template->NewInstance(); |
| 6877 context->Global()->Set(v8_str("obj"), instance); |
| 6878 v8::TryCatch try_catch; |
| 6879 Local<Value> value; |
| 6880 CHECK(!try_catch.HasCaught()); |
| 6881 |
| 6882 // Call the Object's constructor with a 32-bit signed integer. |
| 6883 value = CompileRun("(function() { var o = new obj(28); return o.a; })()"); |
| 6884 CHECK(!try_catch.HasCaught()); |
| 6885 CHECK(value->IsInt32()); |
| 6886 CHECK_EQ(28, value->Int32Value()); |
| 6887 |
| 6888 Local<Value> args1[] = { v8_num(28) }; |
| 6889 Local<Value> value_obj1 = instance->CallAsConstructor(1, args1); |
| 6890 CHECK(value_obj1->IsObject()); |
| 6891 Local<Object> object1 = Local<Object>::Cast(value_obj1); |
| 6892 value = object1->Get(v8_str("a")); |
| 6893 CHECK(value->IsInt32()); |
| 6894 CHECK(!try_catch.HasCaught()); |
| 6895 CHECK_EQ(28, value->Int32Value()); |
| 6896 |
| 6897 // Call the Object's constructor with a String. |
| 6898 value = CompileRun( |
| 6899 "(function() { var o = new obj('tipli'); return o.a; })()"); |
| 6900 CHECK(!try_catch.HasCaught()); |
| 6901 CHECK(value->IsString()); |
| 6902 String::AsciiValue string_value1(value->ToString()); |
| 6903 CHECK_EQ("tipli", *string_value1); |
| 6904 |
| 6905 Local<Value> args2[] = { v8_str("tipli") }; |
| 6906 Local<Value> value_obj2 = instance->CallAsConstructor(1, args2); |
| 6907 CHECK(value_obj2->IsObject()); |
| 6908 Local<Object> object2 = Local<Object>::Cast(value_obj2); |
| 6909 value = object2->Get(v8_str("a")); |
| 6910 CHECK(!try_catch.HasCaught()); |
| 6911 CHECK(value->IsString()); |
| 6912 String::AsciiValue string_value2(value->ToString()); |
| 6913 CHECK_EQ("tipli", *string_value2); |
| 6914 |
| 6915 // Call the Object's constructor with a Boolean. |
| 6916 value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); |
| 6917 CHECK(!try_catch.HasCaught()); |
| 6918 CHECK(value->IsBoolean()); |
| 6919 CHECK_EQ(true, value->BooleanValue()); |
| 6920 |
| 6921 Handle<Value> args3[] = { v8::Boolean::New(true) }; |
| 6922 Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); |
| 6923 CHECK(value_obj3->IsObject()); |
| 6924 Local<Object> object3 = Local<Object>::Cast(value_obj3); |
| 6925 value = object3->Get(v8_str("a")); |
| 6926 CHECK(!try_catch.HasCaught()); |
| 6927 CHECK(value->IsBoolean()); |
| 6928 CHECK_EQ(true, value->BooleanValue()); |
| 6929 |
| 6930 // Call the Object's constructor with undefined. |
| 6931 Handle<Value> args4[] = { v8::Undefined() }; |
| 6932 Local<Value> value_obj4 = instance->CallAsConstructor(1, args4); |
| 6933 CHECK(value_obj4->IsObject()); |
| 6934 Local<Object> object4 = Local<Object>::Cast(value_obj4); |
| 6935 value = object4->Get(v8_str("a")); |
| 6936 CHECK(!try_catch.HasCaught()); |
| 6937 CHECK(value->IsUndefined()); |
| 6938 |
| 6939 // Call the Object's constructor with null. |
| 6940 Handle<Value> args5[] = { v8::Null() }; |
| 6941 Local<Value> value_obj5 = instance->CallAsConstructor(1, args5); |
| 6942 CHECK(value_obj5->IsObject()); |
| 6943 Local<Object> object5 = Local<Object>::Cast(value_obj5); |
| 6944 value = object5->Get(v8_str("a")); |
| 6945 CHECK(!try_catch.HasCaught()); |
| 6946 CHECK(value->IsNull()); |
| 6947 } |
| 6948 |
| 6949 // Check exception handling when there is no constructor set for the Object. |
| 6950 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); |
| 6951 Local<Object> instance = instance_template->NewInstance(); |
| 6952 context->Global()->Set(v8_str("obj2"), instance); |
| 6953 v8::TryCatch try_catch; |
| 6954 Local<Value> value; |
| 6955 CHECK(!try_catch.HasCaught()); |
| 6956 |
| 6957 value = CompileRun("new obj2(28)"); |
| 6958 CHECK(try_catch.HasCaught()); |
| 6959 String::AsciiValue exception_value1(try_catch.Exception()); |
| 6960 CHECK_EQ("TypeError: object is not a function", *exception_value1); |
| 6961 try_catch.Reset(); |
| 6962 |
| 6963 Local<Value> args[] = { v8_num(29) }; |
| 6964 value = instance->CallAsConstructor(1, args); |
| 6965 CHECK(try_catch.HasCaught()); |
| 6966 String::AsciiValue exception_value2(try_catch.Exception()); |
| 6967 CHECK_EQ("TypeError: #<Object> is not a function", *exception_value2); |
| 6968 try_catch.Reset(); |
| 6969 } |
| 6970 |
| 6971 // Check the case when constructor throws exception. |
| 6972 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); |
| 6973 instance_template->SetCallAsFunctionHandler(ThrowValue); |
| 6974 Local<Object> instance = instance_template->NewInstance(); |
| 6975 context->Global()->Set(v8_str("obj3"), instance); |
| 6976 v8::TryCatch try_catch; |
| 6977 Local<Value> value; |
| 6978 CHECK(!try_catch.HasCaught()); |
| 6979 |
| 6980 value = CompileRun("new obj3(22)"); |
| 6981 CHECK(try_catch.HasCaught()); |
| 6982 String::AsciiValue exception_value1(try_catch.Exception()); |
| 6983 CHECK_EQ("22", *exception_value1); |
| 6984 try_catch.Reset(); |
| 6985 |
| 6986 Local<Value> args[] = { v8_num(23) }; |
| 6987 value = instance->CallAsConstructor(1, args); |
| 6988 CHECK(try_catch.HasCaught()); |
| 6989 String::AsciiValue exception_value2(try_catch.Exception()); |
| 6990 CHECK_EQ("23", *exception_value2); |
| 6991 try_catch.Reset(); |
| 6992 } |
| 6993 |
| 6994 // Check whether constructor returns with an object or non-object. |
| 6995 { Local<FunctionTemplate> function_template = |
| 6996 FunctionTemplate::New(FakeConstructorCallback); |
| 6997 Local<Function> function = function_template->GetFunction(); |
| 6998 Local<Object> instance1 = function; |
| 6999 context->Global()->Set(v8_str("obj4"), instance1); |
| 7000 v8::TryCatch try_catch; |
| 7001 Local<Value> value; |
| 7002 CHECK(!try_catch.HasCaught()); |
| 7003 |
| 7004 CHECK(instance1->IsObject()); |
| 7005 CHECK(instance1->IsFunction()); |
| 7006 |
| 7007 value = CompileRun("new obj4(28)"); |
| 7008 CHECK(!try_catch.HasCaught()); |
| 7009 CHECK(value->IsObject()); |
| 7010 |
| 7011 Local<Value> args1[] = { v8_num(28) }; |
| 7012 value = instance1->CallAsConstructor(1, args1); |
| 7013 CHECK(!try_catch.HasCaught()); |
| 7014 CHECK(value->IsObject()); |
| 7015 |
| 7016 Local<ObjectTemplate> instance_template = ObjectTemplate::New(); |
| 7017 instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); |
| 7018 Local<Object> instance2 = instance_template->NewInstance(); |
| 7019 context->Global()->Set(v8_str("obj5"), instance2); |
| 7020 CHECK(!try_catch.HasCaught()); |
| 7021 |
| 7022 CHECK(instance2->IsObject()); |
| 7023 CHECK(!instance2->IsFunction()); |
| 7024 |
| 7025 value = CompileRun("new obj5(28)"); |
| 7026 CHECK(!try_catch.HasCaught()); |
| 7027 CHECK(!value->IsObject()); |
| 7028 |
| 7029 Local<Value> args2[] = { v8_num(28) }; |
| 7030 value = instance2->CallAsConstructor(1, args2); |
| 7031 CHECK(!try_catch.HasCaught()); |
| 7032 CHECK(!value->IsObject()); |
| 7033 } |
| 7034 } |
| 7035 |
| 7036 |
| 6749 THREADED_TEST(FunctionDescriptorException) { | 7037 THREADED_TEST(FunctionDescriptorException) { |
| 6750 v8::HandleScope handle_scope; | 7038 v8::HandleScope handle_scope; |
| 6751 LocalContext context; | 7039 LocalContext context; |
| 6752 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 7040 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 6753 templ->SetClassName(v8_str("Fun")); | 7041 templ->SetClassName(v8_str("Fun")); |
| 6754 Local<Function> cons = templ->GetFunction(); | 7042 Local<Function> cons = templ->GetFunction(); |
| 6755 context->Global()->Set(v8_str("Fun"), cons); | 7043 context->Global()->Set(v8_str("Fun"), cons); |
| 6756 Local<Value> value = CompileRun( | 7044 Local<Value> value = CompileRun( |
| 6757 "function test() {" | 7045 "function test() {" |
| 6758 " try {" | 7046 " try {" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7021 context->Global()->Set(v8_str("obj2"), instance); | 7309 context->Global()->Set(v8_str("obj2"), instance); |
| 7022 v8::TryCatch try_catch; | 7310 v8::TryCatch try_catch; |
| 7023 Local<Value> value; | 7311 Local<Value> value; |
| 7024 CHECK(!try_catch.HasCaught()); | 7312 CHECK(!try_catch.HasCaught()); |
| 7025 | 7313 |
| 7026 // Call an object without call-as-function handler through the JS | 7314 // Call an object without call-as-function handler through the JS |
| 7027 value = CompileRun("obj2(28)"); | 7315 value = CompileRun("obj2(28)"); |
| 7028 CHECK(value.IsEmpty()); | 7316 CHECK(value.IsEmpty()); |
| 7029 CHECK(try_catch.HasCaught()); | 7317 CHECK(try_catch.HasCaught()); |
| 7030 String::AsciiValue exception_value1(try_catch.Exception()); | 7318 String::AsciiValue exception_value1(try_catch.Exception()); |
| 7031 CHECK_EQ(*exception_value1, | 7319 CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function", |
| 7032 "TypeError: Property 'obj2' of object " | 7320 *exception_value1); |
| 7033 "#<Object> is not a function"); | |
| 7034 try_catch.Reset(); | 7321 try_catch.Reset(); |
| 7035 | 7322 |
| 7036 // Call an object without call-as-function handler through the API | 7323 // Call an object without call-as-function handler through the API |
| 7037 value = CompileRun("obj2(28)"); | 7324 value = CompileRun("obj2(28)"); |
| 7038 v8::Handle<Value> args[] = { v8_num(28) }; | 7325 v8::Handle<Value> args[] = { v8_num(28) }; |
| 7039 value = instance->CallAsFunction(instance, 1, args); | 7326 value = instance->CallAsFunction(instance, 1, args); |
| 7040 CHECK(value.IsEmpty()); | 7327 CHECK(value.IsEmpty()); |
| 7041 CHECK(try_catch.HasCaught()); | 7328 CHECK(try_catch.HasCaught()); |
| 7042 String::AsciiValue exception_value2(try_catch.Exception()); | 7329 String::AsciiValue exception_value2(try_catch.Exception()); |
| 7043 CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function"); | 7330 CHECK_EQ("TypeError: [object Object] is not a function", *exception_value2); |
| 7044 try_catch.Reset(); | 7331 try_catch.Reset(); |
| 7045 } | 7332 } |
| 7046 | 7333 |
| 7047 { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); | 7334 { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); |
| 7048 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); | 7335 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
| 7049 instance_template->SetCallAsFunctionHandler(ThrowValue); | 7336 instance_template->SetCallAsFunctionHandler(ThrowValue); |
| 7050 Local<v8::Object> instance = t->GetFunction()->NewInstance(); | 7337 Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
| 7051 context->Global()->Set(v8_str("obj3"), instance); | 7338 context->Global()->Set(v8_str("obj3"), instance); |
| 7052 v8::TryCatch try_catch; | 7339 v8::TryCatch try_catch; |
| 7053 Local<Value> value; | 7340 Local<Value> value; |
| 7054 CHECK(!try_catch.HasCaught()); | 7341 CHECK(!try_catch.HasCaught()); |
| 7055 | 7342 |
| 7056 // Catch the exception which is thrown by call-as-function handler | 7343 // Catch the exception which is thrown by call-as-function handler |
| 7057 value = CompileRun("obj3(22)"); | 7344 value = CompileRun("obj3(22)"); |
| 7058 CHECK(try_catch.HasCaught()); | 7345 CHECK(try_catch.HasCaught()); |
| 7059 String::AsciiValue exception_value1(try_catch.Exception()); | 7346 String::AsciiValue exception_value1(try_catch.Exception()); |
| 7060 CHECK_EQ(*exception_value1, "22"); | 7347 CHECK_EQ("22", *exception_value1); |
| 7061 try_catch.Reset(); | 7348 try_catch.Reset(); |
| 7062 | 7349 |
| 7063 v8::Handle<Value> args[] = { v8_num(23) }; | 7350 v8::Handle<Value> args[] = { v8_num(23) }; |
| 7064 value = instance->CallAsFunction(instance, 1, args); | 7351 value = instance->CallAsFunction(instance, 1, args); |
| 7065 CHECK(try_catch.HasCaught()); | 7352 CHECK(try_catch.HasCaught()); |
| 7066 String::AsciiValue exception_value2(try_catch.Exception()); | 7353 String::AsciiValue exception_value2(try_catch.Exception()); |
| 7067 CHECK_EQ(*exception_value2, "23"); | 7354 CHECK_EQ("23", *exception_value2); |
| 7068 try_catch.Reset(); | 7355 try_catch.Reset(); |
| 7069 } | 7356 } |
| 7070 } | 7357 } |
| 7071 | 7358 |
| 7072 | 7359 |
| 7360 // Check whether a non-function object is callable. |
| 7361 THREADED_TEST(CallableObject) { |
| 7362 v8::HandleScope scope; |
| 7363 LocalContext context; |
| 7364 |
| 7365 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); |
| 7366 instance_template->SetCallAsFunctionHandler(call_as_function); |
| 7367 Local<Object> instance = instance_template->NewInstance(); |
| 7368 v8::TryCatch try_catch; |
| 7369 |
| 7370 CHECK(instance->IsCallable()); |
| 7371 CHECK(!try_catch.HasCaught()); |
| 7372 } |
| 7373 |
| 7374 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(); |
| 7375 Local<Object> instance = instance_template->NewInstance(); |
| 7376 v8::TryCatch try_catch; |
| 7377 |
| 7378 CHECK(!instance->IsCallable()); |
| 7379 CHECK(!try_catch.HasCaught()); |
| 7380 } |
| 7381 |
| 7382 { Local<FunctionTemplate> function_template = |
| 7383 FunctionTemplate::New(call_as_function); |
| 7384 Local<Function> function = function_template->GetFunction(); |
| 7385 Local<Object> instance = function; |
| 7386 v8::TryCatch try_catch; |
| 7387 |
| 7388 CHECK(instance->IsCallable()); |
| 7389 CHECK(!try_catch.HasCaught()); |
| 7390 } |
| 7391 |
| 7392 { Local<FunctionTemplate> function_template = FunctionTemplate::New(); |
| 7393 Local<Function> function = function_template->GetFunction(); |
| 7394 Local<Object> instance = function; |
| 7395 v8::TryCatch try_catch; |
| 7396 |
| 7397 CHECK(instance->IsCallable()); |
| 7398 CHECK(!try_catch.HasCaught()); |
| 7399 } |
| 7400 } |
| 7401 |
| 7402 |
| 7073 static int CountHandles() { | 7403 static int CountHandles() { |
| 7074 return v8::HandleScope::NumberOfHandles(); | 7404 return v8::HandleScope::NumberOfHandles(); |
| 7075 } | 7405 } |
| 7076 | 7406 |
| 7077 | 7407 |
| 7078 static int Recurse(int depth, int iterations) { | 7408 static int Recurse(int depth, int iterations) { |
| 7079 v8::HandleScope scope; | 7409 v8::HandleScope scope; |
| 7080 if (depth == 0) return CountHandles(); | 7410 if (depth == 0) return CountHandles(); |
| 7081 for (int i = 0; i < iterations; i++) { | 7411 for (int i = 0; i < iterations; i++) { |
| 7082 Local<v8::Number> n = v8::Integer::New(42); | 7412 Local<v8::Number> n = v8::Integer::New(42); |
| (...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9000 } | 9330 } |
| 9001 } | 9331 } |
| 9002 | 9332 |
| 9003 | 9333 |
| 9004 static unsigned linear_congruential_generator; | 9334 static unsigned linear_congruential_generator; |
| 9005 | 9335 |
| 9006 | 9336 |
| 9007 void ApiTestFuzzer::Setup(PartOfTest part) { | 9337 void ApiTestFuzzer::Setup(PartOfTest part) { |
| 9008 linear_congruential_generator = i::FLAG_testing_prng_seed; | 9338 linear_congruential_generator = i::FLAG_testing_prng_seed; |
| 9009 fuzzing_ = true; | 9339 fuzzing_ = true; |
| 9010 int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1); | 9340 int count = RegisterThreadedTest::count(); |
| 9011 int end = (part == FIRST_PART) | 9341 int start = count * part / (LAST_PART + 1); |
| 9012 ? (RegisterThreadedTest::count() >> 1) | 9342 int end = (count * (part + 1) / (LAST_PART + 1)) - 1; |
| 9013 : RegisterThreadedTest::count(); | 9343 active_tests_ = tests_being_run_ = end - start + 1; |
| 9014 active_tests_ = tests_being_run_ = end - start; | |
| 9015 for (int i = 0; i < tests_being_run_; i++) { | 9344 for (int i = 0; i < tests_being_run_; i++) { |
| 9016 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer( | 9345 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer( |
| 9017 i::Isolate::Current(), i + start); | 9346 i::Isolate::Current(), i + start); |
| 9018 } | 9347 } |
| 9019 for (int i = 0; i < active_tests_; i++) { | 9348 for (int i = 0; i < active_tests_; i++) { |
| 9020 RegisterThreadedTest::nth(i)->fuzzer_->Start(); | 9349 RegisterThreadedTest::nth(i)->fuzzer_->Start(); |
| 9021 } | 9350 } |
| 9022 } | 9351 } |
| 9023 | 9352 |
| 9024 | 9353 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9074 ApiTestFuzzer::RunAllTests(); | 9403 ApiTestFuzzer::RunAllTests(); |
| 9075 ApiTestFuzzer::TearDown(); | 9404 ApiTestFuzzer::TearDown(); |
| 9076 } | 9405 } |
| 9077 | 9406 |
| 9078 TEST(Threading2) { | 9407 TEST(Threading2) { |
| 9079 ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART); | 9408 ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART); |
| 9080 ApiTestFuzzer::RunAllTests(); | 9409 ApiTestFuzzer::RunAllTests(); |
| 9081 ApiTestFuzzer::TearDown(); | 9410 ApiTestFuzzer::TearDown(); |
| 9082 } | 9411 } |
| 9083 | 9412 |
| 9413 TEST(Threading3) { |
| 9414 ApiTestFuzzer::Setup(ApiTestFuzzer::THIRD_PART); |
| 9415 ApiTestFuzzer::RunAllTests(); |
| 9416 ApiTestFuzzer::TearDown(); |
| 9417 } |
| 9418 |
| 9419 TEST(Threading4) { |
| 9420 ApiTestFuzzer::Setup(ApiTestFuzzer::FOURTH_PART); |
| 9421 ApiTestFuzzer::RunAllTests(); |
| 9422 ApiTestFuzzer::TearDown(); |
| 9423 } |
| 9084 | 9424 |
| 9085 void ApiTestFuzzer::CallTest() { | 9425 void ApiTestFuzzer::CallTest() { |
| 9086 if (kLogThreading) | 9426 if (kLogThreading) |
| 9087 printf("Start test %d\n", test_number_); | 9427 printf("Start test %d\n", test_number_); |
| 9088 CallTestNumber(test_number_); | 9428 CallTestNumber(test_number_); |
| 9089 if (kLogThreading) | 9429 if (kLogThreading) |
| 9090 printf("End test %d\n", test_number_); | 9430 printf("End test %d\n", test_number_); |
| 9091 } | 9431 } |
| 9092 | 9432 |
| 9093 | 9433 |
| (...skipping 2611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11705 " (ext_array[5] == expected_results[i]);" | 12045 " (ext_array[5] == expected_results[i]);" |
| 11706 "}" | 12046 "}" |
| 11707 "all_passed;", | 12047 "all_passed;", |
| 11708 (is_unsigned ? | 12048 (is_unsigned ? |
| 11709 unsigned_data : | 12049 unsigned_data : |
| 11710 (is_pixel_data ? pixel_data : signed_data))); | 12050 (is_pixel_data ? pixel_data : signed_data))); |
| 11711 result = CompileRun(test_buf.start()); | 12051 result = CompileRun(test_buf.start()); |
| 11712 CHECK_EQ(true, result->BooleanValue()); | 12052 CHECK_EQ(true, result->BooleanValue()); |
| 11713 } | 12053 } |
| 11714 | 12054 |
| 11715 // Test crankshaft external array loads | |
| 11716 for (int i = 0; i < kElementCount; i++) { | |
| 11717 array->set(i, static_cast<ElementType>(i)); | |
| 11718 } | |
| 11719 result = CompileRun("function ee_load_test_func(sum) {" | |
| 11720 " for (var i = 0; i < 40; ++i)" | |
| 11721 " sum += ext_array[i];" | |
| 11722 " return sum;" | |
| 11723 "}" | |
| 11724 "sum=0;" | |
| 11725 "for (var i=0;i<10000;++i) {" | |
| 11726 " sum=ee_load_test_func(sum);" | |
| 11727 "}" | |
| 11728 "sum;"); | |
| 11729 CHECK_EQ(7800000, result->Int32Value()); | |
| 11730 | |
| 11731 // Test crankshaft external array stores | |
| 11732 result = CompileRun("function ee_store_test_func(sum) {" | |
| 11733 " for (var i = 0; i < 40; ++i)" | |
| 11734 " sum += ext_array[i] = i;" | |
| 11735 " return sum;" | |
| 11736 "}" | |
| 11737 "sum=0;" | |
| 11738 "for (var i=0;i<10000;++i) {" | |
| 11739 " sum=ee_store_test_func(sum);" | |
| 11740 "}" | |
| 11741 "sum;"); | |
| 11742 CHECK_EQ(7800000, result->Int32Value()); | |
| 11743 | |
| 11744 for (int i = 0; i < kElementCount; i++) { | 12055 for (int i = 0; i < kElementCount; i++) { |
| 11745 array->set(i, static_cast<ElementType>(i)); | 12056 array->set(i, static_cast<ElementType>(i)); |
| 11746 } | 12057 } |
| 11747 // Test complex assignments | 12058 // Test complex assignments |
| 11748 result = CompileRun("function ee_op_test_complex_func(sum) {" | 12059 result = CompileRun("function ee_op_test_complex_func(sum) {" |
| 11749 " for (var i = 0; i < 40; ++i) {" | 12060 " for (var i = 0; i < 40; ++i) {" |
| 11750 " sum += (ext_array[i] += 1);" | 12061 " sum += (ext_array[i] += 1);" |
| 11751 " sum += (ext_array[i] -= 1);" | 12062 " sum += (ext_array[i] -= 1);" |
| 11752 " } " | 12063 " } " |
| 11753 " return sum;" | 12064 " return sum;" |
| (...skipping 1694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13448 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number | 13759 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number |
| 13449 CHECK_EQ(result1, 10946); | 13760 CHECK_EQ(result1, 10946); |
| 13450 CHECK_EQ(result2, 144); | 13761 CHECK_EQ(result2, 144); |
| 13451 CHECK_EQ(result1, thread1.result()); | 13762 CHECK_EQ(result1, thread1.result()); |
| 13452 CHECK_EQ(result2, thread2.result()); | 13763 CHECK_EQ(result2, thread2.result()); |
| 13453 | 13764 |
| 13454 isolate1->Dispose(); | 13765 isolate1->Dispose(); |
| 13455 isolate2->Dispose(); | 13766 isolate2->Dispose(); |
| 13456 } | 13767 } |
| 13457 | 13768 |
| 13769 TEST(IsolateDifferentContexts) { |
| 13770 v8::Isolate* isolate = v8::Isolate::New(); |
| 13771 Persistent<v8::Context> context; |
| 13772 { |
| 13773 v8::Isolate::Scope isolate_scope(isolate); |
| 13774 v8::HandleScope handle_scope; |
| 13775 context = v8::Context::New(); |
| 13776 v8::Context::Scope context_scope(context); |
| 13777 Local<Value> v = CompileRun("2"); |
| 13778 CHECK(v->IsNumber()); |
| 13779 CHECK_EQ(2, static_cast<int>(v->NumberValue())); |
| 13780 } |
| 13781 { |
| 13782 v8::Isolate::Scope isolate_scope(isolate); |
| 13783 v8::HandleScope handle_scope; |
| 13784 context = v8::Context::New(); |
| 13785 v8::Context::Scope context_scope(context); |
| 13786 Local<Value> v = CompileRun("22"); |
| 13787 CHECK(v->IsNumber()); |
| 13788 CHECK_EQ(22, static_cast<int>(v->NumberValue())); |
| 13789 } |
| 13790 } |
| 13458 | 13791 |
| 13459 class InitDefaultIsolateThread : public v8::internal::Thread { | 13792 class InitDefaultIsolateThread : public v8::internal::Thread { |
| 13460 public: | 13793 public: |
| 13461 enum TestCase { | 13794 enum TestCase { |
| 13462 IgnoreOOM, | 13795 IgnoreOOM, |
| 13463 SetResourceConstraints, | 13796 SetResourceConstraints, |
| 13464 SetFatalHandler, | 13797 SetFatalHandler, |
| 13465 SetCounterFunction, | 13798 SetCounterFunction, |
| 13466 SetCreateHistogramFunction, | 13799 SetCreateHistogramFunction, |
| 13467 SetAddHistogramSampleFunction | 13800 SetAddHistogramSampleFunction |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14097 CHECK(instance->HasOwnProperty(v8_str("bar"))); | 14430 CHECK(instance->HasOwnProperty(v8_str("bar"))); |
| 14098 } | 14431 } |
| 14099 } | 14432 } |
| 14100 | 14433 |
| 14101 | 14434 |
| 14102 void CheckCodeGenerationAllowed() { | 14435 void CheckCodeGenerationAllowed() { |
| 14103 Handle<Value> result = CompileRun("eval('42')"); | 14436 Handle<Value> result = CompileRun("eval('42')"); |
| 14104 CHECK_EQ(42, result->Int32Value()); | 14437 CHECK_EQ(42, result->Int32Value()); |
| 14105 result = CompileRun("(function(e) { return e('42'); })(eval)"); | 14438 result = CompileRun("(function(e) { return e('42'); })(eval)"); |
| 14106 CHECK_EQ(42, result->Int32Value()); | 14439 CHECK_EQ(42, result->Int32Value()); |
| 14107 result = CompileRun("execScript('42')"); | |
| 14108 CHECK(!result.IsEmpty()); | |
| 14109 result = CompileRun("var f = new Function('return 42'); f()"); | 14440 result = CompileRun("var f = new Function('return 42'); f()"); |
| 14110 CHECK_EQ(42, result->Int32Value()); | 14441 CHECK_EQ(42, result->Int32Value()); |
| 14111 } | 14442 } |
| 14112 | 14443 |
| 14113 | 14444 |
| 14114 void CheckCodeGenerationDisallowed() { | 14445 void CheckCodeGenerationDisallowed() { |
| 14115 TryCatch try_catch; | 14446 TryCatch try_catch; |
| 14116 | 14447 |
| 14117 Handle<Value> result = CompileRun("eval('42')"); | 14448 Handle<Value> result = CompileRun("eval('42')"); |
| 14118 CHECK(result.IsEmpty()); | 14449 CHECK(result.IsEmpty()); |
| 14119 CHECK(try_catch.HasCaught()); | 14450 CHECK(try_catch.HasCaught()); |
| 14120 try_catch.Reset(); | 14451 try_catch.Reset(); |
| 14121 | 14452 |
| 14122 result = CompileRun("(function(e) { return e('42'); })(eval)"); | 14453 result = CompileRun("(function(e) { return e('42'); })(eval)"); |
| 14123 CHECK(result.IsEmpty()); | 14454 CHECK(result.IsEmpty()); |
| 14124 CHECK(try_catch.HasCaught()); | 14455 CHECK(try_catch.HasCaught()); |
| 14125 try_catch.Reset(); | 14456 try_catch.Reset(); |
| 14126 | 14457 |
| 14127 result = CompileRun("execScript('42')"); | |
| 14128 CHECK(result.IsEmpty()); | |
| 14129 CHECK(try_catch.HasCaught()); | |
| 14130 try_catch.Reset(); | |
| 14131 | |
| 14132 result = CompileRun("var f = new Function('return 42'); f()"); | 14458 result = CompileRun("var f = new Function('return 42'); f()"); |
| 14133 CHECK(result.IsEmpty()); | 14459 CHECK(result.IsEmpty()); |
| 14134 CHECK(try_catch.HasCaught()); | 14460 CHECK(try_catch.HasCaught()); |
| 14135 } | 14461 } |
| 14136 | 14462 |
| 14137 | 14463 |
| 14138 bool CodeGenerationAllowed(Local<Context> context) { | 14464 bool CodeGenerationAllowed(Local<Context> context) { |
| 14139 ApiTestFuzzer::Fuzz(); | 14465 ApiTestFuzzer::Fuzz(); |
| 14140 return true; | 14466 return true; |
| 14141 } | 14467 } |
| 14142 | 14468 |
| 14143 | 14469 |
| 14144 bool CodeGenerationDisallowed(Local<Context> context) { | 14470 bool CodeGenerationDisallowed(Local<Context> context) { |
| 14145 ApiTestFuzzer::Fuzz(); | 14471 ApiTestFuzzer::Fuzz(); |
| 14146 return false; | 14472 return false; |
| 14147 } | 14473 } |
| 14148 | 14474 |
| 14149 | 14475 |
| 14150 THREADED_TEST(AllowCodeGenFromStrings) { | 14476 THREADED_TEST(AllowCodeGenFromStrings) { |
| 14151 v8::HandleScope scope; | 14477 v8::HandleScope scope; |
| 14152 LocalContext context; | 14478 LocalContext context; |
| 14153 | 14479 |
| 14154 // eval, execScript and the Function constructor allowed by default. | 14480 // eval and the Function constructor allowed by default. |
| 14155 CheckCodeGenerationAllowed(); | 14481 CheckCodeGenerationAllowed(); |
| 14156 | 14482 |
| 14157 // Disallow eval, execScript and the Function constructor. | 14483 // Disallow eval and the Function constructor. |
| 14158 context->AllowCodeGenerationFromStrings(false); | 14484 context->AllowCodeGenerationFromStrings(false); |
| 14159 CheckCodeGenerationDisallowed(); | 14485 CheckCodeGenerationDisallowed(); |
| 14160 | 14486 |
| 14161 // Allow again. | 14487 // Allow again. |
| 14162 context->AllowCodeGenerationFromStrings(true); | 14488 context->AllowCodeGenerationFromStrings(true); |
| 14163 CheckCodeGenerationAllowed(); | 14489 CheckCodeGenerationAllowed(); |
| 14164 | 14490 |
| 14165 // Disallow but setting a global callback that will allow the calls. | 14491 // Disallow but setting a global callback that will allow the calls. |
| 14166 context->AllowCodeGenerationFromStrings(false); | 14492 context->AllowCodeGenerationFromStrings(false); |
| 14167 V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationAllowed); | 14493 V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationAllowed); |
| 14168 CheckCodeGenerationAllowed(); | 14494 CheckCodeGenerationAllowed(); |
| 14169 | 14495 |
| 14170 // Set a callback that disallows the code generation. | 14496 // Set a callback that disallows the code generation. |
| 14171 V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed); | 14497 V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed); |
| 14172 CheckCodeGenerationDisallowed(); | 14498 CheckCodeGenerationDisallowed(); |
| 14173 } | 14499 } |
| 14500 |
| 14501 |
| 14502 static v8::Handle<Value> NonObjectThis(const v8::Arguments& args) { |
| 14503 return v8::Undefined(); |
| 14504 } |
| 14505 |
| 14506 |
| 14507 THREADED_TEST(CallAPIFunctionOnNonObject) { |
| 14508 v8::HandleScope scope; |
| 14509 LocalContext context; |
| 14510 Handle<FunctionTemplate> templ = v8::FunctionTemplate::New(NonObjectThis); |
| 14511 Handle<Function> function = templ->GetFunction(); |
| 14512 context->Global()->Set(v8_str("f"), function); |
| 14513 TryCatch try_catch; |
| 14514 CompileRun("f.call(2)"); |
| 14515 } |
| OLD | NEW |