OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 13 matching lines...) Expand all Loading... |
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 #ifndef WIN32 | 30 #ifndef WIN32 |
31 #include <signal.h> // kill | 31 #include <signal.h> // kill |
32 #include <unistd.h> // getpid | 32 #include <unistd.h> // getpid |
33 #endif // WIN32 | 33 #endif // WIN32 |
| 34 #include <string> |
| 35 #include <map> |
34 | 36 |
35 #include "v8.h" | 37 #include "v8.h" |
36 | 38 |
37 #include "api.h" | 39 #include "api.h" |
38 #include "arguments.h" | 40 #include "arguments.h" |
| 41 #include "cctest.h" |
| 42 #include "compilation-cache.h" |
| 43 #include "cpu-profiler.h" |
| 44 #include "execution.h" |
39 #include "isolate.h" | 45 #include "isolate.h" |
40 #include "compilation-cache.h" | |
41 #include "execution.h" | |
42 #include "objects.h" | 46 #include "objects.h" |
| 47 #include "parser.h" |
| 48 #include "platform.h" |
43 #include "snapshot.h" | 49 #include "snapshot.h" |
44 #include "platform.h" | 50 #include "unicode-inl.h" |
45 #include "utils.h" | 51 #include "utils.h" |
46 #include "cctest.h" | |
47 #include "parser.h" | |
48 #include "unicode-inl.h" | |
49 | 52 |
50 static const bool kLogThreading = false; | 53 static const bool kLogThreading = false; |
51 | 54 |
52 using ::v8::AccessorInfo; | 55 using ::v8::AccessorInfo; |
53 using ::v8::Arguments; | 56 using ::v8::Arguments; |
54 using ::v8::Context; | 57 using ::v8::Context; |
55 using ::v8::Extension; | 58 using ::v8::Extension; |
56 using ::v8::Function; | 59 using ::v8::Function; |
57 using ::v8::FunctionTemplate; | 60 using ::v8::FunctionTemplate; |
58 using ::v8::Handle; | 61 using ::v8::Handle; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 } | 95 } |
93 | 96 |
94 | 97 |
95 static void ExpectString(const char* code, const char* expected) { | 98 static void ExpectString(const char* code, const char* expected) { |
96 Local<Value> result = CompileRun(code); | 99 Local<Value> result = CompileRun(code); |
97 CHECK(result->IsString()); | 100 CHECK(result->IsString()); |
98 String::Utf8Value utf8(result); | 101 String::Utf8Value utf8(result); |
99 CHECK_EQ(expected, *utf8); | 102 CHECK_EQ(expected, *utf8); |
100 } | 103 } |
101 | 104 |
| 105 |
102 static void ExpectInt32(const char* code, int expected) { | 106 static void ExpectInt32(const char* code, int expected) { |
103 Local<Value> result = CompileRun(code); | 107 Local<Value> result = CompileRun(code); |
104 CHECK(result->IsInt32()); | 108 CHECK(result->IsInt32()); |
105 CHECK_EQ(expected, result->Int32Value()); | 109 CHECK_EQ(expected, result->Int32Value()); |
106 } | 110 } |
107 | 111 |
| 112 |
108 static void ExpectBoolean(const char* code, bool expected) { | 113 static void ExpectBoolean(const char* code, bool expected) { |
109 Local<Value> result = CompileRun(code); | 114 Local<Value> result = CompileRun(code); |
110 CHECK(result->IsBoolean()); | 115 CHECK(result->IsBoolean()); |
111 CHECK_EQ(expected, result->BooleanValue()); | 116 CHECK_EQ(expected, result->BooleanValue()); |
112 } | 117 } |
113 | 118 |
114 | 119 |
115 static void ExpectTrue(const char* code) { | 120 static void ExpectTrue(const char* code) { |
116 ExpectBoolean(code, true); | 121 ExpectBoolean(code, true); |
117 } | 122 } |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 | 855 |
851 | 856 |
852 static void handle_callback_impl(const v8::FunctionCallbackInfo<Value>& info, | 857 static void handle_callback_impl(const v8::FunctionCallbackInfo<Value>& info, |
853 i::Address callback) { | 858 i::Address callback) { |
854 ApiTestFuzzer::Fuzz(); | 859 ApiTestFuzzer::Fuzz(); |
855 CheckReturnValue(info, callback); | 860 CheckReturnValue(info, callback); |
856 info.GetReturnValue().Set(v8_str("bad value")); | 861 info.GetReturnValue().Set(v8_str("bad value")); |
857 info.GetReturnValue().Set(v8_num(102)); | 862 info.GetReturnValue().Set(v8_num(102)); |
858 } | 863 } |
859 | 864 |
| 865 |
860 static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) { | 866 static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) { |
861 return handle_callback_impl(info, FUNCTION_ADDR(handle_callback)); | 867 return handle_callback_impl(info, FUNCTION_ADDR(handle_callback)); |
862 } | 868 } |
863 | 869 |
| 870 |
864 static void handle_callback_2(const v8::FunctionCallbackInfo<Value>& info) { | 871 static void handle_callback_2(const v8::FunctionCallbackInfo<Value>& info) { |
865 return handle_callback_impl(info, FUNCTION_ADDR(handle_callback_2)); | 872 return handle_callback_impl(info, FUNCTION_ADDR(handle_callback_2)); |
866 } | 873 } |
867 | 874 |
868 static void construct_callback( | 875 static void construct_callback( |
869 const v8::FunctionCallbackInfo<Value>& info) { | 876 const v8::FunctionCallbackInfo<Value>& info) { |
870 ApiTestFuzzer::Fuzz(); | 877 ApiTestFuzzer::Fuzz(); |
871 CheckReturnValue(info, FUNCTION_ADDR(construct_callback)); | 878 CheckReturnValue(info, FUNCTION_ADDR(construct_callback)); |
872 info.This()->Set(v8_str("x"), v8_num(1)); | 879 info.This()->Set(v8_str("x"), v8_num(1)); |
873 info.This()->Set(v8_str("y"), v8_num(2)); | 880 info.This()->Set(v8_str("y"), v8_num(2)); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 LocalContext env; | 1074 LocalContext env; |
1068 v8::HandleScope scope(env->GetIsolate()); | 1075 v8::HandleScope scope(env->GetIsolate()); |
1069 v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); | 1076 v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); |
1070 v8::FunctionCallback callback = &FastReturnValueCallback<T>; | 1077 v8::FunctionCallback callback = &FastReturnValueCallback<T>; |
1071 object_template->Set("callback", v8::FunctionTemplate::New(callback)); | 1078 object_template->Set("callback", v8::FunctionTemplate::New(callback)); |
1072 v8::Local<v8::Object> object = object_template->NewInstance(); | 1079 v8::Local<v8::Object> object = object_template->NewInstance(); |
1073 (*env)->Global()->Set(v8_str("callback_object"), object); | 1080 (*env)->Global()->Set(v8_str("callback_object"), object); |
1074 return scope.Close(CompileRun("callback_object.callback()")); | 1081 return scope.Close(CompileRun("callback_object.callback()")); |
1075 } | 1082 } |
1076 | 1083 |
| 1084 |
1077 THREADED_PROFILED_TEST(FastReturnValues) { | 1085 THREADED_PROFILED_TEST(FastReturnValues) { |
1078 LocalContext env; | 1086 LocalContext env; |
1079 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1087 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1080 v8::Handle<v8::Value> value; | 1088 v8::Handle<v8::Value> value; |
1081 // check int32_t and uint32_t | 1089 // check int32_t and uint32_t |
1082 int32_t int_values[] = { | 1090 int32_t int_values[] = { |
1083 0, 234, -723, | 1091 0, 234, -723, |
1084 i::Smi::kMinValue, i::Smi::kMaxValue | 1092 i::Smi::kMinValue, i::Smi::kMaxValue |
1085 }; | 1093 }; |
1086 for (size_t i = 0; i < ARRAY_SIZE(int_values); i++) { | 1094 for (size_t i = 0; i < ARRAY_SIZE(int_values); i++) { |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 | 1691 |
1684 | 1692 |
1685 static void EchoNamedProperty(Local<String> name, | 1693 static void EchoNamedProperty(Local<String> name, |
1686 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1694 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1687 ApiTestFuzzer::Fuzz(); | 1695 ApiTestFuzzer::Fuzz(); |
1688 CHECK_EQ(v8_str("data"), info.Data()); | 1696 CHECK_EQ(v8_str("data"), info.Data()); |
1689 echo_named_call_count++; | 1697 echo_named_call_count++; |
1690 info.GetReturnValue().Set(name); | 1698 info.GetReturnValue().Set(name); |
1691 } | 1699 } |
1692 | 1700 |
| 1701 |
1693 // Helper functions for Interceptor/Accessor interaction tests | 1702 // Helper functions for Interceptor/Accessor interaction tests |
1694 | 1703 |
1695 void SimpleAccessorGetter(Local<String> name, | 1704 void SimpleAccessorGetter(Local<String> name, |
1696 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1705 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1697 Handle<Object> self = info.This(); | 1706 Handle<Object> self = info.This(); |
1698 info.GetReturnValue().Set( | 1707 info.GetReturnValue().Set( |
1699 self->Get(String::Concat(v8_str("accessor_"), name))); | 1708 self->Get(String::Concat(v8_str("accessor_"), name))); |
1700 } | 1709 } |
1701 | 1710 |
1702 void SimpleAccessorSetter(Local<String> name, Local<Value> value, | 1711 void SimpleAccessorSetter(Local<String> name, Local<Value> value, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1745 v8::AccessorSetterCallback setter) { | 1754 v8::AccessorSetterCallback setter) { |
1746 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); | 1755 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); |
1747 } | 1756 } |
1748 | 1757 |
1749 void AddInterceptor(Handle<FunctionTemplate> templ, | 1758 void AddInterceptor(Handle<FunctionTemplate> templ, |
1750 v8::NamedPropertyGetterCallback getter, | 1759 v8::NamedPropertyGetterCallback getter, |
1751 v8::NamedPropertySetterCallback setter) { | 1760 v8::NamedPropertySetterCallback setter) { |
1752 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); | 1761 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); |
1753 } | 1762 } |
1754 | 1763 |
| 1764 |
1755 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { | 1765 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { |
1756 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1766 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1757 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1767 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1758 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1768 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1759 child->Inherit(parent); | 1769 child->Inherit(parent); |
1760 AddAccessor(parent, v8_str("age"), | 1770 AddAccessor(parent, v8_str("age"), |
1761 SimpleAccessorGetter, SimpleAccessorSetter); | 1771 SimpleAccessorGetter, SimpleAccessorSetter); |
1762 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | 1772 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
1763 LocalContext env; | 1773 LocalContext env; |
1764 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1774 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1765 CompileRun("var child = new Child;" | 1775 CompileRun("var child = new Child;" |
1766 "child.age = 10;"); | 1776 "child.age = 10;"); |
1767 ExpectBoolean("child.hasOwnProperty('age')", false); | 1777 ExpectBoolean("child.hasOwnProperty('age')", false); |
1768 ExpectInt32("child.age", 10); | 1778 ExpectInt32("child.age", 10); |
1769 ExpectInt32("child.accessor_age", 10); | 1779 ExpectInt32("child.accessor_age", 10); |
1770 } | 1780 } |
1771 | 1781 |
| 1782 |
1772 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { | 1783 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { |
1773 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1784 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1774 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1785 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1775 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1786 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1776 child->Inherit(parent); | 1787 child->Inherit(parent); |
1777 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | 1788 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
1778 LocalContext env; | 1789 LocalContext env; |
1779 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1790 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1780 CompileRun("var child = new Child;" | 1791 CompileRun("var child = new Child;" |
1781 "var parent = child.__proto__;" | 1792 "var parent = child.__proto__;" |
1782 "Object.defineProperty(parent, 'age', " | 1793 "Object.defineProperty(parent, 'age', " |
1783 " {get: function(){ return this.accessor_age; }, " | 1794 " {get: function(){ return this.accessor_age; }, " |
1784 " set: function(v){ this.accessor_age = v; }, " | 1795 " set: function(v){ this.accessor_age = v; }, " |
1785 " enumerable: true, configurable: true});" | 1796 " enumerable: true, configurable: true});" |
1786 "child.age = 10;"); | 1797 "child.age = 10;"); |
1787 ExpectBoolean("child.hasOwnProperty('age')", false); | 1798 ExpectBoolean("child.hasOwnProperty('age')", false); |
1788 ExpectInt32("child.age", 10); | 1799 ExpectInt32("child.age", 10); |
1789 ExpectInt32("child.accessor_age", 10); | 1800 ExpectInt32("child.accessor_age", 10); |
1790 } | 1801 } |
1791 | 1802 |
| 1803 |
1792 THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { | 1804 THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { |
1793 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1805 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1794 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1806 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1795 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1807 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1796 child->Inherit(parent); | 1808 child->Inherit(parent); |
1797 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | 1809 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
1798 LocalContext env; | 1810 LocalContext env; |
1799 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1811 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1800 CompileRun("var child = new Child;" | 1812 CompileRun("var child = new Child;" |
1801 "var parent = child.__proto__;" | 1813 "var parent = child.__proto__;" |
1802 "parent.name = 'Alice';"); | 1814 "parent.name = 'Alice';"); |
1803 ExpectBoolean("child.hasOwnProperty('name')", false); | 1815 ExpectBoolean("child.hasOwnProperty('name')", false); |
1804 ExpectString("child.name", "Alice"); | 1816 ExpectString("child.name", "Alice"); |
1805 CompileRun("child.name = 'Bob';"); | 1817 CompileRun("child.name = 'Bob';"); |
1806 ExpectString("child.name", "Bob"); | 1818 ExpectString("child.name", "Bob"); |
1807 ExpectBoolean("child.hasOwnProperty('name')", true); | 1819 ExpectBoolean("child.hasOwnProperty('name')", true); |
1808 ExpectString("parent.name", "Alice"); | 1820 ExpectString("parent.name", "Alice"); |
1809 } | 1821 } |
1810 | 1822 |
| 1823 |
1811 THREADED_TEST(SwitchFromInterceptorToAccessor) { | 1824 THREADED_TEST(SwitchFromInterceptorToAccessor) { |
1812 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1825 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1813 Handle<FunctionTemplate> templ = FunctionTemplate::New(); | 1826 Handle<FunctionTemplate> templ = FunctionTemplate::New(); |
1814 AddAccessor(templ, v8_str("age"), | 1827 AddAccessor(templ, v8_str("age"), |
1815 SimpleAccessorGetter, SimpleAccessorSetter); | 1828 SimpleAccessorGetter, SimpleAccessorSetter); |
1816 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | 1829 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
1817 LocalContext env; | 1830 LocalContext env; |
1818 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | 1831 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
1819 CompileRun("var obj = new Obj;" | 1832 CompileRun("var obj = new Obj;" |
1820 "function setAge(i){ obj.age = i; };" | 1833 "function setAge(i){ obj.age = i; };" |
1821 "for(var i = 0; i <= 10000; i++) setAge(i);"); | 1834 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
1822 // All i < 10000 go to the interceptor. | 1835 // All i < 10000 go to the interceptor. |
1823 ExpectInt32("obj.interceptor_age", 9999); | 1836 ExpectInt32("obj.interceptor_age", 9999); |
1824 // The last i goes to the accessor. | 1837 // The last i goes to the accessor. |
1825 ExpectInt32("obj.accessor_age", 10000); | 1838 ExpectInt32("obj.accessor_age", 10000); |
1826 } | 1839 } |
1827 | 1840 |
| 1841 |
1828 THREADED_TEST(SwitchFromAccessorToInterceptor) { | 1842 THREADED_TEST(SwitchFromAccessorToInterceptor) { |
1829 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1843 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1830 Handle<FunctionTemplate> templ = FunctionTemplate::New(); | 1844 Handle<FunctionTemplate> templ = FunctionTemplate::New(); |
1831 AddAccessor(templ, v8_str("age"), | 1845 AddAccessor(templ, v8_str("age"), |
1832 SimpleAccessorGetter, SimpleAccessorSetter); | 1846 SimpleAccessorGetter, SimpleAccessorSetter); |
1833 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | 1847 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
1834 LocalContext env; | 1848 LocalContext env; |
1835 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | 1849 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
1836 CompileRun("var obj = new Obj;" | 1850 CompileRun("var obj = new Obj;" |
1837 "function setAge(i){ obj.age = i; };" | 1851 "function setAge(i){ obj.age = i; };" |
1838 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | 1852 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
1839 // All i >= 10000 go to the accessor. | 1853 // All i >= 10000 go to the accessor. |
1840 ExpectInt32("obj.accessor_age", 10000); | 1854 ExpectInt32("obj.accessor_age", 10000); |
1841 // The last i goes to the interceptor. | 1855 // The last i goes to the interceptor. |
1842 ExpectInt32("obj.interceptor_age", 9999); | 1856 ExpectInt32("obj.interceptor_age", 9999); |
1843 } | 1857 } |
1844 | 1858 |
| 1859 |
1845 THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { | 1860 THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { |
1846 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1861 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1847 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1862 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1848 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1863 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1849 child->Inherit(parent); | 1864 child->Inherit(parent); |
1850 AddAccessor(parent, v8_str("age"), | 1865 AddAccessor(parent, v8_str("age"), |
1851 SimpleAccessorGetter, SimpleAccessorSetter); | 1866 SimpleAccessorGetter, SimpleAccessorSetter); |
1852 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | 1867 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
1853 LocalContext env; | 1868 LocalContext env; |
1854 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1869 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1855 CompileRun("var child = new Child;" | 1870 CompileRun("var child = new Child;" |
1856 "function setAge(i){ child.age = i; };" | 1871 "function setAge(i){ child.age = i; };" |
1857 "for(var i = 0; i <= 10000; i++) setAge(i);"); | 1872 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
1858 // All i < 10000 go to the interceptor. | 1873 // All i < 10000 go to the interceptor. |
1859 ExpectInt32("child.interceptor_age", 9999); | 1874 ExpectInt32("child.interceptor_age", 9999); |
1860 // The last i goes to the accessor. | 1875 // The last i goes to the accessor. |
1861 ExpectInt32("child.accessor_age", 10000); | 1876 ExpectInt32("child.accessor_age", 10000); |
1862 } | 1877 } |
1863 | 1878 |
| 1879 |
1864 THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { | 1880 THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { |
1865 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1881 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1866 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1882 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1867 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1883 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1868 child->Inherit(parent); | 1884 child->Inherit(parent); |
1869 AddAccessor(parent, v8_str("age"), | 1885 AddAccessor(parent, v8_str("age"), |
1870 SimpleAccessorGetter, SimpleAccessorSetter); | 1886 SimpleAccessorGetter, SimpleAccessorSetter); |
1871 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | 1887 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
1872 LocalContext env; | 1888 LocalContext env; |
1873 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1889 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1874 CompileRun("var child = new Child;" | 1890 CompileRun("var child = new Child;" |
1875 "function setAge(i){ child.age = i; };" | 1891 "function setAge(i){ child.age = i; };" |
1876 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | 1892 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
1877 // All i >= 10000 go to the accessor. | 1893 // All i >= 10000 go to the accessor. |
1878 ExpectInt32("child.accessor_age", 10000); | 1894 ExpectInt32("child.accessor_age", 10000); |
1879 // The last i goes to the interceptor. | 1895 // The last i goes to the interceptor. |
1880 ExpectInt32("child.interceptor_age", 9999); | 1896 ExpectInt32("child.interceptor_age", 9999); |
1881 } | 1897 } |
1882 | 1898 |
| 1899 |
1883 THREADED_TEST(SwitchFromInterceptorToJSAccessor) { | 1900 THREADED_TEST(SwitchFromInterceptorToJSAccessor) { |
1884 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1901 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1885 Handle<FunctionTemplate> templ = FunctionTemplate::New(); | 1902 Handle<FunctionTemplate> templ = FunctionTemplate::New(); |
1886 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | 1903 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
1887 LocalContext env; | 1904 LocalContext env; |
1888 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | 1905 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
1889 CompileRun("var obj = new Obj;" | 1906 CompileRun("var obj = new Obj;" |
1890 "function setter(i) { this.accessor_age = i; };" | 1907 "function setter(i) { this.accessor_age = i; };" |
1891 "function getter() { return this.accessor_age; };" | 1908 "function getter() { return this.accessor_age; };" |
1892 "function setAge(i) { obj.age = i; };" | 1909 "function setAge(i) { obj.age = i; };" |
1893 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" | 1910 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" |
1894 "for(var i = 0; i <= 10000; i++) setAge(i);"); | 1911 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
1895 // All i < 10000 go to the interceptor. | 1912 // All i < 10000 go to the interceptor. |
1896 ExpectInt32("obj.interceptor_age", 9999); | 1913 ExpectInt32("obj.interceptor_age", 9999); |
1897 // The last i goes to the JavaScript accessor. | 1914 // The last i goes to the JavaScript accessor. |
1898 ExpectInt32("obj.accessor_age", 10000); | 1915 ExpectInt32("obj.accessor_age", 10000); |
1899 // The installed JavaScript getter is still intact. | 1916 // The installed JavaScript getter is still intact. |
1900 // This last part is a regression test for issue 1651 and relies on the fact | 1917 // This last part is a regression test for issue 1651 and relies on the fact |
1901 // that both interceptor and accessor are being installed on the same object. | 1918 // that both interceptor and accessor are being installed on the same object. |
1902 ExpectInt32("obj.age", 10000); | 1919 ExpectInt32("obj.age", 10000); |
1903 ExpectBoolean("obj.hasOwnProperty('age')", true); | 1920 ExpectBoolean("obj.hasOwnProperty('age')", true); |
1904 ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); | 1921 ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); |
1905 } | 1922 } |
1906 | 1923 |
| 1924 |
1907 THREADED_TEST(SwitchFromJSAccessorToInterceptor) { | 1925 THREADED_TEST(SwitchFromJSAccessorToInterceptor) { |
1908 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1926 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1909 Handle<FunctionTemplate> templ = FunctionTemplate::New(); | 1927 Handle<FunctionTemplate> templ = FunctionTemplate::New(); |
1910 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | 1928 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
1911 LocalContext env; | 1929 LocalContext env; |
1912 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | 1930 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
1913 CompileRun("var obj = new Obj;" | 1931 CompileRun("var obj = new Obj;" |
1914 "function setter(i) { this.accessor_age = i; };" | 1932 "function setter(i) { this.accessor_age = i; };" |
1915 "function getter() { return this.accessor_age; };" | 1933 "function getter() { return this.accessor_age; };" |
1916 "function setAge(i) { obj.age = i; };" | 1934 "function setAge(i) { obj.age = i; };" |
1917 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" | 1935 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" |
1918 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | 1936 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
1919 // All i >= 10000 go to the accessor. | 1937 // All i >= 10000 go to the accessor. |
1920 ExpectInt32("obj.accessor_age", 10000); | 1938 ExpectInt32("obj.accessor_age", 10000); |
1921 // The last i goes to the interceptor. | 1939 // The last i goes to the interceptor. |
1922 ExpectInt32("obj.interceptor_age", 9999); | 1940 ExpectInt32("obj.interceptor_age", 9999); |
1923 // The installed JavaScript getter is still intact. | 1941 // The installed JavaScript getter is still intact. |
1924 // This last part is a regression test for issue 1651 and relies on the fact | 1942 // This last part is a regression test for issue 1651 and relies on the fact |
1925 // that both interceptor and accessor are being installed on the same object. | 1943 // that both interceptor and accessor are being installed on the same object. |
1926 ExpectInt32("obj.age", 10000); | 1944 ExpectInt32("obj.age", 10000); |
1927 ExpectBoolean("obj.hasOwnProperty('age')", true); | 1945 ExpectBoolean("obj.hasOwnProperty('age')", true); |
1928 ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); | 1946 ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); |
1929 } | 1947 } |
1930 | 1948 |
| 1949 |
1931 THREADED_TEST(SwitchFromInterceptorToProperty) { | 1950 THREADED_TEST(SwitchFromInterceptorToProperty) { |
1932 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1951 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1933 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1952 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1934 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1953 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1935 child->Inherit(parent); | 1954 child->Inherit(parent); |
1936 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | 1955 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
1937 LocalContext env; | 1956 LocalContext env; |
1938 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1957 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1939 CompileRun("var child = new Child;" | 1958 CompileRun("var child = new Child;" |
1940 "function setAge(i){ child.age = i; };" | 1959 "function setAge(i){ child.age = i; };" |
1941 "for(var i = 0; i <= 10000; i++) setAge(i);"); | 1960 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
1942 // All i < 10000 go to the interceptor. | 1961 // All i < 10000 go to the interceptor. |
1943 ExpectInt32("child.interceptor_age", 9999); | 1962 ExpectInt32("child.interceptor_age", 9999); |
1944 // The last i goes to child's own property. | 1963 // The last i goes to child's own property. |
1945 ExpectInt32("child.age", 10000); | 1964 ExpectInt32("child.age", 10000); |
1946 } | 1965 } |
1947 | 1966 |
| 1967 |
1948 THREADED_TEST(SwitchFromPropertyToInterceptor) { | 1968 THREADED_TEST(SwitchFromPropertyToInterceptor) { |
1949 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1969 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1950 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | 1970 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
1951 Handle<FunctionTemplate> child = FunctionTemplate::New(); | 1971 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
1952 child->Inherit(parent); | 1972 child->Inherit(parent); |
1953 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | 1973 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
1954 LocalContext env; | 1974 LocalContext env; |
1955 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 1975 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1956 CompileRun("var child = new Child;" | 1976 CompileRun("var child = new Child;" |
1957 "function setAge(i){ child.age = i; };" | 1977 "function setAge(i){ child.age = i; };" |
1958 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | 1978 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
1959 // All i >= 10000 go to child's own property. | 1979 // All i >= 10000 go to child's own property. |
1960 ExpectInt32("child.age", 10000); | 1980 ExpectInt32("child.age", 10000); |
1961 // The last i goes to the interceptor. | 1981 // The last i goes to the interceptor. |
1962 ExpectInt32("child.interceptor_age", 9999); | 1982 ExpectInt32("child.interceptor_age", 9999); |
1963 } | 1983 } |
1964 | 1984 |
| 1985 |
1965 THREADED_TEST(NamedPropertyHandlerGetter) { | 1986 THREADED_TEST(NamedPropertyHandlerGetter) { |
1966 echo_named_call_count = 0; | 1987 echo_named_call_count = 0; |
1967 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 1988 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
1968 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1989 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
1969 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, | 1990 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, |
1970 0, 0, 0, 0, | 1991 0, 0, 0, 0, |
1971 v8_str("data")); | 1992 v8_str("data")); |
1972 LocalContext env; | 1993 LocalContext env; |
1973 env->Global()->Set(v8_str("obj"), | 1994 env->Global()->Set(v8_str("obj"), |
1974 templ->GetFunction()->NewInstance()); | 1995 templ->GetFunction()->NewInstance()); |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 } | 2415 } |
2395 | 2416 |
2396 | 2417 |
2397 static void CheckEmbedderData(LocalContext* env, | 2418 static void CheckEmbedderData(LocalContext* env, |
2398 int index, | 2419 int index, |
2399 v8::Handle<Value> data) { | 2420 v8::Handle<Value> data) { |
2400 (*env)->SetEmbedderData(index, data); | 2421 (*env)->SetEmbedderData(index, data); |
2401 CHECK((*env)->GetEmbedderData(index)->StrictEquals(data)); | 2422 CHECK((*env)->GetEmbedderData(index)->StrictEquals(data)); |
2402 } | 2423 } |
2403 | 2424 |
| 2425 |
2404 THREADED_TEST(EmbedderData) { | 2426 THREADED_TEST(EmbedderData) { |
2405 LocalContext env; | 2427 LocalContext env; |
2406 v8::HandleScope scope(env->GetIsolate()); | 2428 v8::HandleScope scope(env->GetIsolate()); |
2407 | 2429 |
2408 CheckEmbedderData(&env, 3, v8::String::New("The quick brown fox jumps")); | 2430 CheckEmbedderData(&env, 3, v8::String::New("The quick brown fox jumps")); |
2409 CheckEmbedderData(&env, 2, v8::String::New("over the lazy dog.")); | 2431 CheckEmbedderData(&env, 2, v8::String::New("over the lazy dog.")); |
2410 CheckEmbedderData(&env, 1, v8::Number::New(1.2345)); | 2432 CheckEmbedderData(&env, 1, v8::Number::New(1.2345)); |
2411 CheckEmbedderData(&env, 0, v8::Boolean::New(true)); | 2433 CheckEmbedderData(&env, 0, v8::Boolean::New(true)); |
2412 } | 2434 } |
2413 | 2435 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2543 explicit ScopedArrayBufferContents( | 2565 explicit ScopedArrayBufferContents( |
2544 const v8::ArrayBuffer::Contents& contents) | 2566 const v8::ArrayBuffer::Contents& contents) |
2545 : contents_(contents) {} | 2567 : contents_(contents) {} |
2546 ~ScopedArrayBufferContents() { free(contents_.Data()); } | 2568 ~ScopedArrayBufferContents() { free(contents_.Data()); } |
2547 void* Data() const { return contents_.Data(); } | 2569 void* Data() const { return contents_.Data(); } |
2548 size_t ByteLength() const { return contents_.ByteLength(); } | 2570 size_t ByteLength() const { return contents_.ByteLength(); } |
2549 private: | 2571 private: |
2550 const v8::ArrayBuffer::Contents contents_; | 2572 const v8::ArrayBuffer::Contents contents_; |
2551 }; | 2573 }; |
2552 | 2574 |
| 2575 template <typename T> |
| 2576 static void CheckInternalFieldsAreZero(v8::Handle<T> value) { |
| 2577 CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount()); |
| 2578 for (int i = 0; i < value->InternalFieldCount(); i++) { |
| 2579 CHECK_EQ(0, value->GetInternalField(i)->Int32Value()); |
| 2580 } |
| 2581 } |
| 2582 |
2553 | 2583 |
2554 THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { | 2584 THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { |
2555 i::FLAG_harmony_array_buffer = true; | 2585 i::FLAG_harmony_array_buffer = true; |
2556 i::FLAG_harmony_typed_arrays = true; | 2586 i::FLAG_harmony_typed_arrays = true; |
2557 | 2587 |
2558 LocalContext env; | 2588 LocalContext env; |
2559 v8::Isolate* isolate = env->GetIsolate(); | 2589 v8::Isolate* isolate = env->GetIsolate(); |
2560 v8::HandleScope handle_scope(isolate); | 2590 v8::HandleScope handle_scope(isolate); |
2561 | 2591 |
2562 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(1024); | 2592 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(1024); |
| 2593 CheckInternalFieldsAreZero(ab); |
2563 CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); | 2594 CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); |
2564 CHECK(!ab->IsExternal()); | 2595 CHECK(!ab->IsExternal()); |
2565 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 2596 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
2566 | 2597 |
2567 ScopedArrayBufferContents ab_contents(ab->Externalize()); | 2598 ScopedArrayBufferContents ab_contents(ab->Externalize()); |
2568 CHECK(ab->IsExternal()); | 2599 CHECK(ab->IsExternal()); |
2569 | 2600 |
2570 CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); | 2601 CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); |
2571 uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); | 2602 uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); |
2572 ASSERT(data != NULL); | 2603 ASSERT(data != NULL); |
(...skipping 24 matching lines...) Expand all Loading... |
2597 v8::Isolate* isolate = env->GetIsolate(); | 2628 v8::Isolate* isolate = env->GetIsolate(); |
2598 v8::HandleScope handle_scope(isolate); | 2629 v8::HandleScope handle_scope(isolate); |
2599 | 2630 |
2600 | 2631 |
2601 v8::Local<v8::Value> result = | 2632 v8::Local<v8::Value> result = |
2602 CompileRun("var ab1 = new ArrayBuffer(2);" | 2633 CompileRun("var ab1 = new ArrayBuffer(2);" |
2603 "var u8_a = new Uint8Array(ab1);" | 2634 "var u8_a = new Uint8Array(ab1);" |
2604 "u8_a[0] = 0xAA;" | 2635 "u8_a[0] = 0xAA;" |
2605 "u8_a[1] = 0xFF; u8_a.buffer"); | 2636 "u8_a[1] = 0xFF; u8_a.buffer"); |
2606 Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); | 2637 Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); |
| 2638 CheckInternalFieldsAreZero(ab1); |
2607 CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); | 2639 CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); |
2608 CHECK(!ab1->IsExternal()); | 2640 CHECK(!ab1->IsExternal()); |
2609 ScopedArrayBufferContents ab1_contents(ab1->Externalize()); | 2641 ScopedArrayBufferContents ab1_contents(ab1->Externalize()); |
2610 CHECK(ab1->IsExternal()); | 2642 CHECK(ab1->IsExternal()); |
2611 | 2643 |
2612 result = CompileRun("ab1.byteLength"); | 2644 result = CompileRun("ab1.byteLength"); |
2613 CHECK_EQ(2, result->Int32Value()); | 2645 CHECK_EQ(2, result->Int32Value()); |
2614 result = CompileRun("u8_a[0]"); | 2646 result = CompileRun("u8_a[0]"); |
2615 CHECK_EQ(0xAA, result->Int32Value()); | 2647 CHECK_EQ(0xAA, result->Int32Value()); |
2616 result = CompileRun("u8_a[1]"); | 2648 result = CompileRun("u8_a[1]"); |
(...skipping 20 matching lines...) Expand all Loading... |
2637 i::FLAG_harmony_array_buffer = true; | 2669 i::FLAG_harmony_array_buffer = true; |
2638 i::FLAG_harmony_typed_arrays = true; | 2670 i::FLAG_harmony_typed_arrays = true; |
2639 | 2671 |
2640 LocalContext env; | 2672 LocalContext env; |
2641 v8::Isolate* isolate = env->GetIsolate(); | 2673 v8::Isolate* isolate = env->GetIsolate(); |
2642 v8::HandleScope handle_scope(isolate); | 2674 v8::HandleScope handle_scope(isolate); |
2643 | 2675 |
2644 i::ScopedVector<uint8_t> my_data(100); | 2676 i::ScopedVector<uint8_t> my_data(100); |
2645 memset(my_data.start(), 0, 100); | 2677 memset(my_data.start(), 0, 100); |
2646 Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(my_data.start(), 100); | 2678 Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(my_data.start(), 100); |
| 2679 CheckInternalFieldsAreZero(ab3); |
2647 CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); | 2680 CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); |
2648 CHECK(ab3->IsExternal()); | 2681 CHECK(ab3->IsExternal()); |
2649 | 2682 |
2650 env->Global()->Set(v8_str("ab3"), ab3); | 2683 env->Global()->Set(v8_str("ab3"), ab3); |
2651 | 2684 |
2652 v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); | 2685 v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); |
2653 CHECK_EQ(100, result->Int32Value()); | 2686 CHECK_EQ(100, result->Int32Value()); |
2654 | 2687 |
2655 result = CompileRun("var u8_b = new Uint8Array(ab3);" | 2688 result = CompileRun("var u8_b = new Uint8Array(ab3);" |
2656 "u8_b[0] = 0xBB;" | 2689 "u8_b[0] = 0xBB;" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2689 v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); | 2722 v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); |
2690 CheckIsNeutered(ta); | 2723 CheckIsNeutered(ta); |
2691 } | 2724 } |
2692 | 2725 |
2693 | 2726 |
2694 template <typename TypedArray, int kElementSize> | 2727 template <typename TypedArray, int kElementSize> |
2695 static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab, | 2728 static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab, |
2696 int byteOffset, | 2729 int byteOffset, |
2697 int length) { | 2730 int length) { |
2698 v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length); | 2731 v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length); |
| 2732 CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); |
2699 CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset())); | 2733 CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset())); |
2700 CHECK_EQ(length, static_cast<int>(ta->Length())); | 2734 CHECK_EQ(length, static_cast<int>(ta->Length())); |
2701 CHECK_EQ(length * kElementSize, static_cast<int>(ta->ByteLength())); | 2735 CHECK_EQ(length * kElementSize, static_cast<int>(ta->ByteLength())); |
2702 return ta; | 2736 return ta; |
2703 } | 2737 } |
2704 | 2738 |
2705 | 2739 |
2706 THREADED_TEST(ArrayBuffer_NeuteringApi) { | 2740 THREADED_TEST(ArrayBuffer_NeuteringApi) { |
2707 LocalContext env; | 2741 LocalContext env; |
2708 v8::Isolate* isolate = env->GetIsolate(); | 2742 v8::Isolate* isolate = env->GetIsolate(); |
(...skipping 17 matching lines...) Expand all Loading... |
2726 CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); | 2760 CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); |
2727 v8::Handle<v8::Int32Array> i32a = | 2761 v8::Handle<v8::Int32Array> i32a = |
2728 CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); | 2762 CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); |
2729 | 2763 |
2730 v8::Handle<v8::Float32Array> f32a = | 2764 v8::Handle<v8::Float32Array> f32a = |
2731 CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); | 2765 CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); |
2732 v8::Handle<v8::Float64Array> f64a = | 2766 v8::Handle<v8::Float64Array> f64a = |
2733 CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); | 2767 CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); |
2734 | 2768 |
2735 v8::Handle<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); | 2769 v8::Handle<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); |
| 2770 CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); |
2736 CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); | 2771 CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); |
2737 CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); | 2772 CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); |
2738 | 2773 |
2739 ScopedArrayBufferContents contents(buffer->Externalize()); | 2774 ScopedArrayBufferContents contents(buffer->Externalize()); |
2740 buffer->Neuter(); | 2775 buffer->Neuter(); |
2741 CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); | 2776 CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); |
2742 CheckIsNeutered(u8a); | 2777 CheckIsNeutered(u8a); |
2743 CheckIsNeutered(u8c); | 2778 CheckIsNeutered(u8c); |
2744 CheckIsNeutered(i8a); | 2779 CheckIsNeutered(i8a); |
2745 CheckIsNeutered(u16a); | 2780 CheckIsNeutered(u16a); |
2746 CheckIsNeutered(i16a); | 2781 CheckIsNeutered(i16a); |
2747 CheckIsNeutered(u32a); | 2782 CheckIsNeutered(u32a); |
2748 CheckIsNeutered(i32a); | 2783 CheckIsNeutered(i32a); |
2749 CheckIsNeutered(f32a); | 2784 CheckIsNeutered(f32a); |
2750 CheckIsNeutered(f64a); | 2785 CheckIsNeutered(f64a); |
2751 CheckDataViewIsNeutered(dv); | 2786 CheckDataViewIsNeutered(dv); |
2752 } | 2787 } |
2753 | 2788 |
| 2789 |
2754 THREADED_TEST(ArrayBuffer_NeuteringScript) { | 2790 THREADED_TEST(ArrayBuffer_NeuteringScript) { |
2755 LocalContext env; | 2791 LocalContext env; |
2756 v8::Isolate* isolate = env->GetIsolate(); | 2792 v8::Isolate* isolate = env->GetIsolate(); |
2757 v8::HandleScope handle_scope(isolate); | 2793 v8::HandleScope handle_scope(isolate); |
2758 | 2794 |
2759 CompileRun( | 2795 CompileRun( |
2760 "var ab = new ArrayBuffer(1024);" | 2796 "var ab = new ArrayBuffer(1024);" |
2761 "var u8a = new Uint8Array(ab, 1, 1023);" | 2797 "var u8a = new Uint8Array(ab, 1, 1023);" |
2762 "var u8c = new Uint8ClampedArray(ab, 1, 1023);" | 2798 "var u8c = new Uint8ClampedArray(ab, 1, 1023);" |
2763 "var i8a = new Int8Array(ab, 1, 1023);" | 2799 "var i8a = new Int8Array(ab, 1, 1023);" |
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3705 | 3741 |
3706 // These tests run for a long time and prevent us from running tests | 3742 // These tests run for a long time and prevent us from running tests |
3707 // that come after them so they cannot run in parallel. | 3743 // that come after them so they cannot run in parallel. |
3708 TEST(OutOfMemory) { | 3744 TEST(OutOfMemory) { |
3709 // It's not possible to read a snapshot into a heap with different dimensions. | 3745 // It's not possible to read a snapshot into a heap with different dimensions. |
3710 if (i::Snapshot::IsEnabled()) return; | 3746 if (i::Snapshot::IsEnabled()) return; |
3711 // Set heap limits. | 3747 // Set heap limits. |
3712 static const int K = 1024; | 3748 static const int K = 1024; |
3713 v8::ResourceConstraints constraints; | 3749 v8::ResourceConstraints constraints; |
3714 constraints.set_max_young_space_size(256 * K); | 3750 constraints.set_max_young_space_size(256 * K); |
3715 constraints.set_max_old_space_size(4 * K * K); | 3751 constraints.set_max_old_space_size(5 * K * K); |
3716 v8::SetResourceConstraints(&constraints); | 3752 v8::SetResourceConstraints(&constraints); |
3717 | 3753 |
3718 // Execute a script that causes out of memory. | 3754 // Execute a script that causes out of memory. |
3719 LocalContext context; | 3755 LocalContext context; |
3720 v8::HandleScope scope(context->GetIsolate()); | 3756 v8::HandleScope scope(context->GetIsolate()); |
3721 v8::V8::IgnoreOutOfMemoryException(); | 3757 v8::V8::IgnoreOutOfMemoryException(); |
3722 Local<Script> script = | 3758 Local<Script> script = |
3723 Script::Compile(String::New(js_code_causing_out_of_memory)); | 3759 Script::Compile(String::New(js_code_causing_out_of_memory)); |
3724 Local<Value> result = script->Run(); | 3760 Local<Value> result = script->Run(); |
3725 | 3761 |
(...skipping 20 matching lines...) Expand all Loading... |
3746 } | 3782 } |
3747 | 3783 |
3748 | 3784 |
3749 TEST(OutOfMemoryNested) { | 3785 TEST(OutOfMemoryNested) { |
3750 // It's not possible to read a snapshot into a heap with different dimensions. | 3786 // It's not possible to read a snapshot into a heap with different dimensions. |
3751 if (i::Snapshot::IsEnabled()) return; | 3787 if (i::Snapshot::IsEnabled()) return; |
3752 // Set heap limits. | 3788 // Set heap limits. |
3753 static const int K = 1024; | 3789 static const int K = 1024; |
3754 v8::ResourceConstraints constraints; | 3790 v8::ResourceConstraints constraints; |
3755 constraints.set_max_young_space_size(256 * K); | 3791 constraints.set_max_young_space_size(256 * K); |
3756 constraints.set_max_old_space_size(4 * K * K); | 3792 constraints.set_max_old_space_size(5 * K * K); |
3757 v8::SetResourceConstraints(&constraints); | 3793 v8::SetResourceConstraints(&constraints); |
3758 | 3794 |
3759 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 3795 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
3760 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 3796 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
3761 templ->Set(v8_str("ProvokeOutOfMemory"), | 3797 templ->Set(v8_str("ProvokeOutOfMemory"), |
3762 v8::FunctionTemplate::New(ProvokeOutOfMemory)); | 3798 v8::FunctionTemplate::New(ProvokeOutOfMemory)); |
3763 LocalContext context(0, templ); | 3799 LocalContext context(0, templ); |
3764 v8::V8::IgnoreOutOfMemoryException(); | 3800 v8::V8::IgnoreOutOfMemoryException(); |
3765 Local<Value> result = CompileRun( | 3801 Local<Value> result = CompileRun( |
3766 "var thrown = false;" | 3802 "var thrown = false;" |
3767 "try {" | 3803 "try {" |
3768 " ProvokeOutOfMemory();" | 3804 " ProvokeOutOfMemory();" |
3769 "} catch (e) {" | 3805 "} catch (e) {" |
3770 " thrown = true;" | 3806 " thrown = true;" |
3771 "}"); | 3807 "}"); |
3772 // Check for out of memory state. | 3808 // Check for out of memory state. |
3773 CHECK(result.IsEmpty()); | 3809 CHECK(result.IsEmpty()); |
3774 CHECK(context->HasOutOfMemoryException()); | 3810 CHECK(context->HasOutOfMemoryException()); |
3775 } | 3811 } |
3776 | 3812 |
3777 | 3813 |
3778 TEST(HugeConsStringOutOfMemory) { | 3814 TEST(HugeConsStringOutOfMemory) { |
3779 // It's not possible to read a snapshot into a heap with different dimensions. | 3815 // It's not possible to read a snapshot into a heap with different dimensions. |
3780 if (i::Snapshot::IsEnabled()) return; | 3816 if (i::Snapshot::IsEnabled()) return; |
3781 // Set heap limits. | 3817 // Set heap limits. |
3782 static const int K = 1024; | 3818 static const int K = 1024; |
3783 v8::ResourceConstraints constraints; | 3819 v8::ResourceConstraints constraints; |
3784 constraints.set_max_young_space_size(256 * K); | 3820 constraints.set_max_young_space_size(256 * K); |
3785 constraints.set_max_old_space_size(3 * K * K); | 3821 constraints.set_max_old_space_size(4 * K * K); |
3786 v8::SetResourceConstraints(&constraints); | 3822 v8::SetResourceConstraints(&constraints); |
3787 | 3823 |
3788 // Execute a script that causes out of memory. | 3824 // Execute a script that causes out of memory. |
3789 v8::V8::IgnoreOutOfMemoryException(); | 3825 v8::V8::IgnoreOutOfMemoryException(); |
3790 | 3826 |
3791 LocalContext context; | 3827 LocalContext context; |
3792 v8::HandleScope scope(context->GetIsolate()); | 3828 v8::HandleScope scope(context->GetIsolate()); |
3793 | 3829 |
3794 // Build huge string. This should fail with out of memory exception. | 3830 // Build huge string. This should fail with out of memory exception. |
3795 Local<Value> result = CompileRun( | 3831 Local<Value> result = CompileRun( |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4376 | 4412 |
4377 // JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] | 4413 // JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] |
4378 v8::Handle<Value> a4[argc] = { v8_num(6), v8_num(4), v8_num(5), v8_num(4) }; | 4414 v8::Handle<Value> a4[argc] = { v8_num(6), v8_num(4), v8_num(5), v8_num(4) }; |
4379 fun->Call(fun, argc, a4); | 4415 fun->Call(fun, argc, a4); |
4380 | 4416 |
4381 // JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] | 4417 // JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] |
4382 v8::Handle<Value> a5[argc] = { v8_num(6), v8_num(4), v8_num(3), v8_num(3) }; | 4418 v8::Handle<Value> a5[argc] = { v8_num(6), v8_num(4), v8_num(3), v8_num(3) }; |
4383 fun->Call(fun, argc, a5); | 4419 fun->Call(fun, argc, a5); |
4384 } | 4420 } |
4385 | 4421 |
| 4422 |
4386 void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) { | 4423 void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) { |
4387 ApiTestFuzzer::Fuzz(); | 4424 ApiTestFuzzer::Fuzz(); |
4388 CHECK_EQ(1, args.Length()); | 4425 CHECK_EQ(1, args.Length()); |
4389 v8::ThrowException(args[0]); | 4426 v8::ThrowException(args[0]); |
4390 } | 4427 } |
4391 | 4428 |
4392 | 4429 |
4393 THREADED_TEST(ThrowValues) { | 4430 THREADED_TEST(ThrowValues) { |
4394 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 4431 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
4395 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 4432 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4493 v8::V8::Initialize(); | 4530 v8::V8::Initialize(); |
4494 LocalContext context; | 4531 LocalContext context; |
4495 v8::HandleScope scope(context->GetIsolate()); | 4532 v8::HandleScope scope(context->GetIsolate()); |
4496 v8::TryCatch try_catch; | 4533 v8::TryCatch try_catch; |
4497 TryCatchNestedHelper(5); | 4534 TryCatchNestedHelper(5); |
4498 CHECK(try_catch.HasCaught()); | 4535 CHECK(try_catch.HasCaught()); |
4499 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "back")); | 4536 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "back")); |
4500 } | 4537 } |
4501 | 4538 |
4502 | 4539 |
| 4540 void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) { |
| 4541 CHECK(try_catch->HasCaught()); |
| 4542 Handle<Message> message = try_catch->Message(); |
| 4543 Handle<Value> resource = message->GetScriptResourceName(); |
| 4544 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner")); |
| 4545 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(message->Get()), |
| 4546 "Uncaught Error: a")); |
| 4547 CHECK_EQ(1, message->GetLineNumber()); |
| 4548 CHECK_EQ(6, message->GetStartColumn()); |
| 4549 } |
| 4550 |
| 4551 |
| 4552 void TryCatchMixedNestingHelper( |
| 4553 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 4554 ApiTestFuzzer::Fuzz(); |
| 4555 v8::TryCatch try_catch; |
| 4556 CompileRunWithOrigin("throw new Error('a');\n", "inner", 0, 0); |
| 4557 CHECK(try_catch.HasCaught()); |
| 4558 TryCatchMixedNestingCheck(&try_catch); |
| 4559 try_catch.ReThrow(); |
| 4560 } |
| 4561 |
| 4562 |
| 4563 // This test ensures that an outer TryCatch in the following situation: |
| 4564 // C++/TryCatch -> JS -> C++/TryCatch -> JS w/ SyntaxError |
| 4565 // does not clobber the Message object generated for the inner TryCatch. |
| 4566 // This exercises the ability of TryCatch.ReThrow() to restore the |
| 4567 // inner pending Message before throwing the exception again. |
| 4568 TEST(TryCatchMixedNesting) { |
| 4569 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 4570 v8::V8::Initialize(); |
| 4571 v8::TryCatch try_catch; |
| 4572 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
| 4573 templ->Set(v8_str("TryCatchMixedNestingHelper"), |
| 4574 v8::FunctionTemplate::New(TryCatchMixedNestingHelper)); |
| 4575 LocalContext context(0, templ); |
| 4576 CompileRunWithOrigin("TryCatchMixedNestingHelper();\n", "outer", 1, 1); |
| 4577 TryCatchMixedNestingCheck(&try_catch); |
| 4578 } |
| 4579 |
| 4580 |
4503 THREADED_TEST(Equality) { | 4581 THREADED_TEST(Equality) { |
4504 LocalContext context; | 4582 LocalContext context; |
4505 v8::Isolate* isolate = context->GetIsolate(); | 4583 v8::Isolate* isolate = context->GetIsolate(); |
4506 v8::HandleScope scope(context->GetIsolate()); | 4584 v8::HandleScope scope(context->GetIsolate()); |
4507 // Check that equality works at all before relying on CHECK_EQ | 4585 // Check that equality works at all before relying on CHECK_EQ |
4508 CHECK(v8_str("a")->Equals(v8_str("a"))); | 4586 CHECK(v8_str("a")->Equals(v8_str("a"))); |
4509 CHECK(!v8_str("a")->Equals(v8_str("b"))); | 4587 CHECK(!v8_str("a")->Equals(v8_str("b"))); |
4510 | 4588 |
4511 CHECK_EQ(v8_str("a"), v8_str("a")); | 4589 CHECK_EQ(v8_str("a"), v8_str("a")); |
4512 CHECK_NE(v8_str("a"), v8_str("b")); | 4590 CHECK_NE(v8_str("a"), v8_str("b")); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4557 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 4635 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
4558 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); | 4636 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); |
4559 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | 4637 context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
4560 Local<Script> script = Script::Compile(v8_str("obj.x")); | 4638 Local<Script> script = Script::Compile(v8_str("obj.x")); |
4561 for (int i = 0; i < 10; i++) { | 4639 for (int i = 0; i < 10; i++) { |
4562 Local<Value> result = script->Run(); | 4640 Local<Value> result = script->Run(); |
4563 CHECK_EQ(result, v8_str("x")); | 4641 CHECK_EQ(result, v8_str("x")); |
4564 } | 4642 } |
4565 } | 4643 } |
4566 | 4644 |
| 4645 |
4567 THREADED_TEST(DefinePropertyOnAPIAccessor) { | 4646 THREADED_TEST(DefinePropertyOnAPIAccessor) { |
4568 LocalContext context; | 4647 LocalContext context; |
4569 v8::HandleScope scope(context->GetIsolate()); | 4648 v8::HandleScope scope(context->GetIsolate()); |
4570 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 4649 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
4571 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); | 4650 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); |
4572 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | 4651 context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
4573 | 4652 |
4574 // Uses getOwnPropertyDescriptor to check the configurable status | 4653 // Uses getOwnPropertyDescriptor to check the configurable status |
4575 Local<Script> script_desc | 4654 Local<Script> script_desc |
4576 = Script::Compile(v8_str("var prop = Object.getOwnPropertyDescriptor( " | 4655 = Script::Compile(v8_str("var prop = Object.getOwnPropertyDescriptor( " |
(...skipping 27 matching lines...) Expand all Loading... |
4604 CHECK_EQ(result->BooleanValue(), false); | 4683 CHECK_EQ(result->BooleanValue(), false); |
4605 | 4684 |
4606 // Make sure that it is not possible to redefine again | 4685 // Make sure that it is not possible to redefine again |
4607 v8::TryCatch try_catch; | 4686 v8::TryCatch try_catch; |
4608 result = script_define->Run(); | 4687 result = script_define->Run(); |
4609 CHECK(try_catch.HasCaught()); | 4688 CHECK(try_catch.HasCaught()); |
4610 String::Utf8Value exception_value(try_catch.Exception()); | 4689 String::Utf8Value exception_value(try_catch.Exception()); |
4611 CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x"); | 4690 CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x"); |
4612 } | 4691 } |
4613 | 4692 |
| 4693 |
4614 THREADED_TEST(DefinePropertyOnDefineGetterSetter) { | 4694 THREADED_TEST(DefinePropertyOnDefineGetterSetter) { |
4615 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 4695 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
4616 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 4696 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
4617 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); | 4697 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); |
4618 LocalContext context; | 4698 LocalContext context; |
4619 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | 4699 context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
4620 | 4700 |
4621 Local<Script> script_desc = Script::Compile(v8_str("var prop =" | 4701 Local<Script> script_desc = Script::Compile(v8_str("var prop =" |
4622 "Object.getOwnPropertyDescriptor( " | 4702 "Object.getOwnPropertyDescriptor( " |
4623 "obj, 'x');" | 4703 "obj, 'x');" |
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6267 v8::Local<v8::Object>::New(info.GetIsolate(), prev) | 6347 v8::Local<v8::Object>::New(info.GetIsolate(), prev) |
6268 ->Set(v8_str("next"), obj); | 6348 ->Set(v8_str("next"), obj); |
6269 prev.MakeWeak<Value, Snorkel>(new Snorkel(), &HandleWeakReference); | 6349 prev.MakeWeak<Value, Snorkel>(new Snorkel(), &HandleWeakReference); |
6270 whammy->objects_[whammy->cursor_].Clear(); | 6350 whammy->objects_[whammy->cursor_].Clear(); |
6271 } | 6351 } |
6272 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); | 6352 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); |
6273 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; | 6353 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; |
6274 info.GetReturnValue().Set(whammy->getScript()->Run()); | 6354 info.GetReturnValue().Set(whammy->getScript()->Run()); |
6275 } | 6355 } |
6276 | 6356 |
| 6357 |
6277 THREADED_TEST(WeakReference) { | 6358 THREADED_TEST(WeakReference) { |
6278 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); | 6359 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); |
6279 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); | 6360 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); |
6280 Whammy* whammy = new Whammy(v8::Isolate::GetCurrent()); | 6361 Whammy* whammy = new Whammy(v8::Isolate::GetCurrent()); |
6281 templ->SetNamedPropertyHandler(WhammyPropertyGetter, | 6362 templ->SetNamedPropertyHandler(WhammyPropertyGetter, |
6282 0, 0, 0, 0, | 6363 0, 0, 0, 0, |
6283 v8::External::New(whammy)); | 6364 v8::External::New(whammy)); |
6284 const char* extension_list[] = { "v8/gc" }; | 6365 const char* extension_list[] = { "v8/gc" }; |
6285 v8::ExtensionConfiguration extensions(1, extension_list); | 6366 v8::ExtensionConfiguration extensions(1, extension_list); |
6286 v8::Handle<Context> context = | 6367 v8::Handle<Context> context = |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7402 v8::Handle<Value>) { | 7483 v8::Handle<Value>) { |
7403 v8::Handle<v8::Value> name_val = message->GetScriptResourceName(); | 7484 v8::Handle<v8::Value> name_val = message->GetScriptResourceName(); |
7404 CHECK(!name_val.IsEmpty() && name_val->IsString()); | 7485 CHECK(!name_val.IsEmpty() && name_val->IsString()); |
7405 v8::String::Utf8Value name(message->GetScriptResourceName()); | 7486 v8::String::Utf8Value name(message->GetScriptResourceName()); |
7406 CHECK_EQ(script_resource_name, *name); | 7487 CHECK_EQ(script_resource_name, *name); |
7407 CHECK_EQ(3, message->GetLineNumber()); | 7488 CHECK_EQ(3, message->GetLineNumber()); |
7408 v8::String::Utf8Value source_line(message->GetSourceLine()); | 7489 v8::String::Utf8Value source_line(message->GetSourceLine()); |
7409 CHECK_EQ(" new o.foo();", *source_line); | 7490 CHECK_EQ(" new o.foo();", *source_line); |
7410 } | 7491 } |
7411 | 7492 |
| 7493 |
7412 TEST(ExceptionInNativeScript) { | 7494 TEST(ExceptionInNativeScript) { |
7413 LocalContext env; | 7495 LocalContext env; |
7414 v8::HandleScope scope(env->GetIsolate()); | 7496 v8::HandleScope scope(env->GetIsolate()); |
7415 v8::V8::AddMessageListener(ExceptionInNativeScriptTestListener); | 7497 v8::V8::AddMessageListener(ExceptionInNativeScriptTestListener); |
7416 | 7498 |
7417 Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(TroubleCallback); | 7499 Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(TroubleCallback); |
7418 v8::Local<v8::Object> global = env->Global(); | 7500 v8::Local<v8::Object> global = env->Global(); |
7419 global->Set(v8_str("trouble"), fun->GetFunction()); | 7501 global->Set(v8_str("trouble"), fun->GetFunction()); |
7420 | 7502 |
7421 Script::Compile(v8_str("function trouble() {\n" | 7503 Script::Compile(v8_str("function trouble() {\n" |
(...skipping 3240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10662 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 10744 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
10663 CHECK_EQ(isolate, args.GetIsolate()); | 10745 CHECK_EQ(isolate, args.GetIsolate()); |
10664 CHECK_EQ(args.This()->GetPrototype(), args.Holder()); | 10746 CHECK_EQ(args.This()->GetPrototype(), args.Holder()); |
10665 CHECK(args.Data()->Equals(v8_str("method_data"))); | 10747 CHECK(args.Data()->Equals(v8_str("method_data"))); |
10666 // Note, we're using HasRealNamedProperty instead of Has to avoid | 10748 // Note, we're using HasRealNamedProperty instead of Has to avoid |
10667 // invoking the interceptor again. | 10749 // invoking the interceptor again. |
10668 CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo"))); | 10750 CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo"))); |
10669 args.GetReturnValue().Set(args[0]->Int32Value() + 1); | 10751 args.GetReturnValue().Set(args[0]->Int32Value() + 1); |
10670 } | 10752 } |
10671 | 10753 |
| 10754 |
10672 // Helper to maximize the odds of object moving. | 10755 // Helper to maximize the odds of object moving. |
10673 static void GenerateSomeGarbage() { | 10756 static void GenerateSomeGarbage() { |
10674 CompileRun( | 10757 CompileRun( |
10675 "var garbage;" | 10758 "var garbage;" |
10676 "for (var i = 0; i < 1000; i++) {" | 10759 "for (var i = 0; i < 1000; i++) {" |
10677 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" | 10760 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" |
10678 "}" | 10761 "}" |
10679 "garbage = undefined;"); | 10762 "garbage = undefined;"); |
10680 } | 10763 } |
10681 | 10764 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10763 v8::Handle<v8::Value> result = CompileRun( | 10846 v8::Handle<v8::Value> result = CompileRun( |
10764 "function f() {" | 10847 "function f() {" |
10765 " for (var i = 0; i < 30; i++) o1.p1;" | 10848 " for (var i = 0; i < 30; i++) o1.p1;" |
10766 " return o1.p1" | 10849 " return o1.p1" |
10767 "}" | 10850 "}" |
10768 "f();"); | 10851 "f();"); |
10769 CHECK_EQ(v8_str("Direct Getter Result"), result); | 10852 CHECK_EQ(v8_str("Direct Getter Result"), result); |
10770 CHECK_EQ(31, p_getter_count); | 10853 CHECK_EQ(31, p_getter_count); |
10771 } | 10854 } |
10772 | 10855 |
| 10856 |
10773 THREADED_PROFILED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { | 10857 THREADED_PROFILED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { |
10774 LoadICFastApi_DirectCall_GCMoveStub(DirectGetterCallback); | 10858 LoadICFastApi_DirectCall_GCMoveStub(DirectGetterCallback); |
10775 } | 10859 } |
10776 | 10860 |
10777 | 10861 |
10778 void ThrowingDirectGetterCallback( | 10862 void ThrowingDirectGetterCallback( |
10779 Local<String> name, | 10863 Local<String> name, |
10780 const v8::PropertyCallbackInfo<v8::Value>& info) { | 10864 const v8::PropertyCallbackInfo<v8::Value>& info) { |
10781 v8::ThrowException(v8_str("g")); | 10865 v8::ThrowException(v8_str("g")); |
10782 } | 10866 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10818 context->Global()->Set(v8_str("o"), fun->NewInstance()); | 10902 context->Global()->Set(v8_str("o"), fun->NewInstance()); |
10819 CompileRun( | 10903 CompileRun( |
10820 "var result = 0;" | 10904 "var result = 0;" |
10821 "for (var i = 0; i < 100; i++) {" | 10905 "for (var i = 0; i < 100; i++) {" |
10822 " result = o.method(41);" | 10906 " result = o.method(41);" |
10823 "}"); | 10907 "}"); |
10824 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); | 10908 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
10825 CHECK_EQ(100, interceptor_call_count); | 10909 CHECK_EQ(100, interceptor_call_count); |
10826 } | 10910 } |
10827 | 10911 |
| 10912 |
10828 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { | 10913 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { |
10829 int interceptor_call_count = 0; | 10914 int interceptor_call_count = 0; |
10830 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 10915 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
10831 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 10916 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
10832 v8::Handle<v8::FunctionTemplate> method_templ = | 10917 v8::Handle<v8::FunctionTemplate> method_templ = |
10833 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 10918 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
10834 v8_str("method_data"), | 10919 v8_str("method_data"), |
10835 v8::Signature::New(fun_templ)); | 10920 v8::Signature::New(fun_templ)); |
10836 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 10921 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
10837 proto_templ->Set(v8_str("method"), method_templ); | 10922 proto_templ->Set(v8_str("method"), method_templ); |
(...skipping 11 matching lines...) Expand all Loading... |
10849 "var receiver = {};" | 10934 "var receiver = {};" |
10850 "receiver.__proto__ = o;" | 10935 "receiver.__proto__ = o;" |
10851 "var result = 0;" | 10936 "var result = 0;" |
10852 "for (var i = 0; i < 100; i++) {" | 10937 "for (var i = 0; i < 100; i++) {" |
10853 " result = receiver.method(41);" | 10938 " result = receiver.method(41);" |
10854 "}"); | 10939 "}"); |
10855 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); | 10940 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
10856 CHECK_EQ(100, interceptor_call_count); | 10941 CHECK_EQ(100, interceptor_call_count); |
10857 } | 10942 } |
10858 | 10943 |
| 10944 |
10859 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { | 10945 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { |
10860 int interceptor_call_count = 0; | 10946 int interceptor_call_count = 0; |
10861 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 10947 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
10862 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 10948 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
10863 v8::Handle<v8::FunctionTemplate> method_templ = | 10949 v8::Handle<v8::FunctionTemplate> method_templ = |
10864 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 10950 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
10865 v8_str("method_data"), | 10951 v8_str("method_data"), |
10866 v8::Signature::New(fun_templ)); | 10952 v8::Signature::New(fun_templ)); |
10867 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 10953 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
10868 proto_templ->Set(v8_str("method"), method_templ); | 10954 proto_templ->Set(v8_str("method"), method_templ); |
(...skipping 17 matching lines...) Expand all Loading... |
10886 " if (i == 50) {" | 10972 " if (i == 50) {" |
10887 " saved_result = result;" | 10973 " saved_result = result;" |
10888 " receiver = {method: function(x) { return x - 1 }};" | 10974 " receiver = {method: function(x) { return x - 1 }};" |
10889 " }" | 10975 " }" |
10890 "}"); | 10976 "}"); |
10891 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); | 10977 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); |
10892 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 10978 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
10893 CHECK_GE(interceptor_call_count, 50); | 10979 CHECK_GE(interceptor_call_count, 50); |
10894 } | 10980 } |
10895 | 10981 |
| 10982 |
10896 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { | 10983 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { |
10897 int interceptor_call_count = 0; | 10984 int interceptor_call_count = 0; |
10898 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 10985 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
10899 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 10986 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
10900 v8::Handle<v8::FunctionTemplate> method_templ = | 10987 v8::Handle<v8::FunctionTemplate> method_templ = |
10901 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 10988 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
10902 v8_str("method_data"), | 10989 v8_str("method_data"), |
10903 v8::Signature::New(fun_templ)); | 10990 v8::Signature::New(fun_templ)); |
10904 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 10991 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
10905 proto_templ->Set(v8_str("method"), method_templ); | 10992 proto_templ->Set(v8_str("method"), method_templ); |
(...skipping 17 matching lines...) Expand all Loading... |
10923 " if (i == 50) {" | 11010 " if (i == 50) {" |
10924 " saved_result = result;" | 11011 " saved_result = result;" |
10925 " o.method = function(x) { return x - 1 };" | 11012 " o.method = function(x) { return x - 1 };" |
10926 " }" | 11013 " }" |
10927 "}"); | 11014 "}"); |
10928 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); | 11015 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); |
10929 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 11016 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
10930 CHECK_GE(interceptor_call_count, 50); | 11017 CHECK_GE(interceptor_call_count, 50); |
10931 } | 11018 } |
10932 | 11019 |
| 11020 |
10933 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { | 11021 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { |
10934 int interceptor_call_count = 0; | 11022 int interceptor_call_count = 0; |
10935 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11023 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
10936 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11024 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
10937 v8::Handle<v8::FunctionTemplate> method_templ = | 11025 v8::Handle<v8::FunctionTemplate> method_templ = |
10938 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 11026 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
10939 v8_str("method_data"), | 11027 v8_str("method_data"), |
10940 v8::Signature::New(fun_templ)); | 11028 v8::Signature::New(fun_templ)); |
10941 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11029 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
10942 proto_templ->Set(v8_str("method"), method_templ); | 11030 proto_templ->Set(v8_str("method"), method_templ); |
(...skipping 20 matching lines...) Expand all Loading... |
10963 " receiver = 333;" | 11051 " receiver = 333;" |
10964 " }" | 11052 " }" |
10965 "}"); | 11053 "}"); |
10966 CHECK(try_catch.HasCaught()); | 11054 CHECK(try_catch.HasCaught()); |
10967 CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), | 11055 CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), |
10968 try_catch.Exception()->ToString()); | 11056 try_catch.Exception()->ToString()); |
10969 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 11057 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
10970 CHECK_GE(interceptor_call_count, 50); | 11058 CHECK_GE(interceptor_call_count, 50); |
10971 } | 11059 } |
10972 | 11060 |
| 11061 |
10973 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { | 11062 THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { |
10974 int interceptor_call_count = 0; | 11063 int interceptor_call_count = 0; |
10975 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11064 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
10976 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11065 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
10977 v8::Handle<v8::FunctionTemplate> method_templ = | 11066 v8::Handle<v8::FunctionTemplate> method_templ = |
10978 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 11067 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
10979 v8_str("method_data"), | 11068 v8_str("method_data"), |
10980 v8::Signature::New(fun_templ)); | 11069 v8::Signature::New(fun_templ)); |
10981 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11070 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
10982 proto_templ->Set(v8_str("method"), method_templ); | 11071 proto_templ->Set(v8_str("method"), method_templ); |
(...skipping 20 matching lines...) Expand all Loading... |
11003 " receiver = {method: receiver.method};" | 11092 " receiver = {method: receiver.method};" |
11004 " }" | 11093 " }" |
11005 "}"); | 11094 "}"); |
11006 CHECK(try_catch.HasCaught()); | 11095 CHECK(try_catch.HasCaught()); |
11007 CHECK_EQ(v8_str("TypeError: Illegal invocation"), | 11096 CHECK_EQ(v8_str("TypeError: Illegal invocation"), |
11008 try_catch.Exception()->ToString()); | 11097 try_catch.Exception()->ToString()); |
11009 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 11098 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
11010 CHECK_GE(interceptor_call_count, 50); | 11099 CHECK_GE(interceptor_call_count, 50); |
11011 } | 11100 } |
11012 | 11101 |
| 11102 |
11013 THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { | 11103 THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { |
11014 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11104 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11015 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11105 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
11016 v8::Handle<v8::FunctionTemplate> method_templ = | 11106 v8::Handle<v8::FunctionTemplate> method_templ = |
11017 v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, | 11107 v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, |
11018 v8_str("method_data"), | 11108 v8_str("method_data"), |
11019 v8::Handle<v8::Signature>()); | 11109 v8::Handle<v8::Signature>()); |
11020 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11110 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
11021 proto_templ->Set(v8_str("method"), method_templ); | 11111 proto_templ->Set(v8_str("method"), method_templ); |
11022 v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); | 11112 v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); |
11023 USE(templ); | 11113 USE(templ); |
11024 LocalContext context; | 11114 LocalContext context; |
11025 v8::Handle<v8::Function> fun = fun_templ->GetFunction(); | 11115 v8::Handle<v8::Function> fun = fun_templ->GetFunction(); |
11026 GenerateSomeGarbage(); | 11116 GenerateSomeGarbage(); |
11027 context->Global()->Set(v8_str("o"), fun->NewInstance()); | 11117 context->Global()->Set(v8_str("o"), fun->NewInstance()); |
11028 CompileRun( | 11118 CompileRun( |
11029 "var result = 0;" | 11119 "var result = 0;" |
11030 "for (var i = 0; i < 100; i++) {" | 11120 "for (var i = 0; i < 100; i++) {" |
11031 " result = o.method(41);" | 11121 " result = o.method(41);" |
11032 "}"); | 11122 "}"); |
11033 | 11123 |
11034 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); | 11124 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
11035 } | 11125 } |
11036 | 11126 |
| 11127 |
11037 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { | 11128 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { |
11038 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11129 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11039 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11130 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
11040 v8::Handle<v8::FunctionTemplate> method_templ = | 11131 v8::Handle<v8::FunctionTemplate> method_templ = |
11041 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 11132 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
11042 v8_str("method_data"), | 11133 v8_str("method_data"), |
11043 v8::Signature::New(fun_templ)); | 11134 v8::Signature::New(fun_templ)); |
11044 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11135 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
11045 proto_templ->Set(v8_str("method"), method_templ); | 11136 proto_templ->Set(v8_str("method"), method_templ); |
11046 fun_templ->SetHiddenPrototype(true); | 11137 fun_templ->SetHiddenPrototype(true); |
11047 v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); | 11138 v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); |
11048 CHECK(!templ.IsEmpty()); | 11139 CHECK(!templ.IsEmpty()); |
11049 LocalContext context; | 11140 LocalContext context; |
11050 v8::Handle<v8::Function> fun = fun_templ->GetFunction(); | 11141 v8::Handle<v8::Function> fun = fun_templ->GetFunction(); |
11051 GenerateSomeGarbage(); | 11142 GenerateSomeGarbage(); |
11052 context->Global()->Set(v8_str("o"), fun->NewInstance()); | 11143 context->Global()->Set(v8_str("o"), fun->NewInstance()); |
11053 CompileRun( | 11144 CompileRun( |
11054 "o.foo = 17;" | 11145 "o.foo = 17;" |
11055 "var receiver = {};" | 11146 "var receiver = {};" |
11056 "receiver.__proto__ = o;" | 11147 "receiver.__proto__ = o;" |
11057 "var result = 0;" | 11148 "var result = 0;" |
11058 "for (var i = 0; i < 100; i++) {" | 11149 "for (var i = 0; i < 100; i++) {" |
11059 " result = receiver.method(41);" | 11150 " result = receiver.method(41);" |
11060 "}"); | 11151 "}"); |
11061 | 11152 |
11062 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); | 11153 CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
11063 } | 11154 } |
11064 | 11155 |
| 11156 |
11065 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { | 11157 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { |
11066 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11158 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11067 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11159 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
11068 v8::Handle<v8::FunctionTemplate> method_templ = | 11160 v8::Handle<v8::FunctionTemplate> method_templ = |
11069 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 11161 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
11070 v8_str("method_data"), | 11162 v8_str("method_data"), |
11071 v8::Signature::New(fun_templ)); | 11163 v8::Signature::New(fun_templ)); |
11072 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11164 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
11073 proto_templ->Set(v8_str("method"), method_templ); | 11165 proto_templ->Set(v8_str("method"), method_templ); |
11074 fun_templ->SetHiddenPrototype(true); | 11166 fun_templ->SetHiddenPrototype(true); |
(...skipping 13 matching lines...) Expand all Loading... |
11088 " result = receiver.method(41);" | 11180 " result = receiver.method(41);" |
11089 " if (i == 50) {" | 11181 " if (i == 50) {" |
11090 " saved_result = result;" | 11182 " saved_result = result;" |
11091 " receiver = {method: function(x) { return x - 1 }};" | 11183 " receiver = {method: function(x) { return x - 1 }};" |
11092 " }" | 11184 " }" |
11093 "}"); | 11185 "}"); |
11094 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); | 11186 CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); |
11095 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 11187 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
11096 } | 11188 } |
11097 | 11189 |
| 11190 |
11098 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { | 11191 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { |
11099 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11192 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11100 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11193 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
11101 v8::Handle<v8::FunctionTemplate> method_templ = | 11194 v8::Handle<v8::FunctionTemplate> method_templ = |
11102 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 11195 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
11103 v8_str("method_data"), | 11196 v8_str("method_data"), |
11104 v8::Signature::New(fun_templ)); | 11197 v8::Signature::New(fun_templ)); |
11105 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11198 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
11106 proto_templ->Set(v8_str("method"), method_templ); | 11199 proto_templ->Set(v8_str("method"), method_templ); |
11107 fun_templ->SetHiddenPrototype(true); | 11200 fun_templ->SetHiddenPrototype(true); |
(...skipping 16 matching lines...) Expand all Loading... |
11124 " saved_result = result;" | 11217 " saved_result = result;" |
11125 " receiver = 333;" | 11218 " receiver = 333;" |
11126 " }" | 11219 " }" |
11127 "}"); | 11220 "}"); |
11128 CHECK(try_catch.HasCaught()); | 11221 CHECK(try_catch.HasCaught()); |
11129 CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), | 11222 CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"), |
11130 try_catch.Exception()->ToString()); | 11223 try_catch.Exception()->ToString()); |
11131 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 11224 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
11132 } | 11225 } |
11133 | 11226 |
| 11227 |
11134 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { | 11228 THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { |
11135 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11229 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11136 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 11230 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
11137 v8::Handle<v8::FunctionTemplate> method_templ = | 11231 v8::Handle<v8::FunctionTemplate> method_templ = |
11138 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, | 11232 v8::FunctionTemplate::New(FastApiCallback_SimpleSignature, |
11139 v8_str("method_data"), | 11233 v8_str("method_data"), |
11140 v8::Signature::New(fun_templ)); | 11234 v8::Signature::New(fun_templ)); |
11141 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 11235 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
11142 proto_templ->Set(v8_str("method"), method_templ); | 11236 proto_templ->Set(v8_str("method"), method_templ); |
11143 fun_templ->SetHiddenPrototype(true); | 11237 fun_templ->SetHiddenPrototype(true); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11274 " if (i == 5) {" | 11368 " if (i == 5) {" |
11275 " m = 'len';" | 11369 " m = 'len';" |
11276 " saved_result = result;" | 11370 " saved_result = result;" |
11277 " };" | 11371 " };" |
11278 " result = o[m]('239');" | 11372 " result = o[m]('239');" |
11279 "}"); | 11373 "}"); |
11280 CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value()); | 11374 CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value()); |
11281 CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 11375 CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
11282 } | 11376 } |
11283 | 11377 |
| 11378 |
11284 // Test the map transition before the interceptor. | 11379 // Test the map transition before the interceptor. |
11285 THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { | 11380 THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { |
11286 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11381 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11287 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); | 11382 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(); |
11288 templ_o->SetNamedPropertyHandler(NoBlockGetterX); | 11383 templ_o->SetNamedPropertyHandler(NoBlockGetterX); |
11289 LocalContext context; | 11384 LocalContext context; |
11290 context->Global()->Set(v8_str("proto"), templ_o->NewInstance()); | 11385 context->Global()->Set(v8_str("proto"), templ_o->NewInstance()); |
11291 | 11386 |
11292 CompileRun( | 11387 CompileRun( |
11293 "var o = new Object();" | 11388 "var o = new Object();" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11376 ApiTestFuzzer::Fuzz(); | 11471 ApiTestFuzzer::Fuzz(); |
11377 if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) { | 11472 if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) { |
11378 info.GetReturnValue().Set(call_ic_function3); | 11473 info.GetReturnValue().Set(call_ic_function3); |
11379 } | 11474 } |
11380 if (interceptor_ic_exception_get_count == 20) { | 11475 if (interceptor_ic_exception_get_count == 20) { |
11381 v8::ThrowException(v8_num(42)); | 11476 v8::ThrowException(v8_num(42)); |
11382 return; | 11477 return; |
11383 } | 11478 } |
11384 } | 11479 } |
11385 | 11480 |
| 11481 |
11386 // Test interceptor load/call IC where the interceptor throws an | 11482 // Test interceptor load/call IC where the interceptor throws an |
11387 // exception once in a while. | 11483 // exception once in a while. |
11388 THREADED_TEST(InterceptorICGetterExceptions) { | 11484 THREADED_TEST(InterceptorICGetterExceptions) { |
11389 interceptor_ic_exception_get_count = 0; | 11485 interceptor_ic_exception_get_count = 0; |
11390 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11486 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11391 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); | 11487 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); |
11392 templ->SetNamedPropertyHandler(InterceptorICExceptionGetter); | 11488 templ->SetNamedPropertyHandler(InterceptorICExceptionGetter); |
11393 LocalContext context(0, templ, v8::Handle<Value>()); | 11489 LocalContext context(0, templ, v8::Handle<Value>()); |
11394 call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run(); | 11490 call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run(); |
11395 v8::Handle<Value> value = CompileRun( | 11491 v8::Handle<Value> value = CompileRun( |
(...skipping 23 matching lines...) Expand all Loading... |
11419 static void InterceptorICExceptionSetter( | 11515 static void InterceptorICExceptionSetter( |
11420 Local<String> key, | 11516 Local<String> key, |
11421 Local<Value> value, | 11517 Local<Value> value, |
11422 const v8::PropertyCallbackInfo<v8::Value>& info) { | 11518 const v8::PropertyCallbackInfo<v8::Value>& info) { |
11423 ApiTestFuzzer::Fuzz(); | 11519 ApiTestFuzzer::Fuzz(); |
11424 if (++interceptor_ic_exception_set_count > 20) { | 11520 if (++interceptor_ic_exception_set_count > 20) { |
11425 v8::ThrowException(v8_num(42)); | 11521 v8::ThrowException(v8_num(42)); |
11426 } | 11522 } |
11427 } | 11523 } |
11428 | 11524 |
| 11525 |
11429 // Test interceptor store IC where the interceptor throws an exception | 11526 // Test interceptor store IC where the interceptor throws an exception |
11430 // once in a while. | 11527 // once in a while. |
11431 THREADED_TEST(InterceptorICSetterExceptions) { | 11528 THREADED_TEST(InterceptorICSetterExceptions) { |
11432 interceptor_ic_exception_set_count = 0; | 11529 interceptor_ic_exception_set_count = 0; |
11433 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 11530 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
11434 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); | 11531 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(); |
11435 templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter); | 11532 templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter); |
11436 LocalContext context(0, templ, v8::Handle<Value>()); | 11533 LocalContext context(0, templ, v8::Handle<Value>()); |
11437 v8::Handle<Value> value = CompileRun( | 11534 v8::Handle<Value> value = CompileRun( |
11438 "function f() {" | 11535 "function f() {" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11582 } | 11679 } |
11583 | 11680 |
11584 | 11681 |
11585 static void WebKitLike(Handle<Message> message, Handle<Value> data) { | 11682 static void WebKitLike(Handle<Message> message, Handle<Value> data) { |
11586 Handle<String> errorMessageString = message->Get(); | 11683 Handle<String> errorMessageString = message->Get(); |
11587 CHECK(!errorMessageString.IsEmpty()); | 11684 CHECK(!errorMessageString.IsEmpty()); |
11588 message->GetStackTrace(); | 11685 message->GetStackTrace(); |
11589 message->GetScriptResourceName(); | 11686 message->GetScriptResourceName(); |
11590 } | 11687 } |
11591 | 11688 |
| 11689 |
11592 THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) { | 11690 THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) { |
11593 LocalContext context; | 11691 LocalContext context; |
11594 HandleScope scope(context->GetIsolate()); | 11692 HandleScope scope(context->GetIsolate()); |
11595 | 11693 |
11596 Local<Function> func = | 11694 Local<Function> func = |
11597 FunctionTemplate::New(ThrowingCallbackWithTryCatch)->GetFunction(); | 11695 FunctionTemplate::New(ThrowingCallbackWithTryCatch)->GetFunction(); |
11598 context->Global()->Set(v8_str("func"), func); | 11696 context->Global()->Set(v8_str("func"), func); |
11599 | 11697 |
11600 MessageCallback callbacks[] = | 11698 MessageCallback callbacks[] = |
11601 { NULL, WebKitLike, ThrowViaApi, ThrowFromJS, WithTryCatch }; | 11699 { NULL, WebKitLike, ThrowViaApi, ThrowFromJS, WithTryCatch }; |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11900 // Lets not be needlessly self-referential. | 11998 // Lets not be needlessly self-referential. |
11901 TEST(Threading1) { | 11999 TEST(Threading1) { |
11902 // TODO(mstarzinger): Disabled in GC stress mode for now, we should find the | 12000 // TODO(mstarzinger): Disabled in GC stress mode for now, we should find the |
11903 // correct timeout for this an re-enable this test again | 12001 // correct timeout for this an re-enable this test again |
11904 if (i::FLAG_stress_compaction) return; | 12002 if (i::FLAG_stress_compaction) return; |
11905 ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART); | 12003 ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART); |
11906 ApiTestFuzzer::RunAllTests(); | 12004 ApiTestFuzzer::RunAllTests(); |
11907 ApiTestFuzzer::TearDown(); | 12005 ApiTestFuzzer::TearDown(); |
11908 } | 12006 } |
11909 | 12007 |
| 12008 |
11910 TEST(Threading2) { | 12009 TEST(Threading2) { |
11911 ApiTestFuzzer::SetUp(ApiTestFuzzer::SECOND_PART); | 12010 ApiTestFuzzer::SetUp(ApiTestFuzzer::SECOND_PART); |
11912 ApiTestFuzzer::RunAllTests(); | 12011 ApiTestFuzzer::RunAllTests(); |
11913 ApiTestFuzzer::TearDown(); | 12012 ApiTestFuzzer::TearDown(); |
11914 } | 12013 } |
11915 | 12014 |
| 12015 |
11916 TEST(Threading3) { | 12016 TEST(Threading3) { |
11917 ApiTestFuzzer::SetUp(ApiTestFuzzer::THIRD_PART); | 12017 ApiTestFuzzer::SetUp(ApiTestFuzzer::THIRD_PART); |
11918 ApiTestFuzzer::RunAllTests(); | 12018 ApiTestFuzzer::RunAllTests(); |
11919 ApiTestFuzzer::TearDown(); | 12019 ApiTestFuzzer::TearDown(); |
11920 } | 12020 } |
11921 | 12021 |
| 12022 |
11922 TEST(Threading4) { | 12023 TEST(Threading4) { |
11923 ApiTestFuzzer::SetUp(ApiTestFuzzer::FOURTH_PART); | 12024 ApiTestFuzzer::SetUp(ApiTestFuzzer::FOURTH_PART); |
11924 ApiTestFuzzer::RunAllTests(); | 12025 ApiTestFuzzer::RunAllTests(); |
11925 ApiTestFuzzer::TearDown(); | 12026 ApiTestFuzzer::TearDown(); |
11926 } | 12027 } |
11927 | 12028 |
| 12029 |
11928 void ApiTestFuzzer::CallTest() { | 12030 void ApiTestFuzzer::CallTest() { |
11929 if (kLogThreading) | 12031 if (kLogThreading) |
11930 printf("Start test %d\n", test_number_); | 12032 printf("Start test %d\n", test_number_); |
11931 CallTestNumber(test_number_); | 12033 CallTestNumber(test_number_); |
11932 if (kLogThreading) | 12034 if (kLogThreading) |
11933 printf("End test %d\n", test_number_); | 12035 printf("End test %d\n", test_number_); |
11934 } | 12036 } |
11935 | 12037 |
11936 | 12038 |
11937 static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) { | 12039 static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) { |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12256 v8::HandleScope outer(isolate); | 12358 v8::HandleScope outer(isolate); |
12257 v8::Local<Context> env = Context::New(isolate); | 12359 v8::Local<Context> env = Context::New(isolate); |
12258 env->Enter(); | 12360 env->Enter(); |
12259 v8::Handle<Value> value = NestedScope(env); | 12361 v8::Handle<Value> value = NestedScope(env); |
12260 v8::Handle<String> str(value->ToString()); | 12362 v8::Handle<String> str(value->ToString()); |
12261 CHECK(!str.IsEmpty()); | 12363 CHECK(!str.IsEmpty()); |
12262 env->Exit(); | 12364 env->Exit(); |
12263 } | 12365 } |
12264 | 12366 |
12265 | 12367 |
12266 static i::Handle<i::JSFunction>* foo_ptr = NULL; | 12368 static bool MatchPointers(void* key1, void* key2) { |
12267 static int foo_entry_count = 0; | 12369 return key1 == key2; |
12268 static i::Handle<i::JSFunction>* bar_ptr = NULL; | 12370 } |
12269 static int bar_entry_count = 0; | 12371 |
12270 static int bar_caller_count = 0; | 12372 |
12271 | 12373 struct SymbolInfo { |
12272 | 12374 size_t id; |
12273 static void entry_hook(uintptr_t function, | 12375 size_t size; |
12274 uintptr_t return_addr_location) { | 12376 std::string name; |
12275 i::Code* code = i::Code::GetCodeFromTargetAddress( | 12377 }; |
| 12378 |
| 12379 |
| 12380 class SetFunctionEntryHookTest { |
| 12381 public: |
| 12382 SetFunctionEntryHookTest() { |
| 12383 CHECK(instance_ == NULL); |
| 12384 instance_ = this; |
| 12385 } |
| 12386 ~SetFunctionEntryHookTest() { |
| 12387 CHECK(instance_ == this); |
| 12388 instance_ = NULL; |
| 12389 } |
| 12390 void Reset() { |
| 12391 symbols_.clear(); |
| 12392 symbol_locations_.clear(); |
| 12393 invocations_.clear(); |
| 12394 } |
| 12395 void RunTest(); |
| 12396 void OnJitEvent(const v8::JitCodeEvent* event); |
| 12397 static void JitEvent(const v8::JitCodeEvent* event) { |
| 12398 CHECK(instance_ != NULL); |
| 12399 instance_->OnJitEvent(event); |
| 12400 } |
| 12401 |
| 12402 void OnEntryHook(uintptr_t function, |
| 12403 uintptr_t return_addr_location); |
| 12404 static void EntryHook(uintptr_t function, |
| 12405 uintptr_t return_addr_location) { |
| 12406 CHECK(instance_ != NULL); |
| 12407 instance_->OnEntryHook(function, return_addr_location); |
| 12408 } |
| 12409 |
| 12410 static void RuntimeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 12411 CHECK(instance_ != NULL); |
| 12412 args.GetReturnValue().Set(v8_num(42)); |
| 12413 } |
| 12414 void RunLoopInNewEnv(v8::Isolate* isolate); |
| 12415 |
| 12416 // Records addr as location of symbol. |
| 12417 void InsertSymbolAt(i::Address addr, SymbolInfo* symbol); |
| 12418 |
| 12419 // Finds the symbol containing addr |
| 12420 SymbolInfo* FindSymbolForAddr(i::Address addr); |
| 12421 // Returns the number of invocations where the caller name contains |
| 12422 // \p caller_name and the function name contains \p function_name. |
| 12423 int CountInvocations(const char* caller_name, |
| 12424 const char* function_name); |
| 12425 |
| 12426 i::Handle<i::JSFunction> foo_func_; |
| 12427 i::Handle<i::JSFunction> bar_func_; |
| 12428 |
| 12429 typedef std::map<size_t, SymbolInfo> SymbolMap; |
| 12430 typedef std::map<i::Address, SymbolInfo*> SymbolLocationMap; |
| 12431 typedef std::map<std::pair<SymbolInfo*, SymbolInfo*>, int> InvocationMap; |
| 12432 SymbolMap symbols_; |
| 12433 SymbolLocationMap symbol_locations_; |
| 12434 InvocationMap invocations_; |
| 12435 |
| 12436 static SetFunctionEntryHookTest* instance_; |
| 12437 }; |
| 12438 SetFunctionEntryHookTest* SetFunctionEntryHookTest::instance_ = NULL; |
| 12439 |
| 12440 |
| 12441 // Returns true if addr is in the range [start, start+len). |
| 12442 static bool Overlaps(i::Address start, size_t len, i::Address addr) { |
| 12443 if (start <= addr && start + len > addr) |
| 12444 return true; |
| 12445 |
| 12446 return false; |
| 12447 } |
| 12448 |
| 12449 void SetFunctionEntryHookTest::InsertSymbolAt(i::Address addr, |
| 12450 SymbolInfo* symbol) { |
| 12451 // Insert the symbol at the new location. |
| 12452 SymbolLocationMap::iterator it = |
| 12453 symbol_locations_.insert(std::make_pair(addr, symbol)).first; |
| 12454 // Now erase symbols to the left and right that overlap this one. |
| 12455 while (it != symbol_locations_.begin()) { |
| 12456 SymbolLocationMap::iterator left = it; |
| 12457 --left; |
| 12458 if (!Overlaps(left->first, left->second->size, addr)) |
| 12459 break; |
| 12460 symbol_locations_.erase(left); |
| 12461 } |
| 12462 |
| 12463 // Now erase symbols to the left and right that overlap this one. |
| 12464 while (true) { |
| 12465 SymbolLocationMap::iterator right = it; |
| 12466 ++right; |
| 12467 if (right == symbol_locations_.end()) |
| 12468 break; |
| 12469 if (!Overlaps(addr, symbol->size, right->first)) |
| 12470 break; |
| 12471 symbol_locations_.erase(right); |
| 12472 } |
| 12473 } |
| 12474 |
| 12475 |
| 12476 void SetFunctionEntryHookTest::OnJitEvent(const v8::JitCodeEvent* event) { |
| 12477 switch (event->type) { |
| 12478 case v8::JitCodeEvent::CODE_ADDED: { |
| 12479 CHECK(event->code_start != NULL); |
| 12480 CHECK_NE(0, static_cast<int>(event->code_len)); |
| 12481 CHECK(event->name.str != NULL); |
| 12482 size_t symbol_id = symbols_.size(); |
| 12483 |
| 12484 // Record the new symbol. |
| 12485 SymbolInfo& info = symbols_[symbol_id]; |
| 12486 info.id = symbol_id; |
| 12487 info.size = event->code_len; |
| 12488 info.name.assign(event->name.str, event->name.str + event->name.len); |
| 12489 |
| 12490 // And record it's location. |
| 12491 InsertSymbolAt(reinterpret_cast<i::Address>(event->code_start), &info); |
| 12492 } |
| 12493 break; |
| 12494 |
| 12495 case v8::JitCodeEvent::CODE_MOVED: { |
| 12496 // We would like to never see code move that we haven't seen before, |
| 12497 // but the code creation event does not happen until the line endings |
| 12498 // have been calculated (this is so that we can report the line in the |
| 12499 // script at which the function source is found, see |
| 12500 // Compiler::RecordFunctionCompilation) and the line endings |
| 12501 // calculations can cause a GC, which can move the newly created code |
| 12502 // before its existence can be logged. |
| 12503 SymbolLocationMap::iterator it( |
| 12504 symbol_locations_.find( |
| 12505 reinterpret_cast<i::Address>(event->code_start))); |
| 12506 if (it != symbol_locations_.end()) { |
| 12507 // Found a symbol at this location, move it. |
| 12508 SymbolInfo* info = it->second; |
| 12509 symbol_locations_.erase(it); |
| 12510 InsertSymbolAt(reinterpret_cast<i::Address>(event->new_code_start), |
| 12511 info); |
| 12512 } |
| 12513 } |
| 12514 default: |
| 12515 break; |
| 12516 } |
| 12517 } |
| 12518 |
| 12519 void SetFunctionEntryHookTest::OnEntryHook( |
| 12520 uintptr_t function, uintptr_t return_addr_location) { |
| 12521 // Get the function's code object. |
| 12522 i::Code* function_code = i::Code::GetCodeFromTargetAddress( |
12276 reinterpret_cast<i::Address>(function)); | 12523 reinterpret_cast<i::Address>(function)); |
12277 CHECK(code != NULL); | 12524 CHECK(function_code != NULL); |
12278 | 12525 |
12279 if (bar_ptr != NULL && code == (*bar_ptr)->code()) | 12526 // Then try and look up the caller's code object. |
12280 ++bar_entry_count; | 12527 i::Address caller = *reinterpret_cast<i::Address*>(return_addr_location); |
12281 | 12528 |
12282 if (foo_ptr != NULL && code == (*foo_ptr)->code()) | 12529 // Count the invocation. |
12283 ++foo_entry_count; | 12530 SymbolInfo* caller_symbol = FindSymbolForAddr(caller); |
12284 | 12531 SymbolInfo* function_symbol = |
12285 // Let's check whether bar is the caller. | 12532 FindSymbolForAddr(reinterpret_cast<i::Address>(function)); |
12286 if (bar_ptr != NULL) { | 12533 ++invocations_[std::make_pair(caller_symbol, function_symbol)]; |
12287 const v8::internal::byte* caller = | 12534 |
12288 *reinterpret_cast<v8::internal::byte**>(return_addr_location); | 12535 if (!bar_func_.is_null() && function_code == bar_func_->code()) { |
12289 | 12536 // Check that we have a symbol for the "bar" function at the right location. |
12290 if ((*bar_ptr)->code()->instruction_start() <= caller && | 12537 SymbolLocationMap::iterator it( |
12291 (*bar_ptr)->code()->instruction_end() > caller) { | 12538 symbol_locations_.find(function_code->instruction_start())); |
12292 ++bar_caller_count; | 12539 CHECK(it != symbol_locations_.end()); |
| 12540 } |
| 12541 |
| 12542 if (!foo_func_.is_null() && function_code == foo_func_->code()) { |
| 12543 // Check that we have a symbol for "foo" at the right location. |
| 12544 SymbolLocationMap::iterator it( |
| 12545 symbol_locations_.find(function_code->instruction_start())); |
| 12546 CHECK(it != symbol_locations_.end()); |
| 12547 } |
| 12548 } |
| 12549 |
| 12550 |
| 12551 SymbolInfo* SetFunctionEntryHookTest::FindSymbolForAddr(i::Address addr) { |
| 12552 SymbolLocationMap::iterator it(symbol_locations_.lower_bound(addr)); |
| 12553 // Do we have a direct hit on a symbol? |
| 12554 if (it != symbol_locations_.end()) { |
| 12555 if (it->first == addr) |
| 12556 return it->second; |
| 12557 } |
| 12558 |
| 12559 // If not a direct hit, it'll have to be the previous symbol. |
| 12560 if (it == symbol_locations_.begin()) |
| 12561 return NULL; |
| 12562 |
| 12563 --it; |
| 12564 size_t offs = addr - it->first; |
| 12565 if (offs < it->second->size) |
| 12566 return it->second; |
| 12567 |
| 12568 return NULL; |
| 12569 } |
| 12570 |
| 12571 |
| 12572 int SetFunctionEntryHookTest::CountInvocations( |
| 12573 const char* caller_name, const char* function_name) { |
| 12574 InvocationMap::iterator it(invocations_.begin()); |
| 12575 int invocations = 0; |
| 12576 for (; it != invocations_.end(); ++it) { |
| 12577 SymbolInfo* caller = it->first.first; |
| 12578 SymbolInfo* function = it->first.second; |
| 12579 |
| 12580 // Filter out non-matching functions. |
| 12581 if (function_name != NULL) { |
| 12582 if (function->name.find(function_name) == std::string::npos) |
| 12583 continue; |
12293 } | 12584 } |
12294 } | 12585 |
12295 } | 12586 // Filter out non-matching callers. |
12296 | 12587 if (caller_name != NULL) { |
12297 | 12588 if (caller == NULL) |
12298 static void RunLoopInNewEnv() { | 12589 continue; |
12299 bar_ptr = NULL; | 12590 if (caller->name.find(caller_name) == std::string::npos) |
12300 foo_ptr = NULL; | 12591 continue; |
12301 | 12592 } |
12302 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 12593 |
| 12594 // It matches add the invocation count to the tally. |
| 12595 invocations += it->second; |
| 12596 } |
| 12597 |
| 12598 return invocations; |
| 12599 } |
| 12600 |
| 12601 |
| 12602 void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) { |
12303 v8::HandleScope outer(isolate); | 12603 v8::HandleScope outer(isolate); |
12304 v8::Local<Context> env = Context::New(isolate); | 12604 v8::Local<Context> env = Context::New(isolate); |
12305 env->Enter(); | 12605 env->Enter(); |
12306 | 12606 |
| 12607 Local<ObjectTemplate> t = ObjectTemplate::New(); |
| 12608 t->Set(v8_str("asdf"), v8::FunctionTemplate::New(RuntimeCallback)); |
| 12609 env->Global()->Set(v8_str("obj"), t->NewInstance()); |
| 12610 |
12307 const char* script = | 12611 const char* script = |
12308 "function bar() {" | 12612 "function bar() {\n" |
12309 " var sum = 0;" | 12613 " var sum = 0;\n" |
12310 " for (i = 0; i < 100; ++i)" | 12614 " for (i = 0; i < 100; ++i)\n" |
12311 " sum = foo(i);" | 12615 " sum = foo(i);\n" |
12312 " return sum;" | 12616 " return sum;\n" |
12313 "}" | 12617 "}\n" |
12314 "function foo(i) { return i * i; }"; | 12618 "function foo(i) { return i * i; }\n" |
| 12619 "// Invoke on the runtime function.\n" |
| 12620 "obj.asdf()"; |
12315 CompileRun(script); | 12621 CompileRun(script); |
12316 i::Handle<i::JSFunction> bar = | 12622 bar_func_ = i::Handle<i::JSFunction>::cast( |
12317 i::Handle<i::JSFunction>::cast( | |
12318 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); | 12623 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); |
12319 ASSERT(*bar); | 12624 ASSERT(!bar_func_.is_null()); |
12320 | 12625 |
12321 i::Handle<i::JSFunction> foo = | 12626 foo_func_ = |
12322 i::Handle<i::JSFunction>::cast( | 12627 i::Handle<i::JSFunction>::cast( |
12323 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); | 12628 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); |
12324 ASSERT(*foo); | 12629 ASSERT(!foo_func_.is_null()); |
12325 | |
12326 bar_ptr = &bar; | |
12327 foo_ptr = &foo; | |
12328 | 12630 |
12329 v8::Handle<v8::Value> value = CompileRun("bar();"); | 12631 v8::Handle<v8::Value> value = CompileRun("bar();"); |
12330 CHECK(value->IsNumber()); | 12632 CHECK(value->IsNumber()); |
12331 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); | 12633 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); |
12332 | 12634 |
12333 // Test the optimized codegen path. | 12635 // Test the optimized codegen path. |
12334 value = CompileRun("%OptimizeFunctionOnNextCall(foo);" | 12636 value = CompileRun("%OptimizeFunctionOnNextCall(foo);" |
12335 "bar();"); | 12637 "bar();"); |
12336 CHECK(value->IsNumber()); | 12638 CHECK(value->IsNumber()); |
12337 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); | 12639 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); |
12338 | 12640 |
12339 env->Exit(); | 12641 env->Exit(); |
12340 } | 12642 } |
12341 | 12643 |
12342 | 12644 |
| 12645 void SetFunctionEntryHookTest::RunTest() { |
| 12646 // Work in a new isolate throughout. |
| 12647 v8::Isolate* isolate = v8::Isolate::New(); |
| 12648 |
| 12649 // Test setting the entry hook on the new isolate. |
| 12650 CHECK(v8::V8::SetFunctionEntryHook(isolate, EntryHook)); |
| 12651 |
| 12652 // Replacing the hook, once set should fail. |
| 12653 CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook)); |
| 12654 |
| 12655 { |
| 12656 v8::Isolate::Scope scope(isolate); |
| 12657 |
| 12658 v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, JitEvent); |
| 12659 |
| 12660 RunLoopInNewEnv(isolate); |
| 12661 |
| 12662 // Check the exepected invocation counts. |
| 12663 CHECK_EQ(2, CountInvocations(NULL, "bar")); |
| 12664 CHECK_EQ(200, CountInvocations("bar", "foo")); |
| 12665 CHECK_EQ(200, CountInvocations(NULL, "foo")); |
| 12666 |
| 12667 // Verify that we have an entry hook on some specific stubs. |
| 12668 CHECK_NE(0, CountInvocations(NULL, "CEntryStub")); |
| 12669 CHECK_NE(0, CountInvocations(NULL, "JSEntryStub")); |
| 12670 CHECK_NE(0, CountInvocations(NULL, "JSEntryTrampoline")); |
| 12671 } |
| 12672 isolate->Dispose(); |
| 12673 |
| 12674 Reset(); |
| 12675 |
| 12676 // Make sure a second isolate is unaffected by the previous entry hook. |
| 12677 isolate = v8::Isolate::New(); |
| 12678 { |
| 12679 v8::Isolate::Scope scope(isolate); |
| 12680 |
| 12681 // Reset the entry count to zero and set the entry hook. |
| 12682 RunLoopInNewEnv(isolate); |
| 12683 |
| 12684 // We should record no invocations in this isolate. |
| 12685 CHECK_EQ(0, static_cast<int>(invocations_.size())); |
| 12686 } |
| 12687 // Since the isolate has been used, we shouldn't be able to set an entry |
| 12688 // hook anymore. |
| 12689 CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook)); |
| 12690 |
| 12691 isolate->Dispose(); |
| 12692 } |
| 12693 |
| 12694 |
12343 TEST(SetFunctionEntryHook) { | 12695 TEST(SetFunctionEntryHook) { |
12344 // FunctionEntryHook does not work well with experimental natives. | 12696 // FunctionEntryHook does not work well with experimental natives. |
12345 // Experimental natives are compiled during snapshot deserialization. | 12697 // Experimental natives are compiled during snapshot deserialization. |
12346 // This test breaks because InstallGetter (function from snapshot that | 12698 // This test breaks because InstallGetter (function from snapshot that |
12347 // only gets called from experimental natives) is compiled with entry hooks. | 12699 // only gets called from experimental natives) is compiled with entry hooks. |
12348 i::FLAG_harmony_typed_arrays = false; | 12700 i::FLAG_harmony_typed_arrays = false; |
12349 i::FLAG_harmony_array_buffer = false; | 12701 i::FLAG_harmony_array_buffer = false; |
12350 | 12702 |
12351 i::FLAG_allow_natives_syntax = true; | 12703 i::FLAG_allow_natives_syntax = true; |
12352 i::FLAG_use_inlining = false; | 12704 i::FLAG_use_inlining = false; |
12353 | 12705 |
12354 // Test setting and resetting the entry hook. | 12706 SetFunctionEntryHookTest test; |
12355 // Nulling it should always succeed. | 12707 test.RunTest(); |
12356 CHECK(v8::V8::SetFunctionEntryHook(NULL)); | |
12357 | |
12358 CHECK(v8::V8::SetFunctionEntryHook(entry_hook)); | |
12359 // Setting a hook while one's active should fail. | |
12360 CHECK_EQ(false, v8::V8::SetFunctionEntryHook(entry_hook)); | |
12361 | |
12362 CHECK(v8::V8::SetFunctionEntryHook(NULL)); | |
12363 | |
12364 // Reset the entry count to zero and set the entry hook. | |
12365 bar_entry_count = 0; | |
12366 bar_caller_count = 0; | |
12367 foo_entry_count = 0; | |
12368 CHECK(v8::V8::SetFunctionEntryHook(entry_hook)); | |
12369 RunLoopInNewEnv(); | |
12370 | |
12371 CHECK_EQ(2, bar_entry_count); | |
12372 CHECK_EQ(200, bar_caller_count); | |
12373 CHECK_EQ(200, foo_entry_count); | |
12374 | |
12375 // Clear the entry hook and count. | |
12376 bar_entry_count = 0; | |
12377 bar_caller_count = 0; | |
12378 foo_entry_count = 0; | |
12379 v8::V8::SetFunctionEntryHook(NULL); | |
12380 | |
12381 // Clear the compilation cache to make sure we don't reuse the | |
12382 // functions from the previous invocation. | |
12383 v8::internal::Isolate::Current()->compilation_cache()->Clear(); | |
12384 | |
12385 // Verify that entry hooking is now disabled. | |
12386 RunLoopInNewEnv(); | |
12387 CHECK_EQ(0u, bar_entry_count); | |
12388 CHECK_EQ(0u, bar_caller_count); | |
12389 CHECK_EQ(0u, foo_entry_count); | |
12390 } | 12708 } |
12391 | 12709 |
12392 | 12710 |
12393 static i::HashMap* code_map = NULL; | 12711 static i::HashMap* code_map = NULL; |
12394 static i::HashMap* jitcode_line_info = NULL; | 12712 static i::HashMap* jitcode_line_info = NULL; |
12395 static int saw_bar = 0; | 12713 static int saw_bar = 0; |
12396 static int move_events = 0; | 12714 static int move_events = 0; |
12397 | 12715 |
12398 | 12716 |
12399 static bool FunctionNameIs(const char* expected, | 12717 static bool FunctionNameIs(const char* expected, |
12400 const v8::JitCodeEvent* event) { | 12718 const v8::JitCodeEvent* event) { |
12401 // Log lines for functions are of the general form: | 12719 // Log lines for functions are of the general form: |
12402 // "LazyCompile:<type><function_name>", where the type is one of | 12720 // "LazyCompile:<type><function_name>", where the type is one of |
12403 // "*", "~" or "". | 12721 // "*", "~" or "". |
12404 static const char kPreamble[] = "LazyCompile:"; | 12722 static const char kPreamble[] = "LazyCompile:"; |
12405 static size_t kPreambleLen = sizeof(kPreamble) - 1; | 12723 static size_t kPreambleLen = sizeof(kPreamble) - 1; |
12406 | 12724 |
12407 if (event->name.len < sizeof(kPreamble) - 1 || | 12725 if (event->name.len < sizeof(kPreamble) - 1 || |
12408 strncmp(kPreamble, event->name.str, kPreambleLen) != 0) { | 12726 strncmp(kPreamble, event->name.str, kPreambleLen) != 0) { |
12409 return false; | 12727 return false; |
12410 } | 12728 } |
12411 | 12729 |
12412 const char* tail = event->name.str + kPreambleLen; | 12730 const char* tail = event->name.str + kPreambleLen; |
12413 size_t tail_len = event->name.len - kPreambleLen; | 12731 size_t tail_len = event->name.len - kPreambleLen; |
12414 size_t expected_len = strlen(expected); | 12732 size_t expected_len = strlen(expected); |
12415 if (tail_len == expected_len + 1) { | 12733 if (tail_len > 1 && (*tail == '*' || *tail == '~')) { |
12416 if (*tail == '*' || *tail == '~') { | 12734 --tail_len; |
12417 --tail_len; | 12735 ++tail; |
12418 ++tail; | 12736 } |
12419 } else { | 12737 |
12420 return false; | 12738 // Check for tails like 'bar :1'. |
12421 } | 12739 if (tail_len > expected_len + 2 && |
| 12740 tail[expected_len] == ' ' && |
| 12741 tail[expected_len + 1] == ':' && |
| 12742 tail[expected_len + 2] && |
| 12743 !strncmp(tail, expected, expected_len)) { |
| 12744 return true; |
12422 } | 12745 } |
12423 | 12746 |
12424 if (tail_len != expected_len) | 12747 if (tail_len != expected_len) |
12425 return false; | 12748 return false; |
12426 | 12749 |
12427 return strncmp(tail, expected, expected_len) == 0; | 12750 return strncmp(tail, expected, expected_len) == 0; |
12428 } | 12751 } |
12429 | 12752 |
12430 | 12753 |
12431 static void event_handler(const v8::JitCodeEvent* event) { | 12754 static void event_handler(const v8::JitCodeEvent* event) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12521 break; | 12844 break; |
12522 | 12845 |
12523 default: | 12846 default: |
12524 // Impossible event. | 12847 // Impossible event. |
12525 CHECK(false); | 12848 CHECK(false); |
12526 break; | 12849 break; |
12527 } | 12850 } |
12528 } | 12851 } |
12529 | 12852 |
12530 | 12853 |
12531 static bool MatchPointers(void* key1, void* key2) { | |
12532 return key1 == key2; | |
12533 } | |
12534 | |
12535 | |
12536 TEST(SetJitCodeEventHandler) { | 12854 TEST(SetJitCodeEventHandler) { |
12537 i::FLAG_stress_compaction = true; | 12855 i::FLAG_stress_compaction = true; |
12538 i::FLAG_incremental_marking = false; | 12856 i::FLAG_incremental_marking = false; |
12539 const char* script = | 12857 const char* script = |
12540 "function bar() {" | 12858 "function bar() {" |
12541 " var sum = 0;" | 12859 " var sum = 0;" |
12542 " for (i = 0; i < 100; ++i)" | 12860 " for (i = 0; i < 100; ++i)" |
12543 " sum = foo(i);" | 12861 " sum = foo(i);" |
12544 " return sum;" | 12862 " return sum;" |
12545 "}" | 12863 "}" |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12865 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); | 13183 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); |
12866 CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); | 13184 CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); |
12867 int elmc3 = 4; | 13185 int elmc3 = 4; |
12868 const char* elmv3[] = {"w", "z", "x", "y"}; | 13186 const char* elmv3[] = {"w", "z", "x", "y"}; |
12869 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); | 13187 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); |
12870 int elmc4 = 2; | 13188 int elmc4 = 2; |
12871 const char* elmv4[] = {"w", "z"}; | 13189 const char* elmv4[] = {"w", "z"}; |
12872 CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4); | 13190 CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4); |
12873 } | 13191 } |
12874 | 13192 |
| 13193 |
12875 THREADED_TEST(PropertyEnumeration2) { | 13194 THREADED_TEST(PropertyEnumeration2) { |
12876 LocalContext context; | 13195 LocalContext context; |
12877 v8::HandleScope scope(context->GetIsolate()); | 13196 v8::HandleScope scope(context->GetIsolate()); |
12878 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( | 13197 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( |
12879 "var result = [];" | 13198 "var result = [];" |
12880 "result[0] = {};" | 13199 "result[0] = {};" |
12881 "result[1] = {a: 1, b: 2};" | 13200 "result[1] = {a: 1, b: 2};" |
12882 "result[2] = [1, 2, 3];" | 13201 "result[2] = [1, 2, 3];" |
12883 "var proto = {x: 1, y: 2, z: 3};" | 13202 "var proto = {x: 1, y: 2, z: 3};" |
12884 "var x = { __proto__: proto, w: 0, z: 1 };" | 13203 "var x = { __proto__: proto, w: 0, z: 1 };" |
(...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13973 } | 14292 } |
13974 | 14293 |
13975 static void ForceSetInterceptSetter( | 14294 static void ForceSetInterceptSetter( |
13976 v8::Local<v8::String> name, | 14295 v8::Local<v8::String> name, |
13977 v8::Local<v8::Value> value, | 14296 v8::Local<v8::Value> value, |
13978 const v8::PropertyCallbackInfo<v8::Value>& info) { | 14297 const v8::PropertyCallbackInfo<v8::Value>& info) { |
13979 force_set_set_count++; | 14298 force_set_set_count++; |
13980 info.GetReturnValue().SetUndefined(); | 14299 info.GetReturnValue().SetUndefined(); |
13981 } | 14300 } |
13982 | 14301 |
| 14302 |
13983 TEST(ForceSet) { | 14303 TEST(ForceSet) { |
13984 force_set_get_count = 0; | 14304 force_set_get_count = 0; |
13985 force_set_set_count = 0; | 14305 force_set_set_count = 0; |
13986 pass_on_get = false; | 14306 pass_on_get = false; |
13987 | 14307 |
13988 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 14308 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
13989 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); | 14309 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |
13990 v8::Handle<v8::String> access_property = v8::String::New("a"); | 14310 v8::Handle<v8::String> access_property = v8::String::New("a"); |
13991 templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter); | 14311 templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter); |
13992 LocalContext context(NULL, templ); | 14312 LocalContext context(NULL, templ); |
(...skipping 21 matching lines...) Expand all Loading... |
14014 CHECK_EQ(1, force_set_set_count); | 14334 CHECK_EQ(1, force_set_set_count); |
14015 CHECK_EQ(2, force_set_get_count); | 14335 CHECK_EQ(2, force_set_get_count); |
14016 // Forcing the property to be set should override the accessor without | 14336 // Forcing the property to be set should override the accessor without |
14017 // calling it | 14337 // calling it |
14018 global->ForceSet(access_property, v8::Int32::New(8)); | 14338 global->ForceSet(access_property, v8::Int32::New(8)); |
14019 CHECK_EQ(8, global->Get(access_property)->Int32Value()); | 14339 CHECK_EQ(8, global->Get(access_property)->Int32Value()); |
14020 CHECK_EQ(1, force_set_set_count); | 14340 CHECK_EQ(1, force_set_set_count); |
14021 CHECK_EQ(2, force_set_get_count); | 14341 CHECK_EQ(2, force_set_get_count); |
14022 } | 14342 } |
14023 | 14343 |
| 14344 |
14024 TEST(ForceSetWithInterceptor) { | 14345 TEST(ForceSetWithInterceptor) { |
14025 force_set_get_count = 0; | 14346 force_set_get_count = 0; |
14026 force_set_set_count = 0; | 14347 force_set_set_count = 0; |
14027 pass_on_get = false; | 14348 pass_on_get = false; |
14028 | 14349 |
14029 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 14350 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
14030 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); | 14351 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |
14031 templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter); | 14352 templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter); |
14032 LocalContext context(NULL, templ); | 14353 LocalContext context(NULL, templ); |
14033 v8::Handle<v8::Object> global = context->Global(); | 14354 v8::Handle<v8::Object> global = context->Global(); |
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15473 i::ScopedVector<ElementType> backing_store(kElementCount+2); | 15794 i::ScopedVector<ElementType> backing_store(kElementCount+2); |
15474 | 15795 |
15475 LocalContext env; | 15796 LocalContext env; |
15476 v8::Isolate* isolate = env->GetIsolate(); | 15797 v8::Isolate* isolate = env->GetIsolate(); |
15477 v8::HandleScope handle_scope(isolate); | 15798 v8::HandleScope handle_scope(isolate); |
15478 | 15799 |
15479 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( | 15800 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( |
15480 backing_store.start(), (kElementCount+2)*sizeof(ElementType)); | 15801 backing_store.start(), (kElementCount+2)*sizeof(ElementType)); |
15481 Local<TypedArray> ta = | 15802 Local<TypedArray> ta = |
15482 TypedArray::New(ab, 2*sizeof(ElementType), kElementCount); | 15803 TypedArray::New(ab, 2*sizeof(ElementType), kElementCount); |
| 15804 CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); |
15483 CHECK_EQ(kElementCount, static_cast<int>(ta->Length())); | 15805 CHECK_EQ(kElementCount, static_cast<int>(ta->Length())); |
15484 CHECK_EQ(2*sizeof(ElementType), static_cast<int>(ta->ByteOffset())); | 15806 CHECK_EQ(2*sizeof(ElementType), static_cast<int>(ta->ByteOffset())); |
15485 CHECK_EQ(kElementCount*sizeof(ElementType), | 15807 CHECK_EQ(kElementCount*sizeof(ElementType), |
15486 static_cast<int>(ta->ByteLength())); | 15808 static_cast<int>(ta->ByteLength())); |
15487 CHECK_EQ(ab, ta->Buffer()); | 15809 CHECK_EQ(ab, ta->Buffer()); |
15488 | 15810 |
15489 ElementType* data = backing_store.start() + 2; | 15811 ElementType* data = backing_store.start() + 2; |
15490 for (int i = 0; i < kElementCount; i++) { | 15812 for (int i = 0; i < kElementCount; i++) { |
15491 data[i] = static_cast<ElementType>(i); | 15813 data[i] = static_cast<ElementType>(i); |
15492 } | 15814 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15558 i::ScopedVector<uint8_t> backing_store(kSize+2); | 15880 i::ScopedVector<uint8_t> backing_store(kSize+2); |
15559 | 15881 |
15560 LocalContext env; | 15882 LocalContext env; |
15561 v8::Isolate* isolate = env->GetIsolate(); | 15883 v8::Isolate* isolate = env->GetIsolate(); |
15562 v8::HandleScope handle_scope(isolate); | 15884 v8::HandleScope handle_scope(isolate); |
15563 | 15885 |
15564 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( | 15886 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( |
15565 backing_store.start(), 2 + kSize); | 15887 backing_store.start(), 2 + kSize); |
15566 Local<v8::DataView> dv = | 15888 Local<v8::DataView> dv = |
15567 v8::DataView::New(ab, 2, kSize); | 15889 v8::DataView::New(ab, 2, kSize); |
| 15890 CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); |
15568 CHECK_EQ(2, static_cast<int>(dv->ByteOffset())); | 15891 CHECK_EQ(2, static_cast<int>(dv->ByteOffset())); |
15569 CHECK_EQ(kSize, static_cast<int>(dv->ByteLength())); | 15892 CHECK_EQ(kSize, static_cast<int>(dv->ByteLength())); |
15570 CHECK_EQ(ab, dv->Buffer()); | 15893 CHECK_EQ(ab, dv->Buffer()); |
15571 } | 15894 } |
15572 | 15895 |
15573 | 15896 |
15574 #define IS_ARRAY_BUFFER_VIEW_TEST(View) \ | 15897 #define IS_ARRAY_BUFFER_VIEW_TEST(View) \ |
15575 THREADED_TEST(Is##View) { \ | 15898 THREADED_TEST(Is##View) { \ |
15576 i::FLAG_harmony_array_buffer = true; \ | 15899 i::FLAG_harmony_array_buffer = true; \ |
15577 i::FLAG_harmony_typed_arrays = true; \ | 15900 i::FLAG_harmony_typed_arrays = true; \ |
15578 LocalContext env; \ | 15901 LocalContext env; \ |
15579 v8::Isolate* isolate = env->GetIsolate(); \ | 15902 v8::Isolate* isolate = env->GetIsolate(); \ |
15580 v8::HandleScope handle_scope(isolate); \ | 15903 v8::HandleScope handle_scope(isolate); \ |
15581 \ | 15904 \ |
15582 Handle<Value> result = CompileRun( \ | 15905 Handle<Value> result = CompileRun( \ |
15583 "var ab = new ArrayBuffer(128);" \ | 15906 "var ab = new ArrayBuffer(128);" \ |
15584 "new " #View "(ab)"); \ | 15907 "new " #View "(ab)"); \ |
15585 CHECK(result->IsArrayBufferView()); \ | 15908 CHECK(result->IsArrayBufferView()); \ |
15586 CHECK(result->Is##View()); \ | 15909 CHECK(result->Is##View()); \ |
| 15910 CheckInternalFieldsAreZero<v8::ArrayBufferView>(result.As<v8::View>()); \ |
15587 } | 15911 } |
15588 | 15912 |
15589 IS_ARRAY_BUFFER_VIEW_TEST(Uint8Array) | 15913 IS_ARRAY_BUFFER_VIEW_TEST(Uint8Array) |
15590 IS_ARRAY_BUFFER_VIEW_TEST(Int8Array) | 15914 IS_ARRAY_BUFFER_VIEW_TEST(Int8Array) |
15591 IS_ARRAY_BUFFER_VIEW_TEST(Uint16Array) | 15915 IS_ARRAY_BUFFER_VIEW_TEST(Uint16Array) |
15592 IS_ARRAY_BUFFER_VIEW_TEST(Int16Array) | 15916 IS_ARRAY_BUFFER_VIEW_TEST(Int16Array) |
15593 IS_ARRAY_BUFFER_VIEW_TEST(Uint32Array) | 15917 IS_ARRAY_BUFFER_VIEW_TEST(Uint32Array) |
15594 IS_ARRAY_BUFFER_VIEW_TEST(Int32Array) | 15918 IS_ARRAY_BUFFER_VIEW_TEST(Int32Array) |
15595 IS_ARRAY_BUFFER_VIEW_TEST(Float32Array) | 15919 IS_ARRAY_BUFFER_VIEW_TEST(Float32Array) |
15596 IS_ARRAY_BUFFER_VIEW_TEST(Float64Array) | 15920 IS_ARRAY_BUFFER_VIEW_TEST(Float64Array) |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15758 v8::Handle<v8::Message> message, | 16082 v8::Handle<v8::Message> message, |
15759 v8::Handle<Value>) { | 16083 v8::Handle<Value>) { |
15760 v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); | 16084 v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); |
15761 CHECK_EQ(2, stack_trace->GetFrameCount()); | 16085 CHECK_EQ(2, stack_trace->GetFrameCount()); |
15762 checkStackFrame("origin", "foo", 2, 3, false, false, | 16086 checkStackFrame("origin", "foo", 2, 3, false, false, |
15763 stack_trace->GetFrame(0)); | 16087 stack_trace->GetFrame(0)); |
15764 checkStackFrame("origin", "bar", 5, 3, false, false, | 16088 checkStackFrame("origin", "bar", 5, 3, false, false, |
15765 stack_trace->GetFrame(1)); | 16089 stack_trace->GetFrame(1)); |
15766 } | 16090 } |
15767 | 16091 |
| 16092 |
15768 TEST(CaptureStackTraceForUncaughtException) { | 16093 TEST(CaptureStackTraceForUncaughtException) { |
15769 report_count = 0; | 16094 report_count = 0; |
15770 LocalContext env; | 16095 LocalContext env; |
15771 v8::HandleScope scope(env->GetIsolate()); | 16096 v8::HandleScope scope(env->GetIsolate()); |
15772 v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener); | 16097 v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener); |
15773 v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); | 16098 v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); |
15774 | 16099 |
15775 Script::Compile(v8_str("function foo() {\n" | 16100 Script::Compile(v8_str("function foo() {\n" |
15776 " throw 1;\n" | 16101 " throw 1;\n" |
15777 "};\n" | 16102 "};\n" |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16065 "}\n" | 16390 "}\n" |
16066 "outer()\n%s"; | 16391 "outer()\n%s"; |
16067 | 16392 |
16068 i::ScopedVector<char> code(1024); | 16393 i::ScopedVector<char> code(1024); |
16069 i::OS::SNPrintF(code, source, "//# sourceURL=source_url"); | 16394 i::OS::SNPrintF(code, source, "//# sourceURL=source_url"); |
16070 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); | 16395 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); |
16071 i::OS::SNPrintF(code, source, "//@ sourceURL=source_url"); | 16396 i::OS::SNPrintF(code, source, "//@ sourceURL=source_url"); |
16072 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); | 16397 CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); |
16073 } | 16398 } |
16074 | 16399 |
| 16400 |
16075 static void CreateGarbageInOldSpace() { | 16401 static void CreateGarbageInOldSpace() { |
16076 i::Factory* factory = i::Isolate::Current()->factory(); | 16402 i::Factory* factory = i::Isolate::Current()->factory(); |
16077 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 16403 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
16078 i::AlwaysAllocateScope always_allocate; | 16404 i::AlwaysAllocateScope always_allocate; |
16079 for (int i = 0; i < 1000; i++) { | 16405 for (int i = 0; i < 1000; i++) { |
16080 factory->NewFixedArray(1000, i::TENURED); | 16406 factory->NewFixedArray(1000, i::TENURED); |
16081 } | 16407 } |
16082 } | 16408 } |
16083 | 16409 |
| 16410 |
16084 // Test that idle notification can be handled and eventually returns true. | 16411 // Test that idle notification can be handled and eventually returns true. |
16085 TEST(IdleNotification) { | 16412 TEST(IdleNotification) { |
16086 const intptr_t MB = 1024 * 1024; | 16413 const intptr_t MB = 1024 * 1024; |
16087 LocalContext env; | 16414 LocalContext env; |
16088 v8::HandleScope scope(env->GetIsolate()); | 16415 v8::HandleScope scope(env->GetIsolate()); |
16089 intptr_t initial_size = HEAP->SizeOfObjects(); | 16416 intptr_t initial_size = HEAP->SizeOfObjects(); |
16090 CreateGarbageInOldSpace(); | 16417 CreateGarbageInOldSpace(); |
16091 intptr_t size_with_garbage = HEAP->SizeOfObjects(); | 16418 intptr_t size_with_garbage = HEAP->SizeOfObjects(); |
16092 CHECK_GT(size_with_garbage, initial_size + MB); | 16419 CHECK_GT(size_with_garbage, initial_size + MB); |
16093 bool finished = false; | 16420 bool finished = false; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16291 for (int i = 0; i < 4; i++) { | 16618 for (int i = 0; i < 4; i++) { |
16292 CHECK(found_resource_[i]); | 16619 CHECK(found_resource_[i]); |
16293 } | 16620 } |
16294 } | 16621 } |
16295 | 16622 |
16296 private: | 16623 private: |
16297 v8::String::ExternalStringResource* resource_[4]; | 16624 v8::String::ExternalStringResource* resource_[4]; |
16298 bool found_resource_[4]; | 16625 bool found_resource_[4]; |
16299 }; | 16626 }; |
16300 | 16627 |
| 16628 |
16301 TEST(VisitExternalStrings) { | 16629 TEST(VisitExternalStrings) { |
16302 LocalContext env; | 16630 LocalContext env; |
16303 v8::HandleScope scope(env->GetIsolate()); | 16631 v8::HandleScope scope(env->GetIsolate()); |
16304 const char* string = "Some string"; | 16632 const char* string = "Some string"; |
16305 uint16_t* two_byte_string = AsciiToTwoByteString(string); | 16633 uint16_t* two_byte_string = AsciiToTwoByteString(string); |
16306 TestResource* resource[4]; | 16634 TestResource* resource[4]; |
16307 resource[0] = new TestResource(two_byte_string); | 16635 resource[0] = new TestResource(two_byte_string); |
16308 v8::Local<v8::String> string0 = v8::String::NewExternal(resource[0]); | 16636 v8::Local<v8::String> string0 = v8::String::NewExternal(resource[0]); |
16309 resource[1] = new TestResource(two_byte_string); | 16637 resource[1] = new TestResource(two_byte_string); |
16310 v8::Local<v8::String> string1 = v8::String::NewExternal(resource[1]); | 16638 v8::Local<v8::String> string1 = v8::String::NewExternal(resource[1]); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16350 | 16678 |
16351 | 16679 |
16352 static double DoubleToDateTime(double input) { | 16680 static double DoubleToDateTime(double input) { |
16353 double date_limit = 864e13; | 16681 double date_limit = 864e13; |
16354 if (std::isnan(input) || input < -date_limit || input > date_limit) { | 16682 if (std::isnan(input) || input < -date_limit || input > date_limit) { |
16355 return i::OS::nan_value(); | 16683 return i::OS::nan_value(); |
16356 } | 16684 } |
16357 return (input < 0) ? -(floor(-input)) : floor(input); | 16685 return (input < 0) ? -(floor(-input)) : floor(input); |
16358 } | 16686 } |
16359 | 16687 |
| 16688 |
16360 // We don't have a consistent way to write 64-bit constants syntactically, so we | 16689 // We don't have a consistent way to write 64-bit constants syntactically, so we |
16361 // split them into two 32-bit constants and combine them programmatically. | 16690 // split them into two 32-bit constants and combine them programmatically. |
16362 static double DoubleFromBits(uint32_t high_bits, uint32_t low_bits) { | 16691 static double DoubleFromBits(uint32_t high_bits, uint32_t low_bits) { |
16363 return DoubleFromBits((static_cast<uint64_t>(high_bits) << 32) | low_bits); | 16692 return DoubleFromBits((static_cast<uint64_t>(high_bits) << 32) | low_bits); |
16364 } | 16693 } |
16365 | 16694 |
16366 | 16695 |
16367 THREADED_TEST(QuietSignalingNaNs) { | 16696 THREADED_TEST(QuietSignalingNaNs) { |
16368 LocalContext context; | 16697 LocalContext context; |
16369 v8::HandleScope scope(context->GetIsolate()); | 16698 v8::HandleScope scope(context->GetIsolate()); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16589 | 16918 |
16590 v8::ScriptOrigin script_origin_f = f->GetScriptOrigin(); | 16919 v8::ScriptOrigin script_origin_f = f->GetScriptOrigin(); |
16591 CHECK_EQ("test", *v8::String::Utf8Value(script_origin_f.ResourceName())); | 16920 CHECK_EQ("test", *v8::String::Utf8Value(script_origin_f.ResourceName())); |
16592 CHECK_EQ(0, script_origin_f.ResourceLineOffset()->Int32Value()); | 16921 CHECK_EQ(0, script_origin_f.ResourceLineOffset()->Int32Value()); |
16593 | 16922 |
16594 v8::ScriptOrigin script_origin_g = g->GetScriptOrigin(); | 16923 v8::ScriptOrigin script_origin_g = g->GetScriptOrigin(); |
16595 CHECK_EQ("test", *v8::String::Utf8Value(script_origin_g.ResourceName())); | 16924 CHECK_EQ("test", *v8::String::Utf8Value(script_origin_g.ResourceName())); |
16596 CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value()); | 16925 CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value()); |
16597 } | 16926 } |
16598 | 16927 |
| 16928 |
16599 THREADED_TEST(FunctionGetInferredName) { | 16929 THREADED_TEST(FunctionGetInferredName) { |
16600 LocalContext env; | 16930 LocalContext env; |
16601 v8::HandleScope scope(env->GetIsolate()); | 16931 v8::HandleScope scope(env->GetIsolate()); |
16602 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); | 16932 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); |
16603 v8::Handle<v8::String> script = v8::String::New( | 16933 v8::Handle<v8::String> script = v8::String::New( |
16604 "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;"); | 16934 "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;"); |
16605 v8::Script::Compile(script, &origin)->Run(); | 16935 v8::Script::Compile(script, &origin)->Run(); |
16606 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 16936 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
16607 env->Global()->Get(v8::String::New("f"))); | 16937 env->Global()->Get(v8::String::New("f"))); |
16608 CHECK_EQ("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName())); | 16938 CHECK_EQ("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName())); |
16609 } | 16939 } |
16610 | 16940 |
| 16941 |
16611 THREADED_TEST(ScriptLineNumber) { | 16942 THREADED_TEST(ScriptLineNumber) { |
16612 LocalContext env; | 16943 LocalContext env; |
16613 v8::HandleScope scope(env->GetIsolate()); | 16944 v8::HandleScope scope(env->GetIsolate()); |
16614 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); | 16945 v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); |
16615 v8::Handle<v8::String> script = v8::String::New( | 16946 v8::Handle<v8::String> script = v8::String::New( |
16616 "function f() {}\n\nfunction g() {}"); | 16947 "function f() {}\n\nfunction g() {}"); |
16617 v8::Script::Compile(script, &origin)->Run(); | 16948 v8::Script::Compile(script, &origin)->Run(); |
16618 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 16949 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
16619 env->Global()->Get(v8::String::New("f"))); | 16950 env->Global()->Get(v8::String::New("f"))); |
16620 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( | 16951 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16831 | 17162 |
16832 int prologue_call_count = 0; | 17163 int prologue_call_count = 0; |
16833 int epilogue_call_count = 0; | 17164 int epilogue_call_count = 0; |
16834 int prologue_call_count_second = 0; | 17165 int prologue_call_count_second = 0; |
16835 int epilogue_call_count_second = 0; | 17166 int epilogue_call_count_second = 0; |
16836 | 17167 |
16837 void PrologueCallback(v8::GCType, v8::GCCallbackFlags) { | 17168 void PrologueCallback(v8::GCType, v8::GCCallbackFlags) { |
16838 ++prologue_call_count; | 17169 ++prologue_call_count; |
16839 } | 17170 } |
16840 | 17171 |
| 17172 |
16841 void EpilogueCallback(v8::GCType, v8::GCCallbackFlags) { | 17173 void EpilogueCallback(v8::GCType, v8::GCCallbackFlags) { |
16842 ++epilogue_call_count; | 17174 ++epilogue_call_count; |
16843 } | 17175 } |
16844 | 17176 |
| 17177 |
16845 void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags) { | 17178 void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags) { |
16846 ++prologue_call_count_second; | 17179 ++prologue_call_count_second; |
16847 } | 17180 } |
16848 | 17181 |
| 17182 |
16849 void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags) { | 17183 void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags) { |
16850 ++epilogue_call_count_second; | 17184 ++epilogue_call_count_second; |
16851 } | 17185 } |
16852 | 17186 |
| 17187 |
16853 TEST(GCCallbacks) { | 17188 TEST(GCCallbacks) { |
16854 LocalContext context; | 17189 LocalContext context; |
16855 | 17190 |
16856 v8::V8::AddGCPrologueCallback(PrologueCallback); | 17191 v8::V8::AddGCPrologueCallback(PrologueCallback); |
16857 v8::V8::AddGCEpilogueCallback(EpilogueCallback); | 17192 v8::V8::AddGCEpilogueCallback(EpilogueCallback); |
16858 CHECK_EQ(0, prologue_call_count); | 17193 CHECK_EQ(0, prologue_call_count); |
16859 CHECK_EQ(0, epilogue_call_count); | 17194 CHECK_EQ(0, epilogue_call_count); |
16860 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 17195 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
16861 CHECK_EQ(1, prologue_call_count); | 17196 CHECK_EQ(1, prologue_call_count); |
16862 CHECK_EQ(1, epilogue_call_count); | 17197 CHECK_EQ(1, epilogue_call_count); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17233 | 17568 |
17234 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); | 17569 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); |
17235 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); | 17570 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); |
17236 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); | 17571 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); |
17237 | 17572 |
17238 // Reset the failed access check callback so it does not influence | 17573 // Reset the failed access check callback so it does not influence |
17239 // the other tests. | 17574 // the other tests. |
17240 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); | 17575 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); |
17241 } | 17576 } |
17242 | 17577 |
| 17578 |
17243 TEST(DefaultIsolateGetCurrent) { | 17579 TEST(DefaultIsolateGetCurrent) { |
17244 CHECK(v8::Isolate::GetCurrent() != NULL); | 17580 CHECK(v8::Isolate::GetCurrent() != NULL); |
17245 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 17581 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
17246 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); | 17582 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
17247 printf("*** %s\n", "DefaultIsolateGetCurrent success"); | 17583 printf("*** %s\n", "DefaultIsolateGetCurrent success"); |
17248 } | 17584 } |
17249 | 17585 |
| 17586 |
17250 TEST(IsolateNewDispose) { | 17587 TEST(IsolateNewDispose) { |
17251 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); | 17588 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
17252 v8::Isolate* isolate = v8::Isolate::New(); | 17589 v8::Isolate* isolate = v8::Isolate::New(); |
17253 CHECK(isolate != NULL); | 17590 CHECK(isolate != NULL); |
17254 CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); | 17591 CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
17255 CHECK(current_isolate != isolate); | 17592 CHECK(current_isolate != isolate); |
17256 CHECK(current_isolate == v8::Isolate::GetCurrent()); | 17593 CHECK(current_isolate == v8::Isolate::GetCurrent()); |
17257 | 17594 |
17258 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 17595 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
17259 last_location = last_message = NULL; | 17596 last_location = last_message = NULL; |
17260 isolate->Dispose(); | 17597 isolate->Dispose(); |
17261 CHECK_EQ(last_location, NULL); | 17598 CHECK_EQ(last_location, NULL); |
17262 CHECK_EQ(last_message, NULL); | 17599 CHECK_EQ(last_message, NULL); |
17263 } | 17600 } |
17264 | 17601 |
| 17602 |
17265 TEST(IsolateEnterExitDefault) { | 17603 TEST(IsolateEnterExitDefault) { |
17266 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); | 17604 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
17267 CHECK(current_isolate != NULL); // Default isolate. | 17605 CHECK(current_isolate != NULL); // Default isolate. |
17268 v8::HandleScope scope(current_isolate); | 17606 v8::HandleScope scope(current_isolate); |
17269 LocalContext context; | 17607 LocalContext context; |
17270 ExpectString("'hello'", "hello"); | 17608 ExpectString("'hello'", "hello"); |
17271 current_isolate->Enter(); | 17609 current_isolate->Enter(); |
17272 ExpectString("'still working'", "still working"); | 17610 ExpectString("'still working'", "still working"); |
17273 current_isolate->Exit(); | 17611 current_isolate->Exit(); |
17274 ExpectString("'still working 2'", "still working 2"); | 17612 ExpectString("'still working 2'", "still working 2"); |
17275 current_isolate->Exit(); | 17613 current_isolate->Exit(); |
17276 // Default isolate is always, well, 'default current'. | 17614 // Default isolate is always, well, 'default current'. |
17277 CHECK_EQ(v8::Isolate::GetCurrent(), current_isolate); | 17615 CHECK_EQ(v8::Isolate::GetCurrent(), current_isolate); |
17278 // Still working since default isolate is auto-entering any thread | 17616 // Still working since default isolate is auto-entering any thread |
17279 // that has no isolate and attempts to execute V8 APIs. | 17617 // that has no isolate and attempts to execute V8 APIs. |
17280 ExpectString("'still working 3'", "still working 3"); | 17618 ExpectString("'still working 3'", "still working 3"); |
17281 } | 17619 } |
17282 | 17620 |
| 17621 |
17283 TEST(DisposeDefaultIsolate) { | 17622 TEST(DisposeDefaultIsolate) { |
17284 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 17623 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
17285 | 17624 |
17286 // Run some V8 code to trigger default isolate to become 'current'. | 17625 // Run some V8 code to trigger default isolate to become 'current'. |
17287 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 17626 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
17288 LocalContext context; | 17627 LocalContext context; |
17289 ExpectString("'run some V8'", "run some V8"); | 17628 ExpectString("'run some V8'", "run some V8"); |
17290 | 17629 |
17291 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 17630 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
17292 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); | 17631 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
17293 last_location = last_message = NULL; | 17632 last_location = last_message = NULL; |
17294 isolate->Dispose(); | 17633 isolate->Dispose(); |
17295 // It is not possible to dispose default isolate via Isolate API. | 17634 // It is not possible to dispose default isolate via Isolate API. |
17296 CHECK_NE(last_location, NULL); | 17635 CHECK_NE(last_location, NULL); |
17297 CHECK_NE(last_message, NULL); | 17636 CHECK_NE(last_message, NULL); |
17298 } | 17637 } |
17299 | 17638 |
| 17639 |
17300 TEST(RunDefaultAndAnotherIsolate) { | 17640 TEST(RunDefaultAndAnotherIsolate) { |
17301 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 17641 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
17302 LocalContext context; | 17642 LocalContext context; |
17303 | 17643 |
17304 // Enter new isolate. | 17644 // Enter new isolate. |
17305 v8::Isolate* isolate = v8::Isolate::New(); | 17645 v8::Isolate* isolate = v8::Isolate::New(); |
17306 CHECK(isolate); | 17646 CHECK(isolate); |
17307 isolate->Enter(); | 17647 isolate->Enter(); |
17308 { // Need this block because subsequent Exit() will deallocate Heap, | 17648 { // Need this block because subsequent Exit() will deallocate Heap, |
17309 // so we need all scope objects to be deconstructed when it happens. | 17649 // so we need all scope objects to be deconstructed when it happens. |
(...skipping 22 matching lines...) Expand all Loading... |
17332 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 17672 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
17333 last_location = last_message = NULL; | 17673 last_location = last_message = NULL; |
17334 isolate->Dispose(); | 17674 isolate->Dispose(); |
17335 CHECK_EQ(last_location, NULL); | 17675 CHECK_EQ(last_location, NULL); |
17336 CHECK_EQ(last_message, NULL); | 17676 CHECK_EQ(last_message, NULL); |
17337 | 17677 |
17338 // Check that default isolate still runs. | 17678 // Check that default isolate still runs. |
17339 ExpectTrue("function f() { return bar == 371; }; f()"); | 17679 ExpectTrue("function f() { return bar == 371; }; f()"); |
17340 } | 17680 } |
17341 | 17681 |
| 17682 |
17342 TEST(DisposeIsolateWhenInUse) { | 17683 TEST(DisposeIsolateWhenInUse) { |
17343 v8::Isolate* isolate = v8::Isolate::New(); | 17684 v8::Isolate* isolate = v8::Isolate::New(); |
17344 CHECK(isolate); | 17685 CHECK(isolate); |
17345 isolate->Enter(); | 17686 isolate->Enter(); |
17346 v8::HandleScope scope(isolate); | 17687 v8::HandleScope scope(isolate); |
17347 LocalContext context; | 17688 LocalContext context; |
17348 // Run something in this isolate. | 17689 // Run something in this isolate. |
17349 ExpectTrue("true"); | 17690 ExpectTrue("true"); |
17350 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 17691 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
17351 last_location = last_message = NULL; | 17692 last_location = last_message = NULL; |
17352 // Still entered, should fail. | 17693 // Still entered, should fail. |
17353 isolate->Dispose(); | 17694 isolate->Dispose(); |
17354 CHECK_NE(last_location, NULL); | 17695 CHECK_NE(last_location, NULL); |
17355 CHECK_NE(last_message, NULL); | 17696 CHECK_NE(last_message, NULL); |
17356 } | 17697 } |
17357 | 17698 |
| 17699 |
17358 TEST(RunTwoIsolatesOnSingleThread) { | 17700 TEST(RunTwoIsolatesOnSingleThread) { |
17359 // Run isolate 1. | 17701 // Run isolate 1. |
17360 v8::Isolate* isolate1 = v8::Isolate::New(); | 17702 v8::Isolate* isolate1 = v8::Isolate::New(); |
17361 isolate1->Enter(); | 17703 isolate1->Enter(); |
17362 v8::Persistent<v8::Context> context1; | 17704 v8::Persistent<v8::Context> context1; |
17363 { | 17705 { |
17364 v8::HandleScope scope(isolate1); | 17706 v8::HandleScope scope(isolate1); |
17365 context1.Reset(isolate1, Context::New(isolate1)); | 17707 context1.Reset(isolate1, Context::New(isolate1)); |
17366 } | 17708 } |
17367 | 17709 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17472 // Check that default isolate still runs. | 17814 // Check that default isolate still runs. |
17473 { | 17815 { |
17474 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 17816 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
17475 v8::Local<v8::Context> context = | 17817 v8::Local<v8::Context> context = |
17476 v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context_default); | 17818 v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context_default); |
17477 v8::Context::Scope context_scope(context); | 17819 v8::Context::Scope context_scope(context); |
17478 ExpectTrue("function f() { return isDefaultIsolate; }; f()"); | 17820 ExpectTrue("function f() { return isDefaultIsolate; }; f()"); |
17479 } | 17821 } |
17480 } | 17822 } |
17481 | 17823 |
| 17824 |
17482 static int CalcFibonacci(v8::Isolate* isolate, int limit) { | 17825 static int CalcFibonacci(v8::Isolate* isolate, int limit) { |
17483 v8::Isolate::Scope isolate_scope(isolate); | 17826 v8::Isolate::Scope isolate_scope(isolate); |
17484 v8::HandleScope scope(isolate); | 17827 v8::HandleScope scope(isolate); |
17485 LocalContext context; | 17828 LocalContext context; |
17486 i::ScopedVector<char> code(1024); | 17829 i::ScopedVector<char> code(1024); |
17487 i::OS::SNPrintF(code, "function fib(n) {" | 17830 i::OS::SNPrintF(code, "function fib(n) {" |
17488 " if (n <= 2) return 1;" | 17831 " if (n <= 2) return 1;" |
17489 " return fib(n-1) + fib(n-2);" | 17832 " return fib(n-1) + fib(n-2);" |
17490 "}" | 17833 "}" |
17491 "fib(%d)", limit); | 17834 "fib(%d)", limit); |
(...skipping 15 matching lines...) Expand all Loading... |
17507 } | 17850 } |
17508 | 17851 |
17509 int result() { return result_; } | 17852 int result() { return result_; } |
17510 | 17853 |
17511 private: | 17854 private: |
17512 v8::Isolate* isolate_; | 17855 v8::Isolate* isolate_; |
17513 int fib_limit_; | 17856 int fib_limit_; |
17514 int result_; | 17857 int result_; |
17515 }; | 17858 }; |
17516 | 17859 |
| 17860 |
17517 TEST(MultipleIsolatesOnIndividualThreads) { | 17861 TEST(MultipleIsolatesOnIndividualThreads) { |
17518 v8::Isolate* isolate1 = v8::Isolate::New(); | 17862 v8::Isolate* isolate1 = v8::Isolate::New(); |
17519 v8::Isolate* isolate2 = v8::Isolate::New(); | 17863 v8::Isolate* isolate2 = v8::Isolate::New(); |
17520 | 17864 |
17521 IsolateThread thread1(isolate1, 21); | 17865 IsolateThread thread1(isolate1, 21); |
17522 IsolateThread thread2(isolate2, 12); | 17866 IsolateThread thread2(isolate2, 12); |
17523 | 17867 |
17524 // Compute some fibonacci numbers on 3 threads in 3 isolates. | 17868 // Compute some fibonacci numbers on 3 threads in 3 isolates. |
17525 thread1.Start(); | 17869 thread1.Start(); |
17526 thread2.Start(); | 17870 thread2.Start(); |
17527 | 17871 |
17528 int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21); | 17872 int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21); |
17529 int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12); | 17873 int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12); |
17530 | 17874 |
17531 thread1.Join(); | 17875 thread1.Join(); |
17532 thread2.Join(); | 17876 thread2.Join(); |
17533 | 17877 |
17534 // Compare results. The actual fibonacci numbers for 12 and 21 are taken | 17878 // Compare results. The actual fibonacci numbers for 12 and 21 are taken |
17535 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number | 17879 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number |
17536 CHECK_EQ(result1, 10946); | 17880 CHECK_EQ(result1, 10946); |
17537 CHECK_EQ(result2, 144); | 17881 CHECK_EQ(result2, 144); |
17538 CHECK_EQ(result1, thread1.result()); | 17882 CHECK_EQ(result1, thread1.result()); |
17539 CHECK_EQ(result2, thread2.result()); | 17883 CHECK_EQ(result2, thread2.result()); |
17540 | 17884 |
17541 isolate1->Dispose(); | 17885 isolate1->Dispose(); |
17542 isolate2->Dispose(); | 17886 isolate2->Dispose(); |
17543 } | 17887 } |
17544 | 17888 |
| 17889 |
17545 TEST(IsolateDifferentContexts) { | 17890 TEST(IsolateDifferentContexts) { |
17546 v8::Isolate* isolate = v8::Isolate::New(); | 17891 v8::Isolate* isolate = v8::Isolate::New(); |
17547 Local<v8::Context> context; | 17892 Local<v8::Context> context; |
17548 { | 17893 { |
17549 v8::Isolate::Scope isolate_scope(isolate); | 17894 v8::Isolate::Scope isolate_scope(isolate); |
17550 v8::HandleScope handle_scope(isolate); | 17895 v8::HandleScope handle_scope(isolate); |
17551 context = v8::Context::New(isolate); | 17896 context = v8::Context::New(isolate); |
17552 v8::Context::Scope context_scope(context); | 17897 v8::Context::Scope context_scope(context); |
17553 Local<Value> v = CompileRun("2"); | 17898 Local<Value> v = CompileRun("2"); |
17554 CHECK(v->IsNumber()); | 17899 CHECK(v->IsNumber()); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17623 }; | 17968 }; |
17624 | 17969 |
17625 | 17970 |
17626 static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) { | 17971 static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) { |
17627 InitDefaultIsolateThread thread(testCase); | 17972 InitDefaultIsolateThread thread(testCase); |
17628 thread.Start(); | 17973 thread.Start(); |
17629 thread.Join(); | 17974 thread.Join(); |
17630 CHECK_EQ(thread.result(), true); | 17975 CHECK_EQ(thread.result(), true); |
17631 } | 17976 } |
17632 | 17977 |
| 17978 |
17633 TEST(InitializeDefaultIsolateOnSecondaryThread1) { | 17979 TEST(InitializeDefaultIsolateOnSecondaryThread1) { |
17634 InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM); | 17980 InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM); |
17635 } | 17981 } |
17636 | 17982 |
| 17983 |
17637 TEST(InitializeDefaultIsolateOnSecondaryThread2) { | 17984 TEST(InitializeDefaultIsolateOnSecondaryThread2) { |
17638 InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints); | 17985 InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints); |
17639 } | 17986 } |
17640 | 17987 |
| 17988 |
17641 TEST(InitializeDefaultIsolateOnSecondaryThread3) { | 17989 TEST(InitializeDefaultIsolateOnSecondaryThread3) { |
17642 InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler); | 17990 InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler); |
17643 } | 17991 } |
17644 | 17992 |
| 17993 |
17645 TEST(InitializeDefaultIsolateOnSecondaryThread4) { | 17994 TEST(InitializeDefaultIsolateOnSecondaryThread4) { |
17646 InitializeTestHelper(InitDefaultIsolateThread::SetCounterFunction); | 17995 InitializeTestHelper(InitDefaultIsolateThread::SetCounterFunction); |
17647 } | 17996 } |
17648 | 17997 |
| 17998 |
17649 TEST(InitializeDefaultIsolateOnSecondaryThread5) { | 17999 TEST(InitializeDefaultIsolateOnSecondaryThread5) { |
17650 InitializeTestHelper(InitDefaultIsolateThread::SetCreateHistogramFunction); | 18000 InitializeTestHelper(InitDefaultIsolateThread::SetCreateHistogramFunction); |
17651 } | 18001 } |
17652 | 18002 |
| 18003 |
17653 TEST(InitializeDefaultIsolateOnSecondaryThread6) { | 18004 TEST(InitializeDefaultIsolateOnSecondaryThread6) { |
17654 InitializeTestHelper(InitDefaultIsolateThread::SetAddHistogramSampleFunction); | 18005 InitializeTestHelper(InitDefaultIsolateThread::SetAddHistogramSampleFunction); |
17655 } | 18006 } |
17656 | 18007 |
17657 | 18008 |
17658 TEST(StringCheckMultipleContexts) { | 18009 TEST(StringCheckMultipleContexts) { |
17659 const char* code = | 18010 const char* code = |
17660 "(function() { return \"a\".charAt(0); })()"; | 18011 "(function() { return \"a\".charAt(0); })()"; |
17661 | 18012 |
17662 { | 18013 { |
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19348 i::Semaphore* sem_; | 19699 i::Semaphore* sem_; |
19349 volatile int sem_value_; | 19700 volatile int sem_value_; |
19350 }; | 19701 }; |
19351 | 19702 |
19352 | 19703 |
19353 THREADED_TEST(SemaphoreInterruption) { | 19704 THREADED_TEST(SemaphoreInterruption) { |
19354 ThreadInterruptTest().RunTest(); | 19705 ThreadInterruptTest().RunTest(); |
19355 } | 19706 } |
19356 | 19707 |
19357 #endif // WIN32 | 19708 #endif // WIN32 |
OLD | NEW |