| OLD | NEW |
| 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 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 5659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5670 Local<Value> global_object; | 5670 Local<Value> global_object; |
| 5671 | 5671 |
| 5672 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); | 5672 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); |
| 5673 t->InstanceTemplate()->SetNamedPropertyHandler( | 5673 t->InstanceTemplate()->SetNamedPropertyHandler( |
| 5674 GlobalObjectInstancePropertiesGet); | 5674 GlobalObjectInstancePropertiesGet); |
| 5675 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); | 5675 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
| 5676 instance_template->Set(v8_str("x"), v8_num(42)); | 5676 instance_template->Set(v8_str("x"), v8_num(42)); |
| 5677 instance_template->Set(v8_str("f"), | 5677 instance_template->Set(v8_str("f"), |
| 5678 v8::FunctionTemplate::New(InstanceFunctionCallback)); | 5678 v8::FunctionTemplate::New(InstanceFunctionCallback)); |
| 5679 | 5679 |
| 5680 // The script to check how Crankshaft compiles missing global function |
| 5681 // invocations. function g is not defined and should throw on call. |
| 5682 const char* script = |
| 5683 "function wrapper(call) {" |
| 5684 " var x = 0, y = 1;" |
| 5685 " for (var i = 0; i < 1000; i++) {" |
| 5686 " x += i * 100;" |
| 5687 " y += i * 100;" |
| 5688 " }" |
| 5689 " if (call) g();" |
| 5690 "}" |
| 5691 "for (var i = 0; i < 17; i++) wrapper(false);" |
| 5692 "var thrown = 0;" |
| 5693 "try { wrapper(true); } catch (e) { thrown = 1; };" |
| 5694 "thrown"; |
| 5695 |
| 5680 { | 5696 { |
| 5681 LocalContext env(NULL, instance_template); | 5697 LocalContext env(NULL, instance_template); |
| 5682 // Hold on to the global object so it can be used again in another | 5698 // Hold on to the global object so it can be used again in another |
| 5683 // environment initialization. | 5699 // environment initialization. |
| 5684 global_object = env->Global(); | 5700 global_object = env->Global(); |
| 5685 | 5701 |
| 5686 Local<Value> value = Script::Compile(v8_str("x"))->Run(); | 5702 Local<Value> value = Script::Compile(v8_str("x"))->Run(); |
| 5687 CHECK_EQ(42, value->Int32Value()); | 5703 CHECK_EQ(42, value->Int32Value()); |
| 5688 value = Script::Compile(v8_str("f()"))->Run(); | 5704 value = Script::Compile(v8_str("f()"))->Run(); |
| 5689 CHECK_EQ(12, value->Int32Value()); | 5705 CHECK_EQ(12, value->Int32Value()); |
| 5706 value = Script::Compile(v8_str(script))->Run(); |
| 5707 CHECK_EQ(1, value->Int32Value()); |
| 5690 } | 5708 } |
| 5691 | 5709 |
| 5692 { | 5710 { |
| 5693 // Create new environment reusing the global object. | 5711 // Create new environment reusing the global object. |
| 5694 LocalContext env(NULL, instance_template, global_object); | 5712 LocalContext env(NULL, instance_template, global_object); |
| 5695 Local<Value> value = Script::Compile(v8_str("x"))->Run(); | 5713 Local<Value> value = Script::Compile(v8_str("x"))->Run(); |
| 5696 CHECK_EQ(42, value->Int32Value()); | 5714 CHECK_EQ(42, value->Int32Value()); |
| 5697 value = Script::Compile(v8_str("f()"))->Run(); | 5715 value = Script::Compile(v8_str("f()"))->Run(); |
| 5698 CHECK_EQ(12, value->Int32Value()); | 5716 CHECK_EQ(12, value->Int32Value()); |
| 5717 value = Script::Compile(v8_str(script))->Run(); |
| 5718 CHECK_EQ(1, value->Int32Value()); |
| 5699 } | 5719 } |
| 5700 } | 5720 } |
| 5701 | 5721 |
| 5722 |
| 5723 THREADED_TEST(CallKnownGlobalReceiver) { |
| 5724 v8::HandleScope handle_scope; |
| 5725 |
| 5726 Local<Value> global_object; |
| 5727 |
| 5728 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); |
| 5729 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
| 5730 |
| 5731 // The script to check that we leave global object not |
| 5732 // global object proxy on stack when we deoptimize from inside |
| 5733 // arguments evaluation. |
| 5734 // To provoke error we need to both force deoptimization |
| 5735 // from arguments evaluation and to force CallIC to take |
| 5736 // CallIC_Miss code path that can't cope with global proxy. |
| 5737 const char* script = |
| 5738 "function bar(x, y) { try { } finally { } }" |
| 5739 "function baz(x) { try { } finally { } }" |
| 5740 "function bom(x) { try { } finally { } }" |
| 5741 "function foo(x) { bar([x], bom(2)); }" |
| 5742 "for (var i = 0; i < 10000; i++) foo(1);" |
| 5743 "foo"; |
| 5744 |
| 5745 Local<Value> foo; |
| 5746 { |
| 5747 LocalContext env(NULL, instance_template); |
| 5748 // Hold on to the global object so it can be used again in another |
| 5749 // environment initialization. |
| 5750 global_object = env->Global(); |
| 5751 foo = Script::Compile(v8_str(script))->Run(); |
| 5752 } |
| 5753 |
| 5754 { |
| 5755 // Create new environment reusing the global object. |
| 5756 LocalContext env(NULL, instance_template, global_object); |
| 5757 env->Global()->Set(v8_str("foo"), foo); |
| 5758 Local<Value> value = Script::Compile(v8_str("foo()"))->Run(); |
| 5759 } |
| 5760 } |
| 5761 |
| 5702 | 5762 |
| 5703 static v8::Handle<Value> ShadowFunctionCallback(const v8::Arguments& args) { | 5763 static v8::Handle<Value> ShadowFunctionCallback(const v8::Arguments& args) { |
| 5704 ApiTestFuzzer::Fuzz(); | 5764 ApiTestFuzzer::Fuzz(); |
| 5705 return v8_num(42); | 5765 return v8_num(42); |
| 5706 } | 5766 } |
| 5707 | 5767 |
| 5708 | 5768 |
| 5709 static int shadow_y; | 5769 static int shadow_y; |
| 5710 static int shadow_y_setter_call_count; | 5770 static int shadow_y_setter_call_count; |
| 5711 static int shadow_y_getter_call_count; | 5771 static int shadow_y_getter_call_count; |
| (...skipping 2977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8689 | 8749 |
| 8690 // Failing access check to function call results in exception. | 8750 // Failing access check to function call results in exception. |
| 8691 CHECK(g1->Call(global, 0, NULL).IsEmpty()); | 8751 CHECK(g1->Call(global, 0, NULL).IsEmpty()); |
| 8692 CHECK(g2->Call(global, 0, NULL).IsEmpty()); | 8752 CHECK(g2->Call(global, 0, NULL).IsEmpty()); |
| 8693 | 8753 |
| 8694 // No failing access check when just returning a constant. | 8754 // No failing access check when just returning a constant. |
| 8695 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); | 8755 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 8696 } | 8756 } |
| 8697 | 8757 |
| 8698 | 8758 |
| 8759 v8::Handle<v8::String> a; |
| 8760 v8::Handle<v8::String> h; |
| 8761 |
| 8762 static bool NamedGetAccessBlockAandH(Local<v8::Object> obj, |
| 8763 Local<Value> name, |
| 8764 v8::AccessType type, |
| 8765 Local<Value> data) { |
| 8766 return !(name->Equals(a) || name->Equals(h)); |
| 8767 } |
| 8768 |
| 8769 |
| 8770 THREADED_TEST(TurnOnAccessCheckAndRecompile) { |
| 8771 v8::HandleScope handle_scope; |
| 8772 |
| 8773 // Create an environment with access check to the global object disabled by |
| 8774 // default. When the registered access checker will block access to properties |
| 8775 // a and h |
| 8776 a = v8_str("a"); |
| 8777 h = v8_str("h"); |
| 8778 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 8779 global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH, |
| 8780 IndexedGetAccessBlocker, |
| 8781 v8::Handle<v8::Value>(), |
| 8782 false); |
| 8783 v8::Persistent<Context> context = Context::New(NULL, global_template); |
| 8784 Context::Scope context_scope(context); |
| 8785 |
| 8786 // Set up a property and a number of functions. |
| 8787 context->Global()->Set(v8_str("a"), v8_num(1)); |
| 8788 static const char* source = "function f1() {return a;}" |
| 8789 "function f2() {return a;}" |
| 8790 "function g1() {return h();}" |
| 8791 "function g2() {return h();}" |
| 8792 "function h() {return 1;}"; |
| 8793 |
| 8794 CompileRun(source); |
| 8795 Local<Function> f1; |
| 8796 Local<Function> f2; |
| 8797 Local<Function> g1; |
| 8798 Local<Function> g2; |
| 8799 Local<Function> h; |
| 8800 f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1"))); |
| 8801 f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2"))); |
| 8802 g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1"))); |
| 8803 g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2"))); |
| 8804 h = Local<Function>::Cast(context->Global()->Get(v8_str("h"))); |
| 8805 |
| 8806 // Get the global object. |
| 8807 v8::Handle<v8::Object> global = context->Global(); |
| 8808 |
| 8809 // Call f1 one time and f2 a number of times. This will ensure that f1 still |
| 8810 // uses the runtime system to retreive property a whereas f2 uses global load |
| 8811 // inline cache. |
| 8812 CHECK(f1->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 8813 for (int i = 0; i < 4; i++) { |
| 8814 CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 8815 } |
| 8816 |
| 8817 // Same for g1 and g2. |
| 8818 CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 8819 for (int i = 0; i < 4; i++) { |
| 8820 CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 8821 } |
| 8822 |
| 8823 // Detach the global and turn on access check now blocking access to property |
| 8824 // a and function h. |
| 8825 context->DetachGlobal(); |
| 8826 context->Global()->TurnOnAccessCheck(); |
| 8827 |
| 8828 // Failing access check to property get results in undefined. |
| 8829 CHECK(f1->Call(global, 0, NULL)->IsUndefined()); |
| 8830 CHECK(f2->Call(global, 0, NULL)->IsUndefined()); |
| 8831 |
| 8832 // Failing access check to function call results in exception. |
| 8833 CHECK(g1->Call(global, 0, NULL).IsEmpty()); |
| 8834 CHECK(g2->Call(global, 0, NULL).IsEmpty()); |
| 8835 |
| 8836 // No failing access check when just returning a constant. |
| 8837 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 8838 |
| 8839 // Now compile the source again. And get the newly compiled functions, except |
| 8840 // for h for which access is blocked. |
| 8841 CompileRun(source); |
| 8842 f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1"))); |
| 8843 f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2"))); |
| 8844 g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1"))); |
| 8845 g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2"))); |
| 8846 CHECK(context->Global()->Get(v8_str("h"))->IsUndefined()); |
| 8847 |
| 8848 // Failing access check to property get results in undefined. |
| 8849 CHECK(f1->Call(global, 0, NULL)->IsUndefined()); |
| 8850 CHECK(f2->Call(global, 0, NULL)->IsUndefined()); |
| 8851 |
| 8852 // Failing access check to function call results in exception. |
| 8853 CHECK(g1->Call(global, 0, NULL).IsEmpty()); |
| 8854 CHECK(g2->Call(global, 0, NULL).IsEmpty()); |
| 8855 } |
| 8856 |
| 8857 |
| 8699 // This test verifies that pre-compilation (aka preparsing) can be called | 8858 // This test verifies that pre-compilation (aka preparsing) can be called |
| 8700 // without initializing the whole VM. Thus we cannot run this test in a | 8859 // without initializing the whole VM. Thus we cannot run this test in a |
| 8701 // multi-threaded setup. | 8860 // multi-threaded setup. |
| 8702 TEST(PreCompile) { | 8861 TEST(PreCompile) { |
| 8703 // TODO(155): This test would break without the initialization of V8. This is | 8862 // TODO(155): This test would break without the initialization of V8. This is |
| 8704 // a workaround for now to make this test not fail. | 8863 // a workaround for now to make this test not fail. |
| 8705 v8::V8::Initialize(); | 8864 v8::V8::Initialize(); |
| 8706 const char* script = "function foo(a) { return a+1; }"; | 8865 const char* script = "function foo(a) { return a+1; }"; |
| 8707 v8::ScriptData* sd = | 8866 v8::ScriptData* sd = |
| 8708 v8::ScriptData::PreCompile(script, i::StrLength(script)); | 8867 v8::ScriptData::PreCompile(script, i::StrLength(script)); |
| (...skipping 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10540 checkStackFrame(origin, "", 10, 1, false, false, | 10699 checkStackFrame(origin, "", 10, 1, false, false, |
| 10541 stackTrace->GetFrame(3)); | 10700 stackTrace->GetFrame(3)); |
| 10542 | 10701 |
| 10543 CHECK(stackTrace->AsArray()->IsArray()); | 10702 CHECK(stackTrace->AsArray()->IsArray()); |
| 10544 } | 10703 } |
| 10545 return v8::Undefined(); | 10704 return v8::Undefined(); |
| 10546 } | 10705 } |
| 10547 | 10706 |
| 10548 | 10707 |
| 10549 // Tests the C++ StackTrace API. | 10708 // Tests the C++ StackTrace API. |
| 10550 THREADED_TEST(CaptureStackTrace) { | 10709 // TODO(3074796): Reenable this as a THREADED_TEST once it passes. |
| 10710 // THREADED_TEST(CaptureStackTrace) { |
| 10711 TEST(CaptureStackTrace) { |
| 10551 v8::HandleScope scope; | 10712 v8::HandleScope scope; |
| 10552 v8::Handle<v8::String> origin = v8::String::New("capture-stack-trace-test"); | 10713 v8::Handle<v8::String> origin = v8::String::New("capture-stack-trace-test"); |
| 10553 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 10714 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
| 10554 templ->Set(v8_str("AnalyzeStackInNativeCode"), | 10715 templ->Set(v8_str("AnalyzeStackInNativeCode"), |
| 10555 v8::FunctionTemplate::New(AnalyzeStackInNativeCode)); | 10716 v8::FunctionTemplate::New(AnalyzeStackInNativeCode)); |
| 10556 LocalContext context(0, templ); | 10717 LocalContext context(0, templ); |
| 10557 | 10718 |
| 10558 // Test getting OVERVIEW information. Should ignore information that is not | 10719 // Test getting OVERVIEW information. Should ignore information that is not |
| 10559 // script name, function name, line number, and column offset. | 10720 // script name, function name, line number, and column offset. |
| 10560 const char *overview_source = | 10721 const char *overview_source = |
| (...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12096 v8::Context::Scope context_scope(context.local()); | 12257 v8::Context::Scope context_scope(context.local()); |
| 12097 | 12258 |
| 12098 v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(); | 12259 v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(); |
| 12099 tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator); | 12260 tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator); |
| 12100 context->Global()->Set(v8_str("o"), tmpl->NewInstance()); | 12261 context->Global()->Set(v8_str("o"), tmpl->NewInstance()); |
| 12101 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( | 12262 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( |
| 12102 "var result = []; for (var k in o) result.push(k); result")); | 12263 "var result = []; for (var k in o) result.push(k); result")); |
| 12103 CHECK_EQ(1, result->Length()); | 12264 CHECK_EQ(1, result->Length()); |
| 12104 CHECK_EQ(v8_str("universalAnswer"), result->Get(0)); | 12265 CHECK_EQ(v8_str("universalAnswer"), result->Get(0)); |
| 12105 } | 12266 } |
| OLD | NEW |