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 12 matching lines...) Expand all Loading... |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <climits> | 28 #include <climits> |
29 #include <csignal> | 29 #include <csignal> |
30 #include <map> | 30 #include <map> |
31 #include <string> | 31 #include <string> |
32 | 32 |
33 #include "src/v8.h" | 33 #include "test/cctest/test-api.h" |
34 | 34 |
35 #if V8_OS_POSIX | 35 #if V8_OS_POSIX |
36 #include <unistd.h> // NOLINT | 36 #include <unistd.h> // NOLINT |
37 #endif | 37 #endif |
38 | 38 |
39 #include "include/v8-util.h" | 39 #include "include/v8-util.h" |
40 #include "src/api.h" | 40 #include "src/api.h" |
41 #include "src/arguments.h" | 41 #include "src/arguments.h" |
42 #include "src/base/platform/platform.h" | 42 #include "src/base/platform/platform.h" |
43 #include "src/compilation-cache.h" | 43 #include "src/compilation-cache.h" |
44 #include "src/cpu-profiler.h" | |
45 #include "src/execution.h" | 44 #include "src/execution.h" |
46 #include "src/isolate.h" | |
47 #include "src/objects.h" | 45 #include "src/objects.h" |
48 #include "src/parser.h" | 46 #include "src/parser.h" |
49 #include "src/smart-pointers.h" | 47 #include "src/smart-pointers.h" |
50 #include "src/snapshot.h" | 48 #include "src/snapshot.h" |
51 #include "src/unicode-inl.h" | 49 #include "src/unicode-inl.h" |
52 #include "src/utils.h" | 50 #include "src/utils.h" |
53 #include "src/vm-state.h" | 51 #include "src/vm-state.h" |
54 #include "test/cctest/cctest.h" | |
55 | 52 |
56 static const bool kLogThreading = false; | 53 static const bool kLogThreading = false; |
57 | 54 |
58 using ::v8::Boolean; | 55 using ::v8::Boolean; |
59 using ::v8::BooleanObject; | 56 using ::v8::BooleanObject; |
60 using ::v8::Context; | 57 using ::v8::Context; |
61 using ::v8::Extension; | 58 using ::v8::Extension; |
62 using ::v8::Function; | 59 using ::v8::Function; |
63 using ::v8::FunctionTemplate; | 60 using ::v8::FunctionTemplate; |
64 using ::v8::Handle; | 61 using ::v8::Handle; |
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 THREADED_TEST(GlobalProperties) { | 883 THREADED_TEST(GlobalProperties) { |
887 LocalContext env; | 884 LocalContext env; |
888 v8::HandleScope scope(env->GetIsolate()); | 885 v8::HandleScope scope(env->GetIsolate()); |
889 v8::Handle<v8::Object> global = env->Global(); | 886 v8::Handle<v8::Object> global = env->Global(); |
890 global->Set(v8_str("pi"), v8_num(3.1415926)); | 887 global->Set(v8_str("pi"), v8_num(3.1415926)); |
891 Local<Value> pi = global->Get(v8_str("pi")); | 888 Local<Value> pi = global->Get(v8_str("pi")); |
892 CHECK_EQ(3.1415926, pi->NumberValue()); | 889 CHECK_EQ(3.1415926, pi->NumberValue()); |
893 } | 890 } |
894 | 891 |
895 | 892 |
896 template<typename T> | |
897 static void CheckReturnValue(const T& t, i::Address callback) { | |
898 v8::ReturnValue<v8::Value> rv = t.GetReturnValue(); | |
899 i::Object** o = *reinterpret_cast<i::Object***>(&rv); | |
900 CHECK_EQ(CcTest::isolate(), t.GetIsolate()); | |
901 CHECK_EQ(t.GetIsolate(), rv.GetIsolate()); | |
902 CHECK((*o)->IsTheHole() || (*o)->IsUndefined()); | |
903 // Verify reset | |
904 bool is_runtime = (*o)->IsTheHole(); | |
905 rv.Set(true); | |
906 CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined()); | |
907 rv.Set(v8::Handle<v8::Object>()); | |
908 CHECK((*o)->IsTheHole() || (*o)->IsUndefined()); | |
909 CHECK_EQ(is_runtime, (*o)->IsTheHole()); | |
910 | |
911 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(t.GetIsolate()); | |
912 // If CPU profiler is active check that when API callback is invoked | |
913 // VMState is set to EXTERNAL. | |
914 if (isolate->cpu_profiler()->is_profiling()) { | |
915 CHECK_EQ(v8::EXTERNAL, isolate->current_vm_state()); | |
916 CHECK(isolate->external_callback_scope()); | |
917 CHECK_EQ(callback, isolate->external_callback_scope()->callback()); | |
918 } | |
919 } | |
920 | |
921 | |
922 static void handle_callback_impl(const v8::FunctionCallbackInfo<Value>& info, | 893 static void handle_callback_impl(const v8::FunctionCallbackInfo<Value>& info, |
923 i::Address callback) { | 894 i::Address callback) { |
924 ApiTestFuzzer::Fuzz(); | 895 ApiTestFuzzer::Fuzz(); |
925 CheckReturnValue(info, callback); | 896 CheckReturnValue(info, callback); |
926 info.GetReturnValue().Set(v8_str("bad value")); | 897 info.GetReturnValue().Set(v8_str("bad value")); |
927 info.GetReturnValue().Set(v8_num(102)); | 898 info.GetReturnValue().Set(v8_num(102)); |
928 } | 899 } |
929 | 900 |
930 | 901 |
931 static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) { | 902 static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) { |
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 CHECK_EQ(15.2, v8_compile("obj2.knurd")->Run()->NumberValue()); | 1872 CHECK_EQ(15.2, v8_compile("obj2.knurd")->Run()->NumberValue()); |
1902 CHECK(v8_compile("'knurd' in obj2")->Run()->BooleanValue()); | 1873 CHECK(v8_compile("'knurd' in obj2")->Run()->BooleanValue()); |
1903 CHECK_EQ(10.1, v8_compile("obj2.v2")->Run()->NumberValue()); | 1874 CHECK_EQ(10.1, v8_compile("obj2.v2")->Run()->NumberValue()); |
1904 | 1875 |
1905 // base1 and base2 cannot cross reference to each's prototype | 1876 // base1 and base2 cannot cross reference to each's prototype |
1906 CHECK(v8_compile("obj.v2")->Run()->IsUndefined()); | 1877 CHECK(v8_compile("obj.v2")->Run()->IsUndefined()); |
1907 CHECK(v8_compile("obj2.v1")->Run()->IsUndefined()); | 1878 CHECK(v8_compile("obj2.v1")->Run()->IsUndefined()); |
1908 } | 1879 } |
1909 | 1880 |
1910 | 1881 |
1911 int echo_named_call_count; | |
1912 | |
1913 | |
1914 static void EchoNamedProperty(Local<Name> name, | |
1915 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
1916 ApiTestFuzzer::Fuzz(); | |
1917 CHECK(v8_str("data")->Equals(info.Data())); | |
1918 echo_named_call_count++; | |
1919 info.GetReturnValue().Set(name); | |
1920 } | |
1921 | |
1922 | |
1923 // Helper functions for Interceptor/Accessor interaction tests | 1882 // Helper functions for Interceptor/Accessor interaction tests |
1924 | 1883 |
1925 void SimpleAccessorGetter(Local<String> name, | 1884 void SimpleAccessorGetter(Local<String> name, |
1926 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1885 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1927 Handle<Object> self = Handle<Object>::Cast(info.This()); | 1886 Handle<Object> self = Handle<Object>::Cast(info.This()); |
1928 info.GetReturnValue().Set( | 1887 info.GetReturnValue().Set( |
1929 self->Get(String::Concat(v8_str("accessor_"), name))); | 1888 self->Get(String::Concat(v8_str("accessor_"), name))); |
1930 } | 1889 } |
1931 | 1890 |
1932 void SimpleAccessorSetter(Local<String> name, Local<Value> value, | 1891 void SimpleAccessorSetter(Local<String> name, Local<Value> value, |
(...skipping 27 matching lines...) Expand all Loading... |
1960 if (sym->Name()->IsUndefined()) return; | 1919 if (sym->Name()->IsUndefined()) return; |
1961 info.GetReturnValue().Set(info.Data()); | 1920 info.GetReturnValue().Set(info.Data()); |
1962 } | 1921 } |
1963 | 1922 |
1964 static void ThrowingSymbolAccessorGetter( | 1923 static void ThrowingSymbolAccessorGetter( |
1965 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | 1924 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
1966 info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name)); | 1925 info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name)); |
1967 } | 1926 } |
1968 | 1927 |
1969 | 1928 |
1970 void EmptyInterceptorGetter(Local<Name> name, | |
1971 const v8::PropertyCallbackInfo<v8::Value>& info) {} | |
1972 | |
1973 | |
1974 void EmptyInterceptorSetter(Local<Name> name, Local<Value> value, | |
1975 const v8::PropertyCallbackInfo<v8::Value>& info) {} | |
1976 | |
1977 | |
1978 void EmptyGenericInterceptorGetter( | |
1979 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {} | |
1980 | |
1981 | |
1982 void EmptyGenericInterceptorSetter( | |
1983 Local<Name> name, Local<Value> value, | |
1984 const v8::PropertyCallbackInfo<v8::Value>& info) {} | |
1985 | |
1986 | |
1987 void StringInterceptorGetter( | |
1988 Local<String> name, | |
1989 const v8::PropertyCallbackInfo<v8::Value>& | |
1990 info) { // Intercept names that start with 'interceptor_'. | |
1991 String::Utf8Value utf8(name); | |
1992 char* name_str = *utf8; | |
1993 char prefix[] = "interceptor_"; | |
1994 int i; | |
1995 for (i = 0; name_str[i] && prefix[i]; ++i) { | |
1996 if (name_str[i] != prefix[i]) return; | |
1997 } | |
1998 Handle<Object> self = Handle<Object>::Cast(info.This()); | |
1999 info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i))); | |
2000 } | |
2001 | |
2002 | |
2003 void StringInterceptorSetter(Local<String> name, Local<Value> value, | |
2004 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2005 // Intercept accesses that set certain integer values, for which the name does | |
2006 // not start with 'accessor_'. | |
2007 String::Utf8Value utf8(name); | |
2008 char* name_str = *utf8; | |
2009 char prefix[] = "accessor_"; | |
2010 int i; | |
2011 for (i = 0; name_str[i] && prefix[i]; ++i) { | |
2012 if (name_str[i] != prefix[i]) break; | |
2013 } | |
2014 if (!prefix[i]) return; | |
2015 | |
2016 if (value->IsInt32() && value->Int32Value() < 10000) { | |
2017 Handle<Object> self = Handle<Object>::Cast(info.This()); | |
2018 self->SetHiddenValue(name, value); | |
2019 info.GetReturnValue().Set(value); | |
2020 } | |
2021 } | |
2022 | |
2023 void InterceptorGetter(Local<Name> generic_name, | |
2024 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2025 if (generic_name->IsSymbol()) return; | |
2026 StringInterceptorGetter(Local<String>::Cast(generic_name), info); | |
2027 } | |
2028 | |
2029 void InterceptorSetter(Local<Name> generic_name, Local<Value> value, | |
2030 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2031 if (generic_name->IsSymbol()) return; | |
2032 StringInterceptorSetter(Local<String>::Cast(generic_name), value, info); | |
2033 } | |
2034 | |
2035 void GenericInterceptorGetter(Local<Name> generic_name, | |
2036 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2037 Local<String> str; | |
2038 if (generic_name->IsSymbol()) { | |
2039 Local<Value> name = Local<Symbol>::Cast(generic_name)->Name(); | |
2040 if (name->IsUndefined()) return; | |
2041 str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name)); | |
2042 } else { | |
2043 Local<String> name = Local<String>::Cast(generic_name); | |
2044 String::Utf8Value utf8(name); | |
2045 char* name_str = *utf8; | |
2046 if (*name_str == '_') return; | |
2047 str = String::Concat(v8_str("_str_"), name); | |
2048 } | |
2049 | |
2050 Handle<Object> self = Handle<Object>::Cast(info.This()); | |
2051 info.GetReturnValue().Set(self->Get(str)); | |
2052 } | |
2053 | |
2054 void GenericInterceptorSetter(Local<Name> generic_name, Local<Value> value, | |
2055 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2056 Local<String> str; | |
2057 if (generic_name->IsSymbol()) { | |
2058 Local<Value> name = Local<Symbol>::Cast(generic_name)->Name(); | |
2059 if (name->IsUndefined()) return; | |
2060 str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name)); | |
2061 } else { | |
2062 Local<String> name = Local<String>::Cast(generic_name); | |
2063 String::Utf8Value utf8(name); | |
2064 char* name_str = *utf8; | |
2065 if (*name_str == '_') return; | |
2066 str = String::Concat(v8_str("_str_"), name); | |
2067 } | |
2068 | |
2069 Handle<Object> self = Handle<Object>::Cast(info.This()); | |
2070 self->Set(str, value); | |
2071 info.GetReturnValue().Set(value); | |
2072 } | |
2073 | |
2074 void AddAccessor(Handle<FunctionTemplate> templ, | |
2075 Handle<String> name, | |
2076 v8::AccessorGetterCallback getter, | |
2077 v8::AccessorSetterCallback setter) { | |
2078 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); | |
2079 } | |
2080 | |
2081 void AddInterceptor(Handle<FunctionTemplate> templ, | |
2082 v8::NamedPropertyGetterCallback getter, | |
2083 v8::NamedPropertySetterCallback setter) { | |
2084 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); | |
2085 } | |
2086 | |
2087 | |
2088 void AddAccessor(Handle<FunctionTemplate> templ, | |
2089 Handle<Name> name, | |
2090 v8::AccessorNameGetterCallback getter, | |
2091 v8::AccessorNameSetterCallback setter) { | |
2092 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); | |
2093 } | |
2094 | |
2095 void AddInterceptor(Handle<FunctionTemplate> templ, | |
2096 v8::GenericNamedPropertyGetterCallback getter, | |
2097 v8::GenericNamedPropertySetterCallback setter) { | |
2098 templ->InstanceTemplate()->SetHandler( | |
2099 v8::NamedPropertyHandlerConfiguration(getter, setter)); | |
2100 } | |
2101 | |
2102 | |
2103 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { | |
2104 v8::HandleScope scope(CcTest::isolate()); | |
2105 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); | |
2106 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); | |
2107 child->Inherit(parent); | |
2108 AddAccessor(parent, v8_str("age"), | |
2109 SimpleAccessorGetter, SimpleAccessorSetter); | |
2110 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
2111 LocalContext env; | |
2112 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2113 CompileRun("var child = new Child;" | |
2114 "child.age = 10;"); | |
2115 ExpectBoolean("child.hasOwnProperty('age')", false); | |
2116 ExpectInt32("child.age", 10); | |
2117 ExpectInt32("child.accessor_age", 10); | |
2118 } | |
2119 | |
2120 | |
2121 THREADED_TEST(LegacyInterceptorDoesNotSeeSymbols) { | |
2122 LocalContext env; | |
2123 v8::Isolate* isolate = CcTest::isolate(); | |
2124 v8::HandleScope scope(isolate); | |
2125 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); | |
2126 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); | |
2127 v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age")); | |
2128 | |
2129 child->Inherit(parent); | |
2130 AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter); | |
2131 AddInterceptor(child, StringInterceptorGetter, StringInterceptorSetter); | |
2132 | |
2133 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2134 env->Global()->Set(v8_str("age"), age); | |
2135 CompileRun( | |
2136 "var child = new Child;" | |
2137 "child[age] = 10;"); | |
2138 ExpectInt32("child[age]", 10); | |
2139 ExpectBoolean("child.hasOwnProperty('age')", false); | |
2140 ExpectBoolean("child.hasOwnProperty('accessor_age')", true); | |
2141 } | |
2142 | |
2143 | |
2144 THREADED_TEST(GenericInterceptorDoesSeeSymbols) { | |
2145 LocalContext env; | |
2146 v8::Isolate* isolate = CcTest::isolate(); | |
2147 v8::HandleScope scope(isolate); | |
2148 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); | |
2149 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); | |
2150 v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age")); | |
2151 v8::Local<v8::Symbol> anon = v8::Symbol::New(isolate); | |
2152 | |
2153 child->Inherit(parent); | |
2154 AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter); | |
2155 AddInterceptor(child, GenericInterceptorGetter, GenericInterceptorSetter); | |
2156 | |
2157 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2158 env->Global()->Set(v8_str("age"), age); | |
2159 env->Global()->Set(v8_str("anon"), anon); | |
2160 CompileRun( | |
2161 "var child = new Child;" | |
2162 "child[age] = 10;"); | |
2163 ExpectInt32("child[age]", 10); | |
2164 ExpectInt32("child._sym_age", 10); | |
2165 | |
2166 // Check that it also sees strings. | |
2167 CompileRun("child.foo = 47"); | |
2168 ExpectInt32("child.foo", 47); | |
2169 ExpectInt32("child._str_foo", 47); | |
2170 | |
2171 // Check that the interceptor can punt (in this case, on anonymous symbols). | |
2172 CompileRun("child[anon] = 31337"); | |
2173 ExpectInt32("child[anon]", 31337); | |
2174 } | |
2175 | |
2176 | |
2177 THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { | 1929 THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { |
2178 v8::Isolate* isolate = CcTest::isolate(); | 1930 v8::Isolate* isolate = CcTest::isolate(); |
2179 v8::HandleScope scope(isolate); | 1931 v8::HandleScope scope(isolate); |
2180 LocalContext env; | 1932 LocalContext env; |
2181 v8::Local<v8::Value> res = CompileRun("var a = []; a;"); | 1933 v8::Local<v8::Value> res = CompileRun("var a = []; a;"); |
2182 i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res))); | 1934 i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res))); |
2183 CHECK(a->map()->instance_descriptors()->IsFixedArray()); | 1935 CHECK(a->map()->instance_descriptors()->IsFixedArray()); |
2184 CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); | 1936 CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); |
2185 CompileRun("Object.defineProperty(a, 'length', { writable: false });"); | 1937 CompileRun("Object.defineProperty(a, 'length', { writable: false });"); |
2186 CHECK_EQ(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); | 1938 CHECK_EQ(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); |
2187 // But we should still have an ExecutableAccessorInfo. | 1939 // But we should still have an ExecutableAccessorInfo. |
2188 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 1940 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
2189 i::LookupResult lookup(i_isolate); | 1941 i::LookupResult lookup(i_isolate); |
2190 i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length"))); | 1942 i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length"))); |
2191 i::LookupIterator it(a, name, i::LookupIterator::OWN_SKIP_INTERCEPTOR); | 1943 i::LookupIterator it(a, name, i::LookupIterator::OWN_SKIP_INTERCEPTOR); |
2192 CHECK_EQ(i::LookupIterator::ACCESSOR, it.state()); | 1944 CHECK_EQ(i::LookupIterator::ACCESSOR, it.state()); |
2193 CHECK(it.GetAccessors()->IsExecutableAccessorInfo()); | 1945 CHECK(it.GetAccessors()->IsExecutableAccessorInfo()); |
2194 } | 1946 } |
2195 | 1947 |
2196 | 1948 |
2197 THREADED_TEST(EmptyInterceptorBreakTransitions) { | |
2198 v8::HandleScope scope(CcTest::isolate()); | |
2199 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
2200 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
2201 LocalContext env; | |
2202 env->Global()->Set(v8_str("Constructor"), templ->GetFunction()); | |
2203 CompileRun("var o1 = new Constructor;" | |
2204 "o1.a = 1;" // Ensure a and x share the descriptor array. | |
2205 "Object.defineProperty(o1, 'x', {value: 10});"); | |
2206 CompileRun("var o2 = new Constructor;" | |
2207 "o2.a = 1;" | |
2208 "Object.defineProperty(o2, 'x', {value: 10});"); | |
2209 } | |
2210 | |
2211 | |
2212 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { | |
2213 v8::Isolate* isolate = CcTest::isolate(); | |
2214 v8::HandleScope scope(isolate); | |
2215 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); | |
2216 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); | |
2217 child->Inherit(parent); | |
2218 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
2219 LocalContext env; | |
2220 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2221 CompileRun("var child = new Child;" | |
2222 "var parent = child.__proto__;" | |
2223 "Object.defineProperty(parent, 'age', " | |
2224 " {get: function(){ return this.accessor_age; }, " | |
2225 " set: function(v){ this.accessor_age = v; }, " | |
2226 " enumerable: true, configurable: true});" | |
2227 "child.age = 10;"); | |
2228 ExpectBoolean("child.hasOwnProperty('age')", false); | |
2229 ExpectInt32("child.age", 10); | |
2230 ExpectInt32("child.accessor_age", 10); | |
2231 } | |
2232 | |
2233 | |
2234 THREADED_TEST(EmptyInterceptorDoesNotShadowApiAccessors) { | |
2235 v8::Isolate* isolate = CcTest::isolate(); | |
2236 v8::HandleScope scope(isolate); | |
2237 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); | |
2238 auto returns_42 = FunctionTemplate::New(isolate, Returns42); | |
2239 parent->PrototypeTemplate()->SetAccessorProperty(v8_str("age"), returns_42); | |
2240 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); | |
2241 child->Inherit(parent); | |
2242 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
2243 LocalContext env; | |
2244 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2245 CompileRun( | |
2246 "var child = new Child;" | |
2247 "var parent = child.__proto__;"); | |
2248 ExpectBoolean("child.hasOwnProperty('age')", false); | |
2249 ExpectInt32("child.age", 42); | |
2250 // Check interceptor followup. | |
2251 ExpectInt32( | |
2252 "var result;" | |
2253 "for (var i = 0; i < 4; ++i) {" | |
2254 " result = child.age;" | |
2255 "}" | |
2256 "result", | |
2257 42); | |
2258 } | |
2259 | |
2260 | |
2261 THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { | |
2262 v8::Isolate* isolate = CcTest::isolate(); | |
2263 v8::HandleScope scope(isolate); | |
2264 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); | |
2265 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); | |
2266 child->Inherit(parent); | |
2267 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
2268 LocalContext env; | |
2269 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2270 CompileRun("var child = new Child;" | |
2271 "var parent = child.__proto__;" | |
2272 "parent.name = 'Alice';"); | |
2273 ExpectBoolean("child.hasOwnProperty('name')", false); | |
2274 ExpectString("child.name", "Alice"); | |
2275 CompileRun("child.name = 'Bob';"); | |
2276 ExpectString("child.name", "Bob"); | |
2277 ExpectBoolean("child.hasOwnProperty('name')", true); | |
2278 ExpectString("parent.name", "Alice"); | |
2279 } | |
2280 | |
2281 | |
2282 THREADED_TEST(SwitchFromInterceptorToAccessor) { | |
2283 v8::HandleScope scope(CcTest::isolate()); | |
2284 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
2285 AddAccessor(templ, v8_str("age"), | |
2286 SimpleAccessorGetter, SimpleAccessorSetter); | |
2287 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
2288 LocalContext env; | |
2289 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
2290 CompileRun("var obj = new Obj;" | |
2291 "function setAge(i){ obj.age = i; };" | |
2292 "for(var i = 0; i <= 10000; i++) setAge(i);"); | |
2293 // All i < 10000 go to the interceptor. | |
2294 ExpectInt32("obj.interceptor_age", 9999); | |
2295 // The last i goes to the accessor. | |
2296 ExpectInt32("obj.accessor_age", 10000); | |
2297 } | |
2298 | |
2299 | |
2300 THREADED_TEST(SwitchFromAccessorToInterceptor) { | |
2301 v8::HandleScope scope(CcTest::isolate()); | |
2302 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
2303 AddAccessor(templ, v8_str("age"), | |
2304 SimpleAccessorGetter, SimpleAccessorSetter); | |
2305 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
2306 LocalContext env; | |
2307 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
2308 CompileRun("var obj = new Obj;" | |
2309 "function setAge(i){ obj.age = i; };" | |
2310 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | |
2311 // All i >= 10000 go to the accessor. | |
2312 ExpectInt32("obj.accessor_age", 10000); | |
2313 // The last i goes to the interceptor. | |
2314 ExpectInt32("obj.interceptor_age", 9999); | |
2315 } | |
2316 | |
2317 | |
2318 THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { | |
2319 v8::HandleScope scope(CcTest::isolate()); | |
2320 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); | |
2321 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); | |
2322 child->Inherit(parent); | |
2323 AddAccessor(parent, v8_str("age"), | |
2324 SimpleAccessorGetter, SimpleAccessorSetter); | |
2325 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
2326 LocalContext env; | |
2327 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2328 CompileRun("var child = new Child;" | |
2329 "function setAge(i){ child.age = i; };" | |
2330 "for(var i = 0; i <= 10000; i++) setAge(i);"); | |
2331 // All i < 10000 go to the interceptor. | |
2332 ExpectInt32("child.interceptor_age", 9999); | |
2333 // The last i goes to the accessor. | |
2334 ExpectInt32("child.accessor_age", 10000); | |
2335 } | |
2336 | |
2337 | |
2338 THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { | |
2339 v8::HandleScope scope(CcTest::isolate()); | |
2340 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); | |
2341 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); | |
2342 child->Inherit(parent); | |
2343 AddAccessor(parent, v8_str("age"), | |
2344 SimpleAccessorGetter, SimpleAccessorSetter); | |
2345 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
2346 LocalContext env; | |
2347 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2348 CompileRun("var child = new Child;" | |
2349 "function setAge(i){ child.age = i; };" | |
2350 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | |
2351 // All i >= 10000 go to the accessor. | |
2352 ExpectInt32("child.accessor_age", 10000); | |
2353 // The last i goes to the interceptor. | |
2354 ExpectInt32("child.interceptor_age", 9999); | |
2355 } | |
2356 | |
2357 | |
2358 THREADED_TEST(SwitchFromInterceptorToJSAccessor) { | |
2359 v8::HandleScope scope(CcTest::isolate()); | |
2360 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
2361 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
2362 LocalContext env; | |
2363 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
2364 CompileRun("var obj = new Obj;" | |
2365 "function setter(i) { this.accessor_age = i; };" | |
2366 "function getter() { return this.accessor_age; };" | |
2367 "function setAge(i) { obj.age = i; };" | |
2368 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" | |
2369 "for(var i = 0; i <= 10000; i++) setAge(i);"); | |
2370 // All i < 10000 go to the interceptor. | |
2371 ExpectInt32("obj.interceptor_age", 9999); | |
2372 // The last i goes to the JavaScript accessor. | |
2373 ExpectInt32("obj.accessor_age", 10000); | |
2374 // The installed JavaScript getter is still intact. | |
2375 // This last part is a regression test for issue 1651 and relies on the fact | |
2376 // that both interceptor and accessor are being installed on the same object. | |
2377 ExpectInt32("obj.age", 10000); | |
2378 ExpectBoolean("obj.hasOwnProperty('age')", true); | |
2379 ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); | |
2380 } | |
2381 | |
2382 | |
2383 THREADED_TEST(SwitchFromJSAccessorToInterceptor) { | |
2384 v8::HandleScope scope(CcTest::isolate()); | |
2385 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
2386 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
2387 LocalContext env; | |
2388 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
2389 CompileRun("var obj = new Obj;" | |
2390 "function setter(i) { this.accessor_age = i; };" | |
2391 "function getter() { return this.accessor_age; };" | |
2392 "function setAge(i) { obj.age = i; };" | |
2393 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" | |
2394 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | |
2395 // All i >= 10000 go to the accessor. | |
2396 ExpectInt32("obj.accessor_age", 10000); | |
2397 // The last i goes to the interceptor. | |
2398 ExpectInt32("obj.interceptor_age", 9999); | |
2399 // The installed JavaScript getter is still intact. | |
2400 // This last part is a regression test for issue 1651 and relies on the fact | |
2401 // that both interceptor and accessor are being installed on the same object. | |
2402 ExpectInt32("obj.age", 10000); | |
2403 ExpectBoolean("obj.hasOwnProperty('age')", true); | |
2404 ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); | |
2405 } | |
2406 | |
2407 | |
2408 THREADED_TEST(SwitchFromInterceptorToProperty) { | |
2409 v8::HandleScope scope(CcTest::isolate()); | |
2410 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); | |
2411 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); | |
2412 child->Inherit(parent); | |
2413 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
2414 LocalContext env; | |
2415 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2416 CompileRun("var child = new Child;" | |
2417 "function setAge(i){ child.age = i; };" | |
2418 "for(var i = 0; i <= 10000; i++) setAge(i);"); | |
2419 // All i < 10000 go to the interceptor. | |
2420 ExpectInt32("child.interceptor_age", 9999); | |
2421 // The last i goes to child's own property. | |
2422 ExpectInt32("child.age", 10000); | |
2423 } | |
2424 | |
2425 | |
2426 THREADED_TEST(SwitchFromPropertyToInterceptor) { | |
2427 v8::HandleScope scope(CcTest::isolate()); | |
2428 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); | |
2429 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); | |
2430 child->Inherit(parent); | |
2431 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
2432 LocalContext env; | |
2433 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
2434 CompileRun("var child = new Child;" | |
2435 "function setAge(i){ child.age = i; };" | |
2436 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | |
2437 // All i >= 10000 go to child's own property. | |
2438 ExpectInt32("child.age", 10000); | |
2439 // The last i goes to the interceptor. | |
2440 ExpectInt32("child.interceptor_age", 9999); | |
2441 } | |
2442 | |
2443 | |
2444 THREADED_TEST(NamedPropertyHandlerGetter) { | |
2445 echo_named_call_count = 0; | |
2446 v8::HandleScope scope(CcTest::isolate()); | |
2447 v8::Handle<v8::FunctionTemplate> templ = | |
2448 v8::FunctionTemplate::New(CcTest::isolate()); | |
2449 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
2450 EchoNamedProperty, 0, 0, 0, 0, v8_str("data"))); | |
2451 LocalContext env; | |
2452 env->Global()->Set(v8_str("obj"), | |
2453 templ->GetFunction()->NewInstance()); | |
2454 CHECK_EQ(echo_named_call_count, 0); | |
2455 v8_compile("obj.x")->Run(); | |
2456 CHECK_EQ(echo_named_call_count, 1); | |
2457 const char* code = "var str = 'oddle'; obj[str] + obj.poddle;"; | |
2458 v8::Handle<Value> str = CompileRun(code); | |
2459 String::Utf8Value value(str); | |
2460 CHECK_EQ(0, strcmp(*value, "oddlepoddle")); | |
2461 // Check default behavior | |
2462 CHECK_EQ(10, v8_compile("obj.flob = 10;")->Run()->Int32Value()); | |
2463 CHECK(v8_compile("'myProperty' in obj")->Run()->BooleanValue()); | |
2464 CHECK(v8_compile("delete obj.myProperty")->Run()->BooleanValue()); | |
2465 } | |
2466 | |
2467 | |
2468 int echo_indexed_call_count = 0; | |
2469 | |
2470 | |
2471 static void EchoIndexedProperty( | |
2472 uint32_t index, | |
2473 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2474 ApiTestFuzzer::Fuzz(); | |
2475 CHECK(v8_num(637)->Equals(info.Data())); | |
2476 echo_indexed_call_count++; | |
2477 info.GetReturnValue().Set(v8_num(index)); | |
2478 } | |
2479 | |
2480 | |
2481 THREADED_TEST(IndexedPropertyHandlerGetter) { | |
2482 v8::Isolate* isolate = CcTest::isolate(); | |
2483 v8::HandleScope scope(isolate); | |
2484 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | |
2485 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
2486 EchoIndexedProperty, 0, 0, 0, 0, v8_num(637))); | |
2487 LocalContext env; | |
2488 env->Global()->Set(v8_str("obj"), | |
2489 templ->GetFunction()->NewInstance()); | |
2490 Local<Script> script = v8_compile("obj[900]"); | |
2491 CHECK_EQ(script->Run()->Int32Value(), 900); | |
2492 } | |
2493 | |
2494 | |
2495 v8::Handle<v8::Object> bottom; | |
2496 | |
2497 static void CheckThisIndexedPropertyHandler( | |
2498 uint32_t index, | |
2499 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2500 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyHandler)); | |
2501 ApiTestFuzzer::Fuzz(); | |
2502 CHECK(info.This()->Equals(bottom)); | |
2503 } | |
2504 | |
2505 static void CheckThisNamedPropertyHandler( | |
2506 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2507 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler)); | |
2508 ApiTestFuzzer::Fuzz(); | |
2509 CHECK(info.This()->Equals(bottom)); | |
2510 } | |
2511 | |
2512 void CheckThisIndexedPropertySetter( | |
2513 uint32_t index, | |
2514 Local<Value> value, | |
2515 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2516 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); | |
2517 ApiTestFuzzer::Fuzz(); | |
2518 CHECK(info.This()->Equals(bottom)); | |
2519 } | |
2520 | |
2521 | |
2522 void CheckThisNamedPropertySetter( | |
2523 Local<Name> property, Local<Value> value, | |
2524 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2525 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); | |
2526 ApiTestFuzzer::Fuzz(); | |
2527 CHECK(info.This()->Equals(bottom)); | |
2528 } | |
2529 | |
2530 void CheckThisIndexedPropertyQuery( | |
2531 uint32_t index, | |
2532 const v8::PropertyCallbackInfo<v8::Integer>& info) { | |
2533 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyQuery)); | |
2534 ApiTestFuzzer::Fuzz(); | |
2535 CHECK(info.This()->Equals(bottom)); | |
2536 } | |
2537 | |
2538 | |
2539 void CheckThisNamedPropertyQuery( | |
2540 Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) { | |
2541 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyQuery)); | |
2542 ApiTestFuzzer::Fuzz(); | |
2543 CHECK(info.This()->Equals(bottom)); | |
2544 } | |
2545 | |
2546 | |
2547 void CheckThisIndexedPropertyDeleter( | |
2548 uint32_t index, | |
2549 const v8::PropertyCallbackInfo<v8::Boolean>& info) { | |
2550 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDeleter)); | |
2551 ApiTestFuzzer::Fuzz(); | |
2552 CHECK(info.This()->Equals(bottom)); | |
2553 } | |
2554 | |
2555 | |
2556 void CheckThisNamedPropertyDeleter( | |
2557 Local<Name> property, const v8::PropertyCallbackInfo<v8::Boolean>& info) { | |
2558 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDeleter)); | |
2559 ApiTestFuzzer::Fuzz(); | |
2560 CHECK(info.This()->Equals(bottom)); | |
2561 } | |
2562 | |
2563 | |
2564 void CheckThisIndexedPropertyEnumerator( | |
2565 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
2566 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyEnumerator)); | |
2567 ApiTestFuzzer::Fuzz(); | |
2568 CHECK(info.This()->Equals(bottom)); | |
2569 } | |
2570 | |
2571 | |
2572 void CheckThisNamedPropertyEnumerator( | |
2573 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
2574 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyEnumerator)); | |
2575 ApiTestFuzzer::Fuzz(); | |
2576 CHECK(info.This()->Equals(bottom)); | |
2577 } | |
2578 | |
2579 | |
2580 THREADED_PROFILED_TEST(PropertyHandlerInPrototype) { | |
2581 LocalContext env; | |
2582 v8::Isolate* isolate = env->GetIsolate(); | |
2583 v8::HandleScope scope(isolate); | |
2584 | |
2585 // Set up a prototype chain with three interceptors. | |
2586 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | |
2587 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
2588 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, | |
2589 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, | |
2590 CheckThisIndexedPropertyEnumerator)); | |
2591 | |
2592 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
2593 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, | |
2594 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, | |
2595 CheckThisNamedPropertyEnumerator)); | |
2596 | |
2597 bottom = templ->GetFunction()->NewInstance(); | |
2598 Local<v8::Object> top = templ->GetFunction()->NewInstance(); | |
2599 Local<v8::Object> middle = templ->GetFunction()->NewInstance(); | |
2600 | |
2601 bottom->SetPrototype(middle); | |
2602 middle->SetPrototype(top); | |
2603 env->Global()->Set(v8_str("obj"), bottom); | |
2604 | |
2605 // Indexed and named get. | |
2606 CompileRun("obj[0]"); | |
2607 CompileRun("obj.x"); | |
2608 | |
2609 // Indexed and named set. | |
2610 CompileRun("obj[1] = 42"); | |
2611 CompileRun("obj.y = 42"); | |
2612 | |
2613 // Indexed and named query. | |
2614 CompileRun("0 in obj"); | |
2615 CompileRun("'x' in obj"); | |
2616 | |
2617 // Indexed and named deleter. | |
2618 CompileRun("delete obj[0]"); | |
2619 CompileRun("delete obj.x"); | |
2620 | |
2621 // Enumerators. | |
2622 CompileRun("for (var p in obj) ;"); | |
2623 } | |
2624 | |
2625 | |
2626 static void PrePropertyHandlerGet( | |
2627 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
2628 ApiTestFuzzer::Fuzz(); | |
2629 if (v8_str("pre")->Equals(key)) { | |
2630 info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre")); | |
2631 } | |
2632 } | |
2633 | |
2634 | |
2635 static void PrePropertyHandlerQuery( | |
2636 Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) { | |
2637 if (v8_str("pre")->Equals(key)) { | |
2638 info.GetReturnValue().Set(static_cast<int32_t>(v8::None)); | |
2639 } | |
2640 } | |
2641 | |
2642 | |
2643 THREADED_TEST(PrePropertyHandler) { | |
2644 v8::Isolate* isolate = CcTest::isolate(); | |
2645 v8::HandleScope scope(isolate); | |
2646 v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); | |
2647 desc->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
2648 PrePropertyHandlerGet, 0, PrePropertyHandlerQuery)); | |
2649 LocalContext env(NULL, desc->InstanceTemplate()); | |
2650 CompileRun("var pre = 'Object: pre'; var on = 'Object: on';"); | |
2651 v8::Handle<Value> result_pre = CompileRun("pre"); | |
2652 CHECK(v8_str("PrePropertyHandler: pre")->Equals(result_pre)); | |
2653 v8::Handle<Value> result_on = CompileRun("on"); | |
2654 CHECK(v8_str("Object: on")->Equals(result_on)); | |
2655 v8::Handle<Value> result_post = CompileRun("post"); | |
2656 CHECK(result_post.IsEmpty()); | |
2657 } | |
2658 | |
2659 | |
2660 THREADED_TEST(UndefinedIsNotEnumerable) { | 1949 THREADED_TEST(UndefinedIsNotEnumerable) { |
2661 LocalContext env; | 1950 LocalContext env; |
2662 v8::HandleScope scope(env->GetIsolate()); | 1951 v8::HandleScope scope(env->GetIsolate()); |
2663 v8::Handle<Value> result = CompileRun("this.propertyIsEnumerable(undefined)"); | 1952 v8::Handle<Value> result = CompileRun("this.propertyIsEnumerable(undefined)"); |
2664 CHECK(result->IsFalse()); | 1953 CHECK(result->IsFalse()); |
2665 } | 1954 } |
2666 | 1955 |
2667 | 1956 |
2668 v8::Handle<Script> call_recursively_script; | 1957 v8::Handle<Script> call_recursively_script; |
2669 static const int kTargetRecursionDepth = 200; // near maximum | 1958 static const int kTargetRecursionDepth = 200; // near maximum |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2736 | 2025 |
2737 | 2026 |
2738 THREADED_TEST(CallbackExceptionRegression) { | 2027 THREADED_TEST(CallbackExceptionRegression) { |
2739 v8::Isolate* isolate = CcTest::isolate(); | 2028 v8::Isolate* isolate = CcTest::isolate(); |
2740 v8::HandleScope scope(isolate); | 2029 v8::HandleScope scope(isolate); |
2741 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); | 2030 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); |
2742 obj->SetHandler(v8::NamedPropertyHandlerConfiguration( | 2031 obj->SetHandler(v8::NamedPropertyHandlerConfiguration( |
2743 ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet)); | 2032 ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet)); |
2744 LocalContext env; | 2033 LocalContext env; |
2745 env->Global()->Set(v8_str("obj"), obj->NewInstance()); | 2034 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
2746 v8::Handle<Value> otto = CompileRun( | 2035 v8::Handle<Value> otto = |
2747 "try { with (obj) { otto; } } catch (e) { e; }"); | 2036 CompileRun("try { with (obj) { otto; } } catch (e) { e; }"); |
2748 CHECK(v8_str("otto")->Equals(otto)); | 2037 CHECK(v8_str("otto")->Equals(otto)); |
2749 v8::Handle<Value> netto = CompileRun( | 2038 v8::Handle<Value> netto = |
2750 "try { with (obj) { netto = 4; } } catch (e) { e; }"); | 2039 CompileRun("try { with (obj) { netto = 4; } } catch (e) { e; }"); |
2751 CHECK(v8_str("netto")->Equals(netto)); | 2040 CHECK(v8_str("netto")->Equals(netto)); |
2752 } | 2041 } |
2753 | 2042 |
2754 | 2043 |
2755 THREADED_TEST(FunctionPrototype) { | 2044 THREADED_TEST(FunctionPrototype) { |
2756 v8::Isolate* isolate = CcTest::isolate(); | 2045 v8::Isolate* isolate = CcTest::isolate(); |
2757 v8::HandleScope scope(isolate); | 2046 v8::HandleScope scope(isolate); |
2758 Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(isolate); | 2047 Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(isolate); |
2759 Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); | 2048 Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); |
2760 LocalContext env; | 2049 LocalContext env; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 | 2125 |
2837 void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1)); | 2126 void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1)); |
2838 CheckAlignedPointerInInternalField(obj, huge); | 2127 CheckAlignedPointerInInternalField(obj, huge); |
2839 | 2128 |
2840 v8::UniquePersistent<v8::Object> persistent(isolate, obj); | 2129 v8::UniquePersistent<v8::Object> persistent(isolate, obj); |
2841 CHECK_EQ(1, Object::InternalFieldCount(persistent)); | 2130 CHECK_EQ(1, Object::InternalFieldCount(persistent)); |
2842 CHECK_EQ(huge, Object::GetAlignedPointerFromInternalField(persistent, 0)); | 2131 CHECK_EQ(huge, Object::GetAlignedPointerFromInternalField(persistent, 0)); |
2843 } | 2132 } |
2844 | 2133 |
2845 | 2134 |
2846 static void CheckAlignedPointerInEmbedderData(LocalContext* env, | 2135 static void CheckAlignedPointerInEmbedderData(LocalContext* env, int index, |
2847 int index, | |
2848 void* value) { | 2136 void* value) { |
2849 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); | 2137 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); |
2850 (*env)->SetAlignedPointerInEmbedderData(index, value); | 2138 (*env)->SetAlignedPointerInEmbedderData(index, value); |
2851 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 2139 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
2852 CHECK_EQ(value, (*env)->GetAlignedPointerFromEmbedderData(index)); | 2140 CHECK_EQ(value, (*env)->GetAlignedPointerFromEmbedderData(index)); |
2853 } | 2141 } |
2854 | 2142 |
2855 | 2143 |
2856 static void* AlignedTestPointer(int i) { | 2144 static void* AlignedTestPointer(int i) { |
2857 return reinterpret_cast<void*>(i * 1234); | 2145 return reinterpret_cast<void*>(i * 1234); |
(...skipping 20 matching lines...) Expand all Loading... |
2878 for (int i = 0; i < 100; i++) { | 2166 for (int i = 0; i < 100; i++) { |
2879 env->SetAlignedPointerInEmbedderData(i, AlignedTestPointer(i)); | 2167 env->SetAlignedPointerInEmbedderData(i, AlignedTestPointer(i)); |
2880 } | 2168 } |
2881 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 2169 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
2882 for (int i = 0; i < 100; i++) { | 2170 for (int i = 0; i < 100; i++) { |
2883 CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i)); | 2171 CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i)); |
2884 } | 2172 } |
2885 } | 2173 } |
2886 | 2174 |
2887 | 2175 |
2888 static void CheckEmbedderData(LocalContext* env, | 2176 static void CheckEmbedderData(LocalContext* env, int index, |
2889 int index, | |
2890 v8::Handle<Value> data) { | 2177 v8::Handle<Value> data) { |
2891 (*env)->SetEmbedderData(index, data); | 2178 (*env)->SetEmbedderData(index, data); |
2892 CHECK((*env)->GetEmbedderData(index)->StrictEquals(data)); | 2179 CHECK((*env)->GetEmbedderData(index)->StrictEquals(data)); |
2893 } | 2180 } |
2894 | 2181 |
2895 | 2182 |
2896 THREADED_TEST(EmbedderData) { | 2183 THREADED_TEST(EmbedderData) { |
2897 LocalContext env; | 2184 LocalContext env; |
2898 v8::Isolate* isolate = env->GetIsolate(); | 2185 v8::Isolate* isolate = env->GetIsolate(); |
2899 v8::HandleScope scope(isolate); | 2186 v8::HandleScope scope(isolate); |
2900 | 2187 |
2901 CheckEmbedderData( | 2188 CheckEmbedderData( |
2902 &env, 3, | 2189 &env, 3, v8::String::NewFromUtf8(isolate, "The quick brown fox jumps")); |
2903 v8::String::NewFromUtf8(isolate, "The quick brown fox jumps")); | 2190 CheckEmbedderData(&env, 2, |
2904 CheckEmbedderData(&env, 2, v8::String::NewFromUtf8(isolate, | 2191 v8::String::NewFromUtf8(isolate, "over the lazy dog.")); |
2905 "over the lazy dog.")); | |
2906 CheckEmbedderData(&env, 1, v8::Number::New(isolate, 1.2345)); | 2192 CheckEmbedderData(&env, 1, v8::Number::New(isolate, 1.2345)); |
2907 CheckEmbedderData(&env, 0, v8::Boolean::New(isolate, true)); | 2193 CheckEmbedderData(&env, 0, v8::Boolean::New(isolate, true)); |
2908 } | 2194 } |
2909 | 2195 |
2910 | 2196 |
2911 THREADED_TEST(GetIsolate) { | 2197 THREADED_TEST(GetIsolate) { |
2912 LocalContext env; | 2198 LocalContext env; |
2913 v8::Isolate* isolate = env->GetIsolate(); | 2199 v8::Isolate* isolate = env->GetIsolate(); |
2914 v8::HandleScope scope(isolate); | 2200 v8::HandleScope scope(isolate); |
2915 Local<v8::Object> obj = v8::Object::New(isolate); | 2201 Local<v8::Object> obj = v8::Object::New(isolate); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3029 } | 2315 } |
3030 | 2316 |
3031 | 2317 |
3032 THREADED_TEST(SymbolProperties) { | 2318 THREADED_TEST(SymbolProperties) { |
3033 LocalContext env; | 2319 LocalContext env; |
3034 v8::Isolate* isolate = env->GetIsolate(); | 2320 v8::Isolate* isolate = env->GetIsolate(); |
3035 v8::HandleScope scope(isolate); | 2321 v8::HandleScope scope(isolate); |
3036 | 2322 |
3037 v8::Local<v8::Object> obj = v8::Object::New(isolate); | 2323 v8::Local<v8::Object> obj = v8::Object::New(isolate); |
3038 v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate); | 2324 v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate); |
3039 v8::Local<v8::Symbol> sym2 = | 2325 v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, v8_str("my-symbol")); |
3040 v8::Symbol::New(isolate, v8_str("my-symbol")); | 2326 v8::Local<v8::Symbol> sym3 = v8::Symbol::New(isolate, v8_str("sym3")); |
3041 v8::Local<v8::Symbol> sym3 = | |
3042 v8::Symbol::New(isolate, v8_str("sym3")); | |
3043 | 2327 |
3044 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 2328 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
3045 | 2329 |
3046 // Check basic symbol functionality. | 2330 // Check basic symbol functionality. |
3047 CHECK(sym1->IsSymbol()); | 2331 CHECK(sym1->IsSymbol()); |
3048 CHECK(sym2->IsSymbol()); | 2332 CHECK(sym2->IsSymbol()); |
3049 CHECK(!obj->IsSymbol()); | 2333 CHECK(!obj->IsSymbol()); |
3050 | 2334 |
3051 CHECK(sym1->Equals(sym1)); | 2335 CHECK(sym1->Equals(sym1)); |
3052 CHECK(sym2->Equals(sym2)); | 2336 CHECK(sym2->Equals(sym2)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3092 v8::Integer::New(isolate, 20))); | 2376 v8::Integer::New(isolate, 20))); |
3093 CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length()); | 2377 CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length()); |
3094 CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); | 2378 CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); |
3095 | 2379 |
3096 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 2380 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
3097 | 2381 |
3098 CHECK(obj->SetAccessor(sym3, SymbolAccessorGetter, SymbolAccessorSetter)); | 2382 CHECK(obj->SetAccessor(sym3, SymbolAccessorGetter, SymbolAccessorSetter)); |
3099 CHECK(obj->Get(sym3)->IsUndefined()); | 2383 CHECK(obj->Get(sym3)->IsUndefined()); |
3100 CHECK(obj->Set(sym3, v8::Integer::New(isolate, 42))); | 2384 CHECK(obj->Set(sym3, v8::Integer::New(isolate, 42))); |
3101 CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); | 2385 CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); |
3102 CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals( | 2386 CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) |
3103 v8::Integer::New(isolate, 42))); | 2387 ->Equals(v8::Integer::New(isolate, 42))); |
3104 | 2388 |
3105 // Add another property and delete it afterwards to force the object in | 2389 // Add another property and delete it afterwards to force the object in |
3106 // slow case. | 2390 // slow case. |
3107 CHECK(obj->Set(sym2, v8::Integer::New(isolate, 2008))); | 2391 CHECK(obj->Set(sym2, v8::Integer::New(isolate, 2008))); |
3108 CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); | 2392 CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); |
3109 CHECK_EQ(2008, obj->Get(sym2)->Int32Value()); | 2393 CHECK_EQ(2008, obj->Get(sym2)->Int32Value()); |
3110 CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); | 2394 CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); |
3111 CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); | 2395 CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); |
3112 | 2396 |
3113 CHECK(obj->Has(sym1)); | 2397 CHECK(obj->Has(sym1)); |
3114 CHECK(obj->Has(sym2)); | 2398 CHECK(obj->Has(sym2)); |
3115 CHECK(obj->Has(sym3)); | 2399 CHECK(obj->Has(sym3)); |
3116 CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); | 2400 CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); |
3117 CHECK(obj->Delete(sym2)); | 2401 CHECK(obj->Delete(sym2)); |
3118 CHECK(obj->Has(sym1)); | 2402 CHECK(obj->Has(sym1)); |
3119 CHECK(!obj->Has(sym2)); | 2403 CHECK(!obj->Has(sym2)); |
3120 CHECK(obj->Has(sym3)); | 2404 CHECK(obj->Has(sym3)); |
3121 CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); | 2405 CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); |
3122 CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); | 2406 CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); |
3123 CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); | 2407 CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); |
3124 CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals( | 2408 CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) |
3125 v8::Integer::New(isolate, 42))); | 2409 ->Equals(v8::Integer::New(isolate, 42))); |
3126 CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); | 2410 CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); |
3127 | 2411 |
3128 // Symbol properties are inherited. | 2412 // Symbol properties are inherited. |
3129 v8::Local<v8::Object> child = v8::Object::New(isolate); | 2413 v8::Local<v8::Object> child = v8::Object::New(isolate); |
3130 child->SetPrototype(obj); | 2414 child->SetPrototype(obj); |
3131 CHECK(child->Has(sym1)); | 2415 CHECK(child->Has(sym1)); |
3132 CHECK_EQ(2002, child->Get(sym1)->Int32Value()); | 2416 CHECK_EQ(2002, child->Get(sym1)->Int32Value()); |
3133 CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); | 2417 CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); |
3134 CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals( | 2418 CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) |
3135 v8::Integer::New(isolate, 42))); | 2419 ->Equals(v8::Integer::New(isolate, 42))); |
3136 CHECK_EQ(0u, child->GetOwnPropertyNames()->Length()); | 2420 CHECK_EQ(0u, child->GetOwnPropertyNames()->Length()); |
3137 } | 2421 } |
3138 | 2422 |
3139 | 2423 |
3140 THREADED_TEST(SymbolTemplateProperties) { | 2424 THREADED_TEST(SymbolTemplateProperties) { |
3141 LocalContext env; | 2425 LocalContext env; |
3142 v8::Isolate* isolate = env->GetIsolate(); | 2426 v8::Isolate* isolate = env->GetIsolate(); |
3143 v8::HandleScope scope(isolate); | 2427 v8::HandleScope scope(isolate); |
3144 v8::Local<v8::FunctionTemplate> foo = v8::FunctionTemplate::New(isolate); | 2428 v8::Local<v8::FunctionTemplate> foo = v8::FunctionTemplate::New(isolate); |
3145 v8::Local<v8::Name> name = v8::Symbol::New(isolate); | 2429 v8::Local<v8::Name> name = v8::Symbol::New(isolate); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3275 CHECK(!obj->HasPrivate(priv)); | 2559 CHECK(!obj->HasPrivate(priv)); |
3276 | 2560 |
3277 CompileRun("var intern = %CreateGlobalPrivateSymbol('my-private')"); | 2561 CompileRun("var intern = %CreateGlobalPrivateSymbol('my-private')"); |
3278 v8::Local<Value> intern = env->Global()->Get(v8_str("intern")); | 2562 v8::Local<Value> intern = env->Global()->Get(v8_str("intern")); |
3279 CHECK(!obj->Has(intern)); | 2563 CHECK(!obj->Has(intern)); |
3280 } | 2564 } |
3281 | 2565 |
3282 | 2566 |
3283 class ScopedArrayBufferContents { | 2567 class ScopedArrayBufferContents { |
3284 public: | 2568 public: |
3285 explicit ScopedArrayBufferContents( | 2569 explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents) |
3286 const v8::ArrayBuffer::Contents& contents) | 2570 : contents_(contents) {} |
3287 : contents_(contents) {} | |
3288 ~ScopedArrayBufferContents() { free(contents_.Data()); } | 2571 ~ScopedArrayBufferContents() { free(contents_.Data()); } |
3289 void* Data() const { return contents_.Data(); } | 2572 void* Data() const { return contents_.Data(); } |
3290 size_t ByteLength() const { return contents_.ByteLength(); } | 2573 size_t ByteLength() const { return contents_.ByteLength(); } |
| 2574 |
3291 private: | 2575 private: |
3292 const v8::ArrayBuffer::Contents contents_; | 2576 const v8::ArrayBuffer::Contents contents_; |
3293 }; | 2577 }; |
3294 | 2578 |
3295 template <typename T> | 2579 template <typename T> |
3296 static void CheckInternalFieldsAreZero(v8::Handle<T> value) { | 2580 static void CheckInternalFieldsAreZero(v8::Handle<T> value) { |
3297 CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount()); | 2581 CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount()); |
3298 for (int i = 0; i < value->InternalFieldCount(); i++) { | 2582 for (int i = 0; i < value->InternalFieldCount(); i++) { |
3299 CHECK_EQ(0, value->GetInternalField(i)->Int32Value()); | 2583 CHECK_EQ(0, value->GetInternalField(i)->Int32Value()); |
3300 } | 2584 } |
(...skipping 15 matching lines...) Expand all Loading... |
3316 CHECK(ab->IsExternal()); | 2600 CHECK(ab->IsExternal()); |
3317 | 2601 |
3318 CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); | 2602 CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); |
3319 uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); | 2603 uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); |
3320 DCHECK(data != NULL); | 2604 DCHECK(data != NULL); |
3321 env->Global()->Set(v8_str("ab"), ab); | 2605 env->Global()->Set(v8_str("ab"), ab); |
3322 | 2606 |
3323 v8::Handle<v8::Value> result = CompileRun("ab.byteLength"); | 2607 v8::Handle<v8::Value> result = CompileRun("ab.byteLength"); |
3324 CHECK_EQ(1024, result->Int32Value()); | 2608 CHECK_EQ(1024, result->Int32Value()); |
3325 | 2609 |
3326 result = CompileRun("var u8 = new Uint8Array(ab);" | 2610 result = CompileRun( |
3327 "u8[0] = 0xFF;" | 2611 "var u8 = new Uint8Array(ab);" |
3328 "u8[1] = 0xAA;" | 2612 "u8[0] = 0xFF;" |
3329 "u8.length"); | 2613 "u8[1] = 0xAA;" |
| 2614 "u8.length"); |
3330 CHECK_EQ(1024, result->Int32Value()); | 2615 CHECK_EQ(1024, result->Int32Value()); |
3331 CHECK_EQ(0xFF, data[0]); | 2616 CHECK_EQ(0xFF, data[0]); |
3332 CHECK_EQ(0xAA, data[1]); | 2617 CHECK_EQ(0xAA, data[1]); |
3333 data[0] = 0xCC; | 2618 data[0] = 0xCC; |
3334 data[1] = 0x11; | 2619 data[1] = 0x11; |
3335 result = CompileRun("u8[0] + u8[1]"); | 2620 result = CompileRun("u8[0] + u8[1]"); |
3336 CHECK_EQ(0xDD, result->Int32Value()); | 2621 CHECK_EQ(0xDD, result->Int32Value()); |
3337 } | 2622 } |
3338 | 2623 |
3339 | 2624 |
3340 THREADED_TEST(ArrayBuffer_JSInternalToExternal) { | 2625 THREADED_TEST(ArrayBuffer_JSInternalToExternal) { |
3341 LocalContext env; | 2626 LocalContext env; |
3342 v8::Isolate* isolate = env->GetIsolate(); | 2627 v8::Isolate* isolate = env->GetIsolate(); |
3343 v8::HandleScope handle_scope(isolate); | 2628 v8::HandleScope handle_scope(isolate); |
3344 | 2629 |
3345 | 2630 |
3346 v8::Local<v8::Value> result = | 2631 v8::Local<v8::Value> result = CompileRun( |
3347 CompileRun("var ab1 = new ArrayBuffer(2);" | 2632 "var ab1 = new ArrayBuffer(2);" |
3348 "var u8_a = new Uint8Array(ab1);" | 2633 "var u8_a = new Uint8Array(ab1);" |
3349 "u8_a[0] = 0xAA;" | 2634 "u8_a[0] = 0xAA;" |
3350 "u8_a[1] = 0xFF; u8_a.buffer"); | 2635 "u8_a[1] = 0xFF; u8_a.buffer"); |
3351 Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); | 2636 Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); |
3352 CheckInternalFieldsAreZero(ab1); | 2637 CheckInternalFieldsAreZero(ab1); |
3353 CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); | 2638 CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); |
3354 CHECK(!ab1->IsExternal()); | 2639 CHECK(!ab1->IsExternal()); |
3355 ScopedArrayBufferContents ab1_contents(ab1->Externalize()); | 2640 ScopedArrayBufferContents ab1_contents(ab1->Externalize()); |
3356 CHECK(ab1->IsExternal()); | 2641 CHECK(ab1->IsExternal()); |
3357 | 2642 |
3358 result = CompileRun("ab1.byteLength"); | 2643 result = CompileRun("ab1.byteLength"); |
3359 CHECK_EQ(2, result->Int32Value()); | 2644 CHECK_EQ(2, result->Int32Value()); |
3360 result = CompileRun("u8_a[0]"); | 2645 result = CompileRun("u8_a[0]"); |
3361 CHECK_EQ(0xAA, result->Int32Value()); | 2646 CHECK_EQ(0xAA, result->Int32Value()); |
3362 result = CompileRun("u8_a[1]"); | 2647 result = CompileRun("u8_a[1]"); |
3363 CHECK_EQ(0xFF, result->Int32Value()); | 2648 CHECK_EQ(0xFF, result->Int32Value()); |
3364 result = CompileRun("var u8_b = new Uint8Array(ab1);" | 2649 result = CompileRun( |
3365 "u8_b[0] = 0xBB;" | 2650 "var u8_b = new Uint8Array(ab1);" |
3366 "u8_a[0]"); | 2651 "u8_b[0] = 0xBB;" |
| 2652 "u8_a[0]"); |
3367 CHECK_EQ(0xBB, result->Int32Value()); | 2653 CHECK_EQ(0xBB, result->Int32Value()); |
3368 result = CompileRun("u8_b[1]"); | 2654 result = CompileRun("u8_b[1]"); |
3369 CHECK_EQ(0xFF, result->Int32Value()); | 2655 CHECK_EQ(0xFF, result->Int32Value()); |
3370 | 2656 |
3371 CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); | 2657 CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); |
3372 uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); | 2658 uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); |
3373 CHECK_EQ(0xBB, ab1_data[0]); | 2659 CHECK_EQ(0xBB, ab1_data[0]); |
3374 CHECK_EQ(0xFF, ab1_data[1]); | 2660 CHECK_EQ(0xFF, ab1_data[1]); |
3375 ab1_data[0] = 0xCC; | 2661 ab1_data[0] = 0xCC; |
3376 ab1_data[1] = 0x11; | 2662 ab1_data[1] = 0x11; |
(...skipping 13 matching lines...) Expand all Loading... |
3390 v8::ArrayBuffer::New(isolate, my_data.start(), 100); | 2676 v8::ArrayBuffer::New(isolate, my_data.start(), 100); |
3391 CheckInternalFieldsAreZero(ab3); | 2677 CheckInternalFieldsAreZero(ab3); |
3392 CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); | 2678 CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); |
3393 CHECK(ab3->IsExternal()); | 2679 CHECK(ab3->IsExternal()); |
3394 | 2680 |
3395 env->Global()->Set(v8_str("ab3"), ab3); | 2681 env->Global()->Set(v8_str("ab3"), ab3); |
3396 | 2682 |
3397 v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); | 2683 v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); |
3398 CHECK_EQ(100, result->Int32Value()); | 2684 CHECK_EQ(100, result->Int32Value()); |
3399 | 2685 |
3400 result = CompileRun("var u8_b = new Uint8Array(ab3);" | 2686 result = CompileRun( |
3401 "u8_b[0] = 0xBB;" | 2687 "var u8_b = new Uint8Array(ab3);" |
3402 "u8_b[1] = 0xCC;" | 2688 "u8_b[0] = 0xBB;" |
3403 "u8_b.length"); | 2689 "u8_b[1] = 0xCC;" |
| 2690 "u8_b.length"); |
3404 CHECK_EQ(100, result->Int32Value()); | 2691 CHECK_EQ(100, result->Int32Value()); |
3405 CHECK_EQ(0xBB, my_data[0]); | 2692 CHECK_EQ(0xBB, my_data[0]); |
3406 CHECK_EQ(0xCC, my_data[1]); | 2693 CHECK_EQ(0xCC, my_data[1]); |
3407 my_data[0] = 0xCC; | 2694 my_data[0] = 0xCC; |
3408 my_data[1] = 0x11; | 2695 my_data[1] = 0x11; |
3409 result = CompileRun("u8_b[0] + u8_b[1]"); | 2696 result = CompileRun("u8_b[0] + u8_b[1]"); |
3410 CHECK_EQ(0xDD, result->Int32Value()); | 2697 CHECK_EQ(0xDD, result->Int32Value()); |
3411 } | 2698 } |
3412 | 2699 |
3413 | 2700 |
(...skipping 24 matching lines...) Expand all Loading... |
3438 static void CheckIsNeutered(v8::Handle<v8::TypedArray> ta) { | 2725 static void CheckIsNeutered(v8::Handle<v8::TypedArray> ta) { |
3439 CHECK_EQ(0, static_cast<int>(ta->ByteLength())); | 2726 CHECK_EQ(0, static_cast<int>(ta->ByteLength())); |
3440 CHECK_EQ(0, static_cast<int>(ta->Length())); | 2727 CHECK_EQ(0, static_cast<int>(ta->Length())); |
3441 CHECK_EQ(0, static_cast<int>(ta->ByteOffset())); | 2728 CHECK_EQ(0, static_cast<int>(ta->ByteOffset())); |
3442 } | 2729 } |
3443 | 2730 |
3444 | 2731 |
3445 static void CheckIsTypedArrayVarNeutered(const char* name) { | 2732 static void CheckIsTypedArrayVarNeutered(const char* name) { |
3446 i::ScopedVector<char> source(1024); | 2733 i::ScopedVector<char> source(1024); |
3447 i::SNPrintF(source, | 2734 i::SNPrintF(source, |
3448 "%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0", | 2735 "%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0", |
3449 name, name, name); | 2736 name, name, name); |
3450 CHECK(CompileRun(source.start())->IsTrue()); | 2737 CHECK(CompileRun(source.start())->IsTrue()); |
3451 v8::Handle<v8::TypedArray> ta = | 2738 v8::Handle<v8::TypedArray> ta = |
3452 v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); | 2739 v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); |
3453 CheckIsNeutered(ta); | 2740 CheckIsNeutered(ta); |
3454 } | 2741 } |
3455 | 2742 |
3456 | 2743 |
3457 template <typename TypedArray, int kElementSize> | 2744 template <typename TypedArray, int kElementSize> |
3458 static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab, | 2745 static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab, |
3459 int byteOffset, | 2746 int byteOffset, int length) { |
3460 int length) { | |
3461 v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length); | 2747 v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length); |
3462 CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); | 2748 CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); |
3463 CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset())); | 2749 CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset())); |
3464 CHECK_EQ(length, static_cast<int>(ta->Length())); | 2750 CHECK_EQ(length, static_cast<int>(ta->Length())); |
3465 CHECK_EQ(length * kElementSize, static_cast<int>(ta->ByteLength())); | 2751 CHECK_EQ(length * kElementSize, static_cast<int>(ta->ByteLength())); |
3466 return ta; | 2752 return ta; |
3467 } | 2753 } |
3468 | 2754 |
3469 | 2755 |
3470 THREADED_TEST(ArrayBuffer_NeuteringApi) { | 2756 THREADED_TEST(ArrayBuffer_NeuteringApi) { |
3471 LocalContext env; | 2757 LocalContext env; |
3472 v8::Isolate* isolate = env->GetIsolate(); | 2758 v8::Isolate* isolate = env->GetIsolate(); |
3473 v8::HandleScope handle_scope(isolate); | 2759 v8::HandleScope handle_scope(isolate); |
3474 | 2760 |
3475 v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024); | 2761 v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024); |
3476 | 2762 |
3477 v8::Handle<v8::Uint8Array> u8a = | 2763 v8::Handle<v8::Uint8Array> u8a = |
3478 CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023); | 2764 CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023); |
3479 v8::Handle<v8::Uint8ClampedArray> u8c = | 2765 v8::Handle<v8::Uint8ClampedArray> u8c = |
3480 CreateAndCheck<v8::Uint8ClampedArray, 1>(buffer, 1, 1023); | 2766 CreateAndCheck<v8::Uint8ClampedArray, 1>(buffer, 1, 1023); |
3481 v8::Handle<v8::Int8Array> i8a = | 2767 v8::Handle<v8::Int8Array> i8a = |
3482 CreateAndCheck<v8::Int8Array, 1>(buffer, 1, 1023); | 2768 CreateAndCheck<v8::Int8Array, 1>(buffer, 1, 1023); |
3483 | 2769 |
3484 v8::Handle<v8::Uint16Array> u16a = | 2770 v8::Handle<v8::Uint16Array> u16a = |
3485 CreateAndCheck<v8::Uint16Array, 2>(buffer, 2, 511); | 2771 CreateAndCheck<v8::Uint16Array, 2>(buffer, 2, 511); |
3486 v8::Handle<v8::Int16Array> i16a = | 2772 v8::Handle<v8::Int16Array> i16a = |
3487 CreateAndCheck<v8::Int16Array, 2>(buffer, 2, 511); | 2773 CreateAndCheck<v8::Int16Array, 2>(buffer, 2, 511); |
3488 | 2774 |
3489 v8::Handle<v8::Uint32Array> u32a = | 2775 v8::Handle<v8::Uint32Array> u32a = |
3490 CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); | 2776 CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); |
3491 v8::Handle<v8::Int32Array> i32a = | 2777 v8::Handle<v8::Int32Array> i32a = |
3492 CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); | 2778 CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); |
3493 | 2779 |
3494 v8::Handle<v8::Float32Array> f32a = | 2780 v8::Handle<v8::Float32Array> f32a = |
3495 CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); | 2781 CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); |
3496 v8::Handle<v8::Float64Array> f64a = | 2782 v8::Handle<v8::Float64Array> f64a = |
3497 CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); | 2783 CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); |
3498 | 2784 |
3499 v8::Handle<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); | 2785 v8::Handle<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); |
3500 CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); | 2786 CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); |
3501 CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); | 2787 CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); |
3502 CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); | 2788 CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); |
3503 | 2789 |
3504 ScopedArrayBufferContents contents(buffer->Externalize()); | 2790 ScopedArrayBufferContents contents(buffer->Externalize()); |
3505 buffer->Neuter(); | 2791 buffer->Neuter(); |
3506 CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); | 2792 CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); |
3507 CheckIsNeutered(u8a); | 2793 CheckIsNeutered(u8a); |
(...skipping 24 matching lines...) Expand all Loading... |
3532 "var u32a = new Uint32Array(ab, 4, 255);" | 2818 "var u32a = new Uint32Array(ab, 4, 255);" |
3533 "var i32a = new Int32Array(ab, 4, 255);" | 2819 "var i32a = new Int32Array(ab, 4, 255);" |
3534 "var f32a = new Float32Array(ab, 4, 255);" | 2820 "var f32a = new Float32Array(ab, 4, 255);" |
3535 "var f64a = new Float64Array(ab, 8, 127);" | 2821 "var f64a = new Float64Array(ab, 8, 127);" |
3536 "var dv = new DataView(ab, 1, 1023);"); | 2822 "var dv = new DataView(ab, 1, 1023);"); |
3537 | 2823 |
3538 v8::Handle<v8::ArrayBuffer> ab = | 2824 v8::Handle<v8::ArrayBuffer> ab = |
3539 Local<v8::ArrayBuffer>::Cast(CompileRun("ab")); | 2825 Local<v8::ArrayBuffer>::Cast(CompileRun("ab")); |
3540 | 2826 |
3541 v8::Handle<v8::DataView> dv = | 2827 v8::Handle<v8::DataView> dv = |
3542 v8::Handle<v8::DataView>::Cast(CompileRun("dv")); | 2828 v8::Handle<v8::DataView>::Cast(CompileRun("dv")); |
3543 | 2829 |
3544 ScopedArrayBufferContents contents(ab->Externalize()); | 2830 ScopedArrayBufferContents contents(ab->Externalize()); |
3545 ab->Neuter(); | 2831 ab->Neuter(); |
3546 CHECK_EQ(0, static_cast<int>(ab->ByteLength())); | 2832 CHECK_EQ(0, static_cast<int>(ab->ByteLength())); |
3547 CHECK_EQ(0, CompileRun("ab.byteLength")->Int32Value()); | 2833 CHECK_EQ(0, CompileRun("ab.byteLength")->Int32Value()); |
3548 | 2834 |
3549 CheckIsTypedArrayVarNeutered("u8a"); | 2835 CheckIsTypedArrayVarNeutered("u8a"); |
3550 CheckIsTypedArrayVarNeutered("u8c"); | 2836 CheckIsTypedArrayVarNeutered("u8c"); |
3551 CheckIsTypedArrayVarNeutered("i8a"); | 2837 CheckIsTypedArrayVarNeutered("i8a"); |
3552 CheckIsTypedArrayVarNeutered("u16a"); | 2838 CheckIsTypedArrayVarNeutered("u16a"); |
3553 CheckIsTypedArrayVarNeutered("i16a"); | 2839 CheckIsTypedArrayVarNeutered("i16a"); |
3554 CheckIsTypedArrayVarNeutered("u32a"); | 2840 CheckIsTypedArrayVarNeutered("u32a"); |
3555 CheckIsTypedArrayVarNeutered("i32a"); | 2841 CheckIsTypedArrayVarNeutered("i32a"); |
3556 CheckIsTypedArrayVarNeutered("f32a"); | 2842 CheckIsTypedArrayVarNeutered("f32a"); |
3557 CheckIsTypedArrayVarNeutered("f64a"); | 2843 CheckIsTypedArrayVarNeutered("f64a"); |
3558 | 2844 |
3559 CHECK(CompileRun("dv.byteLength == 0 && dv.byteOffset == 0")->IsTrue()); | 2845 CHECK(CompileRun("dv.byteLength == 0 && dv.byteOffset == 0")->IsTrue()); |
3560 CheckDataViewIsNeutered(dv); | 2846 CheckDataViewIsNeutered(dv); |
3561 } | 2847 } |
3562 | 2848 |
3563 | 2849 |
3564 | |
3565 THREADED_TEST(HiddenProperties) { | 2850 THREADED_TEST(HiddenProperties) { |
3566 LocalContext env; | 2851 LocalContext env; |
3567 v8::Isolate* isolate = env->GetIsolate(); | 2852 v8::Isolate* isolate = env->GetIsolate(); |
3568 v8::HandleScope scope(isolate); | 2853 v8::HandleScope scope(isolate); |
3569 | 2854 |
3570 v8::Local<v8::Object> obj = v8::Object::New(env->GetIsolate()); | 2855 v8::Local<v8::Object> obj = v8::Object::New(env->GetIsolate()); |
3571 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | 2856 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
3572 v8::Local<v8::String> empty = v8_str(""); | 2857 v8::Local<v8::String> empty = v8_str(""); |
3573 v8::Local<v8::String> prop_name = v8_str("prop_name"); | 2858 v8::Local<v8::String> prop_name = v8_str("prop_name"); |
3574 | 2859 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3636 CHECK(obj->GetHiddenValue(key).IsEmpty()); | 2921 CHECK(obj->GetHiddenValue(key).IsEmpty()); |
3637 // Make sure that the getter and setter from Object.prototype is not invoked. | 2922 // Make sure that the getter and setter from Object.prototype is not invoked. |
3638 // If it did we would have full access to the hidden properties in | 2923 // If it did we would have full access to the hidden properties in |
3639 // the accessor. | 2924 // the accessor. |
3640 CHECK(obj->SetHiddenValue(key, v8::Integer::New(env->GetIsolate(), 42))); | 2925 CHECK(obj->SetHiddenValue(key, v8::Integer::New(env->GetIsolate(), 42))); |
3641 ExpectFalse("set_called"); | 2926 ExpectFalse("set_called"); |
3642 CHECK_EQ(42, obj->GetHiddenValue(key)->Int32Value()); | 2927 CHECK_EQ(42, obj->GetHiddenValue(key)->Int32Value()); |
3643 } | 2928 } |
3644 | 2929 |
3645 | 2930 |
3646 static bool interceptor_for_hidden_properties_called; | |
3647 static void InterceptorForHiddenProperties( | |
3648 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
3649 interceptor_for_hidden_properties_called = true; | |
3650 } | |
3651 | |
3652 | |
3653 THREADED_TEST(HiddenPropertiesWithInterceptors) { | |
3654 LocalContext context; | |
3655 v8::Isolate* isolate = context->GetIsolate(); | |
3656 v8::HandleScope scope(isolate); | |
3657 | |
3658 interceptor_for_hidden_properties_called = false; | |
3659 | |
3660 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | |
3661 | |
3662 // Associate an interceptor with an object and start setting hidden values. | |
3663 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); | |
3664 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | |
3665 instance_templ->SetHandler( | |
3666 v8::NamedPropertyHandlerConfiguration(InterceptorForHiddenProperties)); | |
3667 Local<v8::Function> function = fun_templ->GetFunction(); | |
3668 Local<v8::Object> obj = function->NewInstance(); | |
3669 CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2302))); | |
3670 CHECK_EQ(2302, obj->GetHiddenValue(key)->Int32Value()); | |
3671 CHECK(!interceptor_for_hidden_properties_called); | |
3672 } | |
3673 | |
3674 | |
3675 THREADED_TEST(External) { | 2931 THREADED_TEST(External) { |
3676 v8::HandleScope scope(CcTest::isolate()); | 2932 v8::HandleScope scope(CcTest::isolate()); |
3677 int x = 3; | 2933 int x = 3; |
3678 Local<v8::External> ext = v8::External::New(CcTest::isolate(), &x); | 2934 Local<v8::External> ext = v8::External::New(CcTest::isolate(), &x); |
3679 LocalContext env; | 2935 LocalContext env; |
3680 env->Global()->Set(v8_str("ext"), ext); | 2936 env->Global()->Set(v8_str("ext"), ext); |
3681 Local<Value> reext_obj = CompileRun("this.ext"); | 2937 Local<Value> reext_obj = CompileRun("this.ext"); |
3682 v8::Handle<v8::External> reext = reext_obj.As<v8::External>(); | 2938 v8::Handle<v8::External> reext = reext_obj.As<v8::External>(); |
3683 int* ptr = static_cast<int*>(reext->Value()); | 2939 int* ptr = static_cast<int*>(reext->Value()); |
3684 CHECK_EQ(x, 3); | 2940 CHECK_EQ(x, 3); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3773 { | 3029 { |
3774 v8::HandleScope scope(isolate); | 3030 v8::HandleScope scope(isolate); |
3775 Local<String> empty; | 3031 Local<String> empty; |
3776 global.Reset(isolate, empty); | 3032 global.Reset(isolate, empty); |
3777 } | 3033 } |
3778 CHECK(global.IsEmpty()); | 3034 CHECK(global.IsEmpty()); |
3779 CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1); | 3035 CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1); |
3780 } | 3036 } |
3781 | 3037 |
3782 | 3038 |
3783 template<class T> | 3039 template <class T> |
3784 static v8::UniquePersistent<T> PassUnique(v8::UniquePersistent<T> unique) { | 3040 static v8::UniquePersistent<T> PassUnique(v8::UniquePersistent<T> unique) { |
3785 return unique.Pass(); | 3041 return unique.Pass(); |
3786 } | 3042 } |
3787 | 3043 |
3788 | 3044 |
3789 template<class T> | 3045 template <class T> |
3790 static v8::UniquePersistent<T> ReturnUnique(v8::Isolate* isolate, | 3046 static v8::UniquePersistent<T> ReturnUnique(v8::Isolate* isolate, |
3791 const v8::Persistent<T> & global) { | 3047 const v8::Persistent<T>& global) { |
3792 v8::UniquePersistent<String> unique(isolate, global); | 3048 v8::UniquePersistent<String> unique(isolate, global); |
3793 return unique.Pass(); | 3049 return unique.Pass(); |
3794 } | 3050 } |
3795 | 3051 |
3796 | 3052 |
3797 THREADED_TEST(UniquePersistent) { | 3053 THREADED_TEST(UniquePersistent) { |
3798 v8::Isolate* isolate = CcTest::isolate(); | 3054 v8::Isolate* isolate = CcTest::isolate(); |
3799 v8::Persistent<String> global; | 3055 v8::Persistent<String> global; |
3800 { | 3056 { |
3801 v8::HandleScope scope(isolate); | 3057 v8::HandleScope scope(isolate); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3840 { | 3096 { |
3841 v8::UniquePersistent<String> unique = ReturnUnique(isolate, global); | 3097 v8::UniquePersistent<String> unique = ReturnUnique(isolate, global); |
3842 CHECK(unique == global); | 3098 CHECK(unique == global); |
3843 CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); | 3099 CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); |
3844 } | 3100 } |
3845 CHECK_EQ(initial_handle_count, global_handles->global_handles_count()); | 3101 CHECK_EQ(initial_handle_count, global_handles->global_handles_count()); |
3846 global.Reset(); | 3102 global.Reset(); |
3847 } | 3103 } |
3848 | 3104 |
3849 | 3105 |
3850 template<typename K, typename V> | 3106 template <typename K, typename V> |
3851 class WeakStdMapTraits : public v8::StdMapTraits<K, V> { | 3107 class WeakStdMapTraits : public v8::StdMapTraits<K, V> { |
3852 public: | 3108 public: |
3853 typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V> > | 3109 typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V>> MapType; |
3854 MapType; | |
3855 static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak; | 3110 static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak; |
3856 struct WeakCallbackDataType { | 3111 struct WeakCallbackDataType { |
3857 MapType* map; | 3112 MapType* map; |
3858 K key; | 3113 K key; |
3859 }; | 3114 }; |
3860 static WeakCallbackDataType* WeakCallbackParameter( | 3115 static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key, |
3861 MapType* map, const K& key, Local<V> value) { | 3116 Local<V> value) { |
3862 WeakCallbackDataType* data = new WeakCallbackDataType; | 3117 WeakCallbackDataType* data = new WeakCallbackDataType; |
3863 data->map = map; | 3118 data->map = map; |
3864 data->key = key; | 3119 data->key = key; |
3865 return data; | 3120 return data; |
3866 } | 3121 } |
3867 static MapType* MapFromWeakCallbackData( | 3122 static MapType* MapFromWeakCallbackData( |
3868 const v8::WeakCallbackData<V, WeakCallbackDataType>& data) { | 3123 const v8::WeakCallbackData<V, WeakCallbackDataType>& data) { |
3869 return data.GetParameter()->map; | 3124 return data.GetParameter()->map; |
3870 } | 3125 } |
3871 static K KeyFromWeakCallbackData( | 3126 static K KeyFromWeakCallbackData( |
3872 const v8::WeakCallbackData<V, WeakCallbackDataType>& data) { | 3127 const v8::WeakCallbackData<V, WeakCallbackDataType>& data) { |
3873 return data.GetParameter()->key; | 3128 return data.GetParameter()->key; |
3874 } | 3129 } |
3875 static void DisposeCallbackData(WeakCallbackDataType* data) { | 3130 static void DisposeCallbackData(WeakCallbackDataType* data) { delete data; } |
3876 delete data; | |
3877 } | |
3878 static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value, | 3131 static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value, |
3879 K key) { } | 3132 K key) {} |
3880 }; | 3133 }; |
3881 | 3134 |
3882 | 3135 |
3883 template<typename Map> | 3136 template <typename Map> |
3884 static void TestPersistentValueMap() { | 3137 static void TestPersistentValueMap() { |
3885 LocalContext env; | 3138 LocalContext env; |
3886 v8::Isolate* isolate = env->GetIsolate(); | 3139 v8::Isolate* isolate = env->GetIsolate(); |
3887 Map map(isolate); | 3140 Map map(isolate); |
3888 v8::internal::GlobalHandles* global_handles = | 3141 v8::internal::GlobalHandles* global_handles = |
3889 reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles(); | 3142 reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles(); |
3890 int initial_handle_count = global_handles->global_handles_count(); | 3143 int initial_handle_count = global_handles->global_handles_count(); |
3891 CHECK_EQ(0, static_cast<int>(map.Size())); | 3144 CHECK_EQ(0, static_cast<int>(map.Size())); |
3892 { | 3145 { |
3893 HandleScope scope(isolate); | 3146 HandleScope scope(isolate); |
(...skipping 13 matching lines...) Expand all Loading... |
3907 CHECK(expected == removed); | 3160 CHECK(expected == removed); |
3908 removed = map.Remove(7); | 3161 removed = map.Remove(7); |
3909 CHECK(removed.IsEmpty()); | 3162 CHECK(removed.IsEmpty()); |
3910 map.Set(8, expected); | 3163 map.Set(8, expected); |
3911 CHECK_EQ(1, static_cast<int>(map.Size())); | 3164 CHECK_EQ(1, static_cast<int>(map.Size())); |
3912 map.Set(8, expected); | 3165 map.Set(8, expected); |
3913 CHECK_EQ(1, static_cast<int>(map.Size())); | 3166 CHECK_EQ(1, static_cast<int>(map.Size())); |
3914 { | 3167 { |
3915 typename Map::PersistentValueReference ref; | 3168 typename Map::PersistentValueReference ref; |
3916 Local<v8::Object> expected2 = v8::Object::New(isolate); | 3169 Local<v8::Object> expected2 = v8::Object::New(isolate); |
3917 removed = map.Set(8, | 3170 removed = map.Set(8, v8::UniquePersistent<v8::Object>(isolate, expected2), |
3918 v8::UniquePersistent<v8::Object>(isolate, expected2), &ref); | 3171 &ref); |
3919 CHECK_EQ(1, static_cast<int>(map.Size())); | 3172 CHECK_EQ(1, static_cast<int>(map.Size())); |
3920 CHECK(expected == removed); | 3173 CHECK(expected == removed); |
3921 CHECK(expected2->Equals(ref.NewLocal(isolate))); | 3174 CHECK(expected2->Equals(ref.NewLocal(isolate))); |
3922 } | 3175 } |
3923 } | 3176 } |
3924 CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); | 3177 CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); |
3925 if (map.IsWeak()) { | 3178 if (map.IsWeak()) { |
3926 reinterpret_cast<v8::internal::Isolate*>(isolate)->heap()-> | 3179 reinterpret_cast<v8::internal::Isolate*>(isolate) |
3927 CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 3180 ->heap() |
| 3181 ->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
3928 } else { | 3182 } else { |
3929 map.Clear(); | 3183 map.Clear(); |
3930 } | 3184 } |
3931 CHECK_EQ(0, static_cast<int>(map.Size())); | 3185 CHECK_EQ(0, static_cast<int>(map.Size())); |
3932 CHECK_EQ(initial_handle_count, global_handles->global_handles_count()); | 3186 CHECK_EQ(initial_handle_count, global_handles->global_handles_count()); |
3933 } | 3187 } |
3934 | 3188 |
3935 | 3189 |
3936 TEST(PersistentValueMap) { | 3190 TEST(PersistentValueMap) { |
3937 // Default case, w/o weak callbacks: | 3191 // Default case, w/o weak callbacks: |
3938 TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object> >(); | 3192 TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object>>(); |
3939 | 3193 |
3940 // Custom traits with weak callbacks: | 3194 // Custom traits with weak callbacks: |
3941 typedef v8::PersistentValueMap<int, v8::Object, | 3195 typedef v8::PersistentValueMap<int, v8::Object, |
3942 WeakStdMapTraits<int, v8::Object> > WeakPersistentValueMap; | 3196 WeakStdMapTraits<int, v8::Object>> |
| 3197 WeakPersistentValueMap; |
3943 TestPersistentValueMap<WeakPersistentValueMap>(); | 3198 TestPersistentValueMap<WeakPersistentValueMap>(); |
3944 } | 3199 } |
3945 | 3200 |
3946 | 3201 |
3947 TEST(PersistentValueVector) { | 3202 TEST(PersistentValueVector) { |
3948 LocalContext env; | 3203 LocalContext env; |
3949 v8::Isolate* isolate = env->GetIsolate(); | 3204 v8::Isolate* isolate = env->GetIsolate(); |
3950 v8::internal::GlobalHandles* global_handles = | 3205 v8::internal::GlobalHandles* global_handles = |
3951 reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles(); | 3206 reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles(); |
3952 int handle_count = global_handles->global_handles_count(); | 3207 int handle_count = global_handles->global_handles_count(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4041 THREADED_TEST(LocalHandle) { | 3296 THREADED_TEST(LocalHandle) { |
4042 v8::HandleScope scope(CcTest::isolate()); | 3297 v8::HandleScope scope(CcTest::isolate()); |
4043 v8::Local<String> local = | 3298 v8::Local<String> local = |
4044 v8::Local<String>::New(CcTest::isolate(), v8_str("str")); | 3299 v8::Local<String>::New(CcTest::isolate(), v8_str("str")); |
4045 CHECK_EQ(local->Length(), 3); | 3300 CHECK_EQ(local->Length(), 3); |
4046 } | 3301 } |
4047 | 3302 |
4048 | 3303 |
4049 class WeakCallCounter { | 3304 class WeakCallCounter { |
4050 public: | 3305 public: |
4051 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } | 3306 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) {} |
4052 int id() { return id_; } | 3307 int id() { return id_; } |
4053 void increment() { number_of_weak_calls_++; } | 3308 void increment() { number_of_weak_calls_++; } |
4054 int NumberOfWeakCalls() { return number_of_weak_calls_; } | 3309 int NumberOfWeakCalls() { return number_of_weak_calls_; } |
| 3310 |
4055 private: | 3311 private: |
4056 int id_; | 3312 int id_; |
4057 int number_of_weak_calls_; | 3313 int number_of_weak_calls_; |
4058 }; | 3314 }; |
4059 | 3315 |
4060 | 3316 |
4061 template<typename T> | 3317 template <typename T> |
4062 struct WeakCallCounterAndPersistent { | 3318 struct WeakCallCounterAndPersistent { |
4063 explicit WeakCallCounterAndPersistent(WeakCallCounter* counter) | 3319 explicit WeakCallCounterAndPersistent(WeakCallCounter* counter) |
4064 : counter(counter) {} | 3320 : counter(counter) {} |
4065 WeakCallCounter* counter; | 3321 WeakCallCounter* counter; |
4066 v8::Persistent<T> handle; | 3322 v8::Persistent<T> handle; |
4067 }; | 3323 }; |
4068 | 3324 |
4069 | 3325 |
4070 template <typename T> | 3326 template <typename T> |
4071 static void WeakPointerCallback( | 3327 static void WeakPointerCallback( |
4072 const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T> >& data) { | 3328 const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T>>& data) { |
4073 CHECK_EQ(1234, data.GetParameter()->counter->id()); | 3329 CHECK_EQ(1234, data.GetParameter()->counter->id()); |
4074 data.GetParameter()->counter->increment(); | 3330 data.GetParameter()->counter->increment(); |
4075 data.GetParameter()->handle.Reset(); | 3331 data.GetParameter()->handle.Reset(); |
4076 } | 3332 } |
4077 | 3333 |
4078 | 3334 |
4079 template<typename T> | 3335 template <typename T> |
4080 static UniqueId MakeUniqueId(const Persistent<T>& p) { | 3336 static UniqueId MakeUniqueId(const Persistent<T>& p) { |
4081 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); | 3337 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); |
4082 } | 3338 } |
4083 | 3339 |
4084 | 3340 |
4085 THREADED_TEST(ApiObjectGroups) { | 3341 THREADED_TEST(ApiObjectGroups) { |
4086 LocalContext env; | 3342 LocalContext env; |
4087 v8::Isolate* iso = env->GetIsolate(); | 3343 v8::Isolate* iso = env->GetIsolate(); |
4088 HandleScope scope(iso); | 3344 HandleScope scope(iso); |
4089 | 3345 |
(...skipping 22 matching lines...) Expand all Loading... |
4112 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); | 3368 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); |
4113 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); | 3369 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); |
4114 } | 3370 } |
4115 | 3371 |
4116 WeakCallCounterAndPersistent<Value> root(&counter); | 3372 WeakCallCounterAndPersistent<Value> root(&counter); |
4117 root.handle.Reset(iso, g1s1.handle); // make a root. | 3373 root.handle.Reset(iso, g1s1.handle); // make a root. |
4118 | 3374 |
4119 // Connect group 1 and 2, make a cycle. | 3375 // Connect group 1 and 2, make a cycle. |
4120 { | 3376 { |
4121 HandleScope scope(iso); | 3377 HandleScope scope(iso); |
4122 CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())-> | 3378 CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>()) |
4123 Set(0, Local<Value>::New(iso, g2s2.handle))); | 3379 ->Set(0, Local<Value>::New(iso, g2s2.handle))); |
4124 CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>())-> | 3380 CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>()) |
4125 Set(0, Local<Value>::New(iso, g1s1.handle))); | 3381 ->Set(0, Local<Value>::New(iso, g1s1.handle))); |
4126 } | 3382 } |
4127 | 3383 |
4128 { | 3384 { |
4129 UniqueId id1 = MakeUniqueId(g1s1.handle); | 3385 UniqueId id1 = MakeUniqueId(g1s1.handle); |
4130 UniqueId id2 = MakeUniqueId(g2s2.handle); | 3386 UniqueId id2 = MakeUniqueId(g2s2.handle); |
4131 iso->SetObjectGroupId(g1s1.handle, id1); | 3387 iso->SetObjectGroupId(g1s1.handle, id1); |
4132 iso->SetObjectGroupId(g1s2.handle, id1); | 3388 iso->SetObjectGroupId(g1s2.handle, id1); |
4133 iso->SetReferenceFromGroup(id1, g1c1.handle); | 3389 iso->SetReferenceFromGroup(id1, g1c1.handle); |
4134 iso->SetObjectGroupId(g2s1.handle, id2); | 3390 iso->SetObjectGroupId(g2s1.handle, id2); |
4135 iso->SetObjectGroupId(g2s2.handle, id2); | 3391 iso->SetObjectGroupId(g2s2.handle, id2); |
4136 iso->SetReferenceFromGroup(id2, g2c1.handle); | 3392 iso->SetReferenceFromGroup(id2, g2c1.handle); |
4137 } | 3393 } |
4138 // Do a single full GC, ensure incremental marking is stopped. | 3394 // Do a single full GC, ensure incremental marking is stopped. |
4139 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 3395 v8::internal::Heap* heap = |
4140 iso)->heap(); | 3396 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
4141 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 3397 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
4142 | 3398 |
4143 // All object should be alive. | 3399 // All object should be alive. |
4144 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 3400 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
4145 | 3401 |
4146 // Weaken the root. | 3402 // Weaken the root. |
4147 root.handle.SetWeak(&root, &WeakPointerCallback); | 3403 root.handle.SetWeak(&root, &WeakPointerCallback); |
4148 // But make children strong roots---all the objects (except for children) | 3404 // But make children strong roots---all the objects (except for children) |
4149 // should be collectable now. | 3405 // should be collectable now. |
4150 g1c1.handle.ClearWeak(); | 3406 g1c1.handle.ClearWeak(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4223 UniqueId id1 = MakeUniqueId(g1s1.handle); | 3479 UniqueId id1 = MakeUniqueId(g1s1.handle); |
4224 UniqueId id2 = MakeUniqueId(g2s2.handle); | 3480 UniqueId id2 = MakeUniqueId(g2s2.handle); |
4225 iso->SetObjectGroupId(g1s1.handle, id1); | 3481 iso->SetObjectGroupId(g1s1.handle, id1); |
4226 iso->SetObjectGroupId(g1s2.handle, id1); | 3482 iso->SetObjectGroupId(g1s2.handle, id1); |
4227 iso->SetReference(g1s1.handle, g1c1.handle); | 3483 iso->SetReference(g1s1.handle, g1c1.handle); |
4228 iso->SetObjectGroupId(g2s1.handle, id2); | 3484 iso->SetObjectGroupId(g2s1.handle, id2); |
4229 iso->SetObjectGroupId(g2s2.handle, id2); | 3485 iso->SetObjectGroupId(g2s2.handle, id2); |
4230 iso->SetReferenceFromGroup(id2, g2c1.handle); | 3486 iso->SetReferenceFromGroup(id2, g2c1.handle); |
4231 } | 3487 } |
4232 // Do a single full GC, ensure incremental marking is stopped. | 3488 // Do a single full GC, ensure incremental marking is stopped. |
4233 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 3489 v8::internal::Heap* heap = |
4234 iso)->heap(); | 3490 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
4235 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 3491 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
4236 | 3492 |
4237 // All object should be alive. | 3493 // All object should be alive. |
4238 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 3494 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
4239 | 3495 |
4240 // Weaken the root. | 3496 // Weaken the root. |
4241 root.handle.SetWeak(&root, &WeakPointerCallback); | 3497 root.handle.SetWeak(&root, &WeakPointerCallback); |
4242 // But make children strong roots---all the objects (except for children) | 3498 // But make children strong roots---all the objects (except for children) |
4243 // should be collectable now. | 3499 // should be collectable now. |
4244 g1c1.handle.ClearWeak(); | 3500 g1c1.handle.ClearWeak(); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4335 iso->SetObjectGroupId(g2s2.handle, id2); | 3591 iso->SetObjectGroupId(g2s2.handle, id2); |
4336 iso->SetReferenceFromGroup(id2, g3s1.handle); | 3592 iso->SetReferenceFromGroup(id2, g3s1.handle); |
4337 iso->SetObjectGroupId(g3s1.handle, id3); | 3593 iso->SetObjectGroupId(g3s1.handle, id3); |
4338 iso->SetObjectGroupId(g3s2.handle, id3); | 3594 iso->SetObjectGroupId(g3s2.handle, id3); |
4339 iso->SetReferenceFromGroup(id3, g4s1.handle); | 3595 iso->SetReferenceFromGroup(id3, g4s1.handle); |
4340 iso->SetObjectGroupId(g4s1.handle, id4); | 3596 iso->SetObjectGroupId(g4s1.handle, id4); |
4341 iso->SetObjectGroupId(g4s2.handle, id4); | 3597 iso->SetObjectGroupId(g4s2.handle, id4); |
4342 iso->SetReferenceFromGroup(id4, g1s1.handle); | 3598 iso->SetReferenceFromGroup(id4, g1s1.handle); |
4343 } | 3599 } |
4344 // Do a single full GC | 3600 // Do a single full GC |
4345 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 3601 v8::internal::Heap* heap = |
4346 iso)->heap(); | 3602 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
4347 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 3603 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
4348 | 3604 |
4349 // All object should be alive. | 3605 // All object should be alive. |
4350 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 3606 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
4351 | 3607 |
4352 // Weaken the root. | 3608 // Weaken the root. |
4353 root.handle.SetWeak(&root, &WeakPointerCallback); | 3609 root.handle.SetWeak(&root, &WeakPointerCallback); |
4354 | 3610 |
4355 // Groups are deleted, rebuild groups. | 3611 // Groups are deleted, rebuild groups. |
4356 { | 3612 { |
(...skipping 30 matching lines...) Expand all Loading... |
4387 WeakCallCounter counter(1234); | 3643 WeakCallCounter counter(1234); |
4388 | 3644 |
4389 WeakCallCounterAndPersistent<Value> weak_obj(&counter); | 3645 WeakCallCounterAndPersistent<Value> weak_obj(&counter); |
4390 | 3646 |
4391 // Create a weak object that references a internalized string. | 3647 // Create a weak object that references a internalized string. |
4392 { | 3648 { |
4393 HandleScope scope(iso); | 3649 HandleScope scope(iso); |
4394 weak_obj.handle.Reset(iso, Object::New(iso)); | 3650 weak_obj.handle.Reset(iso, Object::New(iso)); |
4395 weak_obj.handle.SetWeak(&weak_obj, &WeakPointerCallback); | 3651 weak_obj.handle.SetWeak(&weak_obj, &WeakPointerCallback); |
4396 CHECK(weak_obj.handle.IsWeak()); | 3652 CHECK(weak_obj.handle.IsWeak()); |
4397 Local<Object>::New(iso, weak_obj.handle.As<Object>())->Set( | 3653 Local<Object>::New(iso, weak_obj.handle.As<Object>()) |
4398 v8_str("x"), | 3654 ->Set(v8_str("x"), String::NewFromUtf8(iso, "magic cookie", |
4399 String::NewFromUtf8(iso, "magic cookie", String::kInternalizedString)); | 3655 String::kInternalizedString)); |
4400 } | 3656 } |
4401 // Do a single full GC | 3657 // Do a single full GC |
4402 i::Isolate* i_iso = reinterpret_cast<v8::internal::Isolate*>(iso); | 3658 i::Isolate* i_iso = reinterpret_cast<v8::internal::Isolate*>(iso); |
4403 i::Heap* heap = i_iso->heap(); | 3659 i::Heap* heap = i_iso->heap(); |
4404 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 3660 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
4405 | 3661 |
4406 // We should have received the weak callback. | 3662 // We should have received the weak callback. |
4407 CHECK_EQ(1, counter.NumberOfWeakCalls()); | 3663 CHECK_EQ(1, counter.NumberOfWeakCalls()); |
4408 | 3664 |
4409 // Check that the string is still alive. | 3665 // Check that the string is still alive. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4465 { | 3721 { |
4466 HandleScope handle_scope(iso); | 3722 HandleScope handle_scope(iso); |
4467 g1s1.handle.MarkPartiallyDependent(); | 3723 g1s1.handle.MarkPartiallyDependent(); |
4468 g1s2.handle.MarkPartiallyDependent(); | 3724 g1s2.handle.MarkPartiallyDependent(); |
4469 g2s1.handle.MarkPartiallyDependent(); | 3725 g2s1.handle.MarkPartiallyDependent(); |
4470 g2s2.handle.MarkPartiallyDependent(); | 3726 g2s2.handle.MarkPartiallyDependent(); |
4471 g3s1.handle.MarkPartiallyDependent(); | 3727 g3s1.handle.MarkPartiallyDependent(); |
4472 g3s2.handle.MarkPartiallyDependent(); | 3728 g3s2.handle.MarkPartiallyDependent(); |
4473 iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); | 3729 iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); |
4474 iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); | 3730 iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); |
4475 Local<Object>::New(iso, g1s1.handle.As<Object>())->Set( | 3731 Local<Object>::New(iso, g1s1.handle.As<Object>()) |
4476 v8_str("x"), Local<Value>::New(iso, g2s1.handle)); | 3732 ->Set(v8_str("x"), Local<Value>::New(iso, g2s1.handle)); |
4477 iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); | 3733 iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); |
4478 iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); | 3734 iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); |
4479 Local<Object>::New(iso, g2s1.handle.As<Object>())->Set( | 3735 Local<Object>::New(iso, g2s1.handle.As<Object>()) |
4480 v8_str("x"), Local<Value>::New(iso, g3s1.handle)); | 3736 ->Set(v8_str("x"), Local<Value>::New(iso, g3s1.handle)); |
4481 iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); | 3737 iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); |
4482 iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); | 3738 iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); |
4483 Local<Object>::New(iso, g3s1.handle.As<Object>())->Set( | 3739 Local<Object>::New(iso, g3s1.handle.As<Object>()) |
4484 v8_str("x"), Local<Value>::New(iso, g1s1.handle)); | 3740 ->Set(v8_str("x"), Local<Value>::New(iso, g1s1.handle)); |
4485 } | 3741 } |
4486 | 3742 |
4487 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 3743 v8::internal::Heap* heap = |
4488 iso)->heap(); | 3744 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
4489 heap->CollectAllGarbage(i::Heap::kNoGCFlags); | 3745 heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
4490 | 3746 |
4491 // All objects should be alive. | 3747 // All objects should be alive. |
4492 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 3748 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
4493 | 3749 |
4494 // Weaken the root. | 3750 // Weaken the root. |
4495 root.handle.SetWeak(&root, &WeakPointerCallback); | 3751 root.handle.SetWeak(&root, &WeakPointerCallback); |
4496 root.handle.MarkPartiallyDependent(); | 3752 root.handle.MarkPartiallyDependent(); |
4497 | 3753 |
4498 // Groups are deleted, rebuild groups. | 3754 // Groups are deleted, rebuild groups. |
4499 { | 3755 { |
4500 HandleScope handle_scope(iso); | 3756 HandleScope handle_scope(iso); |
4501 g1s1.handle.MarkPartiallyDependent(); | 3757 g1s1.handle.MarkPartiallyDependent(); |
4502 g1s2.handle.MarkPartiallyDependent(); | 3758 g1s2.handle.MarkPartiallyDependent(); |
4503 g2s1.handle.MarkPartiallyDependent(); | 3759 g2s1.handle.MarkPartiallyDependent(); |
4504 g2s2.handle.MarkPartiallyDependent(); | 3760 g2s2.handle.MarkPartiallyDependent(); |
4505 g3s1.handle.MarkPartiallyDependent(); | 3761 g3s1.handle.MarkPartiallyDependent(); |
4506 g3s2.handle.MarkPartiallyDependent(); | 3762 g3s2.handle.MarkPartiallyDependent(); |
4507 iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); | 3763 iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); |
4508 iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); | 3764 iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); |
4509 Local<Object>::New(iso, g1s1.handle.As<Object>())->Set( | 3765 Local<Object>::New(iso, g1s1.handle.As<Object>()) |
4510 v8_str("x"), Local<Value>::New(iso, g2s1.handle)); | 3766 ->Set(v8_str("x"), Local<Value>::New(iso, g2s1.handle)); |
4511 iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); | 3767 iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); |
4512 iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); | 3768 iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); |
4513 Local<Object>::New(iso, g2s1.handle.As<Object>())->Set( | 3769 Local<Object>::New(iso, g2s1.handle.As<Object>()) |
4514 v8_str("x"), Local<Value>::New(iso, g3s1.handle)); | 3770 ->Set(v8_str("x"), Local<Value>::New(iso, g3s1.handle)); |
4515 iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); | 3771 iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); |
4516 iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); | 3772 iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); |
4517 Local<Object>::New(iso, g3s1.handle.As<Object>())->Set( | 3773 Local<Object>::New(iso, g3s1.handle.As<Object>()) |
4518 v8_str("x"), Local<Value>::New(iso, g1s1.handle)); | 3774 ->Set(v8_str("x"), Local<Value>::New(iso, g1s1.handle)); |
4519 } | 3775 } |
4520 | 3776 |
4521 heap->CollectAllGarbage(i::Heap::kNoGCFlags); | 3777 heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
4522 | 3778 |
4523 // All objects should be gone. 7 global handles in total. | 3779 // All objects should be gone. 7 global handles in total. |
4524 CHECK_EQ(7, counter.NumberOfWeakCalls()); | 3780 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
4525 } | 3781 } |
4526 | 3782 |
4527 | 3783 |
4528 THREADED_TEST(ScriptException) { | 3784 THREADED_TEST(ScriptException) { |
4529 LocalContext env; | 3785 LocalContext env; |
4530 v8::HandleScope scope(env->GetIsolate()); | 3786 v8::HandleScope scope(env->GetIsolate()); |
4531 Local<Script> script = v8_compile("throw 'panama!';"); | 3787 Local<Script> script = v8_compile("throw 'panama!';"); |
4532 v8::TryCatch try_catch; | 3788 v8::TryCatch try_catch; |
4533 Local<Value> result = script->Run(); | 3789 Local<Value> result = script->Run(); |
4534 CHECK(result.IsEmpty()); | 3790 CHECK(result.IsEmpty()); |
4535 CHECK(try_catch.HasCaught()); | 3791 CHECK(try_catch.HasCaught()); |
4536 String::Utf8Value exception_value(try_catch.Exception()); | 3792 String::Utf8Value exception_value(try_catch.Exception()); |
4537 CHECK_EQ(0, strcmp(*exception_value, "panama!")); | 3793 CHECK_EQ(0, strcmp(*exception_value, "panama!")); |
4538 } | 3794 } |
4539 | 3795 |
4540 | 3796 |
4541 TEST(TryCatchCustomException) { | 3797 TEST(TryCatchCustomException) { |
4542 LocalContext env; | 3798 LocalContext env; |
4543 v8::Isolate* isolate = env->GetIsolate(); | 3799 v8::Isolate* isolate = env->GetIsolate(); |
4544 v8::HandleScope scope(isolate); | 3800 v8::HandleScope scope(isolate); |
4545 v8::TryCatch try_catch; | 3801 v8::TryCatch try_catch; |
4546 CompileRun("function CustomError() { this.a = 'b'; }" | 3802 CompileRun( |
4547 "(function f() { throw new CustomError(); })();"); | 3803 "function CustomError() { this.a = 'b'; }" |
| 3804 "(function f() { throw new CustomError(); })();"); |
4548 CHECK(try_catch.HasCaught()); | 3805 CHECK(try_catch.HasCaught()); |
4549 CHECK(try_catch.Exception()->ToObject(isolate)->Get(v8_str("a"))->Equals( | 3806 CHECK(try_catch.Exception() |
4550 v8_str("b"))); | 3807 ->ToObject(isolate) |
| 3808 ->Get(v8_str("a")) |
| 3809 ->Equals(v8_str("b"))); |
4551 } | 3810 } |
4552 | 3811 |
4553 | 3812 |
4554 bool message_received; | 3813 bool message_received; |
4555 | 3814 |
4556 | 3815 |
4557 static void check_message_0(v8::Handle<v8::Message> message, | 3816 static void check_message_0(v8::Handle<v8::Message> message, |
4558 v8::Handle<Value> data) { | 3817 v8::Handle<Value> data) { |
4559 CHECK_EQ(5.76, data->NumberValue()); | 3818 CHECK_EQ(5.76, data->NumberValue()); |
4560 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); | 3819 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4611 } | 3870 } |
4612 | 3871 |
4613 | 3872 |
4614 TEST(MessageHandler2) { | 3873 TEST(MessageHandler2) { |
4615 message_received = false; | 3874 message_received = false; |
4616 v8::HandleScope scope(CcTest::isolate()); | 3875 v8::HandleScope scope(CcTest::isolate()); |
4617 CHECK(!message_received); | 3876 CHECK(!message_received); |
4618 v8::V8::AddMessageListener(check_message_2); | 3877 v8::V8::AddMessageListener(check_message_2); |
4619 LocalContext context; | 3878 LocalContext context; |
4620 v8::Local<v8::Value> error = v8::Exception::Error(v8_str("custom error")); | 3879 v8::Local<v8::Value> error = v8::Exception::Error(v8_str("custom error")); |
4621 v8::Object::Cast(*error)->SetHiddenValue(v8_str("hidden key"), | 3880 v8::Object::Cast(*error) |
4622 v8_str("hidden value")); | 3881 ->SetHiddenValue(v8_str("hidden key"), v8_str("hidden value")); |
4623 context->Global()->Set(v8_str("error"), error); | 3882 context->Global()->Set(v8_str("error"), error); |
4624 CompileRun("throw error;"); | 3883 CompileRun("throw error;"); |
4625 CHECK(message_received); | 3884 CHECK(message_received); |
4626 // clear out the message listener | 3885 // clear out the message listener |
4627 v8::V8::RemoveMessageListeners(check_message_2); | 3886 v8::V8::RemoveMessageListeners(check_message_2); |
4628 } | 3887 } |
4629 | 3888 |
4630 | 3889 |
4631 static void check_message_3(v8::Handle<v8::Message> message, | 3890 static void check_message_3(v8::Handle<v8::Message> message, |
4632 v8::Handle<Value> data) { | 3891 v8::Handle<Value> data) { |
4633 CHECK(message->IsSharedCrossOrigin()); | 3892 CHECK(message->IsSharedCrossOrigin()); |
4634 CHECK(message->GetScriptOrigin().ResourceIsSharedCrossOrigin()->Value()); | 3893 CHECK(message->GetScriptOrigin().ResourceIsSharedCrossOrigin()->Value()); |
4635 CHECK(message->GetScriptOrigin().ResourceIsEmbedderDebugScript()->Value()); | 3894 CHECK(message->GetScriptOrigin().ResourceIsEmbedderDebugScript()->Value()); |
4636 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); | 3895 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
4637 message_received = true; | 3896 message_received = true; |
4638 } | 3897 } |
4639 | 3898 |
4640 | 3899 |
4641 TEST(MessageHandler3) { | 3900 TEST(MessageHandler3) { |
4642 message_received = false; | 3901 message_received = false; |
4643 v8::Isolate* isolate = CcTest::isolate(); | 3902 v8::Isolate* isolate = CcTest::isolate(); |
4644 v8::HandleScope scope(isolate); | 3903 v8::HandleScope scope(isolate); |
4645 CHECK(!message_received); | 3904 CHECK(!message_received); |
4646 v8::V8::AddMessageListener(check_message_3); | 3905 v8::V8::AddMessageListener(check_message_3); |
4647 LocalContext context; | 3906 LocalContext context; |
4648 v8::ScriptOrigin origin = | 3907 v8::ScriptOrigin origin = |
4649 v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), | 3908 v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
4650 v8::Integer::New(isolate, 2), v8::True(isolate), | 3909 v8::Integer::New(isolate, 2), v8::True(isolate), |
4651 Handle<v8::Integer>(), v8::True(isolate)); | 3910 Handle<v8::Integer>(), v8::True(isolate)); |
4652 v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), | 3911 v8::Handle<v8::Script> script = |
4653 &origin); | 3912 Script::Compile(v8_str("throw 'error'"), &origin); |
4654 script->Run(); | 3913 script->Run(); |
4655 CHECK(message_received); | 3914 CHECK(message_received); |
4656 // clear out the message listener | 3915 // clear out the message listener |
4657 v8::V8::RemoveMessageListeners(check_message_3); | 3916 v8::V8::RemoveMessageListeners(check_message_3); |
4658 } | 3917 } |
4659 | 3918 |
4660 | 3919 |
4661 static void check_message_4(v8::Handle<v8::Message> message, | 3920 static void check_message_4(v8::Handle<v8::Message> message, |
4662 v8::Handle<Value> data) { | 3921 v8::Handle<Value> data) { |
4663 CHECK(!message->IsSharedCrossOrigin()); | 3922 CHECK(!message->IsSharedCrossOrigin()); |
4664 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); | 3923 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
4665 message_received = true; | 3924 message_received = true; |
4666 } | 3925 } |
4667 | 3926 |
4668 | 3927 |
4669 TEST(MessageHandler4) { | 3928 TEST(MessageHandler4) { |
4670 message_received = false; | 3929 message_received = false; |
4671 v8::Isolate* isolate = CcTest::isolate(); | 3930 v8::Isolate* isolate = CcTest::isolate(); |
4672 v8::HandleScope scope(isolate); | 3931 v8::HandleScope scope(isolate); |
4673 CHECK(!message_received); | 3932 CHECK(!message_received); |
4674 v8::V8::AddMessageListener(check_message_4); | 3933 v8::V8::AddMessageListener(check_message_4); |
4675 LocalContext context; | 3934 LocalContext context; |
4676 v8::ScriptOrigin origin = | 3935 v8::ScriptOrigin origin = |
4677 v8::ScriptOrigin(v8_str("6.75"), | 3936 v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
4678 v8::Integer::New(isolate, 1), | 3937 v8::Integer::New(isolate, 2), v8::False(isolate)); |
4679 v8::Integer::New(isolate, 2), | 3938 v8::Handle<v8::Script> script = |
4680 v8::False(isolate)); | 3939 Script::Compile(v8_str("throw 'error'"), &origin); |
4681 v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), | |
4682 &origin); | |
4683 script->Run(); | 3940 script->Run(); |
4684 CHECK(message_received); | 3941 CHECK(message_received); |
4685 // clear out the message listener | 3942 // clear out the message listener |
4686 v8::V8::RemoveMessageListeners(check_message_4); | 3943 v8::V8::RemoveMessageListeners(check_message_4); |
4687 } | 3944 } |
4688 | 3945 |
4689 | 3946 |
4690 static void check_message_5a(v8::Handle<v8::Message> message, | 3947 static void check_message_5a(v8::Handle<v8::Message> message, |
4691 v8::Handle<Value> data) { | 3948 v8::Handle<Value> data) { |
4692 CHECK(message->IsSharedCrossOrigin()); | 3949 CHECK(message->IsSharedCrossOrigin()); |
4693 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); | 3950 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
4694 message_received = true; | 3951 message_received = true; |
4695 } | 3952 } |
4696 | 3953 |
4697 | 3954 |
4698 static void check_message_5b(v8::Handle<v8::Message> message, | 3955 static void check_message_5b(v8::Handle<v8::Message> message, |
4699 v8::Handle<Value> data) { | 3956 v8::Handle<Value> data) { |
4700 CHECK(!message->IsSharedCrossOrigin()); | 3957 CHECK(!message->IsSharedCrossOrigin()); |
4701 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); | 3958 CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
4702 message_received = true; | 3959 message_received = true; |
4703 } | 3960 } |
4704 | 3961 |
4705 | 3962 |
4706 TEST(MessageHandler5) { | 3963 TEST(MessageHandler5) { |
4707 message_received = false; | 3964 message_received = false; |
4708 v8::Isolate* isolate = CcTest::isolate(); | 3965 v8::Isolate* isolate = CcTest::isolate(); |
4709 v8::HandleScope scope(isolate); | 3966 v8::HandleScope scope(isolate); |
4710 CHECK(!message_received); | 3967 CHECK(!message_received); |
4711 v8::V8::AddMessageListener(check_message_5a); | 3968 v8::V8::AddMessageListener(check_message_5a); |
4712 LocalContext context; | 3969 LocalContext context; |
4713 v8::ScriptOrigin origin = | 3970 v8::ScriptOrigin origin = |
4714 v8::ScriptOrigin(v8_str("6.75"), | 3971 v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
4715 v8::Integer::New(isolate, 1), | 3972 v8::Integer::New(isolate, 2), v8::True(isolate)); |
4716 v8::Integer::New(isolate, 2), | 3973 v8::Handle<v8::Script> script = |
4717 v8::True(isolate)); | 3974 Script::Compile(v8_str("throw 'error'"), &origin); |
4718 v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), | |
4719 &origin); | |
4720 script->Run(); | 3975 script->Run(); |
4721 CHECK(message_received); | 3976 CHECK(message_received); |
4722 // clear out the message listener | 3977 // clear out the message listener |
4723 v8::V8::RemoveMessageListeners(check_message_5a); | 3978 v8::V8::RemoveMessageListeners(check_message_5a); |
4724 | 3979 |
4725 message_received = false; | 3980 message_received = false; |
4726 v8::V8::AddMessageListener(check_message_5b); | 3981 v8::V8::AddMessageListener(check_message_5b); |
4727 origin = | 3982 origin = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
4728 v8::ScriptOrigin(v8_str("6.75"), | 3983 v8::Integer::New(isolate, 2), v8::False(isolate)); |
4729 v8::Integer::New(isolate, 1), | 3984 script = Script::Compile(v8_str("throw 'error'"), &origin); |
4730 v8::Integer::New(isolate, 2), | |
4731 v8::False(isolate)); | |
4732 script = Script::Compile(v8_str("throw 'error'"), | |
4733 &origin); | |
4734 script->Run(); | 3985 script->Run(); |
4735 CHECK(message_received); | 3986 CHECK(message_received); |
4736 // clear out the message listener | 3987 // clear out the message listener |
4737 v8::V8::RemoveMessageListeners(check_message_5b); | 3988 v8::V8::RemoveMessageListeners(check_message_5b); |
4738 } | 3989 } |
4739 | 3990 |
4740 | 3991 |
4741 TEST(NativeWeakMap) { | 3992 TEST(NativeWeakMap) { |
4742 v8::Isolate* isolate = CcTest::isolate(); | 3993 v8::Isolate* isolate = CcTest::isolate(); |
4743 HandleScope scope(isolate); | 3994 HandleScope scope(isolate); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4909 CHECK_EQ(27u, array->Length()); | 4160 CHECK_EQ(27u, array->Length()); |
4910 array = v8::Array::New(context->GetIsolate(), -27); | 4161 array = v8::Array::New(context->GetIsolate(), -27); |
4911 CHECK_EQ(0u, array->Length()); | 4162 CHECK_EQ(0u, array->Length()); |
4912 } | 4163 } |
4913 | 4164 |
4914 | 4165 |
4915 void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) { | 4166 void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) { |
4916 v8::EscapableHandleScope scope(args.GetIsolate()); | 4167 v8::EscapableHandleScope scope(args.GetIsolate()); |
4917 ApiTestFuzzer::Fuzz(); | 4168 ApiTestFuzzer::Fuzz(); |
4918 Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length()); | 4169 Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length()); |
4919 for (int i = 0; i < args.Length(); i++) | 4170 for (int i = 0; i < args.Length(); i++) result->Set(i, args[i]); |
4920 result->Set(i, args[i]); | |
4921 args.GetReturnValue().Set(scope.Escape(result)); | 4171 args.GetReturnValue().Set(scope.Escape(result)); |
4922 } | 4172 } |
4923 | 4173 |
4924 | 4174 |
4925 THREADED_TEST(Vector) { | 4175 THREADED_TEST(Vector) { |
4926 v8::Isolate* isolate = CcTest::isolate(); | 4176 v8::Isolate* isolate = CcTest::isolate(); |
4927 v8::HandleScope scope(isolate); | 4177 v8::HandleScope scope(isolate); |
4928 Local<ObjectTemplate> global = ObjectTemplate::New(isolate); | 4178 Local<ObjectTemplate> global = ObjectTemplate::New(isolate); |
4929 global->Set(v8_str("f"), v8::FunctionTemplate::New(isolate, HandleF)); | 4179 global->Set(v8_str("f"), v8::FunctionTemplate::New(isolate, HandleF)); |
4930 LocalContext context(0, global); | 4180 LocalContext context(0, global); |
(...skipping 28 matching lines...) Expand all Loading... |
4959 CHECK_EQ(19, a4->Get(2)->Int32Value()); | 4209 CHECK_EQ(19, a4->Get(2)->Int32Value()); |
4960 CHECK_EQ(20, a4->Get(3)->Int32Value()); | 4210 CHECK_EQ(20, a4->Get(3)->Int32Value()); |
4961 } | 4211 } |
4962 | 4212 |
4963 | 4213 |
4964 THREADED_TEST(FunctionCall) { | 4214 THREADED_TEST(FunctionCall) { |
4965 LocalContext context; | 4215 LocalContext context; |
4966 v8::Isolate* isolate = context->GetIsolate(); | 4216 v8::Isolate* isolate = context->GetIsolate(); |
4967 v8::HandleScope scope(isolate); | 4217 v8::HandleScope scope(isolate); |
4968 CompileRun( | 4218 CompileRun( |
4969 "function Foo() {" | 4219 "function Foo() {" |
4970 " var result = [];" | 4220 " var result = [];" |
4971 " for (var i = 0; i < arguments.length; i++) {" | 4221 " for (var i = 0; i < arguments.length; i++) {" |
4972 " result.push(arguments[i]);" | 4222 " result.push(arguments[i]);" |
4973 " }" | 4223 " }" |
4974 " return result;" | 4224 " return result;" |
4975 "}" | 4225 "}" |
4976 "function ReturnThisSloppy() {" | 4226 "function ReturnThisSloppy() {" |
4977 " return this;" | 4227 " return this;" |
4978 "}" | 4228 "}" |
4979 "function ReturnThisStrict() {" | 4229 "function ReturnThisStrict() {" |
4980 " 'use strict';" | 4230 " 'use strict';" |
4981 " return this;" | 4231 " return this;" |
4982 "}"); | 4232 "}"); |
4983 Local<Function> Foo = | 4233 Local<Function> Foo = |
4984 Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); | 4234 Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); |
4985 Local<Function> ReturnThisSloppy = | 4235 Local<Function> ReturnThisSloppy = |
4986 Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisSloppy"))); | 4236 Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisSloppy"))); |
4987 Local<Function> ReturnThisStrict = | 4237 Local<Function> ReturnThisStrict = |
4988 Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisStrict"))); | 4238 Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisStrict"))); |
4989 | 4239 |
4990 v8::Handle<Value>* args0 = NULL; | 4240 v8::Handle<Value>* args0 = NULL; |
4991 Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->Call(Foo, 0, args0)); | 4241 Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->Call(Foo, 0, args0)); |
4992 CHECK_EQ(0u, a0->Length()); | 4242 CHECK_EQ(0u, a0->Length()); |
4993 | 4243 |
4994 v8::Handle<Value> args1[] = { v8_num(1.1) }; | 4244 v8::Handle<Value> args1[] = {v8_num(1.1)}; |
4995 Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->Call(Foo, 1, args1)); | 4245 Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->Call(Foo, 1, args1)); |
4996 CHECK_EQ(1u, a1->Length()); | 4246 CHECK_EQ(1u, a1->Length()); |
4997 CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4247 CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
4998 | 4248 |
4999 v8::Handle<Value> args2[] = { v8_num(2.2), | 4249 v8::Handle<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; |
5000 v8_num(3.3) }; | |
5001 Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->Call(Foo, 2, args2)); | 4250 Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->Call(Foo, 2, args2)); |
5002 CHECK_EQ(2u, a2->Length()); | 4251 CHECK_EQ(2u, a2->Length()); |
5003 CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4252 CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5004 CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); | 4253 CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
5005 | 4254 |
5006 v8::Handle<Value> args3[] = { v8_num(4.4), | 4255 v8::Handle<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; |
5007 v8_num(5.5), | |
5008 v8_num(6.6) }; | |
5009 Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->Call(Foo, 3, args3)); | 4256 Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->Call(Foo, 3, args3)); |
5010 CHECK_EQ(3u, a3->Length()); | 4257 CHECK_EQ(3u, a3->Length()); |
5011 CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4258 CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5012 CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); | 4259 CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
5013 CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); | 4260 CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); |
5014 | 4261 |
5015 v8::Handle<Value> args4[] = { v8_num(7.7), | 4262 v8::Handle<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), |
5016 v8_num(8.8), | 4263 v8_num(10.11)}; |
5017 v8_num(9.9), | |
5018 v8_num(10.11) }; | |
5019 Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->Call(Foo, 4, args4)); | 4264 Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->Call(Foo, 4, args4)); |
5020 CHECK_EQ(4u, a4->Length()); | 4265 CHECK_EQ(4u, a4->Length()); |
5021 CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4266 CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5022 CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); | 4267 CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
5023 CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); | 4268 CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); |
5024 CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); | 4269 CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); |
5025 | 4270 |
5026 Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL); | 4271 Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL); |
5027 CHECK(r1->StrictEquals(context->Global())); | 4272 CHECK(r1->StrictEquals(context->Global())); |
5028 Local<v8::Value> r2 = ReturnThisSloppy->Call(v8::Null(isolate), 0, NULL); | 4273 Local<v8::Value> r2 = ReturnThisSloppy->Call(v8::Null(isolate), 0, NULL); |
(...skipping 19 matching lines...) Expand all Loading... |
5048 Local<v8::Value> r10 = ReturnThisStrict->Call(v8::True(isolate), 0, NULL); | 4293 Local<v8::Value> r10 = ReturnThisStrict->Call(v8::True(isolate), 0, NULL); |
5049 CHECK(r10->StrictEquals(v8::True(isolate))); | 4294 CHECK(r10->StrictEquals(v8::True(isolate))); |
5050 } | 4295 } |
5051 | 4296 |
5052 | 4297 |
5053 THREADED_TEST(ConstructCall) { | 4298 THREADED_TEST(ConstructCall) { |
5054 LocalContext context; | 4299 LocalContext context; |
5055 v8::Isolate* isolate = context->GetIsolate(); | 4300 v8::Isolate* isolate = context->GetIsolate(); |
5056 v8::HandleScope scope(isolate); | 4301 v8::HandleScope scope(isolate); |
5057 CompileRun( | 4302 CompileRun( |
5058 "function Foo() {" | 4303 "function Foo() {" |
5059 " var result = [];" | 4304 " var result = [];" |
5060 " for (var i = 0; i < arguments.length; i++) {" | 4305 " for (var i = 0; i < arguments.length; i++) {" |
5061 " result.push(arguments[i]);" | 4306 " result.push(arguments[i]);" |
5062 " }" | 4307 " }" |
5063 " return result;" | 4308 " return result;" |
5064 "}"); | 4309 "}"); |
5065 Local<Function> Foo = | 4310 Local<Function> Foo = |
5066 Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); | 4311 Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); |
5067 | 4312 |
5068 v8::Handle<Value>* args0 = NULL; | 4313 v8::Handle<Value>* args0 = NULL; |
5069 Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->NewInstance(0, args0)); | 4314 Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->NewInstance(0, args0)); |
5070 CHECK_EQ(0u, a0->Length()); | 4315 CHECK_EQ(0u, a0->Length()); |
5071 | 4316 |
5072 v8::Handle<Value> args1[] = { v8_num(1.1) }; | 4317 v8::Handle<Value> args1[] = {v8_num(1.1)}; |
5073 Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->NewInstance(1, args1)); | 4318 Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->NewInstance(1, args1)); |
5074 CHECK_EQ(1u, a1->Length()); | 4319 CHECK_EQ(1u, a1->Length()); |
5075 CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4320 CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5076 | 4321 |
5077 v8::Handle<Value> args2[] = { v8_num(2.2), | 4322 v8::Handle<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; |
5078 v8_num(3.3) }; | |
5079 Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->NewInstance(2, args2)); | 4323 Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->NewInstance(2, args2)); |
5080 CHECK_EQ(2u, a2->Length()); | 4324 CHECK_EQ(2u, a2->Length()); |
5081 CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4325 CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5082 CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); | 4326 CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
5083 | 4327 |
5084 v8::Handle<Value> args3[] = { v8_num(4.4), | 4328 v8::Handle<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; |
5085 v8_num(5.5), | |
5086 v8_num(6.6) }; | |
5087 Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->NewInstance(3, args3)); | 4329 Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->NewInstance(3, args3)); |
5088 CHECK_EQ(3u, a3->Length()); | 4330 CHECK_EQ(3u, a3->Length()); |
5089 CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4331 CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5090 CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); | 4332 CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
5091 CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); | 4333 CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); |
5092 | 4334 |
5093 v8::Handle<Value> args4[] = { v8_num(7.7), | 4335 v8::Handle<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), |
5094 v8_num(8.8), | 4336 v8_num(10.11)}; |
5095 v8_num(9.9), | |
5096 v8_num(10.11) }; | |
5097 Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->NewInstance(4, args4)); | 4337 Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->NewInstance(4, args4)); |
5098 CHECK_EQ(4u, a4->Length()); | 4338 CHECK_EQ(4u, a4->Length()); |
5099 CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); | 4339 CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
5100 CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); | 4340 CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
5101 CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); | 4341 CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); |
5102 CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); | 4342 CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); |
5103 } | 4343 } |
5104 | 4344 |
5105 | 4345 |
5106 static void CheckUncle(v8::TryCatch* try_catch) { | 4346 static void CheckUncle(v8::TryCatch* try_catch) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5210 CHECK(!obj->IsInt32()); | 4450 CHECK(!obj->IsInt32()); |
5211 CHECK(!obj->IsUint32()); | 4451 CHECK(!obj->IsUint32()); |
5212 } | 4452 } |
5213 | 4453 |
5214 | 4454 |
5215 THREADED_TEST(ConversionException) { | 4455 THREADED_TEST(ConversionException) { |
5216 LocalContext env; | 4456 LocalContext env; |
5217 v8::Isolate* isolate = env->GetIsolate(); | 4457 v8::Isolate* isolate = env->GetIsolate(); |
5218 v8::HandleScope scope(isolate); | 4458 v8::HandleScope scope(isolate); |
5219 CompileRun( | 4459 CompileRun( |
5220 "function TestClass() { };" | 4460 "function TestClass() { };" |
5221 "TestClass.prototype.toString = function () { throw 'uncle?'; };" | 4461 "TestClass.prototype.toString = function () { throw 'uncle?'; };" |
5222 "var obj = new TestClass();"); | 4462 "var obj = new TestClass();"); |
5223 Local<Value> obj = env->Global()->Get(v8_str("obj")); | 4463 Local<Value> obj = env->Global()->Get(v8_str("obj")); |
5224 | 4464 |
5225 v8::TryCatch try_catch(isolate); | 4465 v8::TryCatch try_catch(isolate); |
5226 | 4466 |
5227 Local<Value> to_string_result = obj->ToString(isolate); | 4467 Local<Value> to_string_result = obj->ToString(isolate); |
5228 CHECK(to_string_result.IsEmpty()); | 4468 CHECK(to_string_result.IsEmpty()); |
5229 CheckUncle(&try_catch); | 4469 CheckUncle(&try_catch); |
5230 | 4470 |
5231 Local<Value> to_number_result = obj->ToNumber(isolate); | 4471 Local<Value> to_number_result = obj->ToNumber(isolate); |
5232 CHECK(to_number_result.IsEmpty()); | 4472 CHECK(to_number_result.IsEmpty()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5287 | 4527 |
5288 | 4528 |
5289 THREADED_TEST(APICatch) { | 4529 THREADED_TEST(APICatch) { |
5290 v8::Isolate* isolate = CcTest::isolate(); | 4530 v8::Isolate* isolate = CcTest::isolate(); |
5291 v8::HandleScope scope(isolate); | 4531 v8::HandleScope scope(isolate); |
5292 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 4532 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
5293 templ->Set(v8_str("ThrowFromC"), | 4533 templ->Set(v8_str("ThrowFromC"), |
5294 v8::FunctionTemplate::New(isolate, ThrowFromC)); | 4534 v8::FunctionTemplate::New(isolate, ThrowFromC)); |
5295 LocalContext context(0, templ); | 4535 LocalContext context(0, templ); |
5296 CompileRun( | 4536 CompileRun( |
5297 "var thrown = false;" | 4537 "var thrown = false;" |
5298 "try {" | 4538 "try {" |
5299 " ThrowFromC();" | 4539 " ThrowFromC();" |
5300 "} catch (e) {" | 4540 "} catch (e) {" |
5301 " thrown = true;" | 4541 " thrown = true;" |
5302 "}"); | 4542 "}"); |
5303 Local<Value> thrown = context->Global()->Get(v8_str("thrown")); | 4543 Local<Value> thrown = context->Global()->Get(v8_str("thrown")); |
5304 CHECK(thrown->BooleanValue()); | 4544 CHECK(thrown->BooleanValue()); |
5305 } | 4545 } |
5306 | 4546 |
5307 | 4547 |
5308 THREADED_TEST(APIThrowTryCatch) { | 4548 THREADED_TEST(APIThrowTryCatch) { |
5309 v8::Isolate* isolate = CcTest::isolate(); | 4549 v8::Isolate* isolate = CcTest::isolate(); |
5310 v8::HandleScope scope(isolate); | 4550 v8::HandleScope scope(isolate); |
5311 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 4551 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
5312 templ->Set(v8_str("ThrowFromC"), | 4552 templ->Set(v8_str("ThrowFromC"), |
5313 v8::FunctionTemplate::New(isolate, ThrowFromC)); | 4553 v8::FunctionTemplate::New(isolate, ThrowFromC)); |
5314 LocalContext context(0, templ); | 4554 LocalContext context(0, templ); |
5315 v8::TryCatch try_catch; | 4555 v8::TryCatch try_catch; |
5316 CompileRun("ThrowFromC();"); | 4556 CompileRun("ThrowFromC();"); |
5317 CHECK(try_catch.HasCaught()); | 4557 CHECK(try_catch.HasCaught()); |
5318 } | 4558 } |
5319 | 4559 |
5320 | 4560 |
5321 // Test that a try-finally block doesn't shadow a try-catch block | 4561 // Test that a try-finally block doesn't shadow a try-catch block |
5322 // when setting up an external handler. | 4562 // when setting up an external handler. |
5323 // | 4563 // |
5324 // BUG(271): Some of the exception propagation does not work on the | 4564 // BUG(271): Some of the exception propagation does not work on the |
5325 // ARM simulator because the simulator separates the C++ stack and the | 4565 // ARM simulator because the simulator separates the C++ stack and the |
5326 // JS stack. This test therefore fails on the simulator. The test is | 4566 // JS stack. This test therefore fails on the simulator. The test is |
5327 // not threaded to allow the threading tests to run on the simulator. | 4567 // not threaded to allow the threading tests to run on the simulator. |
5328 TEST(TryCatchInTryFinally) { | 4568 TEST(TryCatchInTryFinally) { |
5329 v8::Isolate* isolate = CcTest::isolate(); | 4569 v8::Isolate* isolate = CcTest::isolate(); |
5330 v8::HandleScope scope(isolate); | 4570 v8::HandleScope scope(isolate); |
5331 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 4571 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
5332 templ->Set(v8_str("CCatcher"), | 4572 templ->Set(v8_str("CCatcher"), v8::FunctionTemplate::New(isolate, CCatcher)); |
5333 v8::FunctionTemplate::New(isolate, CCatcher)); | |
5334 LocalContext context(0, templ); | 4573 LocalContext context(0, templ); |
5335 Local<Value> result = CompileRun("try {" | 4574 Local<Value> result = CompileRun( |
5336 " try {" | 4575 "try {" |
5337 " CCatcher('throw 7;');" | 4576 " try {" |
5338 " } finally {" | 4577 " CCatcher('throw 7;');" |
5339 " }" | 4578 " } finally {" |
5340 "} catch (e) {" | 4579 " }" |
5341 "}"); | 4580 "} catch (e) {" |
| 4581 "}"); |
5342 CHECK(result->IsTrue()); | 4582 CHECK(result->IsTrue()); |
5343 } | 4583 } |
5344 | 4584 |
5345 | 4585 |
5346 static void check_reference_error_message( | 4586 static void check_reference_error_message(v8::Handle<v8::Message> message, |
5347 v8::Handle<v8::Message> message, | 4587 v8::Handle<v8::Value> data) { |
5348 v8::Handle<v8::Value> data) { | |
5349 const char* reference_error = "Uncaught ReferenceError: asdf is not defined"; | 4588 const char* reference_error = "Uncaught ReferenceError: asdf is not defined"; |
5350 CHECK(message->Get()->Equals(v8_str(reference_error))); | 4589 CHECK(message->Get()->Equals(v8_str(reference_error))); |
5351 } | 4590 } |
5352 | 4591 |
5353 | 4592 |
5354 static void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { | 4593 static void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { |
5355 ApiTestFuzzer::Fuzz(); | 4594 ApiTestFuzzer::Fuzz(); |
5356 CHECK(false); | 4595 CHECK(false); |
5357 } | 4596 } |
5358 | 4597 |
5359 | 4598 |
5360 // Test that overwritten methods are not invoked on uncaught exception | 4599 // Test that overwritten methods are not invoked on uncaught exception |
5361 // formatting. However, they are invoked when performing normal error | 4600 // formatting. However, they are invoked when performing normal error |
5362 // string conversions. | 4601 // string conversions. |
5363 TEST(APIThrowMessageOverwrittenToString) { | 4602 TEST(APIThrowMessageOverwrittenToString) { |
5364 v8::Isolate* isolate = CcTest::isolate(); | 4603 v8::Isolate* isolate = CcTest::isolate(); |
5365 v8::HandleScope scope(isolate); | 4604 v8::HandleScope scope(isolate); |
5366 v8::V8::AddMessageListener(check_reference_error_message); | 4605 v8::V8::AddMessageListener(check_reference_error_message); |
5367 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 4606 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
5368 templ->Set(v8_str("fail"), v8::FunctionTemplate::New(isolate, Fail)); | 4607 templ->Set(v8_str("fail"), v8::FunctionTemplate::New(isolate, Fail)); |
5369 LocalContext context(NULL, templ); | 4608 LocalContext context(NULL, templ); |
5370 CompileRun("asdf;"); | 4609 CompileRun("asdf;"); |
5371 CompileRun("var limit = {};" | 4610 CompileRun( |
5372 "limit.valueOf = fail;" | 4611 "var limit = {};" |
5373 "Error.stackTraceLimit = limit;"); | 4612 "limit.valueOf = fail;" |
| 4613 "Error.stackTraceLimit = limit;"); |
5374 CompileRun("asdf"); | 4614 CompileRun("asdf"); |
5375 CompileRun("Array.prototype.pop = fail;"); | 4615 CompileRun("Array.prototype.pop = fail;"); |
5376 CompileRun("Object.prototype.hasOwnProperty = fail;"); | 4616 CompileRun("Object.prototype.hasOwnProperty = fail;"); |
5377 CompileRun("Object.prototype.toString = function f() { return 'Yikes'; }"); | 4617 CompileRun("Object.prototype.toString = function f() { return 'Yikes'; }"); |
5378 CompileRun("Number.prototype.toString = function f() { return 'Yikes'; }"); | 4618 CompileRun("Number.prototype.toString = function f() { return 'Yikes'; }"); |
5379 CompileRun("String.prototype.toString = function f() { return 'Yikes'; }"); | 4619 CompileRun("String.prototype.toString = function f() { return 'Yikes'; }"); |
5380 CompileRun("ReferenceError.prototype.toString =" | 4620 CompileRun( |
5381 " function() { return 'Whoops' }"); | 4621 "ReferenceError.prototype.toString =" |
| 4622 " function() { return 'Whoops' }"); |
5382 CompileRun("asdf;"); | 4623 CompileRun("asdf;"); |
5383 CompileRun("ReferenceError.prototype.constructor.name = void 0;"); | 4624 CompileRun("ReferenceError.prototype.constructor.name = void 0;"); |
5384 CompileRun("asdf;"); | 4625 CompileRun("asdf;"); |
5385 CompileRun("ReferenceError.prototype.constructor = void 0;"); | 4626 CompileRun("ReferenceError.prototype.constructor = void 0;"); |
5386 CompileRun("asdf;"); | 4627 CompileRun("asdf;"); |
5387 CompileRun("ReferenceError.prototype.__proto__ = new Object();"); | 4628 CompileRun("ReferenceError.prototype.__proto__ = new Object();"); |
5388 CompileRun("asdf;"); | 4629 CompileRun("asdf;"); |
5389 CompileRun("ReferenceError.prototype = new Object();"); | 4630 CompileRun("ReferenceError.prototype = new Object();"); |
5390 CompileRun("asdf;"); | 4631 CompileRun("asdf;"); |
5391 v8::Handle<Value> string = CompileRun("try { asdf; } catch(e) { e + ''; }"); | 4632 v8::Handle<Value> string = CompileRun("try { asdf; } catch(e) { e + ''; }"); |
5392 CHECK(string->Equals(v8_str("Whoops"))); | 4633 CHECK(string->Equals(v8_str("Whoops"))); |
5393 CompileRun("ReferenceError.prototype.constructor = new Object();" | 4634 CompileRun( |
5394 "ReferenceError.prototype.constructor.name = 1;" | 4635 "ReferenceError.prototype.constructor = new Object();" |
5395 "Number.prototype.toString = function() { return 'Whoops'; };" | 4636 "ReferenceError.prototype.constructor.name = 1;" |
5396 "ReferenceError.prototype.toString = Object.prototype.toString;"); | 4637 "Number.prototype.toString = function() { return 'Whoops'; };" |
| 4638 "ReferenceError.prototype.toString = Object.prototype.toString;"); |
5397 CompileRun("asdf;"); | 4639 CompileRun("asdf;"); |
5398 v8::V8::RemoveMessageListeners(check_reference_error_message); | 4640 v8::V8::RemoveMessageListeners(check_reference_error_message); |
5399 } | 4641 } |
5400 | 4642 |
5401 | 4643 |
5402 static void check_custom_error_tostring( | 4644 static void check_custom_error_tostring(v8::Handle<v8::Message> message, |
5403 v8::Handle<v8::Message> message, | 4645 v8::Handle<v8::Value> data) { |
5404 v8::Handle<v8::Value> data) { | |
5405 const char* uncaught_error = "Uncaught MyError toString"; | 4646 const char* uncaught_error = "Uncaught MyError toString"; |
5406 CHECK(message->Get()->Equals(v8_str(uncaught_error))); | 4647 CHECK(message->Get()->Equals(v8_str(uncaught_error))); |
5407 } | 4648 } |
5408 | 4649 |
5409 | 4650 |
5410 TEST(CustomErrorToString) { | 4651 TEST(CustomErrorToString) { |
5411 LocalContext context; | 4652 LocalContext context; |
5412 v8::HandleScope scope(context->GetIsolate()); | 4653 v8::HandleScope scope(context->GetIsolate()); |
5413 v8::V8::AddMessageListener(check_custom_error_tostring); | 4654 v8::V8::AddMessageListener(check_custom_error_tostring); |
5414 CompileRun( | 4655 CompileRun( |
5415 "function MyError(name, message) { " | 4656 "function MyError(name, message) { " |
5416 " this.name = name; " | 4657 " this.name = name; " |
5417 " this.message = message; " | 4658 " this.message = message; " |
5418 "} " | 4659 "} " |
5419 "MyError.prototype = Object.create(Error.prototype); " | 4660 "MyError.prototype = Object.create(Error.prototype); " |
5420 "MyError.prototype.toString = function() { " | 4661 "MyError.prototype.toString = function() { " |
5421 " return 'MyError toString'; " | 4662 " return 'MyError toString'; " |
5422 "}; " | 4663 "}; " |
5423 "throw new MyError('my name', 'my message'); "); | 4664 "throw new MyError('my name', 'my message'); "); |
5424 v8::V8::RemoveMessageListeners(check_custom_error_tostring); | 4665 v8::V8::RemoveMessageListeners(check_custom_error_tostring); |
5425 } | 4666 } |
5426 | 4667 |
5427 | 4668 |
5428 static void check_custom_error_message( | 4669 static void check_custom_error_message(v8::Handle<v8::Message> message, |
5429 v8::Handle<v8::Message> message, | 4670 v8::Handle<v8::Value> data) { |
5430 v8::Handle<v8::Value> data) { | |
5431 const char* uncaught_error = "Uncaught MyError: my message"; | 4671 const char* uncaught_error = "Uncaught MyError: my message"; |
5432 printf("%s\n", *v8::String::Utf8Value(message->Get())); | 4672 printf("%s\n", *v8::String::Utf8Value(message->Get())); |
5433 CHECK(message->Get()->Equals(v8_str(uncaught_error))); | 4673 CHECK(message->Get()->Equals(v8_str(uncaught_error))); |
5434 } | 4674 } |
5435 | 4675 |
5436 | 4676 |
5437 TEST(CustomErrorMessage) { | 4677 TEST(CustomErrorMessage) { |
5438 LocalContext context; | 4678 LocalContext context; |
5439 v8::HandleScope scope(context->GetIsolate()); | 4679 v8::HandleScope scope(context->GetIsolate()); |
5440 v8::V8::AddMessageListener(check_custom_error_message); | 4680 v8::V8::AddMessageListener(check_custom_error_message); |
5441 | 4681 |
5442 // Handlebars. | 4682 // Handlebars. |
5443 CompileRun( | 4683 CompileRun( |
5444 "function MyError(msg) { " | 4684 "function MyError(msg) { " |
5445 " this.name = 'MyError'; " | 4685 " this.name = 'MyError'; " |
5446 " this.message = msg; " | 4686 " this.message = msg; " |
5447 "} " | 4687 "} " |
5448 "MyError.prototype = new Error(); " | 4688 "MyError.prototype = new Error(); " |
5449 "throw new MyError('my message'); "); | 4689 "throw new MyError('my message'); "); |
5450 | 4690 |
5451 // Closure. | 4691 // Closure. |
5452 CompileRun( | 4692 CompileRun( |
5453 "function MyError(msg) { " | 4693 "function MyError(msg) { " |
5454 " this.name = 'MyError'; " | 4694 " this.name = 'MyError'; " |
5455 " this.message = msg; " | 4695 " this.message = msg; " |
5456 "} " | 4696 "} " |
5457 "inherits = function(childCtor, parentCtor) { " | 4697 "inherits = function(childCtor, parentCtor) { " |
5458 " function tempCtor() {}; " | 4698 " function tempCtor() {}; " |
5459 " tempCtor.prototype = parentCtor.prototype; " | 4699 " tempCtor.prototype = parentCtor.prototype; " |
5460 " childCtor.superClass_ = parentCtor.prototype; " | 4700 " childCtor.superClass_ = parentCtor.prototype; " |
5461 " childCtor.prototype = new tempCtor(); " | 4701 " childCtor.prototype = new tempCtor(); " |
5462 " childCtor.prototype.constructor = childCtor; " | 4702 " childCtor.prototype.constructor = childCtor; " |
5463 "}; " | 4703 "}; " |
5464 "inherits(MyError, Error); " | 4704 "inherits(MyError, Error); " |
5465 "throw new MyError('my message'); "); | 4705 "throw new MyError('my message'); "); |
5466 | 4706 |
5467 // Object.create. | 4707 // Object.create. |
5468 CompileRun( | 4708 CompileRun( |
5469 "function MyError(msg) { " | 4709 "function MyError(msg) { " |
5470 " this.name = 'MyError'; " | 4710 " this.name = 'MyError'; " |
5471 " this.message = msg; " | 4711 " this.message = msg; " |
5472 "} " | 4712 "} " |
5473 "MyError.prototype = Object.create(Error.prototype); " | 4713 "MyError.prototype = Object.create(Error.prototype); " |
5474 "throw new MyError('my message'); "); | 4714 "throw new MyError('my message'); "); |
5475 | 4715 |
5476 v8::V8::RemoveMessageListeners(check_custom_error_message); | 4716 v8::V8::RemoveMessageListeners(check_custom_error_message); |
5477 } | 4717 } |
5478 | 4718 |
5479 | 4719 |
5480 static void receive_message(v8::Handle<v8::Message> message, | 4720 static void receive_message(v8::Handle<v8::Message> message, |
5481 v8::Handle<v8::Value> data) { | 4721 v8::Handle<v8::Value> data) { |
5482 message->Get(); | 4722 message->Get(); |
5483 message_received = true; | 4723 message_received = true; |
5484 } | 4724 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5543 | 4783 |
5544 v8::TryCatch try_catch; | 4784 v8::TryCatch try_catch; |
5545 Local<Value> result = CompileRun("ThrowFromC(); throw 'panama';"); | 4785 Local<Value> result = CompileRun("ThrowFromC(); throw 'panama';"); |
5546 CHECK(result.IsEmpty()); | 4786 CHECK(result.IsEmpty()); |
5547 CHECK(try_catch.HasCaught()); | 4787 CHECK(try_catch.HasCaught()); |
5548 String::Utf8Value exception_value(try_catch.Exception()); | 4788 String::Utf8Value exception_value(try_catch.Exception()); |
5549 CHECK_EQ(0, strcmp("konto", *exception_value)); | 4789 CHECK_EQ(0, strcmp("konto", *exception_value)); |
5550 } | 4790 } |
5551 | 4791 |
5552 | 4792 |
5553 | |
5554 void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { | 4793 void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { |
5555 ApiTestFuzzer::Fuzz(); | 4794 ApiTestFuzzer::Fuzz(); |
5556 CHECK_EQ(4, args.Length()); | 4795 CHECK_EQ(4, args.Length()); |
5557 int count = args[0]->Int32Value(); | 4796 int count = args[0]->Int32Value(); |
5558 int cInterval = args[2]->Int32Value(); | 4797 int cInterval = args[2]->Int32Value(); |
5559 if (count == 0) { | 4798 if (count == 0) { |
5560 args.GetIsolate()->ThrowException(v8_str("FromC")); | 4799 args.GetIsolate()->ThrowException(v8_str("FromC")); |
5561 return; | 4800 return; |
5562 } else { | 4801 } else { |
5563 Local<v8::Object> global = | 4802 Local<v8::Object> global = args.GetIsolate()->GetCurrentContext()->Global(); |
5564 args.GetIsolate()->GetCurrentContext()->Global(); | |
5565 Local<Value> fun = global->Get(v8_str("JSThrowCountDown")); | 4803 Local<Value> fun = global->Get(v8_str("JSThrowCountDown")); |
5566 v8::Handle<Value> argv[] = { v8_num(count - 1), | 4804 v8::Handle<Value> argv[] = {v8_num(count - 1), args[1], args[2], args[3]}; |
5567 args[1], | |
5568 args[2], | |
5569 args[3] }; | |
5570 if (count % cInterval == 0) { | 4805 if (count % cInterval == 0) { |
5571 v8::TryCatch try_catch; | 4806 v8::TryCatch try_catch; |
5572 Local<Value> result = fun.As<Function>()->Call(global, 4, argv); | 4807 Local<Value> result = fun.As<Function>()->Call(global, 4, argv); |
5573 int expected = args[3]->Int32Value(); | 4808 int expected = args[3]->Int32Value(); |
5574 if (try_catch.HasCaught()) { | 4809 if (try_catch.HasCaught()) { |
5575 CHECK_EQ(expected, count); | 4810 CHECK_EQ(expected, count); |
5576 CHECK(result.IsEmpty()); | 4811 CHECK(result.IsEmpty()); |
5577 CHECK(!CcTest::i_isolate()->has_scheduled_exception()); | 4812 CHECK(!CcTest::i_isolate()->has_scheduled_exception()); |
5578 } else { | 4813 } else { |
5579 CHECK_NE(expected, count); | 4814 CHECK_NE(expected, count); |
(...skipping 19 matching lines...) Expand all Loading... |
5599 } else { | 4834 } else { |
5600 CHECK_NE(count, expected); | 4835 CHECK_NE(count, expected); |
5601 } | 4836 } |
5602 } | 4837 } |
5603 | 4838 |
5604 | 4839 |
5605 THREADED_TEST(EvalInTryFinally) { | 4840 THREADED_TEST(EvalInTryFinally) { |
5606 LocalContext context; | 4841 LocalContext context; |
5607 v8::HandleScope scope(context->GetIsolate()); | 4842 v8::HandleScope scope(context->GetIsolate()); |
5608 v8::TryCatch try_catch; | 4843 v8::TryCatch try_catch; |
5609 CompileRun("(function() {" | 4844 CompileRun( |
5610 " try {" | 4845 "(function() {" |
5611 " eval('asldkf (*&^&*^');" | 4846 " try {" |
5612 " } finally {" | 4847 " eval('asldkf (*&^&*^');" |
5613 " return;" | 4848 " } finally {" |
5614 " }" | 4849 " return;" |
5615 "})()"); | 4850 " }" |
| 4851 "})()"); |
5616 CHECK(!try_catch.HasCaught()); | 4852 CHECK(!try_catch.HasCaught()); |
5617 } | 4853 } |
5618 | 4854 |
5619 | 4855 |
5620 // This test works by making a stack of alternating JavaScript and C | 4856 // This test works by making a stack of alternating JavaScript and C |
5621 // activations. These activations set up exception handlers with regular | 4857 // activations. These activations set up exception handlers with regular |
5622 // intervals, one interval for C activations and another for JavaScript | 4858 // intervals, one interval for C activations and another for JavaScript |
5623 // activations. When enough activations have been created an exception is | 4859 // activations. When enough activations have been created an exception is |
5624 // thrown and we check that the right activation catches the exception and that | 4860 // thrown and we check that the right activation catches the exception and that |
5625 // no other activations do. The right activation is always the topmost one with | 4861 // no other activations do. The right activation is always the topmost one with |
(...skipping 13 matching lines...) Expand all Loading... |
5639 // not threaded to allow the threading tests to run on the simulator. | 4875 // not threaded to allow the threading tests to run on the simulator. |
5640 TEST(ExceptionOrder) { | 4876 TEST(ExceptionOrder) { |
5641 v8::Isolate* isolate = CcTest::isolate(); | 4877 v8::Isolate* isolate = CcTest::isolate(); |
5642 v8::HandleScope scope(isolate); | 4878 v8::HandleScope scope(isolate); |
5643 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 4879 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
5644 templ->Set(v8_str("check"), v8::FunctionTemplate::New(isolate, JSCheck)); | 4880 templ->Set(v8_str("check"), v8::FunctionTemplate::New(isolate, JSCheck)); |
5645 templ->Set(v8_str("CThrowCountDown"), | 4881 templ->Set(v8_str("CThrowCountDown"), |
5646 v8::FunctionTemplate::New(isolate, CThrowCountDown)); | 4882 v8::FunctionTemplate::New(isolate, CThrowCountDown)); |
5647 LocalContext context(0, templ); | 4883 LocalContext context(0, templ); |
5648 CompileRun( | 4884 CompileRun( |
5649 "function JSThrowCountDown(count, jsInterval, cInterval, expected) {" | 4885 "function JSThrowCountDown(count, jsInterval, cInterval, expected) {" |
5650 " if (count == 0) throw 'FromJS';" | 4886 " if (count == 0) throw 'FromJS';" |
5651 " if (count % jsInterval == 0) {" | 4887 " if (count % jsInterval == 0) {" |
5652 " try {" | 4888 " try {" |
5653 " var value = CThrowCountDown(count - 1," | 4889 " var value = CThrowCountDown(count - 1," |
5654 " jsInterval," | 4890 " jsInterval," |
5655 " cInterval," | 4891 " cInterval," |
5656 " expected);" | 4892 " expected);" |
5657 " check(false, count, expected);" | 4893 " check(false, count, expected);" |
5658 " return value;" | 4894 " return value;" |
5659 " } catch (e) {" | 4895 " } catch (e) {" |
5660 " check(true, count, expected);" | 4896 " check(true, count, expected);" |
5661 " }" | 4897 " }" |
5662 " } else {" | 4898 " } else {" |
5663 " return CThrowCountDown(count - 1, jsInterval, cInterval, expected);" | 4899 " return CThrowCountDown(count - 1, jsInterval, cInterval, expected);" |
5664 " }" | 4900 " }" |
5665 "}"); | 4901 "}"); |
5666 Local<Function> fun = | 4902 Local<Function> fun = |
5667 Local<Function>::Cast(context->Global()->Get(v8_str("JSThrowCountDown"))); | 4903 Local<Function>::Cast(context->Global()->Get(v8_str("JSThrowCountDown"))); |
5668 | 4904 |
5669 const int argc = 4; | 4905 const int argc = 4; |
5670 // count jsInterval cInterval expected | 4906 // count jsInterval cInterval expected |
5671 | 4907 |
5672 // *JS[4] *C[3] @JS[2] C[1] JS[0] | 4908 // *JS[4] *C[3] @JS[2] C[1] JS[0] |
5673 v8::Handle<Value> a0[argc] = { v8_num(4), v8_num(2), v8_num(3), v8_num(2) }; | 4909 v8::Handle<Value> a0[argc] = {v8_num(4), v8_num(2), v8_num(3), v8_num(2)}; |
5674 fun->Call(fun, argc, a0); | 4910 fun->Call(fun, argc, a0); |
5675 | 4911 |
5676 // JS[5] *C[4] JS[3] @C[2] JS[1] C[0] | 4912 // JS[5] *C[4] JS[3] @C[2] JS[1] C[0] |
5677 v8::Handle<Value> a1[argc] = { v8_num(5), v8_num(6), v8_num(1), v8_num(2) }; | 4913 v8::Handle<Value> a1[argc] = {v8_num(5), v8_num(6), v8_num(1), v8_num(2)}; |
5678 fun->Call(fun, argc, a1); | 4914 fun->Call(fun, argc, a1); |
5679 | 4915 |
5680 // JS[6] @C[5] JS[4] C[3] JS[2] C[1] JS[0] | 4916 // JS[6] @C[5] JS[4] C[3] JS[2] C[1] JS[0] |
5681 v8::Handle<Value> a2[argc] = { v8_num(6), v8_num(7), v8_num(5), v8_num(5) }; | 4917 v8::Handle<Value> a2[argc] = {v8_num(6), v8_num(7), v8_num(5), v8_num(5)}; |
5682 fun->Call(fun, argc, a2); | 4918 fun->Call(fun, argc, a2); |
5683 | 4919 |
5684 // @JS[6] C[5] JS[4] C[3] JS[2] C[1] JS[0] | 4920 // @JS[6] C[5] JS[4] C[3] JS[2] C[1] JS[0] |
5685 v8::Handle<Value> a3[argc] = { v8_num(6), v8_num(6), v8_num(7), v8_num(6) }; | 4921 v8::Handle<Value> a3[argc] = {v8_num(6), v8_num(6), v8_num(7), v8_num(6)}; |
5686 fun->Call(fun, argc, a3); | 4922 fun->Call(fun, argc, a3); |
5687 | 4923 |
5688 // JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] | 4924 // JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] |
5689 v8::Handle<Value> a4[argc] = { v8_num(6), v8_num(4), v8_num(5), v8_num(4) }; | 4925 v8::Handle<Value> a4[argc] = {v8_num(6), v8_num(4), v8_num(5), v8_num(4)}; |
5690 fun->Call(fun, argc, a4); | 4926 fun->Call(fun, argc, a4); |
5691 | 4927 |
5692 // JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] | 4928 // JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] |
5693 v8::Handle<Value> a5[argc] = { v8_num(6), v8_num(4), v8_num(3), v8_num(3) }; | 4929 v8::Handle<Value> a5[argc] = {v8_num(6), v8_num(4), v8_num(3), v8_num(3)}; |
5694 fun->Call(fun, argc, a5); | 4930 fun->Call(fun, argc, a5); |
5695 } | 4931 } |
5696 | 4932 |
5697 | 4933 |
5698 void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) { | 4934 void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) { |
5699 ApiTestFuzzer::Fuzz(); | 4935 ApiTestFuzzer::Fuzz(); |
5700 CHECK_EQ(1, args.Length()); | 4936 CHECK_EQ(1, args.Length()); |
5701 args.GetIsolate()->ThrowException(args[0]); | 4937 args.GetIsolate()->ThrowException(args[0]); |
5702 } | 4938 } |
5703 | 4939 |
5704 | 4940 |
5705 THREADED_TEST(ThrowValues) { | 4941 THREADED_TEST(ThrowValues) { |
5706 v8::Isolate* isolate = CcTest::isolate(); | 4942 v8::Isolate* isolate = CcTest::isolate(); |
5707 v8::HandleScope scope(isolate); | 4943 v8::HandleScope scope(isolate); |
5708 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 4944 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
5709 templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(isolate, ThrowValue)); | 4945 templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(isolate, ThrowValue)); |
5710 LocalContext context(0, templ); | 4946 LocalContext context(0, templ); |
5711 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( | 4947 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( |
5712 "function Run(obj) {" | 4948 "function Run(obj) {" |
5713 " try {" | 4949 " try {" |
5714 " Throw(obj);" | 4950 " Throw(obj);" |
5715 " } catch (e) {" | 4951 " } catch (e) {" |
5716 " return e;" | 4952 " return e;" |
5717 " }" | 4953 " }" |
5718 " return 'no exception';" | 4954 " return 'no exception';" |
5719 "}" | 4955 "}" |
5720 "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); | 4956 "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); |
5721 CHECK_EQ(5u, result->Length()); | 4957 CHECK_EQ(5u, result->Length()); |
5722 CHECK(result->Get(v8::Integer::New(isolate, 0))->IsString()); | 4958 CHECK(result->Get(v8::Integer::New(isolate, 0))->IsString()); |
5723 CHECK(result->Get(v8::Integer::New(isolate, 1))->IsNumber()); | 4959 CHECK(result->Get(v8::Integer::New(isolate, 1))->IsNumber()); |
5724 CHECK_EQ(1, result->Get(v8::Integer::New(isolate, 1))->Int32Value()); | 4960 CHECK_EQ(1, result->Get(v8::Integer::New(isolate, 1))->Int32Value()); |
5725 CHECK(result->Get(v8::Integer::New(isolate, 2))->IsNumber()); | 4961 CHECK(result->Get(v8::Integer::New(isolate, 2))->IsNumber()); |
5726 CHECK_EQ(0, result->Get(v8::Integer::New(isolate, 2))->Int32Value()); | 4962 CHECK_EQ(0, result->Get(v8::Integer::New(isolate, 2))->Int32Value()); |
5727 CHECK(result->Get(v8::Integer::New(isolate, 3))->IsNull()); | 4963 CHECK(result->Get(v8::Integer::New(isolate, 3))->IsNull()); |
5728 CHECK(result->Get(v8::Integer::New(isolate, 4))->IsUndefined()); | 4964 CHECK(result->Get(v8::Integer::New(isolate, 4))->IsUndefined()); |
5729 } | 4965 } |
5730 | 4966 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5837 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E2")); | 5073 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E2")); |
5838 } | 5074 } |
5839 } | 5075 } |
5840 | 5076 |
5841 | 5077 |
5842 void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) { | 5078 void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) { |
5843 CHECK(try_catch->HasCaught()); | 5079 CHECK(try_catch->HasCaught()); |
5844 Handle<Message> message = try_catch->Message(); | 5080 Handle<Message> message = try_catch->Message(); |
5845 Handle<Value> resource = message->GetScriptOrigin().ResourceName(); | 5081 Handle<Value> resource = message->GetScriptOrigin().ResourceName(); |
5846 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner")); | 5082 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner")); |
5847 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(message->Get()), | 5083 CHECK_EQ(0, |
5848 "Uncaught Error: a")); | 5084 strcmp(*v8::String::Utf8Value(message->Get()), "Uncaught Error: a")); |
5849 CHECK_EQ(1, message->GetLineNumber()); | 5085 CHECK_EQ(1, message->GetLineNumber()); |
5850 CHECK_EQ(6, message->GetStartColumn()); | 5086 CHECK_EQ(6, message->GetStartColumn()); |
5851 } | 5087 } |
5852 | 5088 |
5853 | 5089 |
5854 void TryCatchMixedNestingHelper( | 5090 void TryCatchMixedNestingHelper( |
5855 const v8::FunctionCallbackInfo<v8::Value>& args) { | 5091 const v8::FunctionCallbackInfo<v8::Value>& args) { |
5856 ApiTestFuzzer::Fuzz(); | 5092 ApiTestFuzzer::Fuzz(); |
5857 v8::TryCatch try_catch; | 5093 v8::TryCatch try_catch; |
5858 CompileRunWithOrigin("throw new Error('a');\n", "inner", 0, 0); | 5094 CompileRunWithOrigin("throw new Error('a');\n", "inner", 0, 0); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5968 CHECK(not_a_number->SameValue(not_a_number)); | 5204 CHECK(not_a_number->SameValue(not_a_number)); |
5969 CHECK(v8::False(isolate)->SameValue(v8::False(isolate))); | 5205 CHECK(v8::False(isolate)->SameValue(v8::False(isolate))); |
5970 CHECK(!v8::False(isolate)->SameValue(v8::Undefined(isolate))); | 5206 CHECK(!v8::False(isolate)->SameValue(v8::Undefined(isolate))); |
5971 } | 5207 } |
5972 | 5208 |
5973 | 5209 |
5974 THREADED_TEST(MultiRun) { | 5210 THREADED_TEST(MultiRun) { |
5975 LocalContext context; | 5211 LocalContext context; |
5976 v8::HandleScope scope(context->GetIsolate()); | 5212 v8::HandleScope scope(context->GetIsolate()); |
5977 Local<Script> script = v8_compile("x"); | 5213 Local<Script> script = v8_compile("x"); |
5978 for (int i = 0; i < 10; i++) | 5214 for (int i = 0; i < 10; i++) script->Run(); |
5979 script->Run(); | |
5980 } | 5215 } |
5981 | 5216 |
5982 | 5217 |
5983 static void GetXValue(Local<String> name, | 5218 static void GetXValue(Local<String> name, |
5984 const v8::PropertyCallbackInfo<v8::Value>& info) { | 5219 const v8::PropertyCallbackInfo<v8::Value>& info) { |
5985 ApiTestFuzzer::Fuzz(); | 5220 ApiTestFuzzer::Fuzz(); |
5986 CHECK(info.Data()->Equals(v8_str("donut"))); | 5221 CHECK(info.Data()->Equals(v8_str("donut"))); |
5987 CHECK(name->Equals(v8_str("x"))); | 5222 CHECK(name->Equals(v8_str("x"))); |
5988 info.GetReturnValue().Set(name); | 5223 info.GetReturnValue().Set(name); |
5989 } | 5224 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6114 v8::HandleScope scope(isolate); | 5349 v8::HandleScope scope(isolate); |
6115 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 5350 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
6116 LocalContext context; | 5351 LocalContext context; |
6117 | 5352 |
6118 context->Global()->Set(v8_str("obj1"), templ->NewInstance()); | 5353 context->Global()->Set(v8_str("obj1"), templ->NewInstance()); |
6119 CompileRun("var obj2 = {};"); | 5354 CompileRun("var obj2 = {};"); |
6120 | 5355 |
6121 CHECK(CompileRun("obj1.x")->IsUndefined()); | 5356 CHECK(CompileRun("obj1.x")->IsUndefined()); |
6122 CHECK(CompileRun("obj2.x")->IsUndefined()); | 5357 CHECK(CompileRun("obj2.x")->IsUndefined()); |
6123 | 5358 |
6124 CHECK(GetGlobalProperty(&context, "obj1")-> | 5359 CHECK(GetGlobalProperty(&context, "obj1") |
6125 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5360 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6126 | 5361 |
6127 ExpectString("obj1.x", "x"); | 5362 ExpectString("obj1.x", "x"); |
6128 CHECK(CompileRun("obj2.x")->IsUndefined()); | 5363 CHECK(CompileRun("obj2.x")->IsUndefined()); |
6129 | 5364 |
6130 CHECK(GetGlobalProperty(&context, "obj2")-> | 5365 CHECK(GetGlobalProperty(&context, "obj2") |
6131 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5366 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6132 | 5367 |
6133 ExpectString("obj1.x", "x"); | 5368 ExpectString("obj1.x", "x"); |
6134 ExpectString("obj2.x", "x"); | 5369 ExpectString("obj2.x", "x"); |
6135 | 5370 |
6136 ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); | 5371 ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
6137 ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); | 5372 ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
6138 | 5373 |
6139 CompileRun("Object.defineProperty(obj1, 'x'," | 5374 CompileRun( |
6140 "{ get: function() { return 'y'; }, configurable: true })"); | 5375 "Object.defineProperty(obj1, 'x'," |
| 5376 "{ get: function() { return 'y'; }, configurable: true })"); |
6141 | 5377 |
6142 ExpectString("obj1.x", "y"); | 5378 ExpectString("obj1.x", "y"); |
6143 ExpectString("obj2.x", "x"); | 5379 ExpectString("obj2.x", "x"); |
6144 | 5380 |
6145 CompileRun("Object.defineProperty(obj2, 'x'," | 5381 CompileRun( |
6146 "{ get: function() { return 'y'; }, configurable: true })"); | 5382 "Object.defineProperty(obj2, 'x'," |
| 5383 "{ get: function() { return 'y'; }, configurable: true })"); |
6147 | 5384 |
6148 ExpectString("obj1.x", "y"); | 5385 ExpectString("obj1.x", "y"); |
6149 ExpectString("obj2.x", "y"); | 5386 ExpectString("obj2.x", "y"); |
6150 | 5387 |
6151 ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); | 5388 ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
6152 ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); | 5389 ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
6153 | 5390 |
6154 CHECK(GetGlobalProperty(&context, "obj1")-> | 5391 CHECK(GetGlobalProperty(&context, "obj1") |
6155 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5392 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6156 CHECK(GetGlobalProperty(&context, "obj2")-> | 5393 CHECK(GetGlobalProperty(&context, "obj2") |
6157 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5394 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6158 | 5395 |
6159 ExpectString("obj1.x", "x"); | 5396 ExpectString("obj1.x", "x"); |
6160 ExpectString("obj2.x", "x"); | 5397 ExpectString("obj2.x", "x"); |
6161 | 5398 |
6162 ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); | 5399 ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
6163 ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); | 5400 ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
6164 | 5401 |
6165 // Define getters/setters, but now make them not configurable. | 5402 // Define getters/setters, but now make them not configurable. |
6166 CompileRun("Object.defineProperty(obj1, 'x'," | 5403 CompileRun( |
6167 "{ get: function() { return 'z'; }, configurable: false })"); | 5404 "Object.defineProperty(obj1, 'x'," |
6168 CompileRun("Object.defineProperty(obj2, 'x'," | 5405 "{ get: function() { return 'z'; }, configurable: false })"); |
6169 "{ get: function() { return 'z'; }, configurable: false })"); | 5406 CompileRun( |
| 5407 "Object.defineProperty(obj2, 'x'," |
| 5408 "{ get: function() { return 'z'; }, configurable: false })"); |
6170 | 5409 |
6171 ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); | 5410 ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
6172 ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); | 5411 ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
6173 | 5412 |
6174 ExpectString("obj1.x", "z"); | 5413 ExpectString("obj1.x", "z"); |
6175 ExpectString("obj2.x", "z"); | 5414 ExpectString("obj2.x", "z"); |
6176 | 5415 |
6177 CHECK(!GetGlobalProperty(&context, "obj1")-> | 5416 CHECK(!GetGlobalProperty(&context, "obj1") |
6178 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5417 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6179 CHECK(!GetGlobalProperty(&context, "obj2")-> | 5418 CHECK(!GetGlobalProperty(&context, "obj2") |
6180 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5419 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6181 | 5420 |
6182 ExpectString("obj1.x", "z"); | 5421 ExpectString("obj1.x", "z"); |
6183 ExpectString("obj2.x", "z"); | 5422 ExpectString("obj2.x", "z"); |
6184 } | 5423 } |
6185 | 5424 |
6186 | 5425 |
6187 THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { | 5426 THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { |
6188 v8::Isolate* isolate = CcTest::isolate(); | 5427 v8::Isolate* isolate = CcTest::isolate(); |
6189 v8::HandleScope scope(isolate); | 5428 v8::HandleScope scope(isolate); |
6190 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 5429 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
6191 LocalContext context; | 5430 LocalContext context; |
6192 | 5431 |
6193 context->Global()->Set(v8_str("obj1"), templ->NewInstance()); | 5432 context->Global()->Set(v8_str("obj1"), templ->NewInstance()); |
6194 CompileRun("var obj2 = {};"); | 5433 CompileRun("var obj2 = {};"); |
6195 | 5434 |
6196 CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor( | 5435 CHECK(GetGlobalProperty(&context, "obj1") |
6197 v8_str("x"), | 5436 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"), |
6198 GetXValue, NULL, | 5437 v8::DEFAULT, v8::DontDelete)); |
6199 v8_str("donut"), v8::DEFAULT, v8::DontDelete)); | 5438 CHECK(GetGlobalProperty(&context, "obj2") |
6200 CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor( | 5439 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"), |
6201 v8_str("x"), | 5440 v8::DEFAULT, v8::DontDelete)); |
6202 GetXValue, NULL, | |
6203 v8_str("donut"), v8::DEFAULT, v8::DontDelete)); | |
6204 | 5441 |
6205 ExpectString("obj1.x", "x"); | 5442 ExpectString("obj1.x", "x"); |
6206 ExpectString("obj2.x", "x"); | 5443 ExpectString("obj2.x", "x"); |
6207 | 5444 |
6208 ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); | 5445 ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
6209 ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); | 5446 ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
6210 | 5447 |
6211 CHECK(!GetGlobalProperty(&context, "obj1")-> | 5448 CHECK(!GetGlobalProperty(&context, "obj1") |
6212 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5449 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6213 CHECK(!GetGlobalProperty(&context, "obj2")-> | 5450 CHECK(!GetGlobalProperty(&context, "obj2") |
6214 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); | 5451 ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
6215 | 5452 |
6216 { | 5453 { |
6217 v8::TryCatch try_catch; | 5454 v8::TryCatch try_catch; |
6218 CompileRun("Object.defineProperty(obj1, 'x'," | 5455 CompileRun( |
| 5456 "Object.defineProperty(obj1, 'x'," |
6219 "{get: function() { return 'func'; }})"); | 5457 "{get: function() { return 'func'; }})"); |
6220 CHECK(try_catch.HasCaught()); | 5458 CHECK(try_catch.HasCaught()); |
6221 String::Utf8Value exception_value(try_catch.Exception()); | 5459 String::Utf8Value exception_value(try_catch.Exception()); |
6222 CHECK_EQ( | 5460 CHECK_EQ( |
6223 0, strcmp(*exception_value, "TypeError: Cannot redefine property: x")); | 5461 0, strcmp(*exception_value, "TypeError: Cannot redefine property: x")); |
6224 } | 5462 } |
6225 { | 5463 { |
6226 v8::TryCatch try_catch; | 5464 v8::TryCatch try_catch; |
6227 CompileRun("Object.defineProperty(obj2, 'x'," | 5465 CompileRun( |
| 5466 "Object.defineProperty(obj2, 'x'," |
6228 "{get: function() { return 'func'; }})"); | 5467 "{get: function() { return 'func'; }})"); |
6229 CHECK(try_catch.HasCaught()); | 5468 CHECK(try_catch.HasCaught()); |
6230 String::Utf8Value exception_value(try_catch.Exception()); | 5469 String::Utf8Value exception_value(try_catch.Exception()); |
6231 CHECK_EQ( | 5470 CHECK_EQ( |
6232 0, strcmp(*exception_value, "TypeError: Cannot redefine property: x")); | 5471 0, strcmp(*exception_value, "TypeError: Cannot redefine property: x")); |
6233 } | 5472 } |
6234 } | 5473 } |
6235 | 5474 |
6236 | 5475 |
6237 static void Get239Value(Local<String> name, | 5476 static void Get239Value(Local<String> name, |
6238 const v8::PropertyCallbackInfo<v8::Value>& info) { | 5477 const v8::PropertyCallbackInfo<v8::Value>& info) { |
6239 ApiTestFuzzer::Fuzz(); | 5478 ApiTestFuzzer::Fuzz(); |
6240 CHECK(info.Data()->Equals(v8_str("donut"))); | 5479 CHECK(info.Data()->Equals(v8_str("donut"))); |
6241 CHECK(name->Equals(v8_str("239"))); | 5480 CHECK(name->Equals(v8_str("239"))); |
6242 info.GetReturnValue().Set(name); | 5481 info.GetReturnValue().Set(name); |
6243 } | 5482 } |
6244 | 5483 |
6245 | 5484 |
6246 THREADED_TEST(ElementAPIAccessor) { | 5485 THREADED_TEST(ElementAPIAccessor) { |
6247 v8::Isolate* isolate = CcTest::isolate(); | 5486 v8::Isolate* isolate = CcTest::isolate(); |
6248 v8::HandleScope scope(isolate); | 5487 v8::HandleScope scope(isolate); |
6249 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 5488 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
6250 LocalContext context; | 5489 LocalContext context; |
6251 | 5490 |
6252 context->Global()->Set(v8_str("obj1"), templ->NewInstance()); | 5491 context->Global()->Set(v8_str("obj1"), templ->NewInstance()); |
6253 CompileRun("var obj2 = {};"); | 5492 CompileRun("var obj2 = {};"); |
6254 | 5493 |
6255 CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor( | 5494 CHECK(GetGlobalProperty(&context, "obj1") |
6256 v8_str("239"), | 5495 ->SetAccessor(v8_str("239"), Get239Value, NULL, v8_str("donut"))); |
6257 Get239Value, NULL, | 5496 CHECK(GetGlobalProperty(&context, "obj2") |
6258 v8_str("donut"))); | 5497 ->SetAccessor(v8_str("239"), Get239Value, NULL, v8_str("donut"))); |
6259 CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor( | |
6260 v8_str("239"), | |
6261 Get239Value, NULL, | |
6262 v8_str("donut"))); | |
6263 | 5498 |
6264 ExpectString("obj1[239]", "239"); | 5499 ExpectString("obj1[239]", "239"); |
6265 ExpectString("obj2[239]", "239"); | 5500 ExpectString("obj2[239]", "239"); |
6266 ExpectString("obj1['239']", "239"); | 5501 ExpectString("obj1['239']", "239"); |
6267 ExpectString("obj2['239']", "239"); | 5502 ExpectString("obj2['239']", "239"); |
6268 } | 5503 } |
6269 | 5504 |
6270 | 5505 |
6271 v8::Persistent<Value> xValue; | 5506 v8::Persistent<Value> xValue; |
6272 | 5507 |
6273 | 5508 |
6274 static void SetXValue(Local<String> name, | 5509 static void SetXValue(Local<String> name, Local<Value> value, |
6275 Local<Value> value, | |
6276 const v8::PropertyCallbackInfo<void>& info) { | 5510 const v8::PropertyCallbackInfo<void>& info) { |
6277 CHECK(value->Equals(v8_num(4))); | 5511 CHECK(value->Equals(v8_num(4))); |
6278 CHECK(info.Data()->Equals(v8_str("donut"))); | 5512 CHECK(info.Data()->Equals(v8_str("donut"))); |
6279 CHECK(name->Equals(v8_str("x"))); | 5513 CHECK(name->Equals(v8_str("x"))); |
6280 CHECK(xValue.IsEmpty()); | 5514 CHECK(xValue.IsEmpty()); |
6281 xValue.Reset(info.GetIsolate(), value); | 5515 xValue.Reset(info.GetIsolate(), value); |
6282 } | 5516 } |
6283 | 5517 |
6284 | 5518 |
6285 THREADED_TEST(SimplePropertyWrite) { | 5519 THREADED_TEST(SimplePropertyWrite) { |
(...skipping 27 matching lines...) Expand all Loading... |
6313 CHECK(v8_num(4)->Equals(Local<Value>::New(CcTest::isolate(), xValue))); | 5547 CHECK(v8_num(4)->Equals(Local<Value>::New(CcTest::isolate(), xValue))); |
6314 xValue.Reset(); | 5548 xValue.Reset(); |
6315 } | 5549 } |
6316 } | 5550 } |
6317 | 5551 |
6318 | 5552 |
6319 THREADED_TEST(NoAccessors) { | 5553 THREADED_TEST(NoAccessors) { |
6320 v8::Isolate* isolate = CcTest::isolate(); | 5554 v8::Isolate* isolate = CcTest::isolate(); |
6321 v8::HandleScope scope(isolate); | 5555 v8::HandleScope scope(isolate); |
6322 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 5556 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
6323 templ->SetAccessor(v8_str("x"), | 5557 templ->SetAccessor(v8_str("x"), static_cast<v8::AccessorGetterCallback>(NULL), |
6324 static_cast<v8::AccessorGetterCallback>(NULL), | 5558 NULL, v8_str("donut")); |
6325 NULL, | |
6326 v8_str("donut")); | |
6327 LocalContext context; | 5559 LocalContext context; |
6328 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | 5560 context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
6329 Local<Script> script = v8_compile("obj.x = 4; obj.x"); | 5561 Local<Script> script = v8_compile("obj.x = 4; obj.x"); |
6330 for (int i = 0; i < 10; i++) { | 5562 for (int i = 0; i < 10; i++) { |
6331 script->Run(); | 5563 script->Run(); |
6332 } | 5564 } |
6333 } | 5565 } |
6334 | 5566 |
6335 | 5567 |
6336 static void XPropertyGetter(Local<Name> property, | |
6337 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6338 ApiTestFuzzer::Fuzz(); | |
6339 CHECK(info.Data()->IsUndefined()); | |
6340 info.GetReturnValue().Set(property); | |
6341 } | |
6342 | |
6343 | |
6344 THREADED_TEST(NamedInterceptorPropertyRead) { | |
6345 v8::Isolate* isolate = CcTest::isolate(); | |
6346 v8::HandleScope scope(isolate); | |
6347 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6348 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); | |
6349 LocalContext context; | |
6350 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | |
6351 Local<Script> script = v8_compile("obj.x"); | |
6352 for (int i = 0; i < 10; i++) { | |
6353 Local<Value> result = script->Run(); | |
6354 CHECK(result->Equals(v8_str("x"))); | |
6355 } | |
6356 } | |
6357 | |
6358 | |
6359 THREADED_TEST(NamedInterceptorDictionaryIC) { | |
6360 v8::Isolate* isolate = CcTest::isolate(); | |
6361 v8::HandleScope scope(isolate); | |
6362 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6363 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); | |
6364 LocalContext context; | |
6365 // Create an object with a named interceptor. | |
6366 context->Global()->Set(v8_str("interceptor_obj"), templ->NewInstance()); | |
6367 Local<Script> script = v8_compile("interceptor_obj.x"); | |
6368 for (int i = 0; i < 10; i++) { | |
6369 Local<Value> result = script->Run(); | |
6370 CHECK(result->Equals(v8_str("x"))); | |
6371 } | |
6372 // Create a slow case object and a function accessing a property in | |
6373 // that slow case object (with dictionary probing in generated | |
6374 // code). Then force object with a named interceptor into slow-case, | |
6375 // pass it to the function, and check that the interceptor is called | |
6376 // instead of accessing the local property. | |
6377 Local<Value> result = | |
6378 CompileRun("function get_x(o) { return o.x; };" | |
6379 "var obj = { x : 42, y : 0 };" | |
6380 "delete obj.y;" | |
6381 "for (var i = 0; i < 10; i++) get_x(obj);" | |
6382 "interceptor_obj.x = 42;" | |
6383 "interceptor_obj.y = 10;" | |
6384 "delete interceptor_obj.y;" | |
6385 "get_x(interceptor_obj)"); | |
6386 CHECK(result->Equals(v8_str("x"))); | |
6387 } | |
6388 | |
6389 | |
6390 THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { | |
6391 v8::Isolate* isolate = CcTest::isolate(); | |
6392 v8::HandleScope scope(isolate); | |
6393 v8::Local<Context> context1 = Context::New(isolate); | |
6394 | |
6395 context1->Enter(); | |
6396 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6397 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); | |
6398 // Create an object with a named interceptor. | |
6399 v8::Local<v8::Object> object = templ->NewInstance(); | |
6400 context1->Global()->Set(v8_str("interceptor_obj"), object); | |
6401 | |
6402 // Force the object into the slow case. | |
6403 CompileRun("interceptor_obj.y = 0;" | |
6404 "delete interceptor_obj.y;"); | |
6405 context1->Exit(); | |
6406 | |
6407 { | |
6408 // Introduce the object into a different context. | |
6409 // Repeat named loads to exercise ICs. | |
6410 LocalContext context2; | |
6411 context2->Global()->Set(v8_str("interceptor_obj"), object); | |
6412 Local<Value> result = | |
6413 CompileRun("function get_x(o) { return o.x; }" | |
6414 "interceptor_obj.x = 42;" | |
6415 "for (var i=0; i != 10; i++) {" | |
6416 " get_x(interceptor_obj);" | |
6417 "}" | |
6418 "get_x(interceptor_obj)"); | |
6419 // Check that the interceptor was actually invoked. | |
6420 CHECK(result->Equals(v8_str("x"))); | |
6421 } | |
6422 | |
6423 // Return to the original context and force some object to the slow case | |
6424 // to cause the NormalizedMapCache to verify. | |
6425 context1->Enter(); | |
6426 CompileRun("var obj = { x : 0 }; delete obj.x;"); | |
6427 context1->Exit(); | |
6428 } | |
6429 | |
6430 | |
6431 static void SetXOnPrototypeGetter( | |
6432 Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6433 // Set x on the prototype object and do not handle the get request. | |
6434 v8::Handle<v8::Value> proto = info.Holder()->GetPrototype(); | |
6435 proto.As<v8::Object>()->Set(v8_str("x"), | |
6436 v8::Integer::New(info.GetIsolate(), 23)); | |
6437 } | |
6438 | |
6439 | |
6440 // This is a regression test for http://crbug.com/20104. Map | |
6441 // transitions should not interfere with post interceptor lookup. | |
6442 THREADED_TEST(NamedInterceptorMapTransitionRead) { | |
6443 v8::Isolate* isolate = CcTest::isolate(); | |
6444 v8::HandleScope scope(isolate); | |
6445 Local<v8::FunctionTemplate> function_template = | |
6446 v8::FunctionTemplate::New(isolate); | |
6447 Local<v8::ObjectTemplate> instance_template | |
6448 = function_template->InstanceTemplate(); | |
6449 instance_template->SetHandler( | |
6450 v8::NamedPropertyHandlerConfiguration(SetXOnPrototypeGetter)); | |
6451 LocalContext context; | |
6452 context->Global()->Set(v8_str("F"), function_template->GetFunction()); | |
6453 // Create an instance of F and introduce a map transition for x. | |
6454 CompileRun("var o = new F(); o.x = 23;"); | |
6455 // Create an instance of F and invoke the getter. The result should be 23. | |
6456 Local<Value> result = CompileRun("o = new F(); o.x"); | |
6457 CHECK_EQ(result->Int32Value(), 23); | |
6458 } | |
6459 | |
6460 | |
6461 static void IndexedPropertyGetter( | |
6462 uint32_t index, | |
6463 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6464 ApiTestFuzzer::Fuzz(); | |
6465 if (index == 37) { | |
6466 info.GetReturnValue().Set(v8_num(625)); | |
6467 } | |
6468 } | |
6469 | |
6470 | |
6471 static void IndexedPropertySetter( | |
6472 uint32_t index, | |
6473 Local<Value> value, | |
6474 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6475 ApiTestFuzzer::Fuzz(); | |
6476 if (index == 39) { | |
6477 info.GetReturnValue().Set(value); | |
6478 } | |
6479 } | |
6480 | |
6481 | |
6482 THREADED_TEST(IndexedInterceptorWithIndexedAccessor) { | |
6483 v8::Isolate* isolate = CcTest::isolate(); | |
6484 v8::HandleScope scope(isolate); | |
6485 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6486 templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
6487 IndexedPropertyGetter, IndexedPropertySetter)); | |
6488 LocalContext context; | |
6489 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | |
6490 Local<Script> getter_script = v8_compile( | |
6491 "obj.__defineGetter__(\"3\", function(){return 5;});obj[3];"); | |
6492 Local<Script> setter_script = v8_compile( | |
6493 "obj.__defineSetter__(\"17\", function(val){this.foo = val;});" | |
6494 "obj[17] = 23;" | |
6495 "obj.foo;"); | |
6496 Local<Script> interceptor_setter_script = v8_compile( | |
6497 "obj.__defineSetter__(\"39\", function(val){this.foo = \"hit\";});" | |
6498 "obj[39] = 47;" | |
6499 "obj.foo;"); // This setter should not run, due to the interceptor. | |
6500 Local<Script> interceptor_getter_script = v8_compile( | |
6501 "obj[37];"); | |
6502 Local<Value> result = getter_script->Run(); | |
6503 CHECK(v8_num(5)->Equals(result)); | |
6504 result = setter_script->Run(); | |
6505 CHECK(v8_num(23)->Equals(result)); | |
6506 result = interceptor_setter_script->Run(); | |
6507 CHECK(v8_num(23)->Equals(result)); | |
6508 result = interceptor_getter_script->Run(); | |
6509 CHECK(v8_num(625)->Equals(result)); | |
6510 } | |
6511 | |
6512 | |
6513 static void UnboxedDoubleIndexedPropertyGetter( | |
6514 uint32_t index, | |
6515 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6516 ApiTestFuzzer::Fuzz(); | |
6517 if (index < 25) { | |
6518 info.GetReturnValue().Set(v8_num(index)); | |
6519 } | |
6520 } | |
6521 | |
6522 | |
6523 static void UnboxedDoubleIndexedPropertySetter( | |
6524 uint32_t index, | |
6525 Local<Value> value, | |
6526 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6527 ApiTestFuzzer::Fuzz(); | |
6528 if (index < 25) { | |
6529 info.GetReturnValue().Set(v8_num(index)); | |
6530 } | |
6531 } | |
6532 | |
6533 | |
6534 void UnboxedDoubleIndexedPropertyEnumerator( | |
6535 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
6536 // Force the list of returned keys to be stored in a FastDoubleArray. | |
6537 Local<Script> indexed_property_names_script = v8_compile( | |
6538 "keys = new Array(); keys[125000] = 1;" | |
6539 "for(i = 0; i < 80000; i++) { keys[i] = i; };" | |
6540 "keys.length = 25; keys;"); | |
6541 Local<Value> result = indexed_property_names_script->Run(); | |
6542 info.GetReturnValue().Set(Local<v8::Array>::Cast(result)); | |
6543 } | |
6544 | |
6545 | |
6546 // Make sure that the the interceptor code in the runtime properly handles | |
6547 // merging property name lists for double-array-backed arrays. | |
6548 THREADED_TEST(IndexedInterceptorUnboxedDoubleWithIndexedAccessor) { | |
6549 v8::Isolate* isolate = CcTest::isolate(); | |
6550 v8::HandleScope scope(isolate); | |
6551 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6552 templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
6553 UnboxedDoubleIndexedPropertyGetter, UnboxedDoubleIndexedPropertySetter, 0, | |
6554 0, UnboxedDoubleIndexedPropertyEnumerator)); | |
6555 LocalContext context; | |
6556 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | |
6557 // When obj is created, force it to be Stored in a FastDoubleArray. | |
6558 Local<Script> create_unboxed_double_script = v8_compile( | |
6559 "obj[125000] = 1; for(i = 0; i < 80000; i+=2) { obj[i] = i; } " | |
6560 "key_count = 0; " | |
6561 "for (x in obj) {key_count++;};" | |
6562 "obj;"); | |
6563 Local<Value> result = create_unboxed_double_script->Run(); | |
6564 CHECK(result->ToObject(isolate)->HasRealIndexedProperty(2000)); | |
6565 Local<Script> key_count_check = v8_compile("key_count;"); | |
6566 result = key_count_check->Run(); | |
6567 CHECK(v8_num(40013)->Equals(result)); | |
6568 } | |
6569 | |
6570 | |
6571 void SloppyArgsIndexedPropertyEnumerator( | |
6572 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
6573 // Force the list of returned keys to be stored in a Arguments object. | |
6574 Local<Script> indexed_property_names_script = v8_compile( | |
6575 "function f(w,x) {" | |
6576 " return arguments;" | |
6577 "}" | |
6578 "keys = f(0, 1, 2, 3);" | |
6579 "keys;"); | |
6580 Local<Object> result = | |
6581 Local<Object>::Cast(indexed_property_names_script->Run()); | |
6582 // Have to populate the handle manually, as it's not Cast-able. | |
6583 i::Handle<i::JSObject> o = | |
6584 v8::Utils::OpenHandle<Object, i::JSObject>(result); | |
6585 i::Handle<i::JSArray> array(reinterpret_cast<i::JSArray*>(*o)); | |
6586 info.GetReturnValue().Set(v8::Utils::ToLocal(array)); | |
6587 } | |
6588 | |
6589 | |
6590 static void SloppyIndexedPropertyGetter( | |
6591 uint32_t index, | |
6592 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6593 ApiTestFuzzer::Fuzz(); | |
6594 if (index < 4) { | |
6595 info.GetReturnValue().Set(v8_num(index)); | |
6596 } | |
6597 } | |
6598 | |
6599 | |
6600 // Make sure that the the interceptor code in the runtime properly handles | |
6601 // merging property name lists for non-string arguments arrays. | |
6602 THREADED_TEST(IndexedInterceptorSloppyArgsWithIndexedAccessor) { | |
6603 v8::Isolate* isolate = CcTest::isolate(); | |
6604 v8::HandleScope scope(isolate); | |
6605 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6606 templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
6607 SloppyIndexedPropertyGetter, 0, 0, 0, | |
6608 SloppyArgsIndexedPropertyEnumerator)); | |
6609 LocalContext context; | |
6610 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | |
6611 Local<Script> create_args_script = v8_compile( | |
6612 "var key_count = 0;" | |
6613 "for (x in obj) {key_count++;} key_count;"); | |
6614 Local<Value> result = create_args_script->Run(); | |
6615 CHECK(v8_num(4)->Equals(result)); | |
6616 } | |
6617 | |
6618 | |
6619 static void IdentityIndexedPropertyGetter( | |
6620 uint32_t index, | |
6621 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
6622 info.GetReturnValue().Set(index); | |
6623 } | |
6624 | |
6625 | |
6626 THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { | |
6627 v8::Isolate* isolate = CcTest::isolate(); | |
6628 v8::HandleScope scope(isolate); | |
6629 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6630 templ->SetHandler( | |
6631 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6632 | |
6633 LocalContext context; | |
6634 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | |
6635 | |
6636 // Check fast object case. | |
6637 const char* fast_case_code = | |
6638 "Object.getOwnPropertyDescriptor(obj, 0).value.toString()"; | |
6639 ExpectString(fast_case_code, "0"); | |
6640 | |
6641 // Check slow case. | |
6642 const char* slow_case_code = | |
6643 "obj.x = 1; delete obj.x;" | |
6644 "Object.getOwnPropertyDescriptor(obj, 1).value.toString()"; | |
6645 ExpectString(slow_case_code, "1"); | |
6646 } | |
6647 | |
6648 | |
6649 THREADED_TEST(IndexedInterceptorWithNoSetter) { | |
6650 v8::Isolate* isolate = CcTest::isolate(); | |
6651 v8::HandleScope scope(isolate); | |
6652 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6653 templ->SetHandler( | |
6654 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6655 | |
6656 LocalContext context; | |
6657 context->Global()->Set(v8_str("obj"), templ->NewInstance()); | |
6658 | |
6659 const char* code = | |
6660 "try {" | |
6661 " obj[0] = 239;" | |
6662 " for (var i = 0; i < 100; i++) {" | |
6663 " var v = obj[0];" | |
6664 " if (v != 0) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6665 " }" | |
6666 " 'PASSED'" | |
6667 "} catch(e) {" | |
6668 " e" | |
6669 "}"; | |
6670 ExpectString(code, "PASSED"); | |
6671 } | |
6672 | |
6673 | |
6674 THREADED_TEST(IndexedInterceptorWithAccessorCheck) { | |
6675 v8::Isolate* isolate = CcTest::isolate(); | |
6676 v8::HandleScope scope(isolate); | |
6677 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6678 templ->SetHandler( | |
6679 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6680 | |
6681 LocalContext context; | |
6682 Local<v8::Object> obj = templ->NewInstance(); | |
6683 obj->TurnOnAccessCheck(); | |
6684 context->Global()->Set(v8_str("obj"), obj); | |
6685 | |
6686 const char* code = | |
6687 "var result = 'PASSED';" | |
6688 "for (var i = 0; i < 100; i++) {" | |
6689 " try {" | |
6690 " var v = obj[0];" | |
6691 " result = 'Wrong value ' + v + ' at iteration ' + i;" | |
6692 " break;" | |
6693 " } catch (e) {" | |
6694 " /* pass */" | |
6695 " }" | |
6696 "}" | |
6697 "result"; | |
6698 ExpectString(code, "PASSED"); | |
6699 } | |
6700 | |
6701 | |
6702 THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) { | |
6703 i::FLAG_allow_natives_syntax = true; | |
6704 v8::Isolate* isolate = CcTest::isolate(); | |
6705 v8::HandleScope scope(isolate); | |
6706 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6707 templ->SetHandler( | |
6708 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6709 | |
6710 LocalContext context; | |
6711 Local<v8::Object> obj = templ->NewInstance(); | |
6712 context->Global()->Set(v8_str("obj"), obj); | |
6713 | |
6714 const char* code = | |
6715 "var result = 'PASSED';" | |
6716 "for (var i = 0; i < 100; i++) {" | |
6717 " var expected = i;" | |
6718 " if (i == 5) {" | |
6719 " %EnableAccessChecks(obj);" | |
6720 " }" | |
6721 " try {" | |
6722 " var v = obj[i];" | |
6723 " if (i == 5) {" | |
6724 " result = 'Should not have reached this!';" | |
6725 " break;" | |
6726 " } else if (v != expected) {" | |
6727 " result = 'Wrong value ' + v + ' at iteration ' + i;" | |
6728 " break;" | |
6729 " }" | |
6730 " } catch (e) {" | |
6731 " if (i != 5) {" | |
6732 " result = e;" | |
6733 " }" | |
6734 " }" | |
6735 " if (i == 5) %DisableAccessChecks(obj);" | |
6736 "}" | |
6737 "result"; | |
6738 ExpectString(code, "PASSED"); | |
6739 } | |
6740 | |
6741 | |
6742 THREADED_TEST(IndexedInterceptorWithDifferentIndices) { | |
6743 v8::Isolate* isolate = CcTest::isolate(); | |
6744 v8::HandleScope scope(isolate); | |
6745 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6746 templ->SetHandler( | |
6747 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6748 | |
6749 LocalContext context; | |
6750 Local<v8::Object> obj = templ->NewInstance(); | |
6751 context->Global()->Set(v8_str("obj"), obj); | |
6752 | |
6753 const char* code = | |
6754 "try {" | |
6755 " for (var i = 0; i < 100; i++) {" | |
6756 " var v = obj[i];" | |
6757 " if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6758 " }" | |
6759 " 'PASSED'" | |
6760 "} catch(e) {" | |
6761 " e" | |
6762 "}"; | |
6763 ExpectString(code, "PASSED"); | |
6764 } | |
6765 | |
6766 | |
6767 THREADED_TEST(IndexedInterceptorWithNegativeIndices) { | |
6768 v8::Isolate* isolate = CcTest::isolate(); | |
6769 v8::HandleScope scope(isolate); | |
6770 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6771 templ->SetHandler( | |
6772 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6773 | |
6774 LocalContext context; | |
6775 Local<v8::Object> obj = templ->NewInstance(); | |
6776 context->Global()->Set(v8_str("obj"), obj); | |
6777 | |
6778 const char* code = | |
6779 "try {" | |
6780 " for (var i = 0; i < 100; i++) {" | |
6781 " var expected = i;" | |
6782 " var key = i;" | |
6783 " if (i == 25) {" | |
6784 " key = -1;" | |
6785 " expected = undefined;" | |
6786 " }" | |
6787 " if (i == 50) {" | |
6788 " /* probe minimal Smi number on 32-bit platforms */" | |
6789 " key = -(1 << 30);" | |
6790 " expected = undefined;" | |
6791 " }" | |
6792 " if (i == 75) {" | |
6793 " /* probe minimal Smi number on 64-bit platforms */" | |
6794 " key = 1 << 31;" | |
6795 " expected = undefined;" | |
6796 " }" | |
6797 " var v = obj[key];" | |
6798 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6799 " }" | |
6800 " 'PASSED'" | |
6801 "} catch(e) {" | |
6802 " e" | |
6803 "}"; | |
6804 ExpectString(code, "PASSED"); | |
6805 } | |
6806 | |
6807 | |
6808 THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { | |
6809 v8::Isolate* isolate = CcTest::isolate(); | |
6810 v8::HandleScope scope(isolate); | |
6811 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6812 templ->SetHandler( | |
6813 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6814 | |
6815 LocalContext context; | |
6816 Local<v8::Object> obj = templ->NewInstance(); | |
6817 context->Global()->Set(v8_str("obj"), obj); | |
6818 | |
6819 const char* code = | |
6820 "try {" | |
6821 " for (var i = 0; i < 100; i++) {" | |
6822 " var expected = i;" | |
6823 " var key = i;" | |
6824 " if (i == 50) {" | |
6825 " key = 'foobar';" | |
6826 " expected = undefined;" | |
6827 " }" | |
6828 " var v = obj[key];" | |
6829 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6830 " }" | |
6831 " 'PASSED'" | |
6832 "} catch(e) {" | |
6833 " e" | |
6834 "}"; | |
6835 ExpectString(code, "PASSED"); | |
6836 } | |
6837 | |
6838 | |
6839 THREADED_TEST(IndexedInterceptorGoingMegamorphic) { | |
6840 v8::Isolate* isolate = CcTest::isolate(); | |
6841 v8::HandleScope scope(isolate); | |
6842 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6843 templ->SetHandler( | |
6844 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6845 | |
6846 LocalContext context; | |
6847 Local<v8::Object> obj = templ->NewInstance(); | |
6848 context->Global()->Set(v8_str("obj"), obj); | |
6849 | |
6850 const char* code = | |
6851 "var original = obj;" | |
6852 "try {" | |
6853 " for (var i = 0; i < 100; i++) {" | |
6854 " var expected = i;" | |
6855 " if (i == 50) {" | |
6856 " obj = {50: 'foobar'};" | |
6857 " expected = 'foobar';" | |
6858 " }" | |
6859 " var v = obj[i];" | |
6860 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6861 " if (i == 50) obj = original;" | |
6862 " }" | |
6863 " 'PASSED'" | |
6864 "} catch(e) {" | |
6865 " e" | |
6866 "}"; | |
6867 ExpectString(code, "PASSED"); | |
6868 } | |
6869 | |
6870 | |
6871 THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { | |
6872 v8::Isolate* isolate = CcTest::isolate(); | |
6873 v8::HandleScope scope(isolate); | |
6874 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6875 templ->SetHandler( | |
6876 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6877 | |
6878 LocalContext context; | |
6879 Local<v8::Object> obj = templ->NewInstance(); | |
6880 context->Global()->Set(v8_str("obj"), obj); | |
6881 | |
6882 const char* code = | |
6883 "var original = obj;" | |
6884 "try {" | |
6885 " for (var i = 0; i < 100; i++) {" | |
6886 " var expected = i;" | |
6887 " if (i == 5) {" | |
6888 " obj = 239;" | |
6889 " expected = undefined;" | |
6890 " }" | |
6891 " var v = obj[i];" | |
6892 " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6893 " if (i == 5) obj = original;" | |
6894 " }" | |
6895 " 'PASSED'" | |
6896 "} catch(e) {" | |
6897 " e" | |
6898 "}"; | |
6899 ExpectString(code, "PASSED"); | |
6900 } | |
6901 | |
6902 | |
6903 THREADED_TEST(IndexedInterceptorOnProto) { | |
6904 v8::Isolate* isolate = CcTest::isolate(); | |
6905 v8::HandleScope scope(isolate); | |
6906 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
6907 templ->SetHandler( | |
6908 v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); | |
6909 | |
6910 LocalContext context; | |
6911 Local<v8::Object> obj = templ->NewInstance(); | |
6912 context->Global()->Set(v8_str("obj"), obj); | |
6913 | |
6914 const char* code = | |
6915 "var o = {__proto__: obj};" | |
6916 "try {" | |
6917 " for (var i = 0; i < 100; i++) {" | |
6918 " var v = o[i];" | |
6919 " if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;" | |
6920 " }" | |
6921 " 'PASSED'" | |
6922 "} catch(e) {" | |
6923 " e" | |
6924 "}"; | |
6925 ExpectString(code, "PASSED"); | |
6926 } | |
6927 | |
6928 | |
6929 THREADED_TEST(MultiContexts) { | 5568 THREADED_TEST(MultiContexts) { |
6930 v8::Isolate* isolate = CcTest::isolate(); | 5569 v8::Isolate* isolate = CcTest::isolate(); |
6931 v8::HandleScope scope(isolate); | 5570 v8::HandleScope scope(isolate); |
6932 v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 5571 v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
6933 templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(isolate, | 5572 templ->Set(v8_str("dummy"), |
6934 DummyCallHandler)); | 5573 v8::FunctionTemplate::New(isolate, DummyCallHandler)); |
6935 | 5574 |
6936 Local<String> password = v8_str("Password"); | 5575 Local<String> password = v8_str("Password"); |
6937 | 5576 |
6938 // Create an environment | 5577 // Create an environment |
6939 LocalContext context0(0, templ); | 5578 LocalContext context0(0, templ); |
6940 context0->SetSecurityToken(password); | 5579 context0->SetSecurityToken(password); |
6941 v8::Handle<v8::Object> global0 = context0->Global(); | 5580 v8::Handle<v8::Object> global0 = context0->Global(); |
6942 global0->Set(v8_str("custom"), v8_num(1234)); | 5581 global0->Set(v8_str("custom"), v8_num(1234)); |
6943 CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); | 5582 CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); |
6944 | 5583 |
(...skipping 16 matching lines...) Expand all Loading... |
6961 } | 5600 } |
6962 | 5601 |
6963 | 5602 |
6964 THREADED_TEST(FunctionPrototypeAcrossContexts) { | 5603 THREADED_TEST(FunctionPrototypeAcrossContexts) { |
6965 // Make sure that functions created by cloning boilerplates cannot | 5604 // Make sure that functions created by cloning boilerplates cannot |
6966 // communicate through their __proto__ field. | 5605 // communicate through their __proto__ field. |
6967 | 5606 |
6968 v8::HandleScope scope(CcTest::isolate()); | 5607 v8::HandleScope scope(CcTest::isolate()); |
6969 | 5608 |
6970 LocalContext env0; | 5609 LocalContext env0; |
6971 v8::Handle<v8::Object> global0 = | 5610 v8::Handle<v8::Object> global0 = env0->Global(); |
6972 env0->Global(); | |
6973 v8::Handle<v8::Object> object0 = | 5611 v8::Handle<v8::Object> object0 = |
6974 global0->Get(v8_str("Object")).As<v8::Object>(); | 5612 global0->Get(v8_str("Object")).As<v8::Object>(); |
6975 v8::Handle<v8::Object> tostring0 = | 5613 v8::Handle<v8::Object> tostring0 = |
6976 object0->Get(v8_str("toString")).As<v8::Object>(); | 5614 object0->Get(v8_str("toString")).As<v8::Object>(); |
6977 v8::Handle<v8::Object> proto0 = | 5615 v8::Handle<v8::Object> proto0 = |
6978 tostring0->Get(v8_str("__proto__")).As<v8::Object>(); | 5616 tostring0->Get(v8_str("__proto__")).As<v8::Object>(); |
6979 proto0->Set(v8_str("custom"), v8_num(1234)); | 5617 proto0->Set(v8_str("custom"), v8_num(1234)); |
6980 | 5618 |
6981 LocalContext env1; | 5619 LocalContext env1; |
6982 v8::Handle<v8::Object> global1 = | 5620 v8::Handle<v8::Object> global1 = env1->Global(); |
6983 env1->Global(); | |
6984 v8::Handle<v8::Object> object1 = | 5621 v8::Handle<v8::Object> object1 = |
6985 global1->Get(v8_str("Object")).As<v8::Object>(); | 5622 global1->Get(v8_str("Object")).As<v8::Object>(); |
6986 v8::Handle<v8::Object> tostring1 = | 5623 v8::Handle<v8::Object> tostring1 = |
6987 object1->Get(v8_str("toString")).As<v8::Object>(); | 5624 object1->Get(v8_str("toString")).As<v8::Object>(); |
6988 v8::Handle<v8::Object> proto1 = | 5625 v8::Handle<v8::Object> proto1 = |
6989 tostring1->Get(v8_str("__proto__")).As<v8::Object>(); | 5626 tostring1->Get(v8_str("__proto__")).As<v8::Object>(); |
6990 CHECK(!proto1->Has(v8_str("custom"))); | 5627 CHECK(!proto1->Has(v8_str("custom"))); |
6991 } | 5628 } |
6992 | 5629 |
6993 | 5630 |
6994 THREADED_TEST(Regress892105) { | 5631 THREADED_TEST(Regress892105) { |
6995 // Make sure that object and array literals created by cloning | 5632 // Make sure that object and array literals created by cloning |
6996 // boilerplates cannot communicate through their __proto__ | 5633 // boilerplates cannot communicate through their __proto__ |
6997 // field. This is rather difficult to check, but we try to add stuff | 5634 // field. This is rather difficult to check, but we try to add stuff |
6998 // to Object.prototype and Array.prototype and create a new | 5635 // to Object.prototype and Array.prototype and create a new |
6999 // environment. This should succeed. | 5636 // environment. This should succeed. |
7000 | 5637 |
7001 v8::HandleScope scope(CcTest::isolate()); | 5638 v8::HandleScope scope(CcTest::isolate()); |
7002 | 5639 |
7003 Local<String> source = v8_str("Object.prototype.obj = 1234;" | 5640 Local<String> source = v8_str( |
7004 "Array.prototype.arr = 4567;" | 5641 "Object.prototype.obj = 1234;" |
7005 "8901"); | 5642 "Array.prototype.arr = 4567;" |
| 5643 "8901"); |
7006 | 5644 |
7007 LocalContext env0; | 5645 LocalContext env0; |
7008 Local<Script> script0 = v8_compile(source); | 5646 Local<Script> script0 = v8_compile(source); |
7009 CHECK_EQ(8901.0, script0->Run()->NumberValue()); | 5647 CHECK_EQ(8901.0, script0->Run()->NumberValue()); |
7010 | 5648 |
7011 LocalContext env1; | 5649 LocalContext env1; |
7012 Local<Script> script1 = v8_compile(source); | 5650 Local<Script> script1 = v8_compile(source); |
7013 CHECK_EQ(8901.0, script1->Run()->NumberValue()); | 5651 CHECK_EQ(8901.0, script1->Run()->NumberValue()); |
7014 } | 5652 } |
7015 | 5653 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7076 ExpectBoolean("undetectable === void 0", false); | 5714 ExpectBoolean("undetectable === void 0", false); |
7077 ExpectBoolean("null === void 0", false); | 5715 ExpectBoolean("null === void 0", false); |
7078 | 5716 |
7079 ExpectBoolean("void 0 == undefined", true); | 5717 ExpectBoolean("void 0 == undefined", true); |
7080 ExpectBoolean("void 0 == undetectable", true); | 5718 ExpectBoolean("void 0 == undetectable", true); |
7081 ExpectBoolean("void 0 == null", true); | 5719 ExpectBoolean("void 0 == null", true); |
7082 ExpectBoolean("void 0 === undefined", true); | 5720 ExpectBoolean("void 0 === undefined", true); |
7083 ExpectBoolean("void 0 === undetectable", false); | 5721 ExpectBoolean("void 0 === undetectable", false); |
7084 ExpectBoolean("void 0 === null", false); | 5722 ExpectBoolean("void 0 === null", false); |
7085 | 5723 |
7086 ExpectString("(function() {" | 5724 ExpectString( |
7087 " try {" | 5725 "(function() {" |
7088 " return x === void 0;" | 5726 " try {" |
7089 " } catch(e) {" | 5727 " return x === void 0;" |
7090 " return e.toString();" | 5728 " } catch(e) {" |
7091 " }" | 5729 " return e.toString();" |
7092 "})()", | 5730 " }" |
7093 "ReferenceError: x is not defined"); | 5731 "})()", |
7094 ExpectString("(function() {" | 5732 "ReferenceError: x is not defined"); |
7095 " try {" | 5733 ExpectString( |
7096 " return void 0 === x;" | 5734 "(function() {" |
7097 " } catch(e) {" | 5735 " try {" |
7098 " return e.toString();" | 5736 " return void 0 === x;" |
7099 " }" | 5737 " } catch(e) {" |
7100 "})()", | 5738 " return e.toString();" |
7101 "ReferenceError: x is not defined"); | 5739 " }" |
| 5740 "})()", |
| 5741 "ReferenceError: x is not defined"); |
7102 } | 5742 } |
7103 | 5743 |
7104 | 5744 |
7105 THREADED_TEST(ExtensibleOnUndetectable) { | 5745 THREADED_TEST(ExtensibleOnUndetectable) { |
7106 LocalContext env; | 5746 LocalContext env; |
7107 v8::Isolate* isolate = env->GetIsolate(); | 5747 v8::Isolate* isolate = env->GetIsolate(); |
7108 v8::HandleScope scope(isolate); | 5748 v8::HandleScope scope(isolate); |
7109 | 5749 |
7110 Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); | 5750 Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); |
7111 desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable | 5751 desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
7112 | 5752 |
7113 Local<v8::Object> obj = desc->GetFunction()->NewInstance(); | 5753 Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
7114 env->Global()->Set(v8_str("undetectable"), obj); | 5754 env->Global()->Set(v8_str("undetectable"), obj); |
7115 | 5755 |
7116 Local<String> source = v8_str("undetectable.x = 42;" | 5756 Local<String> source = v8_str( |
7117 "undetectable.x"); | 5757 "undetectable.x = 42;" |
| 5758 "undetectable.x"); |
7118 | 5759 |
7119 Local<Script> script = v8_compile(source); | 5760 Local<Script> script = v8_compile(source); |
7120 | 5761 |
7121 CHECK(v8::Integer::New(isolate, 42)->Equals(script->Run())); | 5762 CHECK(v8::Integer::New(isolate, 42)->Equals(script->Run())); |
7122 | 5763 |
7123 ExpectBoolean("Object.isExtensible(undetectable)", true); | 5764 ExpectBoolean("Object.isExtensible(undetectable)", true); |
7124 | 5765 |
7125 source = v8_str("Object.preventExtensions(undetectable);"); | 5766 source = v8_str("Object.preventExtensions(undetectable);"); |
7126 script = v8_compile(source); | 5767 script = v8_compile(source); |
7127 script->Run(); | 5768 script->Run(); |
7128 ExpectBoolean("Object.isExtensible(undetectable)", false); | 5769 ExpectBoolean("Object.isExtensible(undetectable)", false); |
7129 | 5770 |
7130 source = v8_str("undetectable.y = 2000;"); | 5771 source = v8_str("undetectable.y = 2000;"); |
7131 script = v8_compile(source); | 5772 script = v8_compile(source); |
7132 script->Run(); | 5773 script->Run(); |
7133 ExpectBoolean("undetectable.y == undefined", true); | 5774 ExpectBoolean("undetectable.y == undefined", true); |
7134 } | 5775 } |
7135 | 5776 |
7136 | 5777 |
7137 | |
7138 THREADED_TEST(UndetectableString) { | 5778 THREADED_TEST(UndetectableString) { |
7139 LocalContext env; | 5779 LocalContext env; |
7140 v8::HandleScope scope(env->GetIsolate()); | 5780 v8::HandleScope scope(env->GetIsolate()); |
7141 | 5781 |
7142 Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", | 5782 Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", |
7143 String::kUndetectableString); | 5783 String::kUndetectableString); |
7144 env->Global()->Set(v8_str("undetectable"), obj); | 5784 env->Global()->Set(v8_str("undetectable"), obj); |
7145 | 5785 |
7146 ExpectString("undetectable", "foo"); | 5786 ExpectString("undetectable", "foo"); |
7147 ExpectString("typeof undetectable", "undefined"); | 5787 ExpectString("typeof undetectable", "undefined"); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7239 Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate); | 5879 Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate); |
7240 global_template->Set(v8_str("JSNI_Log"), | 5880 global_template->Set(v8_str("JSNI_Log"), |
7241 v8::FunctionTemplate::New(isolate, HandleLogDelegator)); | 5881 v8::FunctionTemplate::New(isolate, HandleLogDelegator)); |
7242 v8::Local<Context> context = Context::New(isolate, 0, global_template); | 5882 v8::Local<Context> context = Context::New(isolate, 0, global_template); |
7243 Context::Scope context_scope(context); | 5883 Context::Scope context_scope(context); |
7244 CompileRun("JSNI_Log('LOG')"); | 5884 CompileRun("JSNI_Log('LOG')"); |
7245 } | 5885 } |
7246 | 5886 |
7247 | 5887 |
7248 static const char* kSimpleExtensionSource = | 5888 static const char* kSimpleExtensionSource = |
7249 "function Foo() {" | 5889 "function Foo() {" |
7250 " return 4;" | 5890 " return 4;" |
7251 "}"; | 5891 "}"; |
7252 | 5892 |
7253 | 5893 |
7254 TEST(SimpleExtensions) { | 5894 TEST(SimpleExtensions) { |
7255 v8::HandleScope handle_scope(CcTest::isolate()); | 5895 v8::HandleScope handle_scope(CcTest::isolate()); |
7256 v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); | 5896 v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); |
7257 const char* extension_names[] = { "simpletest" }; | 5897 const char* extension_names[] = {"simpletest"}; |
7258 v8::ExtensionConfiguration extensions(1, extension_names); | 5898 v8::ExtensionConfiguration extensions(1, extension_names); |
7259 v8::Handle<Context> context = | 5899 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7260 Context::New(CcTest::isolate(), &extensions); | |
7261 Context::Scope lock(context); | 5900 Context::Scope lock(context); |
7262 v8::Handle<Value> result = CompileRun("Foo()"); | 5901 v8::Handle<Value> result = CompileRun("Foo()"); |
7263 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); | 5902 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
7264 } | 5903 } |
7265 | 5904 |
7266 | 5905 |
7267 static const char* kStackTraceFromExtensionSource = | 5906 static const char* kStackTraceFromExtensionSource = |
7268 "function foo() {" | 5907 "function foo() {" |
7269 " throw new Error();" | 5908 " throw new Error();" |
7270 "}" | 5909 "}" |
7271 "function bar() {" | 5910 "function bar() {" |
7272 " foo();" | 5911 " foo();" |
7273 "}"; | 5912 "}"; |
7274 | 5913 |
7275 | 5914 |
7276 TEST(StackTraceInExtension) { | 5915 TEST(StackTraceInExtension) { |
7277 v8::HandleScope handle_scope(CcTest::isolate()); | 5916 v8::HandleScope handle_scope(CcTest::isolate()); |
7278 v8::RegisterExtension(new Extension("stacktracetest", | 5917 v8::RegisterExtension( |
7279 kStackTraceFromExtensionSource)); | 5918 new Extension("stacktracetest", kStackTraceFromExtensionSource)); |
7280 const char* extension_names[] = { "stacktracetest" }; | 5919 const char* extension_names[] = {"stacktracetest"}; |
7281 v8::ExtensionConfiguration extensions(1, extension_names); | 5920 v8::ExtensionConfiguration extensions(1, extension_names); |
7282 v8::Handle<Context> context = | 5921 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7283 Context::New(CcTest::isolate(), &extensions); | |
7284 Context::Scope lock(context); | 5922 Context::Scope lock(context); |
7285 CompileRun("function user() { bar(); }" | 5923 CompileRun( |
7286 "var error;" | 5924 "function user() { bar(); }" |
7287 "try{ user(); } catch (e) { error = e; }"); | 5925 "var error;" |
| 5926 "try{ user(); } catch (e) { error = e; }"); |
7288 CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value()); | 5927 CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value()); |
7289 CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value()); | 5928 CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value()); |
7290 CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value()); | 5929 CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value()); |
7291 } | 5930 } |
7292 | 5931 |
7293 | 5932 |
7294 TEST(NullExtensions) { | 5933 TEST(NullExtensions) { |
7295 v8::HandleScope handle_scope(CcTest::isolate()); | 5934 v8::HandleScope handle_scope(CcTest::isolate()); |
7296 v8::RegisterExtension(new Extension("nulltest", NULL)); | 5935 v8::RegisterExtension(new Extension("nulltest", NULL)); |
7297 const char* extension_names[] = { "nulltest" }; | 5936 const char* extension_names[] = {"nulltest"}; |
7298 v8::ExtensionConfiguration extensions(1, extension_names); | 5937 v8::ExtensionConfiguration extensions(1, extension_names); |
7299 v8::Handle<Context> context = | 5938 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7300 Context::New(CcTest::isolate(), &extensions); | |
7301 Context::Scope lock(context); | 5939 Context::Scope lock(context); |
7302 v8::Handle<Value> result = CompileRun("1+3"); | 5940 v8::Handle<Value> result = CompileRun("1+3"); |
7303 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); | 5941 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
7304 } | 5942 } |
7305 | 5943 |
7306 | 5944 |
7307 static const char* kEmbeddedExtensionSource = | 5945 static const char* kEmbeddedExtensionSource = |
7308 "function Ret54321(){return 54321;}~~@@$" | 5946 "function Ret54321(){return 54321;}~~@@$" |
7309 "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; | 5947 "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; |
7310 static const int kEmbeddedExtensionSourceValidLen = 34; | 5948 static const int kEmbeddedExtensionSourceValidLen = 34; |
7311 | 5949 |
7312 | 5950 |
7313 TEST(ExtensionMissingSourceLength) { | 5951 TEST(ExtensionMissingSourceLength) { |
7314 v8::HandleScope handle_scope(CcTest::isolate()); | 5952 v8::HandleScope handle_scope(CcTest::isolate()); |
7315 v8::RegisterExtension(new Extension("srclentest_fail", | 5953 v8::RegisterExtension( |
7316 kEmbeddedExtensionSource)); | 5954 new Extension("srclentest_fail", kEmbeddedExtensionSource)); |
7317 const char* extension_names[] = { "srclentest_fail" }; | 5955 const char* extension_names[] = {"srclentest_fail"}; |
7318 v8::ExtensionConfiguration extensions(1, extension_names); | 5956 v8::ExtensionConfiguration extensions(1, extension_names); |
7319 v8::Handle<Context> context = | 5957 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7320 Context::New(CcTest::isolate(), &extensions); | |
7321 CHECK(0 == *context); | 5958 CHECK(0 == *context); |
7322 } | 5959 } |
7323 | 5960 |
7324 | 5961 |
7325 TEST(ExtensionWithSourceLength) { | 5962 TEST(ExtensionWithSourceLength) { |
7326 for (int source_len = kEmbeddedExtensionSourceValidLen - 1; | 5963 for (int source_len = kEmbeddedExtensionSourceValidLen - 1; |
7327 source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { | 5964 source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { |
7328 v8::HandleScope handle_scope(CcTest::isolate()); | 5965 v8::HandleScope handle_scope(CcTest::isolate()); |
7329 i::ScopedVector<char> extension_name(32); | 5966 i::ScopedVector<char> extension_name(32); |
7330 i::SNPrintF(extension_name, "ext #%d", source_len); | 5967 i::SNPrintF(extension_name, "ext #%d", source_len); |
7331 v8::RegisterExtension(new Extension(extension_name.start(), | 5968 v8::RegisterExtension(new Extension( |
7332 kEmbeddedExtensionSource, 0, 0, | 5969 extension_name.start(), kEmbeddedExtensionSource, 0, 0, source_len)); |
7333 source_len)); | 5970 const char* extension_names[1] = {extension_name.start()}; |
7334 const char* extension_names[1] = { extension_name.start() }; | |
7335 v8::ExtensionConfiguration extensions(1, extension_names); | 5971 v8::ExtensionConfiguration extensions(1, extension_names); |
7336 v8::Handle<Context> context = | 5972 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7337 Context::New(CcTest::isolate(), &extensions); | |
7338 if (source_len == kEmbeddedExtensionSourceValidLen) { | 5973 if (source_len == kEmbeddedExtensionSourceValidLen) { |
7339 Context::Scope lock(context); | 5974 Context::Scope lock(context); |
7340 v8::Handle<Value> result = CompileRun("Ret54321()"); | 5975 v8::Handle<Value> result = CompileRun("Ret54321()"); |
7341 CHECK(v8::Integer::New(CcTest::isolate(), 54321)->Equals(result)); | 5976 CHECK(v8::Integer::New(CcTest::isolate(), 54321)->Equals(result)); |
7342 } else { | 5977 } else { |
7343 // Anything but exactly the right length should fail to compile. | 5978 // Anything but exactly the right length should fail to compile. |
7344 CHECK(0 == *context); | 5979 CHECK(0 == *context); |
7345 } | 5980 } |
7346 } | 5981 } |
7347 } | 5982 } |
7348 | 5983 |
7349 | 5984 |
7350 static const char* kEvalExtensionSource1 = | 5985 static const char* kEvalExtensionSource1 = |
7351 "function UseEval1() {" | 5986 "function UseEval1() {" |
7352 " var x = 42;" | 5987 " var x = 42;" |
7353 " return eval('x');" | 5988 " return eval('x');" |
7354 "}"; | 5989 "}"; |
7355 | 5990 |
7356 | 5991 |
7357 static const char* kEvalExtensionSource2 = | 5992 static const char* kEvalExtensionSource2 = |
7358 "(function() {" | 5993 "(function() {" |
7359 " var x = 42;" | 5994 " var x = 42;" |
7360 " function e() {" | 5995 " function e() {" |
7361 " return eval('x');" | 5996 " return eval('x');" |
7362 " }" | 5997 " }" |
7363 " this.UseEval2 = e;" | 5998 " this.UseEval2 = e;" |
7364 "})()"; | 5999 "})()"; |
7365 | 6000 |
7366 | 6001 |
7367 TEST(UseEvalFromExtension) { | 6002 TEST(UseEvalFromExtension) { |
7368 v8::HandleScope handle_scope(CcTest::isolate()); | 6003 v8::HandleScope handle_scope(CcTest::isolate()); |
7369 v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); | 6004 v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); |
7370 v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); | 6005 v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); |
7371 const char* extension_names[] = { "evaltest1", "evaltest2" }; | 6006 const char* extension_names[] = {"evaltest1", "evaltest2"}; |
7372 v8::ExtensionConfiguration extensions(2, extension_names); | 6007 v8::ExtensionConfiguration extensions(2, extension_names); |
7373 v8::Handle<Context> context = | 6008 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7374 Context::New(CcTest::isolate(), &extensions); | |
7375 Context::Scope lock(context); | 6009 Context::Scope lock(context); |
7376 v8::Handle<Value> result = CompileRun("UseEval1()"); | 6010 v8::Handle<Value> result = CompileRun("UseEval1()"); |
7377 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); | 6011 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
7378 result = CompileRun("UseEval2()"); | 6012 result = CompileRun("UseEval2()"); |
7379 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); | 6013 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
7380 } | 6014 } |
7381 | 6015 |
7382 | 6016 |
7383 static const char* kWithExtensionSource1 = | 6017 static const char* kWithExtensionSource1 = |
7384 "function UseWith1() {" | 6018 "function UseWith1() {" |
7385 " var x = 42;" | 6019 " var x = 42;" |
7386 " with({x:87}) { return x; }" | 6020 " with({x:87}) { return x; }" |
7387 "}"; | 6021 "}"; |
7388 | |
7389 | 6022 |
7390 | 6023 |
7391 static const char* kWithExtensionSource2 = | 6024 static const char* kWithExtensionSource2 = |
7392 "(function() {" | 6025 "(function() {" |
7393 " var x = 42;" | 6026 " var x = 42;" |
7394 " function e() {" | 6027 " function e() {" |
7395 " with ({x:87}) { return x; }" | 6028 " with ({x:87}) { return x; }" |
7396 " }" | 6029 " }" |
7397 " this.UseWith2 = e;" | 6030 " this.UseWith2 = e;" |
7398 "})()"; | 6031 "})()"; |
7399 | 6032 |
7400 | 6033 |
7401 TEST(UseWithFromExtension) { | 6034 TEST(UseWithFromExtension) { |
7402 v8::HandleScope handle_scope(CcTest::isolate()); | 6035 v8::HandleScope handle_scope(CcTest::isolate()); |
7403 v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); | 6036 v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); |
7404 v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); | 6037 v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); |
7405 const char* extension_names[] = { "withtest1", "withtest2" }; | 6038 const char* extension_names[] = {"withtest1", "withtest2"}; |
7406 v8::ExtensionConfiguration extensions(2, extension_names); | 6039 v8::ExtensionConfiguration extensions(2, extension_names); |
7407 v8::Handle<Context> context = | 6040 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7408 Context::New(CcTest::isolate(), &extensions); | |
7409 Context::Scope lock(context); | 6041 Context::Scope lock(context); |
7410 v8::Handle<Value> result = CompileRun("UseWith1()"); | 6042 v8::Handle<Value> result = CompileRun("UseWith1()"); |
7411 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); | 6043 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); |
7412 result = CompileRun("UseWith2()"); | 6044 result = CompileRun("UseWith2()"); |
7413 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); | 6045 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); |
7414 } | 6046 } |
7415 | 6047 |
7416 | 6048 |
7417 TEST(AutoExtensions) { | 6049 TEST(AutoExtensions) { |
7418 v8::HandleScope handle_scope(CcTest::isolate()); | 6050 v8::HandleScope handle_scope(CcTest::isolate()); |
7419 Extension* extension = new Extension("autotest", kSimpleExtensionSource); | 6051 Extension* extension = new Extension("autotest", kSimpleExtensionSource); |
7420 extension->set_auto_enable(true); | 6052 extension->set_auto_enable(true); |
7421 v8::RegisterExtension(extension); | 6053 v8::RegisterExtension(extension); |
7422 v8::Handle<Context> context = | 6054 v8::Handle<Context> context = Context::New(CcTest::isolate()); |
7423 Context::New(CcTest::isolate()); | |
7424 Context::Scope lock(context); | 6055 Context::Scope lock(context); |
7425 v8::Handle<Value> result = CompileRun("Foo()"); | 6056 v8::Handle<Value> result = CompileRun("Foo()"); |
7426 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); | 6057 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
7427 } | 6058 } |
7428 | 6059 |
7429 | 6060 |
7430 static const char* kSyntaxErrorInExtensionSource = | 6061 static const char* kSyntaxErrorInExtensionSource = "["; |
7431 "["; | |
7432 | 6062 |
7433 | 6063 |
7434 // Test that a syntax error in an extension does not cause a fatal | 6064 // Test that a syntax error in an extension does not cause a fatal |
7435 // error but results in an empty context. | 6065 // error but results in an empty context. |
7436 TEST(SyntaxErrorExtensions) { | 6066 TEST(SyntaxErrorExtensions) { |
7437 v8::HandleScope handle_scope(CcTest::isolate()); | 6067 v8::HandleScope handle_scope(CcTest::isolate()); |
7438 v8::RegisterExtension(new Extension("syntaxerror", | 6068 v8::RegisterExtension( |
7439 kSyntaxErrorInExtensionSource)); | 6069 new Extension("syntaxerror", kSyntaxErrorInExtensionSource)); |
7440 const char* extension_names[] = { "syntaxerror" }; | 6070 const char* extension_names[] = {"syntaxerror"}; |
7441 v8::ExtensionConfiguration extensions(1, extension_names); | 6071 v8::ExtensionConfiguration extensions(1, extension_names); |
7442 v8::Handle<Context> context = | 6072 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7443 Context::New(CcTest::isolate(), &extensions); | |
7444 CHECK(context.IsEmpty()); | 6073 CHECK(context.IsEmpty()); |
7445 } | 6074 } |
7446 | 6075 |
7447 | 6076 |
7448 static const char* kExceptionInExtensionSource = | 6077 static const char* kExceptionInExtensionSource = "throw 42"; |
7449 "throw 42"; | |
7450 | 6078 |
7451 | 6079 |
7452 // Test that an exception when installing an extension does not cause | 6080 // Test that an exception when installing an extension does not cause |
7453 // a fatal error but results in an empty context. | 6081 // a fatal error but results in an empty context. |
7454 TEST(ExceptionExtensions) { | 6082 TEST(ExceptionExtensions) { |
7455 v8::HandleScope handle_scope(CcTest::isolate()); | 6083 v8::HandleScope handle_scope(CcTest::isolate()); |
7456 v8::RegisterExtension(new Extension("exception", | 6084 v8::RegisterExtension( |
7457 kExceptionInExtensionSource)); | 6085 new Extension("exception", kExceptionInExtensionSource)); |
7458 const char* extension_names[] = { "exception" }; | 6086 const char* extension_names[] = {"exception"}; |
7459 v8::ExtensionConfiguration extensions(1, extension_names); | 6087 v8::ExtensionConfiguration extensions(1, extension_names); |
7460 v8::Handle<Context> context = | 6088 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7461 Context::New(CcTest::isolate(), &extensions); | |
7462 CHECK(context.IsEmpty()); | 6089 CHECK(context.IsEmpty()); |
7463 } | 6090 } |
7464 | 6091 |
7465 | 6092 |
7466 static const char* kNativeCallInExtensionSource = | 6093 static const char* kNativeCallInExtensionSource = |
7467 "function call_runtime_last_index_of(x) {" | 6094 "function call_runtime_last_index_of(x) {" |
7468 " return %StringLastIndexOf(x, 'bob', 10);" | 6095 " return %StringLastIndexOf(x, 'bob', 10);" |
7469 "}"; | 6096 "}"; |
7470 | 6097 |
7471 | 6098 |
7472 static const char* kNativeCallTest = | 6099 static const char* kNativeCallTest = |
7473 "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; | 6100 "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; |
7474 | 6101 |
7475 // Test that a native runtime calls are supported in extensions. | 6102 // Test that a native runtime calls are supported in extensions. |
7476 TEST(NativeCallInExtensions) { | 6103 TEST(NativeCallInExtensions) { |
7477 v8::HandleScope handle_scope(CcTest::isolate()); | 6104 v8::HandleScope handle_scope(CcTest::isolate()); |
7478 v8::RegisterExtension(new Extension("nativecall", | 6105 v8::RegisterExtension( |
7479 kNativeCallInExtensionSource)); | 6106 new Extension("nativecall", kNativeCallInExtensionSource)); |
7480 const char* extension_names[] = { "nativecall" }; | 6107 const char* extension_names[] = {"nativecall"}; |
7481 v8::ExtensionConfiguration extensions(1, extension_names); | 6108 v8::ExtensionConfiguration extensions(1, extension_names); |
7482 v8::Handle<Context> context = | 6109 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7483 Context::New(CcTest::isolate(), &extensions); | |
7484 Context::Scope lock(context); | 6110 Context::Scope lock(context); |
7485 v8::Handle<Value> result = CompileRun(kNativeCallTest); | 6111 v8::Handle<Value> result = CompileRun(kNativeCallTest); |
7486 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 3))); | 6112 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 3))); |
7487 } | 6113 } |
7488 | 6114 |
7489 | 6115 |
7490 class NativeFunctionExtension : public Extension { | 6116 class NativeFunctionExtension : public Extension { |
7491 public: | 6117 public: |
7492 NativeFunctionExtension(const char* name, | 6118 NativeFunctionExtension(const char* name, const char* source, |
7493 const char* source, | |
7494 v8::FunctionCallback fun = &Echo) | 6119 v8::FunctionCallback fun = &Echo) |
7495 : Extension(name, source), | 6120 : Extension(name, source), function_(fun) {} |
7496 function_(fun) { } | |
7497 | 6121 |
7498 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( | 6122 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
7499 v8::Isolate* isolate, | 6123 v8::Isolate* isolate, v8::Handle<v8::String> name) { |
7500 v8::Handle<v8::String> name) { | |
7501 return v8::FunctionTemplate::New(isolate, function_); | 6124 return v8::FunctionTemplate::New(isolate, function_); |
7502 } | 6125 } |
7503 | 6126 |
7504 static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { | 6127 static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { |
7505 if (args.Length() >= 1) args.GetReturnValue().Set(args[0]); | 6128 if (args.Length() >= 1) args.GetReturnValue().Set(args[0]); |
7506 } | 6129 } |
| 6130 |
7507 private: | 6131 private: |
7508 v8::FunctionCallback function_; | 6132 v8::FunctionCallback function_; |
7509 }; | 6133 }; |
7510 | 6134 |
7511 | 6135 |
7512 TEST(NativeFunctionDeclaration) { | 6136 TEST(NativeFunctionDeclaration) { |
7513 v8::HandleScope handle_scope(CcTest::isolate()); | 6137 v8::HandleScope handle_scope(CcTest::isolate()); |
7514 const char* name = "nativedecl"; | 6138 const char* name = "nativedecl"; |
7515 v8::RegisterExtension(new NativeFunctionExtension(name, | 6139 v8::RegisterExtension( |
7516 "native function foo();")); | 6140 new NativeFunctionExtension(name, "native function foo();")); |
7517 const char* extension_names[] = { name }; | 6141 const char* extension_names[] = {name}; |
7518 v8::ExtensionConfiguration extensions(1, extension_names); | 6142 v8::ExtensionConfiguration extensions(1, extension_names); |
7519 v8::Handle<Context> context = | 6143 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7520 Context::New(CcTest::isolate(), &extensions); | |
7521 Context::Scope lock(context); | 6144 Context::Scope lock(context); |
7522 v8::Handle<Value> result = CompileRun("foo(42);"); | 6145 v8::Handle<Value> result = CompileRun("foo(42);"); |
7523 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); | 6146 CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
7524 } | 6147 } |
7525 | 6148 |
7526 | 6149 |
7527 TEST(NativeFunctionDeclarationError) { | 6150 TEST(NativeFunctionDeclarationError) { |
7528 v8::HandleScope handle_scope(CcTest::isolate()); | 6151 v8::HandleScope handle_scope(CcTest::isolate()); |
7529 const char* name = "nativedeclerr"; | 6152 const char* name = "nativedeclerr"; |
7530 // Syntax error in extension code. | 6153 // Syntax error in extension code. |
7531 v8::RegisterExtension(new NativeFunctionExtension(name, | 6154 v8::RegisterExtension( |
7532 "native\nfunction foo();")); | 6155 new NativeFunctionExtension(name, "native\nfunction foo();")); |
7533 const char* extension_names[] = { name }; | 6156 const char* extension_names[] = {name}; |
7534 v8::ExtensionConfiguration extensions(1, extension_names); | 6157 v8::ExtensionConfiguration extensions(1, extension_names); |
7535 v8::Handle<Context> context = | 6158 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7536 Context::New(CcTest::isolate(), &extensions); | |
7537 CHECK(context.IsEmpty()); | 6159 CHECK(context.IsEmpty()); |
7538 } | 6160 } |
7539 | 6161 |
7540 | 6162 |
7541 TEST(NativeFunctionDeclarationErrorEscape) { | 6163 TEST(NativeFunctionDeclarationErrorEscape) { |
7542 v8::HandleScope handle_scope(CcTest::isolate()); | 6164 v8::HandleScope handle_scope(CcTest::isolate()); |
7543 const char* name = "nativedeclerresc"; | 6165 const char* name = "nativedeclerresc"; |
7544 // Syntax error in extension code - escape code in "native" means that | 6166 // Syntax error in extension code - escape code in "native" means that |
7545 // it's not treated as a keyword. | 6167 // it's not treated as a keyword. |
7546 v8::RegisterExtension(new NativeFunctionExtension( | 6168 v8::RegisterExtension( |
7547 name, | 6169 new NativeFunctionExtension(name, "nativ\\u0065 function foo();")); |
7548 "nativ\\u0065 function foo();")); | 6170 const char* extension_names[] = {name}; |
7549 const char* extension_names[] = { name }; | 6171 v8::ExtensionConfiguration extensions(1, extension_names); |
7550 v8::ExtensionConfiguration extensions(1, extension_names); | 6172 v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
7551 v8::Handle<Context> context = | |
7552 Context::New(CcTest::isolate(), &extensions); | |
7553 CHECK(context.IsEmpty()); | 6173 CHECK(context.IsEmpty()); |
7554 } | 6174 } |
7555 | 6175 |
7556 | 6176 |
7557 static void CheckDependencies(const char* name, const char* expected) { | 6177 static void CheckDependencies(const char* name, const char* expected) { |
7558 v8::HandleScope handle_scope(CcTest::isolate()); | 6178 v8::HandleScope handle_scope(CcTest::isolate()); |
7559 v8::ExtensionConfiguration config(1, &name); | 6179 v8::ExtensionConfiguration config(1, &name); |
7560 LocalContext context(&config); | 6180 LocalContext context(&config); |
7561 CHECK(String::NewFromUtf8(CcTest::isolate(), expected) | 6181 CHECK(String::NewFromUtf8(CcTest::isolate(), expected) |
7562 ->Equals(context->Global()->Get(v8_str("loaded")))); | 6182 ->Equals(context->Global()->Get(v8_str("loaded")))); |
7563 } | 6183 } |
7564 | 6184 |
7565 | 6185 |
7566 /* | 6186 /* |
7567 * Configuration: | 6187 * Configuration: |
7568 * | 6188 * |
7569 * /-- B <--\ | 6189 * /-- B <--\ |
7570 * A <- -- D <-- E | 6190 * A <- -- D <-- E |
7571 * \-- C <--/ | 6191 * \-- C <--/ |
7572 */ | 6192 */ |
7573 THREADED_TEST(ExtensionDependency) { | 6193 THREADED_TEST(ExtensionDependency) { |
7574 static const char* kEDeps[] = { "D" }; | 6194 static const char* kEDeps[] = {"D"}; |
7575 v8::RegisterExtension(new Extension("E", "this.loaded += 'E';", 1, kEDeps)); | 6195 v8::RegisterExtension(new Extension("E", "this.loaded += 'E';", 1, kEDeps)); |
7576 static const char* kDDeps[] = { "B", "C" }; | 6196 static const char* kDDeps[] = {"B", "C"}; |
7577 v8::RegisterExtension(new Extension("D", "this.loaded += 'D';", 2, kDDeps)); | 6197 v8::RegisterExtension(new Extension("D", "this.loaded += 'D';", 2, kDDeps)); |
7578 static const char* kBCDeps[] = { "A" }; | 6198 static const char* kBCDeps[] = {"A"}; |
7579 v8::RegisterExtension(new Extension("B", "this.loaded += 'B';", 1, kBCDeps)); | 6199 v8::RegisterExtension(new Extension("B", "this.loaded += 'B';", 1, kBCDeps)); |
7580 v8::RegisterExtension(new Extension("C", "this.loaded += 'C';", 1, kBCDeps)); | 6200 v8::RegisterExtension(new Extension("C", "this.loaded += 'C';", 1, kBCDeps)); |
7581 v8::RegisterExtension(new Extension("A", "this.loaded += 'A';")); | 6201 v8::RegisterExtension(new Extension("A", "this.loaded += 'A';")); |
7582 CheckDependencies("A", "undefinedA"); | 6202 CheckDependencies("A", "undefinedA"); |
7583 CheckDependencies("B", "undefinedAB"); | 6203 CheckDependencies("B", "undefinedAB"); |
7584 CheckDependencies("C", "undefinedAC"); | 6204 CheckDependencies("C", "undefinedAC"); |
7585 CheckDependencies("D", "undefinedABCD"); | 6205 CheckDependencies("D", "undefinedABCD"); |
7586 CheckDependencies("E", "undefinedABCDE"); | 6206 CheckDependencies("E", "undefinedABCDE"); |
7587 v8::HandleScope handle_scope(CcTest::isolate()); | 6207 v8::HandleScope handle_scope(CcTest::isolate()); |
7588 static const char* exts[2] = { "C", "E" }; | 6208 static const char* exts[2] = {"C", "E"}; |
7589 v8::ExtensionConfiguration config(2, exts); | 6209 v8::ExtensionConfiguration config(2, exts); |
7590 LocalContext context(&config); | 6210 LocalContext context(&config); |
7591 CHECK(v8_str("undefinedACBDE") | 6211 CHECK(v8_str("undefinedACBDE") |
7592 ->Equals(context->Global()->Get(v8_str("loaded")))); | 6212 ->Equals(context->Global()->Get(v8_str("loaded")))); |
7593 } | 6213 } |
7594 | 6214 |
7595 | 6215 |
7596 static const char* kExtensionTestScript = | 6216 static const char* kExtensionTestScript = |
7597 "native function A();" | 6217 "native function A();" |
7598 "native function B();" | 6218 "native function B();" |
7599 "native function C();" | 6219 "native function C();" |
7600 "function Foo(i) {" | 6220 "function Foo(i) {" |
7601 " if (i == 0) return A();" | 6221 " if (i == 0) return A();" |
7602 " if (i == 1) return B();" | 6222 " if (i == 1) return B();" |
7603 " if (i == 2) return C();" | 6223 " if (i == 2) return C();" |
7604 "}"; | 6224 "}"; |
7605 | 6225 |
7606 | 6226 |
7607 static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { | 6227 static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { |
7608 ApiTestFuzzer::Fuzz(); | 6228 ApiTestFuzzer::Fuzz(); |
7609 if (args.IsConstructCall()) { | 6229 if (args.IsConstructCall()) { |
7610 args.This()->Set(v8_str("data"), args.Data()); | 6230 args.This()->Set(v8_str("data"), args.Data()); |
7611 args.GetReturnValue().SetNull(); | 6231 args.GetReturnValue().SetNull(); |
7612 return; | 6232 return; |
7613 } | 6233 } |
7614 args.GetReturnValue().Set(args.Data()); | 6234 args.GetReturnValue().Set(args.Data()); |
7615 } | 6235 } |
7616 | 6236 |
7617 | 6237 |
7618 class FunctionExtension : public Extension { | 6238 class FunctionExtension : public Extension { |
7619 public: | 6239 public: |
7620 FunctionExtension() : Extension("functiontest", kExtensionTestScript) { } | 6240 FunctionExtension() : Extension("functiontest", kExtensionTestScript) {} |
7621 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( | 6241 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
7622 v8::Isolate* isolate, | 6242 v8::Isolate* isolate, v8::Handle<String> name); |
7623 v8::Handle<String> name); | |
7624 }; | 6243 }; |
7625 | 6244 |
7626 | 6245 |
7627 static int lookup_count = 0; | 6246 static int lookup_count = 0; |
7628 v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( | 6247 v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( |
7629 v8::Isolate* isolate, v8::Handle<String> name) { | 6248 v8::Isolate* isolate, v8::Handle<String> name) { |
7630 lookup_count++; | 6249 lookup_count++; |
7631 if (name->Equals(v8_str("A"))) { | 6250 if (name->Equals(v8_str("A"))) { |
7632 return v8::FunctionTemplate::New( | 6251 return v8::FunctionTemplate::New(isolate, CallFun, |
7633 isolate, CallFun, v8::Integer::New(isolate, 8)); | 6252 v8::Integer::New(isolate, 8)); |
7634 } else if (name->Equals(v8_str("B"))) { | 6253 } else if (name->Equals(v8_str("B"))) { |
7635 return v8::FunctionTemplate::New( | 6254 return v8::FunctionTemplate::New(isolate, CallFun, |
7636 isolate, CallFun, v8::Integer::New(isolate, 7)); | 6255 v8::Integer::New(isolate, 7)); |
7637 } else if (name->Equals(v8_str("C"))) { | 6256 } else if (name->Equals(v8_str("C"))) { |
7638 return v8::FunctionTemplate::New( | 6257 return v8::FunctionTemplate::New(isolate, CallFun, |
7639 isolate, CallFun, v8::Integer::New(isolate, 6)); | 6258 v8::Integer::New(isolate, 6)); |
7640 } else { | 6259 } else { |
7641 return v8::Handle<v8::FunctionTemplate>(); | 6260 return v8::Handle<v8::FunctionTemplate>(); |
7642 } | 6261 } |
7643 } | 6262 } |
7644 | 6263 |
7645 | 6264 |
7646 THREADED_TEST(FunctionLookup) { | 6265 THREADED_TEST(FunctionLookup) { |
7647 v8::RegisterExtension(new FunctionExtension()); | 6266 v8::RegisterExtension(new FunctionExtension()); |
7648 v8::HandleScope handle_scope(CcTest::isolate()); | 6267 v8::HandleScope handle_scope(CcTest::isolate()); |
7649 static const char* exts[1] = { "functiontest" }; | 6268 static const char* exts[1] = {"functiontest"}; |
7650 v8::ExtensionConfiguration config(1, exts); | 6269 v8::ExtensionConfiguration config(1, exts); |
7651 LocalContext context(&config); | 6270 LocalContext context(&config); |
7652 CHECK_EQ(3, lookup_count); | 6271 CHECK_EQ(3, lookup_count); |
7653 CHECK(v8::Integer::New(CcTest::isolate(), 8)->Equals(CompileRun("Foo(0)"))); | 6272 CHECK(v8::Integer::New(CcTest::isolate(), 8)->Equals(CompileRun("Foo(0)"))); |
7654 CHECK(v8::Integer::New(CcTest::isolate(), 7)->Equals(CompileRun("Foo(1)"))); | 6273 CHECK(v8::Integer::New(CcTest::isolate(), 7)->Equals(CompileRun("Foo(1)"))); |
7655 CHECK(v8::Integer::New(CcTest::isolate(), 6)->Equals(CompileRun("Foo(2)"))); | 6274 CHECK(v8::Integer::New(CcTest::isolate(), 6)->Equals(CompileRun("Foo(2)"))); |
7656 } | 6275 } |
7657 | 6276 |
7658 | 6277 |
7659 THREADED_TEST(NativeFunctionConstructCall) { | 6278 THREADED_TEST(NativeFunctionConstructCall) { |
7660 v8::RegisterExtension(new FunctionExtension()); | 6279 v8::RegisterExtension(new FunctionExtension()); |
7661 v8::HandleScope handle_scope(CcTest::isolate()); | 6280 v8::HandleScope handle_scope(CcTest::isolate()); |
7662 static const char* exts[1] = { "functiontest" }; | 6281 static const char* exts[1] = {"functiontest"}; |
7663 v8::ExtensionConfiguration config(1, exts); | 6282 v8::ExtensionConfiguration config(1, exts); |
7664 LocalContext context(&config); | 6283 LocalContext context(&config); |
7665 for (int i = 0; i < 10; i++) { | 6284 for (int i = 0; i < 10; i++) { |
7666 // Run a few times to ensure that allocation of objects doesn't | 6285 // Run a few times to ensure that allocation of objects doesn't |
7667 // change behavior of a constructor function. | 6286 // change behavior of a constructor function. |
7668 CHECK(v8::Integer::New(CcTest::isolate(), 8) | 6287 CHECK(v8::Integer::New(CcTest::isolate(), 8) |
7669 ->Equals(CompileRun("(new A()).data"))); | 6288 ->Equals(CompileRun("(new A()).data"))); |
7670 CHECK(v8::Integer::New(CcTest::isolate(), 7) | 6289 CHECK(v8::Integer::New(CcTest::isolate(), 7) |
7671 ->Equals(CompileRun("(new B()).data"))); | 6290 ->Equals(CompileRun("(new B()).data"))); |
7672 CHECK(v8::Integer::New(CcTest::isolate(), 6) | 6291 CHECK(v8::Integer::New(CcTest::isolate(), 6) |
(...skipping 10 matching lines...) Expand all Loading... |
7683 last_message = message; | 6302 last_message = message; |
7684 } | 6303 } |
7685 } | 6304 } |
7686 | 6305 |
7687 | 6306 |
7688 // ErrorReporting creates a circular extensions configuration and | 6307 // ErrorReporting creates a circular extensions configuration and |
7689 // tests that the fatal error handler gets called. This renders V8 | 6308 // tests that the fatal error handler gets called. This renders V8 |
7690 // unusable and therefore this test cannot be run in parallel. | 6309 // unusable and therefore this test cannot be run in parallel. |
7691 TEST(ErrorReporting) { | 6310 TEST(ErrorReporting) { |
7692 v8::V8::SetFatalErrorHandler(StoringErrorCallback); | 6311 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
7693 static const char* aDeps[] = { "B" }; | 6312 static const char* aDeps[] = {"B"}; |
7694 v8::RegisterExtension(new Extension("A", "", 1, aDeps)); | 6313 v8::RegisterExtension(new Extension("A", "", 1, aDeps)); |
7695 static const char* bDeps[] = { "A" }; | 6314 static const char* bDeps[] = {"A"}; |
7696 v8::RegisterExtension(new Extension("B", "", 1, bDeps)); | 6315 v8::RegisterExtension(new Extension("B", "", 1, bDeps)); |
7697 last_location = NULL; | 6316 last_location = NULL; |
7698 v8::ExtensionConfiguration config(1, bDeps); | 6317 v8::ExtensionConfiguration config(1, bDeps); |
7699 v8::Handle<Context> context = | 6318 v8::Handle<Context> context = Context::New(CcTest::isolate(), &config); |
7700 Context::New(CcTest::isolate(), &config); | |
7701 CHECK(context.IsEmpty()); | 6319 CHECK(context.IsEmpty()); |
7702 CHECK(last_location); | 6320 CHECK(last_location); |
7703 } | 6321 } |
7704 | 6322 |
7705 | 6323 |
7706 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, | 6324 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, |
7707 v8::Handle<Value> data) { | 6325 v8::Handle<Value> data) { |
7708 CHECK(message->GetScriptOrigin().ResourceName()->IsUndefined()); | 6326 CHECK(message->GetScriptOrigin().ResourceName()->IsUndefined()); |
7709 CHECK(v8::Undefined(CcTest::isolate()) | 6327 CHECK(v8::Undefined(CcTest::isolate()) |
7710 ->Equals(message->GetScriptOrigin().ResourceName())); | 6328 ->Equals(message->GetScriptOrigin().ResourceName())); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7940 CHECK(object_b.flag); | 6558 CHECK(object_b.flag); |
7941 } | 6559 } |
7942 | 6560 |
7943 | 6561 |
7944 THREADED_TEST(ResetWeakHandle) { | 6562 THREADED_TEST(ResetWeakHandle) { |
7945 ResetWeakHandle(false); | 6563 ResetWeakHandle(false); |
7946 ResetWeakHandle(true); | 6564 ResetWeakHandle(true); |
7947 } | 6565 } |
7948 | 6566 |
7949 | 6567 |
7950 static void InvokeScavenge() { | 6568 static void InvokeScavenge() { CcTest::heap()->CollectGarbage(i::NEW_SPACE); } |
7951 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | |
7952 } | |
7953 | 6569 |
7954 | 6570 |
7955 static void InvokeMarkSweep() { | 6571 static void InvokeMarkSweep() { |
7956 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 6572 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
7957 } | 6573 } |
7958 | 6574 |
7959 | 6575 |
7960 static void ForceScavenge( | 6576 static void ForceScavenge( |
7961 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { | 6577 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { |
7962 data.GetParameter()->handle.Reset(); | 6578 data.GetParameter()->handle.Reset(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8067 v8::HandleScope scope(isolate); | 6683 v8::HandleScope scope(isolate); |
8068 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); | 6684 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); |
8069 global->Set(v8_str("f"), | 6685 global->Set(v8_str("f"), |
8070 v8::FunctionTemplate::New(isolate, ArgumentsTestCallback)); | 6686 v8::FunctionTemplate::New(isolate, ArgumentsTestCallback)); |
8071 LocalContext context(NULL, global); | 6687 LocalContext context(NULL, global); |
8072 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); | 6688 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); |
8073 v8_compile("f(1, 2, 3)")->Run(); | 6689 v8_compile("f(1, 2, 3)")->Run(); |
8074 } | 6690 } |
8075 | 6691 |
8076 | 6692 |
8077 static void NoBlockGetterX(Local<Name> name, | 6693 static int p_getter_count; |
8078 const v8::PropertyCallbackInfo<v8::Value>&) {} | 6694 static int p_getter_count2; |
8079 | |
8080 | |
8081 static void NoBlockGetterI(uint32_t index, | |
8082 const v8::PropertyCallbackInfo<v8::Value>&) { | |
8083 } | |
8084 | |
8085 | |
8086 static void PDeleter(Local<Name> name, | |
8087 const v8::PropertyCallbackInfo<v8::Boolean>& info) { | |
8088 if (!name->Equals(v8_str("foo"))) { | |
8089 return; // not intercepted | |
8090 } | |
8091 | |
8092 info.GetReturnValue().Set(false); // intercepted, don't delete the property | |
8093 } | |
8094 | |
8095 | |
8096 static void IDeleter(uint32_t index, | |
8097 const v8::PropertyCallbackInfo<v8::Boolean>& info) { | |
8098 if (index != 2) { | |
8099 return; // not intercepted | |
8100 } | |
8101 | |
8102 info.GetReturnValue().Set(false); // intercepted, don't delete the property | |
8103 } | |
8104 | |
8105 | |
8106 THREADED_TEST(Deleter) { | |
8107 v8::Isolate* isolate = CcTest::isolate(); | |
8108 v8::HandleScope scope(isolate); | |
8109 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); | |
8110 obj->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX, NULL, | |
8111 NULL, PDeleter, NULL)); | |
8112 obj->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
8113 NoBlockGetterI, NULL, NULL, IDeleter, NULL)); | |
8114 LocalContext context; | |
8115 context->Global()->Set(v8_str("k"), obj->NewInstance()); | |
8116 CompileRun( | |
8117 "k.foo = 'foo';" | |
8118 "k.bar = 'bar';" | |
8119 "k[2] = 2;" | |
8120 "k[4] = 4;"); | |
8121 CHECK(v8_compile("delete k.foo")->Run()->IsFalse()); | |
8122 CHECK(v8_compile("delete k.bar")->Run()->IsTrue()); | |
8123 | |
8124 CHECK(v8_compile("k.foo")->Run()->Equals(v8_str("foo"))); | |
8125 CHECK(v8_compile("k.bar")->Run()->IsUndefined()); | |
8126 | |
8127 CHECK(v8_compile("delete k[2]")->Run()->IsFalse()); | |
8128 CHECK(v8_compile("delete k[4]")->Run()->IsTrue()); | |
8129 | |
8130 CHECK(v8_compile("k[2]")->Run()->Equals(v8_num(2))); | |
8131 CHECK(v8_compile("k[4]")->Run()->IsUndefined()); | |
8132 } | |
8133 | |
8134 | |
8135 static void GetK(Local<Name> name, | |
8136 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
8137 ApiTestFuzzer::Fuzz(); | |
8138 if (name->Equals(v8_str("foo")) || | |
8139 name->Equals(v8_str("bar")) || | |
8140 name->Equals(v8_str("baz"))) { | |
8141 info.GetReturnValue().SetUndefined(); | |
8142 } | |
8143 } | |
8144 | |
8145 | |
8146 static void IndexedGetK(uint32_t index, | |
8147 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
8148 ApiTestFuzzer::Fuzz(); | |
8149 if (index == 0 || index == 1) info.GetReturnValue().SetUndefined(); | |
8150 } | |
8151 | |
8152 | |
8153 static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { | |
8154 ApiTestFuzzer::Fuzz(); | |
8155 v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); | |
8156 result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("foo")); | |
8157 result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("bar")); | |
8158 result->Set(v8::Integer::New(info.GetIsolate(), 2), v8_str("baz")); | |
8159 info.GetReturnValue().Set(result); | |
8160 } | |
8161 | |
8162 | |
8163 static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { | |
8164 ApiTestFuzzer::Fuzz(); | |
8165 v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); | |
8166 result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("0")); | |
8167 result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("1")); | |
8168 info.GetReturnValue().Set(result); | |
8169 } | |
8170 | |
8171 | |
8172 THREADED_TEST(Enumerators) { | |
8173 v8::Isolate* isolate = CcTest::isolate(); | |
8174 v8::HandleScope scope(isolate); | |
8175 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); | |
8176 obj->SetHandler( | |
8177 v8::NamedPropertyHandlerConfiguration(GetK, NULL, NULL, NULL, NamedEnum)); | |
8178 obj->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
8179 IndexedGetK, NULL, NULL, NULL, IndexedEnum)); | |
8180 LocalContext context; | |
8181 context->Global()->Set(v8_str("k"), obj->NewInstance()); | |
8182 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( | |
8183 "k[10] = 0;" | |
8184 "k.a = 0;" | |
8185 "k[5] = 0;" | |
8186 "k.b = 0;" | |
8187 "k[4294967295] = 0;" | |
8188 "k.c = 0;" | |
8189 "k[4294967296] = 0;" | |
8190 "k.d = 0;" | |
8191 "k[140000] = 0;" | |
8192 "k.e = 0;" | |
8193 "k[30000000000] = 0;" | |
8194 "k.f = 0;" | |
8195 "var result = [];" | |
8196 "for (var prop in k) {" | |
8197 " result.push(prop);" | |
8198 "}" | |
8199 "result")); | |
8200 // Check that we get all the property names returned including the | |
8201 // ones from the enumerators in the right order: indexed properties | |
8202 // in numerical order, indexed interceptor properties, named | |
8203 // properties in insertion order, named interceptor properties. | |
8204 // This order is not mandated by the spec, so this test is just | |
8205 // documenting our behavior. | |
8206 CHECK_EQ(17u, result->Length()); | |
8207 // Indexed properties in numerical order. | |
8208 CHECK(v8_str("5")->Equals(result->Get(v8::Integer::New(isolate, 0)))); | |
8209 CHECK(v8_str("10")->Equals(result->Get(v8::Integer::New(isolate, 1)))); | |
8210 CHECK(v8_str("140000")->Equals(result->Get(v8::Integer::New(isolate, 2)))); | |
8211 CHECK( | |
8212 v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 3)))); | |
8213 // Indexed interceptor properties in the order they are returned | |
8214 // from the enumerator interceptor. | |
8215 CHECK(v8_str("0")->Equals(result->Get(v8::Integer::New(isolate, 4)))); | |
8216 CHECK(v8_str("1")->Equals(result->Get(v8::Integer::New(isolate, 5)))); | |
8217 // Named properties in insertion order. | |
8218 CHECK(v8_str("a")->Equals(result->Get(v8::Integer::New(isolate, 6)))); | |
8219 CHECK(v8_str("b")->Equals(result->Get(v8::Integer::New(isolate, 7)))); | |
8220 CHECK(v8_str("c")->Equals(result->Get(v8::Integer::New(isolate, 8)))); | |
8221 CHECK( | |
8222 v8_str("4294967296")->Equals(result->Get(v8::Integer::New(isolate, 9)))); | |
8223 CHECK(v8_str("d")->Equals(result->Get(v8::Integer::New(isolate, 10)))); | |
8224 CHECK(v8_str("e")->Equals(result->Get(v8::Integer::New(isolate, 11)))); | |
8225 CHECK(v8_str("30000000000") | |
8226 ->Equals(result->Get(v8::Integer::New(isolate, 12)))); | |
8227 CHECK(v8_str("f")->Equals(result->Get(v8::Integer::New(isolate, 13)))); | |
8228 // Named interceptor properties. | |
8229 CHECK(v8_str("foo")->Equals(result->Get(v8::Integer::New(isolate, 14)))); | |
8230 CHECK(v8_str("bar")->Equals(result->Get(v8::Integer::New(isolate, 15)))); | |
8231 CHECK(v8_str("baz")->Equals(result->Get(v8::Integer::New(isolate, 16)))); | |
8232 } | |
8233 | |
8234 | |
8235 int p_getter_count; | |
8236 int p_getter_count2; | |
8237 | 6695 |
8238 | 6696 |
8239 static void PGetter(Local<String> name, | 6697 static void PGetter(Local<String> name, |
8240 const v8::PropertyCallbackInfo<v8::Value>& info) { | 6698 const v8::PropertyCallbackInfo<v8::Value>& info) { |
8241 ApiTestFuzzer::Fuzz(); | 6699 ApiTestFuzzer::Fuzz(); |
8242 p_getter_count++; | 6700 p_getter_count++; |
8243 v8::Handle<v8::Object> global = | 6701 v8::Handle<v8::Object> global = |
8244 info.GetIsolate()->GetCurrentContext()->Global(); | 6702 info.GetIsolate()->GetCurrentContext()->Global(); |
8245 CHECK(info.Holder()->Equals(global->Get(v8_str("o1")))); | 6703 CHECK(info.Holder()->Equals(global->Get(v8_str("o1")))); |
8246 if (name->Equals(v8_str("p1"))) { | 6704 if (name->Equals(v8_str("p1"))) { |
(...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10297 " 'use strict';" | 8755 " 'use strict';" |
10298 " super.x = function () {}; " | 8756 " super.x = function () {}; " |
10299 "};" | 8757 "};" |
10300 "var m = f.toMethod(prohibited);" | 8758 "var m = f.toMethod(prohibited);" |
10301 "m();"); | 8759 "m();"); |
10302 CHECK(try_catch.HasCaught()); | 8760 CHECK(try_catch.HasCaught()); |
10303 } | 8761 } |
10304 } | 8762 } |
10305 | 8763 |
10306 | 8764 |
10307 static void IndexedPropertyEnumerator( | |
10308 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
10309 v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 1); | |
10310 result->Set(0, v8::Integer::New(info.GetIsolate(), 7)); | |
10311 info.GetReturnValue().Set(result); | |
10312 } | |
10313 | |
10314 | |
10315 static void NamedPropertyEnumerator( | |
10316 const v8::PropertyCallbackInfo<v8::Array>& info) { | |
10317 v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); | |
10318 result->Set(0, v8_str("x")); | |
10319 result->Set(1, v8::Symbol::GetIterator(info.GetIsolate())); | |
10320 info.GetReturnValue().Set(result); | |
10321 } | |
10322 | |
10323 | |
10324 THREADED_TEST(GetOwnPropertyNamesWithInterceptor) { | |
10325 v8::Isolate* isolate = CcTest::isolate(); | |
10326 v8::HandleScope handle_scope(isolate); | |
10327 v8::Handle<v8::ObjectTemplate> obj_template = | |
10328 v8::ObjectTemplate::New(isolate); | |
10329 | |
10330 obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7)); | |
10331 obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42)); | |
10332 obj_template->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
10333 NULL, NULL, NULL, NULL, IndexedPropertyEnumerator)); | |
10334 obj_template->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
10335 NULL, NULL, NULL, NULL, NamedPropertyEnumerator)); | |
10336 | |
10337 LocalContext context; | |
10338 v8::Handle<v8::Object> global = context->Global(); | |
10339 global->Set(v8_str("object"), obj_template->NewInstance()); | |
10340 | |
10341 v8::Handle<v8::Value> result = | |
10342 CompileRun("Object.getOwnPropertyNames(object)"); | |
10343 CHECK(result->IsArray()); | |
10344 v8::Handle<v8::Array> result_array = v8::Handle<v8::Array>::Cast(result); | |
10345 CHECK_EQ(2u, result_array->Length()); | |
10346 CHECK(result_array->Get(0)->IsString()); | |
10347 CHECK(result_array->Get(1)->IsString()); | |
10348 CHECK(v8_str("7")->Equals(result_array->Get(0))); | |
10349 CHECK(v8_str("x")->Equals(result_array->Get(1))); | |
10350 | |
10351 result = CompileRun("var ret = []; for (var k in object) ret.push(k); ret"); | |
10352 CHECK(result->IsArray()); | |
10353 result_array = v8::Handle<v8::Array>::Cast(result); | |
10354 CHECK_EQ(2u, result_array->Length()); | |
10355 CHECK(result_array->Get(0)->IsString()); | |
10356 CHECK(result_array->Get(1)->IsString()); | |
10357 CHECK(v8_str("7")->Equals(result_array->Get(0))); | |
10358 CHECK(v8_str("x")->Equals(result_array->Get(1))); | |
10359 | |
10360 result = CompileRun("Object.getOwnPropertySymbols(object)"); | |
10361 CHECK(result->IsArray()); | |
10362 result_array = v8::Handle<v8::Array>::Cast(result); | |
10363 CHECK_EQ(1u, result_array->Length()); | |
10364 CHECK(result_array->Get(0)->Equals(v8::Symbol::GetIterator(isolate))); | |
10365 } | |
10366 | |
10367 | |
10368 static void ConstTenGetter(Local<String> name, | 8765 static void ConstTenGetter(Local<String> name, |
10369 const v8::PropertyCallbackInfo<v8::Value>& info) { | 8766 const v8::PropertyCallbackInfo<v8::Value>& info) { |
10370 info.GetReturnValue().Set(v8_num(10)); | 8767 info.GetReturnValue().Set(v8_num(10)); |
10371 } | 8768 } |
10372 | 8769 |
10373 | 8770 |
10374 THREADED_TEST(CrossDomainAccessors) { | 8771 THREADED_TEST(CrossDomainAccessors) { |
10375 v8::Isolate* isolate = CcTest::isolate(); | 8772 v8::Isolate* isolate = CcTest::isolate(); |
10376 v8::HandleScope handle_scope(isolate); | 8773 v8::HandleScope handle_scope(isolate); |
10377 | 8774 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10627 v8::Handle<Value> value; | 9024 v8::Handle<Value> value; |
10628 | 9025 |
10629 value = v8_compile("var p = 'as' + 'df';")->Run(); | 9026 value = v8_compile("var p = 'as' + 'df';")->Run(); |
10630 value = v8_compile("obj[p];")->Run(); | 9027 value = v8_compile("obj[p];")->Run(); |
10631 | 9028 |
10632 context1->Exit(); | 9029 context1->Exit(); |
10633 context0->Exit(); | 9030 context0->Exit(); |
10634 } | 9031 } |
10635 | 9032 |
10636 | 9033 |
10637 static void AccessControlNamedGetter( | 9034 THREADED_TEST(Version) { v8::V8::GetVersion(); } |
10638 Local<Name>, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
10639 info.GetReturnValue().Set(42); | |
10640 } | |
10641 | |
10642 | |
10643 static void AccessControlNamedSetter( | |
10644 Local<Name>, Local<Value> value, | |
10645 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
10646 info.GetReturnValue().Set(value); | |
10647 } | |
10648 | |
10649 | |
10650 static void AccessControlIndexedGetter( | |
10651 uint32_t index, | |
10652 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
10653 info.GetReturnValue().Set(v8_num(42)); | |
10654 } | |
10655 | |
10656 | |
10657 static void AccessControlIndexedSetter( | |
10658 uint32_t, | |
10659 Local<Value> value, | |
10660 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
10661 info.GetReturnValue().Set(value); | |
10662 } | |
10663 | |
10664 | |
10665 THREADED_TEST(AccessControlInterceptorIC) { | |
10666 named_access_count = 0; | |
10667 indexed_access_count = 0; | |
10668 | |
10669 v8::Isolate* isolate = CcTest::isolate(); | |
10670 v8::HandleScope handle_scope(isolate); | |
10671 | |
10672 // Create an environment. | |
10673 v8::Local<Context> context0 = Context::New(isolate); | |
10674 context0->Enter(); | |
10675 | |
10676 // Create an object that requires access-check functions to be | |
10677 // called for cross-domain access. The object also has interceptors | |
10678 // interceptor. | |
10679 v8::Handle<v8::ObjectTemplate> object_template = | |
10680 v8::ObjectTemplate::New(isolate); | |
10681 object_template->SetAccessCheckCallbacks(NamedAccessCounter, | |
10682 IndexedAccessCounter); | |
10683 object_template->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
10684 AccessControlNamedGetter, AccessControlNamedSetter)); | |
10685 object_template->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
10686 AccessControlIndexedGetter, AccessControlIndexedSetter)); | |
10687 Local<v8::Object> object = object_template->NewInstance(); | |
10688 | |
10689 v8::HandleScope scope1(isolate); | |
10690 | |
10691 // Create another environment. | |
10692 v8::Local<Context> context1 = Context::New(isolate); | |
10693 context1->Enter(); | |
10694 | |
10695 // Make easy access to the object from the other environment. | |
10696 v8::Handle<v8::Object> global1 = context1->Global(); | |
10697 global1->Set(v8_str("obj"), object); | |
10698 | |
10699 v8::Handle<Value> value; | |
10700 | |
10701 // Check that the named access-control function is called every time | |
10702 // eventhough there is an interceptor on the object. | |
10703 value = v8_compile("for (var i = 0; i < 10; i++) obj.x = 1;")->Run(); | |
10704 value = v8_compile("for (var i = 0; i < 10; i++) obj.x;" | |
10705 "obj.x")->Run(); | |
10706 CHECK(value->IsNumber()); | |
10707 CHECK_EQ(42, value->Int32Value()); | |
10708 CHECK_EQ(21, named_access_count); | |
10709 | |
10710 value = v8_compile("var p = 'x';")->Run(); | |
10711 value = v8_compile("for (var i = 0; i < 10; i++) obj[p] = 1;")->Run(); | |
10712 value = v8_compile("for (var i = 0; i < 10; i++) obj[p];" | |
10713 "obj[p]")->Run(); | |
10714 CHECK(value->IsNumber()); | |
10715 CHECK_EQ(42, value->Int32Value()); | |
10716 CHECK_EQ(42, named_access_count); | |
10717 | |
10718 // Check that the indexed access-control function is called every | |
10719 // time eventhough there is an interceptor on the object. | |
10720 value = v8_compile("for (var i = 0; i < 10; i++) obj[0] = 1;")->Run(); | |
10721 value = v8_compile("for (var i = 0; i < 10; i++) obj[0];" | |
10722 "obj[0]")->Run(); | |
10723 CHECK(value->IsNumber()); | |
10724 CHECK_EQ(42, value->Int32Value()); | |
10725 CHECK_EQ(21, indexed_access_count); | |
10726 | |
10727 context1->Exit(); | |
10728 context0->Exit(); | |
10729 } | |
10730 | |
10731 | |
10732 THREADED_TEST(Version) { | |
10733 v8::V8::GetVersion(); | |
10734 } | |
10735 | 9035 |
10736 | 9036 |
10737 static void InstanceFunctionCallback( | 9037 static void InstanceFunctionCallback( |
10738 const v8::FunctionCallbackInfo<v8::Value>& args) { | 9038 const v8::FunctionCallbackInfo<v8::Value>& args) { |
10739 ApiTestFuzzer::Fuzz(); | 9039 ApiTestFuzzer::Fuzz(); |
10740 args.GetReturnValue().Set(v8_num(12)); | 9040 args.GetReturnValue().Set(v8_num(12)); |
10741 } | 9041 } |
10742 | 9042 |
10743 | 9043 |
10744 THREADED_TEST(InstanceProperties) { | 9044 THREADED_TEST(InstanceProperties) { |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11302 fun->NewInstance(); | 9602 fun->NewInstance(); |
11303 CHECK(try_catch.HasCaught()); | 9603 CHECK(try_catch.HasCaught()); |
11304 } | 9604 } |
11305 | 9605 |
11306 | 9606 |
11307 THREADED_TEST(GetterSetterExceptions) { | 9607 THREADED_TEST(GetterSetterExceptions) { |
11308 LocalContext context; | 9608 LocalContext context; |
11309 v8::Isolate* isolate = context->GetIsolate(); | 9609 v8::Isolate* isolate = context->GetIsolate(); |
11310 v8::HandleScope handle_scope(isolate); | 9610 v8::HandleScope handle_scope(isolate); |
11311 CompileRun( | 9611 CompileRun( |
11312 "function Foo() { };" | 9612 "function Foo() { };" |
11313 "function Throw() { throw 5; };" | 9613 "function Throw() { throw 5; };" |
11314 "var x = { };" | 9614 "var x = { };" |
11315 "x.__defineSetter__('set', Throw);" | 9615 "x.__defineSetter__('set', Throw);" |
11316 "x.__defineGetter__('get', Throw);"); | 9616 "x.__defineGetter__('get', Throw);"); |
11317 Local<v8::Object> x = | 9617 Local<v8::Object> x = |
11318 Local<v8::Object>::Cast(context->Global()->Get(v8_str("x"))); | 9618 Local<v8::Object>::Cast(context->Global()->Get(v8_str("x"))); |
11319 v8::TryCatch try_catch; | 9619 v8::TryCatch try_catch; |
11320 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); | 9620 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); |
11321 x->Get(v8_str("get")); | 9621 x->Get(v8_str("get")); |
11322 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); | 9622 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); |
11323 x->Get(v8_str("get")); | 9623 x->Get(v8_str("get")); |
11324 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); | 9624 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); |
11325 x->Get(v8_str("get")); | 9625 x->Get(v8_str("get")); |
11326 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); | 9626 x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11370 ApiTestFuzzer::Fuzz(); | 9670 ApiTestFuzzer::Fuzz(); |
11371 args.GetReturnValue().Set(args[0]); | 9671 args.GetReturnValue().Set(args[0]); |
11372 } | 9672 } |
11373 | 9673 |
11374 | 9674 |
11375 THREADED_TEST(ConstructorForObject) { | 9675 THREADED_TEST(ConstructorForObject) { |
11376 LocalContext context; | 9676 LocalContext context; |
11377 v8::Isolate* isolate = context->GetIsolate(); | 9677 v8::Isolate* isolate = context->GetIsolate(); |
11378 v8::HandleScope handle_scope(isolate); | 9678 v8::HandleScope handle_scope(isolate); |
11379 | 9679 |
11380 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); | 9680 { |
| 9681 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
11381 instance_template->SetCallAsFunctionHandler(ConstructorCallback); | 9682 instance_template->SetCallAsFunctionHandler(ConstructorCallback); |
11382 Local<Object> instance = instance_template->NewInstance(); | 9683 Local<Object> instance = instance_template->NewInstance(); |
11383 context->Global()->Set(v8_str("obj"), instance); | 9684 context->Global()->Set(v8_str("obj"), instance); |
11384 v8::TryCatch try_catch; | 9685 v8::TryCatch try_catch; |
11385 Local<Value> value; | 9686 Local<Value> value; |
11386 CHECK(!try_catch.HasCaught()); | 9687 CHECK(!try_catch.HasCaught()); |
11387 | 9688 |
11388 // Call the Object's constructor with a 32-bit signed integer. | 9689 // Call the Object's constructor with a 32-bit signed integer. |
11389 value = CompileRun("(function() { var o = new obj(28); return o.a; })()"); | 9690 value = CompileRun("(function() { var o = new obj(28); return o.a; })()"); |
11390 CHECK(!try_catch.HasCaught()); | 9691 CHECK(!try_catch.HasCaught()); |
11391 CHECK(value->IsInt32()); | 9692 CHECK(value->IsInt32()); |
11392 CHECK_EQ(28, value->Int32Value()); | 9693 CHECK_EQ(28, value->Int32Value()); |
11393 | 9694 |
11394 Local<Value> args1[] = { v8_num(28) }; | 9695 Local<Value> args1[] = {v8_num(28)}; |
11395 Local<Value> value_obj1 = instance->CallAsConstructor(1, args1); | 9696 Local<Value> value_obj1 = instance->CallAsConstructor(1, args1); |
11396 CHECK(value_obj1->IsObject()); | 9697 CHECK(value_obj1->IsObject()); |
11397 Local<Object> object1 = Local<Object>::Cast(value_obj1); | 9698 Local<Object> object1 = Local<Object>::Cast(value_obj1); |
11398 value = object1->Get(v8_str("a")); | 9699 value = object1->Get(v8_str("a")); |
11399 CHECK(value->IsInt32()); | 9700 CHECK(value->IsInt32()); |
11400 CHECK(!try_catch.HasCaught()); | 9701 CHECK(!try_catch.HasCaught()); |
11401 CHECK_EQ(28, value->Int32Value()); | 9702 CHECK_EQ(28, value->Int32Value()); |
11402 | 9703 |
11403 // Call the Object's constructor with a String. | 9704 // Call the Object's constructor with a String. |
11404 value = CompileRun( | 9705 value = |
11405 "(function() { var o = new obj('tipli'); return o.a; })()"); | 9706 CompileRun("(function() { var o = new obj('tipli'); return o.a; })()"); |
11406 CHECK(!try_catch.HasCaught()); | 9707 CHECK(!try_catch.HasCaught()); |
11407 CHECK(value->IsString()); | 9708 CHECK(value->IsString()); |
11408 String::Utf8Value string_value1(value->ToString(isolate)); | 9709 String::Utf8Value string_value1(value->ToString(isolate)); |
11409 CHECK_EQ(0, strcmp("tipli", *string_value1)); | 9710 CHECK_EQ(0, strcmp("tipli", *string_value1)); |
11410 | 9711 |
11411 Local<Value> args2[] = { v8_str("tipli") }; | 9712 Local<Value> args2[] = {v8_str("tipli")}; |
11412 Local<Value> value_obj2 = instance->CallAsConstructor(1, args2); | 9713 Local<Value> value_obj2 = instance->CallAsConstructor(1, args2); |
11413 CHECK(value_obj2->IsObject()); | 9714 CHECK(value_obj2->IsObject()); |
11414 Local<Object> object2 = Local<Object>::Cast(value_obj2); | 9715 Local<Object> object2 = Local<Object>::Cast(value_obj2); |
11415 value = object2->Get(v8_str("a")); | 9716 value = object2->Get(v8_str("a")); |
11416 CHECK(!try_catch.HasCaught()); | 9717 CHECK(!try_catch.HasCaught()); |
11417 CHECK(value->IsString()); | 9718 CHECK(value->IsString()); |
11418 String::Utf8Value string_value2(value->ToString(isolate)); | 9719 String::Utf8Value string_value2(value->ToString(isolate)); |
11419 CHECK_EQ(0, strcmp("tipli", *string_value2)); | 9720 CHECK_EQ(0, strcmp("tipli", *string_value2)); |
11420 | 9721 |
11421 // Call the Object's constructor with a Boolean. | 9722 // Call the Object's constructor with a Boolean. |
11422 value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); | 9723 value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); |
11423 CHECK(!try_catch.HasCaught()); | 9724 CHECK(!try_catch.HasCaught()); |
11424 CHECK(value->IsBoolean()); | 9725 CHECK(value->IsBoolean()); |
11425 CHECK_EQ(true, value->BooleanValue()); | 9726 CHECK_EQ(true, value->BooleanValue()); |
11426 | 9727 |
11427 Handle<Value> args3[] = { v8::True(isolate) }; | 9728 Handle<Value> args3[] = {v8::True(isolate)}; |
11428 Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); | 9729 Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); |
11429 CHECK(value_obj3->IsObject()); | 9730 CHECK(value_obj3->IsObject()); |
11430 Local<Object> object3 = Local<Object>::Cast(value_obj3); | 9731 Local<Object> object3 = Local<Object>::Cast(value_obj3); |
11431 value = object3->Get(v8_str("a")); | 9732 value = object3->Get(v8_str("a")); |
11432 CHECK(!try_catch.HasCaught()); | 9733 CHECK(!try_catch.HasCaught()); |
11433 CHECK(value->IsBoolean()); | 9734 CHECK(value->IsBoolean()); |
11434 CHECK_EQ(true, value->BooleanValue()); | 9735 CHECK_EQ(true, value->BooleanValue()); |
11435 | 9736 |
11436 // Call the Object's constructor with undefined. | 9737 // Call the Object's constructor with undefined. |
11437 Handle<Value> args4[] = { v8::Undefined(isolate) }; | 9738 Handle<Value> args4[] = {v8::Undefined(isolate)}; |
11438 Local<Value> value_obj4 = instance->CallAsConstructor(1, args4); | 9739 Local<Value> value_obj4 = instance->CallAsConstructor(1, args4); |
11439 CHECK(value_obj4->IsObject()); | 9740 CHECK(value_obj4->IsObject()); |
11440 Local<Object> object4 = Local<Object>::Cast(value_obj4); | 9741 Local<Object> object4 = Local<Object>::Cast(value_obj4); |
11441 value = object4->Get(v8_str("a")); | 9742 value = object4->Get(v8_str("a")); |
11442 CHECK(!try_catch.HasCaught()); | 9743 CHECK(!try_catch.HasCaught()); |
11443 CHECK(value->IsUndefined()); | 9744 CHECK(value->IsUndefined()); |
11444 | 9745 |
11445 // Call the Object's constructor with null. | 9746 // Call the Object's constructor with null. |
11446 Handle<Value> args5[] = { v8::Null(isolate) }; | 9747 Handle<Value> args5[] = {v8::Null(isolate)}; |
11447 Local<Value> value_obj5 = instance->CallAsConstructor(1, args5); | 9748 Local<Value> value_obj5 = instance->CallAsConstructor(1, args5); |
11448 CHECK(value_obj5->IsObject()); | 9749 CHECK(value_obj5->IsObject()); |
11449 Local<Object> object5 = Local<Object>::Cast(value_obj5); | 9750 Local<Object> object5 = Local<Object>::Cast(value_obj5); |
11450 value = object5->Get(v8_str("a")); | 9751 value = object5->Get(v8_str("a")); |
11451 CHECK(!try_catch.HasCaught()); | 9752 CHECK(!try_catch.HasCaught()); |
11452 CHECK(value->IsNull()); | 9753 CHECK(value->IsNull()); |
11453 } | 9754 } |
11454 | 9755 |
11455 // Check exception handling when there is no constructor set for the Object. | 9756 // Check exception handling when there is no constructor set for the Object. |
11456 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); | 9757 { |
| 9758 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
11457 Local<Object> instance = instance_template->NewInstance(); | 9759 Local<Object> instance = instance_template->NewInstance(); |
11458 context->Global()->Set(v8_str("obj2"), instance); | 9760 context->Global()->Set(v8_str("obj2"), instance); |
11459 v8::TryCatch try_catch; | 9761 v8::TryCatch try_catch; |
11460 Local<Value> value; | 9762 Local<Value> value; |
11461 CHECK(!try_catch.HasCaught()); | 9763 CHECK(!try_catch.HasCaught()); |
11462 | 9764 |
11463 value = CompileRun("new obj2(28)"); | 9765 value = CompileRun("new obj2(28)"); |
11464 CHECK(try_catch.HasCaught()); | 9766 CHECK(try_catch.HasCaught()); |
11465 String::Utf8Value exception_value1(try_catch.Exception()); | 9767 String::Utf8Value exception_value1(try_catch.Exception()); |
11466 CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1)); | 9768 CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1)); |
11467 try_catch.Reset(); | 9769 try_catch.Reset(); |
11468 | 9770 |
11469 Local<Value> args[] = { v8_num(29) }; | 9771 Local<Value> args[] = {v8_num(29)}; |
11470 value = instance->CallAsConstructor(1, args); | 9772 value = instance->CallAsConstructor(1, args); |
11471 CHECK(try_catch.HasCaught()); | 9773 CHECK(try_catch.HasCaught()); |
11472 String::Utf8Value exception_value2(try_catch.Exception()); | 9774 String::Utf8Value exception_value2(try_catch.Exception()); |
11473 CHECK_EQ( | 9775 CHECK_EQ( |
11474 0, strcmp("TypeError: #<Object> is not a function", *exception_value2)); | 9776 0, strcmp("TypeError: #<Object> is not a function", *exception_value2)); |
11475 try_catch.Reset(); | 9777 try_catch.Reset(); |
11476 } | 9778 } |
11477 | 9779 |
11478 // Check the case when constructor throws exception. | 9780 // Check the case when constructor throws exception. |
11479 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); | 9781 { |
| 9782 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
11480 instance_template->SetCallAsFunctionHandler(ThrowValue); | 9783 instance_template->SetCallAsFunctionHandler(ThrowValue); |
11481 Local<Object> instance = instance_template->NewInstance(); | 9784 Local<Object> instance = instance_template->NewInstance(); |
11482 context->Global()->Set(v8_str("obj3"), instance); | 9785 context->Global()->Set(v8_str("obj3"), instance); |
11483 v8::TryCatch try_catch; | 9786 v8::TryCatch try_catch; |
11484 Local<Value> value; | 9787 Local<Value> value; |
11485 CHECK(!try_catch.HasCaught()); | 9788 CHECK(!try_catch.HasCaught()); |
11486 | 9789 |
11487 value = CompileRun("new obj3(22)"); | 9790 value = CompileRun("new obj3(22)"); |
11488 CHECK(try_catch.HasCaught()); | 9791 CHECK(try_catch.HasCaught()); |
11489 String::Utf8Value exception_value1(try_catch.Exception()); | 9792 String::Utf8Value exception_value1(try_catch.Exception()); |
11490 CHECK_EQ(0, strcmp("22", *exception_value1)); | 9793 CHECK_EQ(0, strcmp("22", *exception_value1)); |
11491 try_catch.Reset(); | 9794 try_catch.Reset(); |
11492 | 9795 |
11493 Local<Value> args[] = { v8_num(23) }; | 9796 Local<Value> args[] = {v8_num(23)}; |
11494 value = instance->CallAsConstructor(1, args); | 9797 value = instance->CallAsConstructor(1, args); |
11495 CHECK(try_catch.HasCaught()); | 9798 CHECK(try_catch.HasCaught()); |
11496 String::Utf8Value exception_value2(try_catch.Exception()); | 9799 String::Utf8Value exception_value2(try_catch.Exception()); |
11497 CHECK_EQ(0, strcmp("23", *exception_value2)); | 9800 CHECK_EQ(0, strcmp("23", *exception_value2)); |
11498 try_catch.Reset(); | 9801 try_catch.Reset(); |
11499 } | 9802 } |
11500 | 9803 |
11501 // Check whether constructor returns with an object or non-object. | 9804 // Check whether constructor returns with an object or non-object. |
11502 { Local<FunctionTemplate> function_template = | 9805 { |
| 9806 Local<FunctionTemplate> function_template = |
11503 FunctionTemplate::New(isolate, FakeConstructorCallback); | 9807 FunctionTemplate::New(isolate, FakeConstructorCallback); |
11504 Local<Function> function = function_template->GetFunction(); | 9808 Local<Function> function = function_template->GetFunction(); |
11505 Local<Object> instance1 = function; | 9809 Local<Object> instance1 = function; |
11506 context->Global()->Set(v8_str("obj4"), instance1); | 9810 context->Global()->Set(v8_str("obj4"), instance1); |
11507 v8::TryCatch try_catch; | 9811 v8::TryCatch try_catch; |
11508 Local<Value> value; | 9812 Local<Value> value; |
11509 CHECK(!try_catch.HasCaught()); | 9813 CHECK(!try_catch.HasCaught()); |
11510 | 9814 |
11511 CHECK(instance1->IsObject()); | 9815 CHECK(instance1->IsObject()); |
11512 CHECK(instance1->IsFunction()); | 9816 CHECK(instance1->IsFunction()); |
11513 | 9817 |
11514 value = CompileRun("new obj4(28)"); | 9818 value = CompileRun("new obj4(28)"); |
11515 CHECK(!try_catch.HasCaught()); | 9819 CHECK(!try_catch.HasCaught()); |
11516 CHECK(value->IsObject()); | 9820 CHECK(value->IsObject()); |
11517 | 9821 |
11518 Local<Value> args1[] = { v8_num(28) }; | 9822 Local<Value> args1[] = {v8_num(28)}; |
11519 value = instance1->CallAsConstructor(1, args1); | 9823 value = instance1->CallAsConstructor(1, args1); |
11520 CHECK(!try_catch.HasCaught()); | 9824 CHECK(!try_catch.HasCaught()); |
11521 CHECK(value->IsObject()); | 9825 CHECK(value->IsObject()); |
11522 | 9826 |
11523 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); | 9827 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
11524 instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); | 9828 instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); |
11525 Local<Object> instance2 = instance_template->NewInstance(); | 9829 Local<Object> instance2 = instance_template->NewInstance(); |
11526 context->Global()->Set(v8_str("obj5"), instance2); | 9830 context->Global()->Set(v8_str("obj5"), instance2); |
11527 CHECK(!try_catch.HasCaught()); | 9831 CHECK(!try_catch.HasCaught()); |
11528 | 9832 |
11529 CHECK(instance2->IsObject()); | 9833 CHECK(instance2->IsObject()); |
11530 CHECK(!instance2->IsFunction()); | 9834 CHECK(!instance2->IsFunction()); |
11531 | 9835 |
11532 value = CompileRun("new obj5(28)"); | 9836 value = CompileRun("new obj5(28)"); |
11533 CHECK(!try_catch.HasCaught()); | 9837 CHECK(!try_catch.HasCaught()); |
11534 CHECK(!value->IsObject()); | 9838 CHECK(!value->IsObject()); |
11535 | 9839 |
11536 Local<Value> args2[] = { v8_num(28) }; | 9840 Local<Value> args2[] = {v8_num(28)}; |
11537 value = instance2->CallAsConstructor(1, args2); | 9841 value = instance2->CallAsConstructor(1, args2); |
11538 CHECK(!try_catch.HasCaught()); | 9842 CHECK(!try_catch.HasCaught()); |
11539 CHECK(!value->IsObject()); | 9843 CHECK(!value->IsObject()); |
11540 } | 9844 } |
11541 } | 9845 } |
11542 | 9846 |
11543 | 9847 |
11544 THREADED_TEST(FunctionDescriptorException) { | 9848 THREADED_TEST(FunctionDescriptorException) { |
11545 LocalContext context; | 9849 LocalContext context; |
11546 v8::Isolate* isolate = context->GetIsolate(); | 9850 v8::Isolate* isolate = context->GetIsolate(); |
11547 v8::HandleScope handle_scope(isolate); | 9851 v8::HandleScope handle_scope(isolate); |
11548 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | 9852 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
11549 templ->SetClassName(v8_str("Fun")); | 9853 templ->SetClassName(v8_str("Fun")); |
11550 Local<Function> cons = templ->GetFunction(); | 9854 Local<Function> cons = templ->GetFunction(); |
11551 context->Global()->Set(v8_str("Fun"), cons); | 9855 context->Global()->Set(v8_str("Fun"), cons); |
11552 Local<Value> value = CompileRun( | 9856 Local<Value> value = CompileRun( |
11553 "function test() {" | 9857 "function test() {" |
11554 " try {" | 9858 " try {" |
11555 " (new Fun()).blah()" | 9859 " (new Fun()).blah()" |
11556 " } catch (e) {" | 9860 " } catch (e) {" |
11557 " var str = String(e);" | 9861 " var str = String(e);" |
11558 // " if (str.indexOf('TypeError') == -1) return 1;" | 9862 // " if (str.indexOf('TypeError') == -1) return 1;" |
11559 // " if (str.indexOf('[object Fun]') != -1) return 2;" | 9863 // " if (str.indexOf('[object Fun]') != -1) return 2;" |
11560 // " if (str.indexOf('#<Fun>') == -1) return 3;" | 9864 // " if (str.indexOf('#<Fun>') == -1) return 3;" |
11561 " return 0;" | 9865 " return 0;" |
11562 " }" | 9866 " }" |
11563 " return 4;" | 9867 " return 4;" |
11564 "}" | 9868 "}" |
11565 "test();"); | 9869 "test();"); |
11566 CHECK_EQ(0, value->Int32Value()); | 9870 CHECK_EQ(0, value->Int32Value()); |
11567 } | 9871 } |
11568 | 9872 |
11569 | 9873 |
11570 THREADED_TEST(EvalAliasedDynamic) { | 9874 THREADED_TEST(EvalAliasedDynamic) { |
11571 LocalContext current; | 9875 LocalContext current; |
11572 v8::HandleScope scope(current->GetIsolate()); | 9876 v8::HandleScope scope(current->GetIsolate()); |
11573 | 9877 |
11574 // Tests where aliased eval can only be resolved dynamically. | 9878 // Tests where aliased eval can only be resolved dynamically. |
11575 Local<Script> script = v8_compile( | 9879 Local<Script> script = v8_compile( |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11682 // its global proxy works. | 9986 // its global proxy works. |
11683 THREADED_TEST(EvalInDetachedGlobal) { | 9987 THREADED_TEST(EvalInDetachedGlobal) { |
11684 v8::Isolate* isolate = CcTest::isolate(); | 9988 v8::Isolate* isolate = CcTest::isolate(); |
11685 v8::HandleScope scope(isolate); | 9989 v8::HandleScope scope(isolate); |
11686 | 9990 |
11687 v8::Local<Context> context0 = Context::New(isolate); | 9991 v8::Local<Context> context0 = Context::New(isolate); |
11688 v8::Local<Context> context1 = Context::New(isolate); | 9992 v8::Local<Context> context1 = Context::New(isolate); |
11689 | 9993 |
11690 // Set up function in context0 that uses eval from context0. | 9994 // Set up function in context0 that uses eval from context0. |
11691 context0->Enter(); | 9995 context0->Enter(); |
11692 v8::Handle<v8::Value> fun = | 9996 v8::Handle<v8::Value> fun = CompileRun( |
11693 CompileRun("var x = 42;" | 9997 "var x = 42;" |
11694 "(function() {" | 9998 "(function() {" |
11695 " var e = eval;" | 9999 " var e = eval;" |
11696 " return function(s) { return e(s); }" | 10000 " return function(s) { return e(s); }" |
11697 "})()"); | 10001 "})()"); |
11698 context0->Exit(); | 10002 context0->Exit(); |
11699 | 10003 |
11700 // Put the function into context1 and call it before and after | 10004 // Put the function into context1 and call it before and after |
11701 // detaching the global. Before detaching, the call succeeds and | 10005 // detaching the global. Before detaching, the call succeeds and |
11702 // after detaching and exception is thrown. | 10006 // after detaching and exception is thrown. |
11703 context1->Enter(); | 10007 context1->Enter(); |
11704 context1->Global()->Set(v8_str("fun"), fun); | 10008 context1->Global()->Set(v8_str("fun"), fun); |
11705 v8::Handle<v8::Value> x_value = CompileRun("fun('x')"); | 10009 v8::Handle<v8::Value> x_value = CompileRun("fun('x')"); |
11706 CHECK_EQ(42, x_value->Int32Value()); | 10010 CHECK_EQ(42, x_value->Int32Value()); |
11707 context0->DetachGlobal(); | 10011 context0->DetachGlobal(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11750 | 10054 |
11751 | 10055 |
11752 // Test that a call handler can be set for objects which will allow | 10056 // Test that a call handler can be set for objects which will allow |
11753 // non-function objects created through the API to be called as | 10057 // non-function objects created through the API to be called as |
11754 // functions. | 10058 // functions. |
11755 THREADED_TEST(CallAsFunction) { | 10059 THREADED_TEST(CallAsFunction) { |
11756 LocalContext context; | 10060 LocalContext context; |
11757 v8::Isolate* isolate = context->GetIsolate(); | 10061 v8::Isolate* isolate = context->GetIsolate(); |
11758 v8::HandleScope scope(isolate); | 10062 v8::HandleScope scope(isolate); |
11759 | 10063 |
11760 { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); | 10064 { |
| 10065 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
11761 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); | 10066 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
11762 instance_template->SetCallAsFunctionHandler(call_as_function); | 10067 instance_template->SetCallAsFunctionHandler(call_as_function); |
11763 Local<v8::Object> instance = t->GetFunction()->NewInstance(); | 10068 Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
11764 context->Global()->Set(v8_str("obj"), instance); | 10069 context->Global()->Set(v8_str("obj"), instance); |
11765 v8::TryCatch try_catch; | 10070 v8::TryCatch try_catch; |
11766 Local<Value> value; | 10071 Local<Value> value; |
11767 CHECK(!try_catch.HasCaught()); | 10072 CHECK(!try_catch.HasCaught()); |
11768 | 10073 |
11769 value = CompileRun("obj(42)"); | 10074 value = CompileRun("obj(42)"); |
11770 CHECK(!try_catch.HasCaught()); | 10075 CHECK(!try_catch.HasCaught()); |
11771 CHECK_EQ(42, value->Int32Value()); | 10076 CHECK_EQ(42, value->Int32Value()); |
11772 | 10077 |
11773 value = CompileRun("(function(o){return o(49)})(obj)"); | 10078 value = CompileRun("(function(o){return o(49)})(obj)"); |
11774 CHECK(!try_catch.HasCaught()); | 10079 CHECK(!try_catch.HasCaught()); |
11775 CHECK_EQ(49, value->Int32Value()); | 10080 CHECK_EQ(49, value->Int32Value()); |
11776 | 10081 |
11777 // test special case of call as function | 10082 // test special case of call as function |
11778 value = CompileRun("[obj]['0'](45)"); | 10083 value = CompileRun("[obj]['0'](45)"); |
11779 CHECK(!try_catch.HasCaught()); | 10084 CHECK(!try_catch.HasCaught()); |
11780 CHECK_EQ(45, value->Int32Value()); | 10085 CHECK_EQ(45, value->Int32Value()); |
11781 | 10086 |
11782 value = CompileRun("obj.call = Function.prototype.call;" | 10087 value = CompileRun( |
11783 "obj.call(null, 87)"); | 10088 "obj.call = Function.prototype.call;" |
| 10089 "obj.call(null, 87)"); |
11784 CHECK(!try_catch.HasCaught()); | 10090 CHECK(!try_catch.HasCaught()); |
11785 CHECK_EQ(87, value->Int32Value()); | 10091 CHECK_EQ(87, value->Int32Value()); |
11786 | 10092 |
11787 // Regression tests for bug #1116356: Calling call through call/apply | 10093 // Regression tests for bug #1116356: Calling call through call/apply |
11788 // must work for non-function receivers. | 10094 // must work for non-function receivers. |
11789 const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; | 10095 const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; |
11790 value = CompileRun(apply_99); | 10096 value = CompileRun(apply_99); |
11791 CHECK(!try_catch.HasCaught()); | 10097 CHECK(!try_catch.HasCaught()); |
11792 CHECK_EQ(99, value->Int32Value()); | 10098 CHECK_EQ(99, value->Int32Value()); |
11793 | 10099 |
11794 const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; | 10100 const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; |
11795 value = CompileRun(call_17); | 10101 value = CompileRun(call_17); |
11796 CHECK(!try_catch.HasCaught()); | 10102 CHECK(!try_catch.HasCaught()); |
11797 CHECK_EQ(17, value->Int32Value()); | 10103 CHECK_EQ(17, value->Int32Value()); |
11798 | 10104 |
11799 // Check that the call-as-function handler can be called through | 10105 // Check that the call-as-function handler can be called through |
11800 // new. | 10106 // new. |
11801 value = CompileRun("new obj(43)"); | 10107 value = CompileRun("new obj(43)"); |
11802 CHECK(!try_catch.HasCaught()); | 10108 CHECK(!try_catch.HasCaught()); |
11803 CHECK_EQ(-43, value->Int32Value()); | 10109 CHECK_EQ(-43, value->Int32Value()); |
11804 | 10110 |
11805 // Check that the call-as-function handler can be called through | 10111 // Check that the call-as-function handler can be called through |
11806 // the API. | 10112 // the API. |
11807 v8::Handle<Value> args[] = { v8_num(28) }; | 10113 v8::Handle<Value> args[] = {v8_num(28)}; |
11808 value = instance->CallAsFunction(instance, 1, args); | 10114 value = instance->CallAsFunction(instance, 1, args); |
11809 CHECK(!try_catch.HasCaught()); | 10115 CHECK(!try_catch.HasCaught()); |
11810 CHECK_EQ(28, value->Int32Value()); | 10116 CHECK_EQ(28, value->Int32Value()); |
11811 } | 10117 } |
11812 | 10118 |
11813 { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); | 10119 { |
| 10120 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
11814 Local<ObjectTemplate> instance_template(t->InstanceTemplate()); | 10121 Local<ObjectTemplate> instance_template(t->InstanceTemplate()); |
11815 USE(instance_template); | 10122 USE(instance_template); |
11816 Local<v8::Object> instance = t->GetFunction()->NewInstance(); | 10123 Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
11817 context->Global()->Set(v8_str("obj2"), instance); | 10124 context->Global()->Set(v8_str("obj2"), instance); |
11818 v8::TryCatch try_catch; | 10125 v8::TryCatch try_catch; |
11819 Local<Value> value; | 10126 Local<Value> value; |
11820 CHECK(!try_catch.HasCaught()); | 10127 CHECK(!try_catch.HasCaught()); |
11821 | 10128 |
11822 // Call an object without call-as-function handler through the JS | 10129 // Call an object without call-as-function handler through the JS |
11823 value = CompileRun("obj2(28)"); | 10130 value = CompileRun("obj2(28)"); |
11824 CHECK(value.IsEmpty()); | 10131 CHECK(value.IsEmpty()); |
11825 CHECK(try_catch.HasCaught()); | 10132 CHECK(try_catch.HasCaught()); |
11826 String::Utf8Value exception_value1(try_catch.Exception()); | 10133 String::Utf8Value exception_value1(try_catch.Exception()); |
11827 // TODO(verwaest): Better message | 10134 // TODO(verwaest): Better message |
11828 CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1)); | 10135 CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1)); |
11829 try_catch.Reset(); | 10136 try_catch.Reset(); |
11830 | 10137 |
11831 // Call an object without call-as-function handler through the API | 10138 // Call an object without call-as-function handler through the API |
11832 value = CompileRun("obj2(28)"); | 10139 value = CompileRun("obj2(28)"); |
11833 v8::Handle<Value> args[] = { v8_num(28) }; | 10140 v8::Handle<Value> args[] = {v8_num(28)}; |
11834 value = instance->CallAsFunction(instance, 1, args); | 10141 value = instance->CallAsFunction(instance, 1, args); |
11835 CHECK(value.IsEmpty()); | 10142 CHECK(value.IsEmpty()); |
11836 CHECK(try_catch.HasCaught()); | 10143 CHECK(try_catch.HasCaught()); |
11837 String::Utf8Value exception_value2(try_catch.Exception()); | 10144 String::Utf8Value exception_value2(try_catch.Exception()); |
11838 CHECK_EQ(0, strcmp("TypeError: [object Object] is not a function", | 10145 CHECK_EQ(0, strcmp("TypeError: [object Object] is not a function", |
11839 *exception_value2)); | 10146 *exception_value2)); |
11840 try_catch.Reset(); | 10147 try_catch.Reset(); |
11841 } | 10148 } |
11842 | 10149 |
11843 { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); | 10150 { |
| 10151 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
11844 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); | 10152 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
11845 instance_template->SetCallAsFunctionHandler(ThrowValue); | 10153 instance_template->SetCallAsFunctionHandler(ThrowValue); |
11846 Local<v8::Object> instance = t->GetFunction()->NewInstance(); | 10154 Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
11847 context->Global()->Set(v8_str("obj3"), instance); | 10155 context->Global()->Set(v8_str("obj3"), instance); |
11848 v8::TryCatch try_catch; | 10156 v8::TryCatch try_catch; |
11849 Local<Value> value; | 10157 Local<Value> value; |
11850 CHECK(!try_catch.HasCaught()); | 10158 CHECK(!try_catch.HasCaught()); |
11851 | 10159 |
11852 // Catch the exception which is thrown by call-as-function handler | 10160 // Catch the exception which is thrown by call-as-function handler |
11853 value = CompileRun("obj3(22)"); | 10161 value = CompileRun("obj3(22)"); |
11854 CHECK(try_catch.HasCaught()); | 10162 CHECK(try_catch.HasCaught()); |
11855 String::Utf8Value exception_value1(try_catch.Exception()); | 10163 String::Utf8Value exception_value1(try_catch.Exception()); |
11856 CHECK_EQ(0, strcmp("22", *exception_value1)); | 10164 CHECK_EQ(0, strcmp("22", *exception_value1)); |
11857 try_catch.Reset(); | 10165 try_catch.Reset(); |
11858 | 10166 |
11859 v8::Handle<Value> args[] = { v8_num(23) }; | 10167 v8::Handle<Value> args[] = {v8_num(23)}; |
11860 value = instance->CallAsFunction(instance, 1, args); | 10168 value = instance->CallAsFunction(instance, 1, args); |
11861 CHECK(try_catch.HasCaught()); | 10169 CHECK(try_catch.HasCaught()); |
11862 String::Utf8Value exception_value2(try_catch.Exception()); | 10170 String::Utf8Value exception_value2(try_catch.Exception()); |
11863 CHECK_EQ(0, strcmp("23", *exception_value2)); | 10171 CHECK_EQ(0, strcmp("23", *exception_value2)); |
11864 try_catch.Reset(); | 10172 try_catch.Reset(); |
11865 } | 10173 } |
11866 | 10174 |
11867 { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); | 10175 { |
| 10176 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
11868 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); | 10177 Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
11869 instance_template->SetCallAsFunctionHandler(ReturnThis); | 10178 instance_template->SetCallAsFunctionHandler(ReturnThis); |
11870 Local<v8::Object> instance = t->GetFunction()->NewInstance(); | 10179 Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
11871 | 10180 |
11872 Local<v8::Value> a1 = | 10181 Local<v8::Value> a1 = |
11873 instance->CallAsFunction(v8::Undefined(isolate), 0, NULL); | 10182 instance->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
11874 CHECK(a1->StrictEquals(instance)); | 10183 CHECK(a1->StrictEquals(instance)); |
11875 Local<v8::Value> a2 = | 10184 Local<v8::Value> a2 = instance->CallAsFunction(v8::Null(isolate), 0, NULL); |
11876 instance->CallAsFunction(v8::Null(isolate), 0, NULL); | |
11877 CHECK(a2->StrictEquals(instance)); | 10185 CHECK(a2->StrictEquals(instance)); |
11878 Local<v8::Value> a3 = | 10186 Local<v8::Value> a3 = instance->CallAsFunction(v8_num(42), 0, NULL); |
11879 instance->CallAsFunction(v8_num(42), 0, NULL); | |
11880 CHECK(a3->StrictEquals(instance)); | 10187 CHECK(a3->StrictEquals(instance)); |
11881 Local<v8::Value> a4 = | 10188 Local<v8::Value> a4 = instance->CallAsFunction(v8_str("hello"), 0, NULL); |
11882 instance->CallAsFunction(v8_str("hello"), 0, NULL); | |
11883 CHECK(a4->StrictEquals(instance)); | 10189 CHECK(a4->StrictEquals(instance)); |
11884 Local<v8::Value> a5 = | 10190 Local<v8::Value> a5 = instance->CallAsFunction(v8::True(isolate), 0, NULL); |
11885 instance->CallAsFunction(v8::True(isolate), 0, NULL); | |
11886 CHECK(a5->StrictEquals(instance)); | 10191 CHECK(a5->StrictEquals(instance)); |
11887 } | 10192 } |
11888 | 10193 |
11889 { CompileRun( | 10194 { |
11890 "function ReturnThisSloppy() {" | 10195 CompileRun( |
11891 " return this;" | 10196 "function ReturnThisSloppy() {" |
11892 "}" | 10197 " return this;" |
11893 "function ReturnThisStrict() {" | 10198 "}" |
11894 " 'use strict';" | 10199 "function ReturnThisStrict() {" |
11895 " return this;" | 10200 " 'use strict';" |
11896 "}"); | 10201 " return this;" |
11897 Local<Function> ReturnThisSloppy = | 10202 "}"); |
11898 Local<Function>::Cast( | 10203 Local<Function> ReturnThisSloppy = Local<Function>::Cast( |
11899 context->Global()->Get(v8_str("ReturnThisSloppy"))); | 10204 context->Global()->Get(v8_str("ReturnThisSloppy"))); |
11900 Local<Function> ReturnThisStrict = | 10205 Local<Function> ReturnThisStrict = Local<Function>::Cast( |
11901 Local<Function>::Cast( | 10206 context->Global()->Get(v8_str("ReturnThisStrict"))); |
11902 context->Global()->Get(v8_str("ReturnThisStrict"))); | |
11903 | 10207 |
11904 Local<v8::Value> a1 = | 10208 Local<v8::Value> a1 = |
11905 ReturnThisSloppy->CallAsFunction(v8::Undefined(isolate), 0, NULL); | 10209 ReturnThisSloppy->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
11906 CHECK(a1->StrictEquals(context->Global())); | 10210 CHECK(a1->StrictEquals(context->Global())); |
11907 Local<v8::Value> a2 = | 10211 Local<v8::Value> a2 = |
11908 ReturnThisSloppy->CallAsFunction(v8::Null(isolate), 0, NULL); | 10212 ReturnThisSloppy->CallAsFunction(v8::Null(isolate), 0, NULL); |
11909 CHECK(a2->StrictEquals(context->Global())); | 10213 CHECK(a2->StrictEquals(context->Global())); |
11910 Local<v8::Value> a3 = | 10214 Local<v8::Value> a3 = ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); |
11911 ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); | |
11912 CHECK(a3->IsNumberObject()); | 10215 CHECK(a3->IsNumberObject()); |
11913 CHECK_EQ(42.0, a3.As<v8::NumberObject>()->ValueOf()); | 10216 CHECK_EQ(42.0, a3.As<v8::NumberObject>()->ValueOf()); |
11914 Local<v8::Value> a4 = | 10217 Local<v8::Value> a4 = |
11915 ReturnThisSloppy->CallAsFunction(v8_str("hello"), 0, NULL); | 10218 ReturnThisSloppy->CallAsFunction(v8_str("hello"), 0, NULL); |
11916 CHECK(a4->IsStringObject()); | 10219 CHECK(a4->IsStringObject()); |
11917 CHECK(a4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); | 10220 CHECK(a4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); |
11918 Local<v8::Value> a5 = | 10221 Local<v8::Value> a5 = |
11919 ReturnThisSloppy->CallAsFunction(v8::True(isolate), 0, NULL); | 10222 ReturnThisSloppy->CallAsFunction(v8::True(isolate), 0, NULL); |
11920 CHECK(a5->IsBooleanObject()); | 10223 CHECK(a5->IsBooleanObject()); |
11921 CHECK(a5.As<v8::BooleanObject>()->ValueOf()); | 10224 CHECK(a5.As<v8::BooleanObject>()->ValueOf()); |
11922 | 10225 |
11923 Local<v8::Value> a6 = | 10226 Local<v8::Value> a6 = |
11924 ReturnThisStrict->CallAsFunction(v8::Undefined(isolate), 0, NULL); | 10227 ReturnThisStrict->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
11925 CHECK(a6->IsUndefined()); | 10228 CHECK(a6->IsUndefined()); |
11926 Local<v8::Value> a7 = | 10229 Local<v8::Value> a7 = |
11927 ReturnThisStrict->CallAsFunction(v8::Null(isolate), 0, NULL); | 10230 ReturnThisStrict->CallAsFunction(v8::Null(isolate), 0, NULL); |
11928 CHECK(a7->IsNull()); | 10231 CHECK(a7->IsNull()); |
11929 Local<v8::Value> a8 = | 10232 Local<v8::Value> a8 = ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); |
11930 ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); | |
11931 CHECK(a8->StrictEquals(v8_num(42))); | 10233 CHECK(a8->StrictEquals(v8_num(42))); |
11932 Local<v8::Value> a9 = | 10234 Local<v8::Value> a9 = |
11933 ReturnThisStrict->CallAsFunction(v8_str("hello"), 0, NULL); | 10235 ReturnThisStrict->CallAsFunction(v8_str("hello"), 0, NULL); |
11934 CHECK(a9->StrictEquals(v8_str("hello"))); | 10236 CHECK(a9->StrictEquals(v8_str("hello"))); |
11935 Local<v8::Value> a10 = | 10237 Local<v8::Value> a10 = |
11936 ReturnThisStrict->CallAsFunction(v8::True(isolate), 0, NULL); | 10238 ReturnThisStrict->CallAsFunction(v8::True(isolate), 0, NULL); |
11937 CHECK(a10->StrictEquals(v8::True(isolate))); | 10239 CHECK(a10->StrictEquals(v8::True(isolate))); |
11938 } | 10240 } |
11939 } | 10241 } |
11940 | 10242 |
11941 | 10243 |
11942 // Check whether a non-function object is callable. | 10244 // Check whether a non-function object is callable. |
11943 THREADED_TEST(CallableObject) { | 10245 THREADED_TEST(CallableObject) { |
11944 LocalContext context; | 10246 LocalContext context; |
11945 v8::Isolate* isolate = context->GetIsolate(); | 10247 v8::Isolate* isolate = context->GetIsolate(); |
11946 v8::HandleScope scope(isolate); | 10248 v8::HandleScope scope(isolate); |
11947 | 10249 |
11948 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); | 10250 { |
| 10251 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
11949 instance_template->SetCallAsFunctionHandler(call_as_function); | 10252 instance_template->SetCallAsFunctionHandler(call_as_function); |
11950 Local<Object> instance = instance_template->NewInstance(); | 10253 Local<Object> instance = instance_template->NewInstance(); |
11951 v8::TryCatch try_catch; | 10254 v8::TryCatch try_catch; |
11952 | 10255 |
11953 CHECK(instance->IsCallable()); | 10256 CHECK(instance->IsCallable()); |
11954 CHECK(!try_catch.HasCaught()); | 10257 CHECK(!try_catch.HasCaught()); |
11955 } | 10258 } |
11956 | 10259 |
11957 { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); | 10260 { |
| 10261 Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
11958 Local<Object> instance = instance_template->NewInstance(); | 10262 Local<Object> instance = instance_template->NewInstance(); |
11959 v8::TryCatch try_catch; | 10263 v8::TryCatch try_catch; |
11960 | 10264 |
11961 CHECK(!instance->IsCallable()); | 10265 CHECK(!instance->IsCallable()); |
11962 CHECK(!try_catch.HasCaught()); | 10266 CHECK(!try_catch.HasCaught()); |
11963 } | 10267 } |
11964 | 10268 |
11965 { Local<FunctionTemplate> function_template = | 10269 { |
| 10270 Local<FunctionTemplate> function_template = |
11966 FunctionTemplate::New(isolate, call_as_function); | 10271 FunctionTemplate::New(isolate, call_as_function); |
11967 Local<Function> function = function_template->GetFunction(); | 10272 Local<Function> function = function_template->GetFunction(); |
11968 Local<Object> instance = function; | 10273 Local<Object> instance = function; |
11969 v8::TryCatch try_catch; | 10274 v8::TryCatch try_catch; |
11970 | 10275 |
11971 CHECK(instance->IsCallable()); | 10276 CHECK(instance->IsCallable()); |
11972 CHECK(!try_catch.HasCaught()); | 10277 CHECK(!try_catch.HasCaught()); |
11973 } | 10278 } |
11974 | 10279 |
11975 { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate); | 10280 { |
| 10281 Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate); |
11976 Local<Function> function = function_template->GetFunction(); | 10282 Local<Function> function = function_template->GetFunction(); |
11977 Local<Object> instance = function; | 10283 Local<Object> instance = function; |
11978 v8::TryCatch try_catch; | 10284 v8::TryCatch try_catch; |
11979 | 10285 |
11980 CHECK(instance->IsCallable()); | 10286 CHECK(instance->IsCallable()); |
11981 CHECK(!try_catch.HasCaught()); | 10287 CHECK(!try_catch.HasCaught()); |
11982 } | 10288 } |
11983 } | 10289 } |
11984 | 10290 |
11985 | 10291 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12017 v8::HandleScope::NumberOfHandles(isolate)); | 10323 v8::HandleScope::NumberOfHandles(isolate)); |
12018 } | 10324 } |
12019 } | 10325 } |
12020 CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); | 10326 CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); |
12021 } | 10327 } |
12022 CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); | 10328 CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
12023 CHECK_EQ(kNesting * kIterations, Recurse(isolate, kNesting, kIterations)); | 10329 CHECK_EQ(kNesting * kIterations, Recurse(isolate, kNesting, kIterations)); |
12024 } | 10330 } |
12025 | 10331 |
12026 | 10332 |
12027 static void InterceptorHasOwnPropertyGetter( | |
12028 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12029 ApiTestFuzzer::Fuzz(); | |
12030 } | |
12031 | |
12032 | |
12033 THREADED_TEST(InterceptorHasOwnProperty) { | |
12034 LocalContext context; | |
12035 v8::Isolate* isolate = context->GetIsolate(); | |
12036 v8::HandleScope scope(isolate); | |
12037 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); | |
12038 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | |
12039 instance_templ->SetHandler( | |
12040 v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetter)); | |
12041 Local<Function> function = fun_templ->GetFunction(); | |
12042 context->Global()->Set(v8_str("constructor"), function); | |
12043 v8::Handle<Value> value = CompileRun( | |
12044 "var o = new constructor();" | |
12045 "o.hasOwnProperty('ostehaps');"); | |
12046 CHECK_EQ(false, value->BooleanValue()); | |
12047 value = CompileRun( | |
12048 "o.ostehaps = 42;" | |
12049 "o.hasOwnProperty('ostehaps');"); | |
12050 CHECK_EQ(true, value->BooleanValue()); | |
12051 value = CompileRun( | |
12052 "var p = new constructor();" | |
12053 "p.hasOwnProperty('ostehaps');"); | |
12054 CHECK_EQ(false, value->BooleanValue()); | |
12055 } | |
12056 | |
12057 | |
12058 static void InterceptorHasOwnPropertyGetterGC( | |
12059 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12060 ApiTestFuzzer::Fuzz(); | |
12061 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | |
12062 } | |
12063 | |
12064 | |
12065 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { | |
12066 LocalContext context; | |
12067 v8::Isolate* isolate = context->GetIsolate(); | |
12068 v8::HandleScope scope(isolate); | |
12069 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); | |
12070 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | |
12071 instance_templ->SetHandler( | |
12072 v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetterGC)); | |
12073 Local<Function> function = fun_templ->GetFunction(); | |
12074 context->Global()->Set(v8_str("constructor"), function); | |
12075 // Let's first make some stuff so we can be sure to get a good GC. | |
12076 CompileRun( | |
12077 "function makestr(size) {" | |
12078 " switch (size) {" | |
12079 " case 1: return 'f';" | |
12080 " case 2: return 'fo';" | |
12081 " case 3: return 'foo';" | |
12082 " }" | |
12083 " return makestr(size >> 1) + makestr((size + 1) >> 1);" | |
12084 "}" | |
12085 "var x = makestr(12345);" | |
12086 "x = makestr(31415);" | |
12087 "x = makestr(23456);"); | |
12088 v8::Handle<Value> value = CompileRun( | |
12089 "var o = new constructor();" | |
12090 "o.__proto__ = new String(x);" | |
12091 "o.hasOwnProperty('ostehaps');"); | |
12092 CHECK_EQ(false, value->BooleanValue()); | |
12093 } | |
12094 | |
12095 | |
12096 static void CheckInterceptorLoadIC( | |
12097 v8::GenericNamedPropertyGetterCallback getter, const char* source, | |
12098 int expected) { | |
12099 v8::Isolate* isolate = CcTest::isolate(); | |
12100 v8::HandleScope scope(isolate); | |
12101 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12102 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(getter, 0, 0, 0, 0, | |
12103 v8_str("data"))); | |
12104 LocalContext context; | |
12105 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12106 v8::Handle<Value> value = CompileRun(source); | |
12107 CHECK_EQ(expected, value->Int32Value()); | |
12108 } | |
12109 | |
12110 | |
12111 static void InterceptorLoadICGetter( | |
12112 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12113 ApiTestFuzzer::Fuzz(); | |
12114 v8::Isolate* isolate = CcTest::isolate(); | |
12115 CHECK_EQ(isolate, info.GetIsolate()); | |
12116 CHECK(v8_str("data")->Equals(info.Data())); | |
12117 CHECK(v8_str("x")->Equals(name)); | |
12118 info.GetReturnValue().Set(v8::Integer::New(isolate, 42)); | |
12119 } | |
12120 | |
12121 | |
12122 // This test should hit the load IC for the interceptor case. | |
12123 THREADED_TEST(InterceptorLoadIC) { | |
12124 CheckInterceptorLoadIC(InterceptorLoadICGetter, | |
12125 "var result = 0;" | |
12126 "for (var i = 0; i < 1000; i++) {" | |
12127 " result = o.x;" | |
12128 "}", | |
12129 42); | |
12130 } | |
12131 | |
12132 | |
12133 // Below go several tests which verify that JITing for various | |
12134 // configurations of interceptor and explicit fields works fine | |
12135 // (those cases are special cased to get better performance). | |
12136 | |
12137 static void InterceptorLoadXICGetter( | |
12138 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12139 ApiTestFuzzer::Fuzz(); | |
12140 info.GetReturnValue().Set( | |
12141 v8_str("x")->Equals(name) ? | |
12142 v8::Handle<v8::Value>(v8::Integer::New(info.GetIsolate(), 42)) : | |
12143 v8::Handle<v8::Value>()); | |
12144 } | |
12145 | |
12146 | |
12147 THREADED_TEST(InterceptorLoadICWithFieldOnHolder) { | |
12148 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12149 "var result = 0;" | |
12150 "o.y = 239;" | |
12151 "for (var i = 0; i < 1000; i++) {" | |
12152 " result = o.y;" | |
12153 "}", | |
12154 239); | |
12155 } | |
12156 | |
12157 | |
12158 THREADED_TEST(InterceptorLoadICWithSubstitutedProto) { | |
12159 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12160 "var result = 0;" | |
12161 "o.__proto__ = { 'y': 239 };" | |
12162 "for (var i = 0; i < 1000; i++) {" | |
12163 " result = o.y + o.x;" | |
12164 "}", | |
12165 239 + 42); | |
12166 } | |
12167 | |
12168 | |
12169 THREADED_TEST(InterceptorLoadICWithPropertyOnProto) { | |
12170 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12171 "var result = 0;" | |
12172 "o.__proto__.y = 239;" | |
12173 "for (var i = 0; i < 1000; i++) {" | |
12174 " result = o.y + o.x;" | |
12175 "}", | |
12176 239 + 42); | |
12177 } | |
12178 | |
12179 | |
12180 THREADED_TEST(InterceptorLoadICUndefined) { | |
12181 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12182 "var result = 0;" | |
12183 "for (var i = 0; i < 1000; i++) {" | |
12184 " result = (o.y == undefined) ? 239 : 42;" | |
12185 "}", | |
12186 239); | |
12187 } | |
12188 | |
12189 | |
12190 THREADED_TEST(InterceptorLoadICWithOverride) { | |
12191 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12192 "fst = new Object(); fst.__proto__ = o;" | |
12193 "snd = new Object(); snd.__proto__ = fst;" | |
12194 "var result1 = 0;" | |
12195 "for (var i = 0; i < 1000; i++) {" | |
12196 " result1 = snd.x;" | |
12197 "}" | |
12198 "fst.x = 239;" | |
12199 "var result = 0;" | |
12200 "for (var i = 0; i < 1000; i++) {" | |
12201 " result = snd.x;" | |
12202 "}" | |
12203 "result + result1", | |
12204 239 + 42); | |
12205 } | |
12206 | |
12207 | |
12208 // Test the case when we stored field into | |
12209 // a stub, but interceptor produced value on its own. | |
12210 THREADED_TEST(InterceptorLoadICFieldNotNeeded) { | |
12211 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12212 "proto = new Object();" | |
12213 "o.__proto__ = proto;" | |
12214 "proto.x = 239;" | |
12215 "for (var i = 0; i < 1000; i++) {" | |
12216 " o.x;" | |
12217 // Now it should be ICed and keep a reference to x defined on proto | |
12218 "}" | |
12219 "var result = 0;" | |
12220 "for (var i = 0; i < 1000; i++) {" | |
12221 " result += o.x;" | |
12222 "}" | |
12223 "result;", | |
12224 42 * 1000); | |
12225 } | |
12226 | |
12227 | |
12228 // Test the case when we stored field into | |
12229 // a stub, but it got invalidated later on. | |
12230 THREADED_TEST(InterceptorLoadICInvalidatedField) { | |
12231 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12232 "proto1 = new Object();" | |
12233 "proto2 = new Object();" | |
12234 "o.__proto__ = proto1;" | |
12235 "proto1.__proto__ = proto2;" | |
12236 "proto2.y = 239;" | |
12237 "for (var i = 0; i < 1000; i++) {" | |
12238 " o.y;" | |
12239 // Now it should be ICed and keep a reference to y defined on proto2 | |
12240 "}" | |
12241 "proto1.y = 42;" | |
12242 "var result = 0;" | |
12243 "for (var i = 0; i < 1000; i++) {" | |
12244 " result += o.y;" | |
12245 "}" | |
12246 "result;", | |
12247 42 * 1000); | |
12248 } | |
12249 | |
12250 | |
12251 static int interceptor_load_not_handled_calls = 0; | |
12252 static void InterceptorLoadNotHandled( | |
12253 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12254 ++interceptor_load_not_handled_calls; | |
12255 } | |
12256 | |
12257 | |
12258 // Test how post-interceptor lookups are done in the non-cacheable | |
12259 // case: the interceptor should not be invoked during this lookup. | |
12260 THREADED_TEST(InterceptorLoadICPostInterceptor) { | |
12261 interceptor_load_not_handled_calls = 0; | |
12262 CheckInterceptorLoadIC(InterceptorLoadNotHandled, | |
12263 "receiver = new Object();" | |
12264 "receiver.__proto__ = o;" | |
12265 "proto = new Object();" | |
12266 "/* Make proto a slow-case object. */" | |
12267 "for (var i = 0; i < 1000; i++) {" | |
12268 " proto[\"xxxxxxxx\" + i] = [];" | |
12269 "}" | |
12270 "proto.x = 17;" | |
12271 "o.__proto__ = proto;" | |
12272 "var result = 0;" | |
12273 "for (var i = 0; i < 1000; i++) {" | |
12274 " result += receiver.x;" | |
12275 "}" | |
12276 "result;", | |
12277 17 * 1000); | |
12278 CHECK_EQ(1000, interceptor_load_not_handled_calls); | |
12279 } | |
12280 | |
12281 | |
12282 // Test the case when we stored field into | |
12283 // a stub, but it got invalidated later on due to override on | |
12284 // global object which is between interceptor and fields' holders. | |
12285 THREADED_TEST(InterceptorLoadICInvalidatedFieldViaGlobal) { | |
12286 CheckInterceptorLoadIC(InterceptorLoadXICGetter, | |
12287 "o.__proto__ = this;" // set a global to be a proto of o. | |
12288 "this.__proto__.y = 239;" | |
12289 "for (var i = 0; i < 10; i++) {" | |
12290 " if (o.y != 239) throw 'oops: ' + o.y;" | |
12291 // Now it should be ICed and keep a reference to y defined on field_holder. | |
12292 "}" | |
12293 "this.y = 42;" // Assign on a global. | |
12294 "var result = 0;" | |
12295 "for (var i = 0; i < 10; i++) {" | |
12296 " result += o.y;" | |
12297 "}" | |
12298 "result;", | |
12299 42 * 10); | |
12300 } | |
12301 | |
12302 | |
12303 static void SetOnThis(Local<String> name, | |
12304 Local<Value> value, | |
12305 const v8::PropertyCallbackInfo<void>& info) { | |
12306 Local<Object>::Cast(info.This())->ForceSet(name, value); | |
12307 } | |
12308 | |
12309 | |
12310 THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { | |
12311 v8::Isolate* isolate = CcTest::isolate(); | |
12312 v8::HandleScope scope(isolate); | |
12313 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12314 templ->SetHandler( | |
12315 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12316 templ->SetAccessor(v8_str("y"), Return239Callback); | |
12317 LocalContext context; | |
12318 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12319 | |
12320 // Check the case when receiver and interceptor's holder | |
12321 // are the same objects. | |
12322 v8::Handle<Value> value = CompileRun( | |
12323 "var result = 0;" | |
12324 "for (var i = 0; i < 7; i++) {" | |
12325 " result = o.y;" | |
12326 "}"); | |
12327 CHECK_EQ(239, value->Int32Value()); | |
12328 | |
12329 // Check the case when interceptor's holder is in proto chain | |
12330 // of receiver. | |
12331 value = CompileRun( | |
12332 "r = { __proto__: o };" | |
12333 "var result = 0;" | |
12334 "for (var i = 0; i < 7; i++) {" | |
12335 " result = r.y;" | |
12336 "}"); | |
12337 CHECK_EQ(239, value->Int32Value()); | |
12338 } | |
12339 | |
12340 | |
12341 THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { | |
12342 v8::Isolate* isolate = CcTest::isolate(); | |
12343 v8::HandleScope scope(isolate); | |
12344 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
12345 templ_o->SetHandler( | |
12346 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12347 v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); | |
12348 templ_p->SetAccessor(v8_str("y"), Return239Callback); | |
12349 | |
12350 LocalContext context; | |
12351 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
12352 context->Global()->Set(v8_str("p"), templ_p->NewInstance()); | |
12353 | |
12354 // Check the case when receiver and interceptor's holder | |
12355 // are the same objects. | |
12356 v8::Handle<Value> value = CompileRun( | |
12357 "o.__proto__ = p;" | |
12358 "var result = 0;" | |
12359 "for (var i = 0; i < 7; i++) {" | |
12360 " result = o.x + o.y;" | |
12361 "}"); | |
12362 CHECK_EQ(239 + 42, value->Int32Value()); | |
12363 | |
12364 // Check the case when interceptor's holder is in proto chain | |
12365 // of receiver. | |
12366 value = CompileRun( | |
12367 "r = { __proto__: o };" | |
12368 "var result = 0;" | |
12369 "for (var i = 0; i < 7; i++) {" | |
12370 " result = r.x + r.y;" | |
12371 "}"); | |
12372 CHECK_EQ(239 + 42, value->Int32Value()); | |
12373 } | |
12374 | |
12375 | |
12376 THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { | |
12377 v8::Isolate* isolate = CcTest::isolate(); | |
12378 v8::HandleScope scope(isolate); | |
12379 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12380 templ->SetHandler( | |
12381 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12382 templ->SetAccessor(v8_str("y"), Return239Callback); | |
12383 | |
12384 LocalContext context; | |
12385 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12386 | |
12387 v8::Handle<Value> value = CompileRun( | |
12388 "fst = new Object(); fst.__proto__ = o;" | |
12389 "snd = new Object(); snd.__proto__ = fst;" | |
12390 "var result1 = 0;" | |
12391 "for (var i = 0; i < 7; i++) {" | |
12392 " result1 = snd.x;" | |
12393 "}" | |
12394 "fst.x = 239;" | |
12395 "var result = 0;" | |
12396 "for (var i = 0; i < 7; i++) {" | |
12397 " result = snd.x;" | |
12398 "}" | |
12399 "result + result1"); | |
12400 CHECK_EQ(239 + 42, value->Int32Value()); | |
12401 } | |
12402 | |
12403 | |
12404 // Test the case when we stored callback into | |
12405 // a stub, but interceptor produced value on its own. | |
12406 THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { | |
12407 v8::Isolate* isolate = CcTest::isolate(); | |
12408 v8::HandleScope scope(isolate); | |
12409 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
12410 templ_o->SetHandler( | |
12411 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12412 v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); | |
12413 templ_p->SetAccessor(v8_str("y"), Return239Callback); | |
12414 | |
12415 LocalContext context; | |
12416 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
12417 context->Global()->Set(v8_str("p"), templ_p->NewInstance()); | |
12418 | |
12419 v8::Handle<Value> value = CompileRun( | |
12420 "o.__proto__ = p;" | |
12421 "for (var i = 0; i < 7; i++) {" | |
12422 " o.x;" | |
12423 // Now it should be ICed and keep a reference to x defined on p | |
12424 "}" | |
12425 "var result = 0;" | |
12426 "for (var i = 0; i < 7; i++) {" | |
12427 " result += o.x;" | |
12428 "}" | |
12429 "result"); | |
12430 CHECK_EQ(42 * 7, value->Int32Value()); | |
12431 } | |
12432 | |
12433 | |
12434 // Test the case when we stored callback into | |
12435 // a stub, but it got invalidated later on. | |
12436 THREADED_TEST(InterceptorLoadICInvalidatedCallback) { | |
12437 v8::Isolate* isolate = CcTest::isolate(); | |
12438 v8::HandleScope scope(isolate); | |
12439 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
12440 templ_o->SetHandler( | |
12441 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12442 v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); | |
12443 templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); | |
12444 | |
12445 LocalContext context; | |
12446 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
12447 context->Global()->Set(v8_str("p"), templ_p->NewInstance()); | |
12448 | |
12449 v8::Handle<Value> value = CompileRun( | |
12450 "inbetween = new Object();" | |
12451 "o.__proto__ = inbetween;" | |
12452 "inbetween.__proto__ = p;" | |
12453 "for (var i = 0; i < 10; i++) {" | |
12454 " o.y;" | |
12455 // Now it should be ICed and keep a reference to y defined on p | |
12456 "}" | |
12457 "inbetween.y = 42;" | |
12458 "var result = 0;" | |
12459 "for (var i = 0; i < 10; i++) {" | |
12460 " result += o.y;" | |
12461 "}" | |
12462 "result"); | |
12463 CHECK_EQ(42 * 10, value->Int32Value()); | |
12464 } | |
12465 | |
12466 | |
12467 // Test the case when we stored callback into | |
12468 // a stub, but it got invalidated later on due to override on | |
12469 // global object which is between interceptor and callbacks' holders. | |
12470 THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) { | |
12471 v8::Isolate* isolate = CcTest::isolate(); | |
12472 v8::HandleScope scope(isolate); | |
12473 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
12474 templ_o->SetHandler( | |
12475 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12476 v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); | |
12477 templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); | |
12478 | |
12479 LocalContext context; | |
12480 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
12481 context->Global()->Set(v8_str("p"), templ_p->NewInstance()); | |
12482 | |
12483 v8::Handle<Value> value = CompileRun( | |
12484 "o.__proto__ = this;" | |
12485 "this.__proto__ = p;" | |
12486 "for (var i = 0; i < 10; i++) {" | |
12487 " if (o.y != 239) throw 'oops: ' + o.y;" | |
12488 // Now it should be ICed and keep a reference to y defined on p | |
12489 "}" | |
12490 "this.y = 42;" | |
12491 "var result = 0;" | |
12492 "for (var i = 0; i < 10; i++) {" | |
12493 " result += o.y;" | |
12494 "}" | |
12495 "result"); | |
12496 CHECK_EQ(42 * 10, value->Int32Value()); | |
12497 } | |
12498 | |
12499 | |
12500 static void InterceptorLoadICGetter0( | |
12501 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12502 ApiTestFuzzer::Fuzz(); | |
12503 CHECK(v8_str("x")->Equals(name)); | |
12504 info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 0)); | |
12505 } | |
12506 | |
12507 | |
12508 THREADED_TEST(InterceptorReturningZero) { | |
12509 CheckInterceptorLoadIC(InterceptorLoadICGetter0, | |
12510 "o.x == undefined ? 1 : 0", | |
12511 0); | |
12512 } | |
12513 | |
12514 | |
12515 static void InterceptorStoreICSetter( | |
12516 Local<Name> key, Local<Value> value, | |
12517 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12518 CHECK(v8_str("x")->Equals(key)); | |
12519 CHECK_EQ(42, value->Int32Value()); | |
12520 info.GetReturnValue().Set(value); | |
12521 } | |
12522 | |
12523 | |
12524 // This test should hit the store IC for the interceptor case. | |
12525 THREADED_TEST(InterceptorStoreIC) { | |
12526 v8::Isolate* isolate = CcTest::isolate(); | |
12527 v8::HandleScope scope(isolate); | |
12528 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12529 templ->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
12530 InterceptorLoadICGetter, InterceptorStoreICSetter, 0, 0, 0, | |
12531 v8_str("data"))); | |
12532 LocalContext context; | |
12533 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12534 CompileRun( | |
12535 "for (var i = 0; i < 1000; i++) {" | |
12536 " o.x = 42;" | |
12537 "}"); | |
12538 } | |
12539 | |
12540 | |
12541 THREADED_TEST(InterceptorStoreICWithNoSetter) { | |
12542 v8::Isolate* isolate = CcTest::isolate(); | |
12543 v8::HandleScope scope(isolate); | |
12544 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12545 templ->SetHandler( | |
12546 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
12547 LocalContext context; | |
12548 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12549 v8::Handle<Value> value = CompileRun( | |
12550 "for (var i = 0; i < 1000; i++) {" | |
12551 " o.y = 239;" | |
12552 "}" | |
12553 "42 + o.y"); | |
12554 CHECK_EQ(239 + 42, value->Int32Value()); | |
12555 } | |
12556 | |
12557 | |
12558 | |
12559 | |
12560 v8::Handle<Value> call_ic_function; | |
12561 v8::Handle<Value> call_ic_function2; | |
12562 v8::Handle<Value> call_ic_function3; | |
12563 | |
12564 static void InterceptorCallICGetter( | |
12565 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12566 ApiTestFuzzer::Fuzz(); | |
12567 CHECK(v8_str("x")->Equals(name)); | |
12568 info.GetReturnValue().Set(call_ic_function); | |
12569 } | |
12570 | |
12571 | |
12572 // This test should hit the call IC for the interceptor case. | |
12573 THREADED_TEST(InterceptorCallIC) { | |
12574 v8::Isolate* isolate = CcTest::isolate(); | |
12575 v8::HandleScope scope(isolate); | |
12576 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12577 templ->SetHandler( | |
12578 v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter)); | |
12579 LocalContext context; | |
12580 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12581 call_ic_function = | |
12582 v8_compile("function f(x) { return x + 1; }; f")->Run(); | |
12583 v8::Handle<Value> value = CompileRun( | |
12584 "var result = 0;" | |
12585 "for (var i = 0; i < 1000; i++) {" | |
12586 " result = o.x(41);" | |
12587 "}"); | |
12588 CHECK_EQ(42, value->Int32Value()); | |
12589 } | |
12590 | |
12591 | |
12592 // This test checks that if interceptor doesn't provide | |
12593 // a value, we can fetch regular value. | |
12594 THREADED_TEST(InterceptorCallICSeesOthers) { | |
12595 v8::Isolate* isolate = CcTest::isolate(); | |
12596 v8::HandleScope scope(isolate); | |
12597 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12598 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
12599 LocalContext context; | |
12600 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12601 v8::Handle<Value> value = CompileRun( | |
12602 "o.x = function f(x) { return x + 1; };" | |
12603 "var result = 0;" | |
12604 "for (var i = 0; i < 7; i++) {" | |
12605 " result = o.x(41);" | |
12606 "}"); | |
12607 CHECK_EQ(42, value->Int32Value()); | |
12608 } | |
12609 | |
12610 | |
12611 static v8::Handle<Value> call_ic_function4; | |
12612 static void InterceptorCallICGetter4( | |
12613 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12614 ApiTestFuzzer::Fuzz(); | |
12615 CHECK(v8_str("x")->Equals(name)); | |
12616 info.GetReturnValue().Set(call_ic_function4); | |
12617 } | |
12618 | |
12619 | |
12620 // This test checks that if interceptor provides a function, | |
12621 // even if we cached shadowed variant, interceptor's function | |
12622 // is invoked | |
12623 THREADED_TEST(InterceptorCallICCacheableNotNeeded) { | |
12624 v8::Isolate* isolate = CcTest::isolate(); | |
12625 v8::HandleScope scope(isolate); | |
12626 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12627 templ->SetHandler( | |
12628 v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter4)); | |
12629 LocalContext context; | |
12630 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12631 call_ic_function4 = | |
12632 v8_compile("function f(x) { return x - 1; }; f")->Run(); | |
12633 v8::Handle<Value> value = CompileRun( | |
12634 "Object.getPrototypeOf(o).x = function(x) { return x + 1; };" | |
12635 "var result = 0;" | |
12636 "for (var i = 0; i < 1000; i++) {" | |
12637 " result = o.x(42);" | |
12638 "}"); | |
12639 CHECK_EQ(41, value->Int32Value()); | |
12640 } | |
12641 | |
12642 | |
12643 // Test the case when we stored cacheable lookup into | |
12644 // a stub, but it got invalidated later on | |
12645 THREADED_TEST(InterceptorCallICInvalidatedCacheable) { | |
12646 v8::Isolate* isolate = CcTest::isolate(); | |
12647 v8::HandleScope scope(isolate); | |
12648 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12649 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
12650 LocalContext context; | |
12651 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12652 v8::Handle<Value> value = CompileRun( | |
12653 "proto1 = new Object();" | |
12654 "proto2 = new Object();" | |
12655 "o.__proto__ = proto1;" | |
12656 "proto1.__proto__ = proto2;" | |
12657 "proto2.y = function(x) { return x + 1; };" | |
12658 // Invoke it many times to compile a stub | |
12659 "for (var i = 0; i < 7; i++) {" | |
12660 " o.y(42);" | |
12661 "}" | |
12662 "proto1.y = function(x) { return x - 1; };" | |
12663 "var result = 0;" | |
12664 "for (var i = 0; i < 7; i++) {" | |
12665 " result += o.y(42);" | |
12666 "}"); | |
12667 CHECK_EQ(41 * 7, value->Int32Value()); | |
12668 } | |
12669 | |
12670 | |
12671 // This test checks that if interceptor doesn't provide a function, | |
12672 // cached constant function is used | |
12673 THREADED_TEST(InterceptorCallICConstantFunctionUsed) { | |
12674 v8::Isolate* isolate = CcTest::isolate(); | |
12675 v8::HandleScope scope(isolate); | |
12676 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12677 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
12678 LocalContext context; | |
12679 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12680 v8::Handle<Value> value = CompileRun( | |
12681 "function inc(x) { return x + 1; };" | |
12682 "inc(1);" | |
12683 "o.x = inc;" | |
12684 "var result = 0;" | |
12685 "for (var i = 0; i < 1000; i++) {" | |
12686 " result = o.x(42);" | |
12687 "}"); | |
12688 CHECK_EQ(43, value->Int32Value()); | |
12689 } | |
12690 | |
12691 | |
12692 static v8::Handle<Value> call_ic_function5; | |
12693 static void InterceptorCallICGetter5( | |
12694 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12695 ApiTestFuzzer::Fuzz(); | |
12696 if (v8_str("x")->Equals(name)) | |
12697 info.GetReturnValue().Set(call_ic_function5); | |
12698 } | |
12699 | |
12700 | |
12701 // This test checks that if interceptor provides a function, | |
12702 // even if we cached constant function, interceptor's function | |
12703 // is invoked | |
12704 THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { | |
12705 v8::Isolate* isolate = CcTest::isolate(); | |
12706 v8::HandleScope scope(isolate); | |
12707 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12708 templ->SetHandler( | |
12709 v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter5)); | |
12710 LocalContext context; | |
12711 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12712 call_ic_function5 = | |
12713 v8_compile("function f(x) { return x - 1; }; f")->Run(); | |
12714 v8::Handle<Value> value = CompileRun( | |
12715 "function inc(x) { return x + 1; };" | |
12716 "inc(1);" | |
12717 "o.x = inc;" | |
12718 "var result = 0;" | |
12719 "for (var i = 0; i < 1000; i++) {" | |
12720 " result = o.x(42);" | |
12721 "}"); | |
12722 CHECK_EQ(41, value->Int32Value()); | |
12723 } | |
12724 | |
12725 | |
12726 static v8::Handle<Value> call_ic_function6; | |
12727 static void InterceptorCallICGetter6( | |
12728 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
12729 ApiTestFuzzer::Fuzz(); | |
12730 if (v8_str("x")->Equals(name)) | |
12731 info.GetReturnValue().Set(call_ic_function6); | |
12732 } | |
12733 | |
12734 | |
12735 // Same test as above, except the code is wrapped in a function | |
12736 // to test the optimized compiler. | |
12737 THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { | |
12738 i::FLAG_allow_natives_syntax = true; | |
12739 v8::Isolate* isolate = CcTest::isolate(); | |
12740 v8::HandleScope scope(isolate); | |
12741 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12742 templ->SetHandler( | |
12743 v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter6)); | |
12744 LocalContext context; | |
12745 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12746 call_ic_function6 = | |
12747 v8_compile("function f(x) { return x - 1; }; f")->Run(); | |
12748 v8::Handle<Value> value = CompileRun( | |
12749 "function inc(x) { return x + 1; };" | |
12750 "inc(1);" | |
12751 "o.x = inc;" | |
12752 "function test() {" | |
12753 " var result = 0;" | |
12754 " for (var i = 0; i < 1000; i++) {" | |
12755 " result = o.x(42);" | |
12756 " }" | |
12757 " return result;" | |
12758 "};" | |
12759 "test();" | |
12760 "test();" | |
12761 "test();" | |
12762 "%OptimizeFunctionOnNextCall(test);" | |
12763 "test()"); | |
12764 CHECK_EQ(41, value->Int32Value()); | |
12765 } | |
12766 | |
12767 | |
12768 // Test the case when we stored constant function into | |
12769 // a stub, but it got invalidated later on | |
12770 THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { | |
12771 v8::Isolate* isolate = CcTest::isolate(); | |
12772 v8::HandleScope scope(isolate); | |
12773 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12774 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
12775 LocalContext context; | |
12776 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12777 v8::Handle<Value> value = CompileRun( | |
12778 "function inc(x) { return x + 1; };" | |
12779 "inc(1);" | |
12780 "proto1 = new Object();" | |
12781 "proto2 = new Object();" | |
12782 "o.__proto__ = proto1;" | |
12783 "proto1.__proto__ = proto2;" | |
12784 "proto2.y = inc;" | |
12785 // Invoke it many times to compile a stub | |
12786 "for (var i = 0; i < 7; i++) {" | |
12787 " o.y(42);" | |
12788 "}" | |
12789 "proto1.y = function(x) { return x - 1; };" | |
12790 "var result = 0;" | |
12791 "for (var i = 0; i < 7; i++) {" | |
12792 " result += o.y(42);" | |
12793 "}"); | |
12794 CHECK_EQ(41 * 7, value->Int32Value()); | |
12795 } | |
12796 | |
12797 | |
12798 // Test the case when we stored constant function into | |
12799 // a stub, but it got invalidated later on due to override on | |
12800 // global object which is between interceptor and constant function' holders. | |
12801 THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { | |
12802 v8::Isolate* isolate = CcTest::isolate(); | |
12803 v8::HandleScope scope(isolate); | |
12804 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
12805 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
12806 LocalContext context; | |
12807 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
12808 v8::Handle<Value> value = CompileRun( | |
12809 "function inc(x) { return x + 1; };" | |
12810 "inc(1);" | |
12811 "o.__proto__ = this;" | |
12812 "this.__proto__.y = inc;" | |
12813 // Invoke it many times to compile a stub | |
12814 "for (var i = 0; i < 7; i++) {" | |
12815 " if (o.y(42) != 43) throw 'oops: ' + o.y(42);" | |
12816 "}" | |
12817 "this.y = function(x) { return x - 1; };" | |
12818 "var result = 0;" | |
12819 "for (var i = 0; i < 7; i++) {" | |
12820 " result += o.y(42);" | |
12821 "}"); | |
12822 CHECK_EQ(41 * 7, value->Int32Value()); | |
12823 } | |
12824 | |
12825 | |
12826 // Test the case when actual function to call sits on global object. | |
12827 THREADED_TEST(InterceptorCallICCachedFromGlobal) { | |
12828 v8::Isolate* isolate = CcTest::isolate(); | |
12829 v8::HandleScope scope(isolate); | |
12830 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
12831 templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
12832 | |
12833 LocalContext context; | |
12834 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
12835 | |
12836 v8::Handle<Value> value = CompileRun( | |
12837 "try {" | |
12838 " o.__proto__ = this;" | |
12839 " for (var i = 0; i < 10; i++) {" | |
12840 " var v = o.parseFloat('239');" | |
12841 " if (v != 239) throw v;" | |
12842 // Now it should be ICed and keep a reference to parseFloat. | |
12843 " }" | |
12844 " var result = 0;" | |
12845 " for (var i = 0; i < 10; i++) {" | |
12846 " result += o.parseFloat('239');" | |
12847 " }" | |
12848 " result" | |
12849 "} catch(e) {" | |
12850 " e" | |
12851 "};"); | |
12852 CHECK_EQ(239 * 10, value->Int32Value()); | |
12853 } | |
12854 | |
12855 static void InterceptorCallICFastApi( | 10333 static void InterceptorCallICFastApi( |
12856 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | 10334 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
12857 ApiTestFuzzer::Fuzz(); | 10335 ApiTestFuzzer::Fuzz(); |
12858 CheckReturnValue(info, FUNCTION_ADDR(InterceptorCallICFastApi)); | 10336 CheckReturnValue(info, FUNCTION_ADDR(InterceptorCallICFastApi)); |
12859 int* call_count = | 10337 int* call_count = |
12860 reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value()); | 10338 reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value()); |
12861 ++(*call_count); | 10339 ++(*call_count); |
12862 if ((*call_count) % 20 == 0) { | 10340 if ((*call_count) % 20 == 0) { |
12863 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 10341 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
12864 } | 10342 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12956 "function f() {" | 10434 "function f() {" |
12957 " for (var i = 1; i <= 5; i++) {" | 10435 " for (var i = 1; i <= 5; i++) {" |
12958 " try { nativeobject.callback(); } catch (e) { result += e; }" | 10436 " try { nativeobject.callback(); } catch (e) { result += e; }" |
12959 " }" | 10437 " }" |
12960 "}" | 10438 "}" |
12961 "f(); result;"); | 10439 "f(); result;"); |
12962 CHECK(v8_str("ggggg")->Equals(result)); | 10440 CHECK(v8_str("ggggg")->Equals(result)); |
12963 } | 10441 } |
12964 | 10442 |
12965 | 10443 |
| 10444 static int p_getter_count_3; |
| 10445 |
| 10446 |
12966 static Handle<Value> DoDirectGetter() { | 10447 static Handle<Value> DoDirectGetter() { |
12967 if (++p_getter_count % 3 == 0) { | 10448 if (++p_getter_count_3 % 3 == 0) { |
12968 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 10449 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
12969 GenerateSomeGarbage(); | 10450 GenerateSomeGarbage(); |
12970 } | 10451 } |
12971 return v8_str("Direct Getter Result"); | 10452 return v8_str("Direct Getter Result"); |
12972 } | 10453 } |
12973 | 10454 |
| 10455 |
12974 static void DirectGetterCallback( | 10456 static void DirectGetterCallback( |
12975 Local<String> name, | 10457 Local<String> name, |
12976 const v8::PropertyCallbackInfo<v8::Value>& info) { | 10458 const v8::PropertyCallbackInfo<v8::Value>& info) { |
12977 CheckReturnValue(info, FUNCTION_ADDR(DirectGetterCallback)); | 10459 CheckReturnValue(info, FUNCTION_ADDR(DirectGetterCallback)); |
12978 info.GetReturnValue().Set(DoDirectGetter()); | 10460 info.GetReturnValue().Set(DoDirectGetter()); |
12979 } | 10461 } |
12980 | 10462 |
12981 | 10463 |
12982 template<typename Accessor> | 10464 template<typename Accessor> |
12983 static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) { | 10465 static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) { |
12984 LocalContext context; | 10466 LocalContext context; |
12985 v8::Isolate* isolate = context->GetIsolate(); | 10467 v8::Isolate* isolate = context->GetIsolate(); |
12986 v8::HandleScope scope(isolate); | 10468 v8::HandleScope scope(isolate); |
12987 v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); | 10469 v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); |
12988 obj->SetAccessor(v8_str("p1"), accessor); | 10470 obj->SetAccessor(v8_str("p1"), accessor); |
12989 context->Global()->Set(v8_str("o1"), obj->NewInstance()); | 10471 context->Global()->Set(v8_str("o1"), obj->NewInstance()); |
12990 p_getter_count = 0; | 10472 p_getter_count_3 = 0; |
12991 v8::Handle<v8::Value> result = CompileRun( | 10473 v8::Handle<v8::Value> result = CompileRun( |
12992 "function f() {" | 10474 "function f() {" |
12993 " for (var i = 0; i < 30; i++) o1.p1;" | 10475 " for (var i = 0; i < 30; i++) o1.p1;" |
12994 " return o1.p1" | 10476 " return o1.p1" |
12995 "}" | 10477 "}" |
12996 "f();"); | 10478 "f();"); |
12997 CHECK(v8_str("Direct Getter Result")->Equals(result)); | 10479 CHECK(v8_str("Direct Getter Result")->Equals(result)); |
12998 CHECK_EQ(31, p_getter_count); | 10480 CHECK_EQ(31, p_getter_count_3); |
12999 } | 10481 } |
13000 | 10482 |
13001 | 10483 |
13002 THREADED_PROFILED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { | 10484 THREADED_PROFILED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { |
13003 LoadICFastApi_DirectCall_GCMoveStub(DirectGetterCallback); | 10485 LoadICFastApi_DirectCall_GCMoveStub(DirectGetterCallback); |
13004 } | 10486 } |
13005 | 10487 |
13006 | 10488 |
13007 void ThrowingDirectGetterCallback( | 10489 void ThrowingDirectGetterCallback( |
13008 Local<String> name, | 10490 Local<String> name, |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13418 " receiver = Object.create(receiver);" | 10900 " receiver = Object.create(receiver);" |
13419 " }" | 10901 " }" |
13420 "}"); | 10902 "}"); |
13421 CHECK(try_catch.HasCaught()); | 10903 CHECK(try_catch.HasCaught()); |
13422 CHECK(v8_str("TypeError: Illegal invocation") | 10904 CHECK(v8_str("TypeError: Illegal invocation") |
13423 ->Equals(try_catch.Exception()->ToString(isolate))); | 10905 ->Equals(try_catch.Exception()->ToString(isolate))); |
13424 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | 10906 CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
13425 } | 10907 } |
13426 | 10908 |
13427 | 10909 |
13428 v8::Handle<Value> keyed_call_ic_function; | |
13429 | |
13430 static void InterceptorKeyedCallICGetter( | |
13431 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
13432 ApiTestFuzzer::Fuzz(); | |
13433 if (v8_str("x")->Equals(name)) { | |
13434 info.GetReturnValue().Set(keyed_call_ic_function); | |
13435 } | |
13436 } | |
13437 | |
13438 | |
13439 // Test the case when we stored cacheable lookup into | |
13440 // a stub, but the function name changed (to another cacheable function). | |
13441 THREADED_TEST(InterceptorKeyedCallICKeyChange1) { | |
13442 v8::Isolate* isolate = CcTest::isolate(); | |
13443 v8::HandleScope scope(isolate); | |
13444 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13445 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
13446 LocalContext context; | |
13447 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
13448 CompileRun( | |
13449 "proto = new Object();" | |
13450 "proto.y = function(x) { return x + 1; };" | |
13451 "proto.z = function(x) { return x - 1; };" | |
13452 "o.__proto__ = proto;" | |
13453 "var result = 0;" | |
13454 "var method = 'y';" | |
13455 "for (var i = 0; i < 10; i++) {" | |
13456 " if (i == 5) { method = 'z'; };" | |
13457 " result += o[method](41);" | |
13458 "}"); | |
13459 CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); | |
13460 } | |
13461 | |
13462 | |
13463 // Test the case when we stored cacheable lookup into | |
13464 // a stub, but the function name changed (and the new function is present | |
13465 // both before and after the interceptor in the prototype chain). | |
13466 THREADED_TEST(InterceptorKeyedCallICKeyChange2) { | |
13467 v8::Isolate* isolate = CcTest::isolate(); | |
13468 v8::HandleScope scope(isolate); | |
13469 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13470 templ->SetHandler( | |
13471 v8::NamedPropertyHandlerConfiguration(InterceptorKeyedCallICGetter)); | |
13472 LocalContext context; | |
13473 context->Global()->Set(v8_str("proto1"), templ->NewInstance()); | |
13474 keyed_call_ic_function = | |
13475 v8_compile("function f(x) { return x - 1; }; f")->Run(); | |
13476 CompileRun( | |
13477 "o = new Object();" | |
13478 "proto2 = new Object();" | |
13479 "o.y = function(x) { return x + 1; };" | |
13480 "proto2.y = function(x) { return x + 2; };" | |
13481 "o.__proto__ = proto1;" | |
13482 "proto1.__proto__ = proto2;" | |
13483 "var result = 0;" | |
13484 "var method = 'x';" | |
13485 "for (var i = 0; i < 10; i++) {" | |
13486 " if (i == 5) { method = 'y'; };" | |
13487 " result += o[method](41);" | |
13488 "}"); | |
13489 CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); | |
13490 } | |
13491 | |
13492 | |
13493 // Same as InterceptorKeyedCallICKeyChange1 only the cacheable function sit | |
13494 // on the global object. | |
13495 THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { | |
13496 v8::Isolate* isolate = CcTest::isolate(); | |
13497 v8::HandleScope scope(isolate); | |
13498 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13499 templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
13500 LocalContext context; | |
13501 context->Global()->Set(v8_str("o"), templ->NewInstance()); | |
13502 CompileRun( | |
13503 "function inc(x) { return x + 1; };" | |
13504 "inc(1);" | |
13505 "function dec(x) { return x - 1; };" | |
13506 "dec(1);" | |
13507 "o.__proto__ = this;" | |
13508 "this.__proto__.x = inc;" | |
13509 "this.__proto__.y = dec;" | |
13510 "var result = 0;" | |
13511 "var method = 'x';" | |
13512 "for (var i = 0; i < 10; i++) {" | |
13513 " if (i == 5) { method = 'y'; };" | |
13514 " result += o[method](41);" | |
13515 "}"); | |
13516 CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); | |
13517 } | |
13518 | |
13519 | |
13520 // Test the case when actual function to call sits on global object. | |
13521 THREADED_TEST(InterceptorKeyedCallICFromGlobal) { | |
13522 v8::Isolate* isolate = CcTest::isolate(); | |
13523 v8::HandleScope scope(isolate); | |
13524 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
13525 templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
13526 LocalContext context; | |
13527 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
13528 | |
13529 CompileRun( | |
13530 "function len(x) { return x.length; };" | |
13531 "o.__proto__ = this;" | |
13532 "var m = 'parseFloat';" | |
13533 "var result = 0;" | |
13534 "for (var i = 0; i < 10; i++) {" | |
13535 " if (i == 5) {" | |
13536 " m = 'len';" | |
13537 " saved_result = result;" | |
13538 " };" | |
13539 " result = o[m]('239');" | |
13540 "}"); | |
13541 CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value()); | |
13542 CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value()); | |
13543 } | |
13544 | |
13545 | |
13546 // Test the map transition before the interceptor. | |
13547 THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { | |
13548 v8::Isolate* isolate = CcTest::isolate(); | |
13549 v8::HandleScope scope(isolate); | |
13550 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
13551 templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
13552 LocalContext context; | |
13553 context->Global()->Set(v8_str("proto"), templ_o->NewInstance()); | |
13554 | |
13555 CompileRun( | |
13556 "var o = new Object();" | |
13557 "o.__proto__ = proto;" | |
13558 "o.method = function(x) { return x + 1; };" | |
13559 "var m = 'method';" | |
13560 "var result = 0;" | |
13561 "for (var i = 0; i < 10; i++) {" | |
13562 " if (i == 5) { o.method = function(x) { return x - 1; }; };" | |
13563 " result += o[m](41);" | |
13564 "}"); | |
13565 CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); | |
13566 } | |
13567 | |
13568 | |
13569 // Test the map transition after the interceptor. | |
13570 THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) { | |
13571 v8::Isolate* isolate = CcTest::isolate(); | |
13572 v8::HandleScope scope(isolate); | |
13573 v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); | |
13574 templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); | |
13575 LocalContext context; | |
13576 context->Global()->Set(v8_str("o"), templ_o->NewInstance()); | |
13577 | |
13578 CompileRun( | |
13579 "var proto = new Object();" | |
13580 "o.__proto__ = proto;" | |
13581 "proto.method = function(x) { return x + 1; };" | |
13582 "var m = 'method';" | |
13583 "var result = 0;" | |
13584 "for (var i = 0; i < 10; i++) {" | |
13585 " if (i == 5) { proto.method = function(x) { return x - 1; }; };" | |
13586 " result += o[m](41);" | |
13587 "}"); | |
13588 CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); | |
13589 } | |
13590 | |
13591 | |
13592 static int interceptor_call_count = 0; | |
13593 | |
13594 static void InterceptorICRefErrorGetter( | |
13595 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
13596 ApiTestFuzzer::Fuzz(); | |
13597 if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) { | |
13598 info.GetReturnValue().Set(call_ic_function2); | |
13599 } | |
13600 } | |
13601 | |
13602 | |
13603 // This test should hit load and call ICs for the interceptor case. | |
13604 // Once in a while, the interceptor will reply that a property was not | |
13605 // found in which case we should get a reference error. | |
13606 THREADED_TEST(InterceptorICReferenceErrors) { | |
13607 v8::Isolate* isolate = CcTest::isolate(); | |
13608 v8::HandleScope scope(isolate); | |
13609 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13610 templ->SetHandler( | |
13611 v8::NamedPropertyHandlerConfiguration(InterceptorICRefErrorGetter)); | |
13612 LocalContext context(0, templ, v8::Handle<Value>()); | |
13613 call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run(); | |
13614 v8::Handle<Value> value = CompileRun( | |
13615 "function f() {" | |
13616 " for (var i = 0; i < 1000; i++) {" | |
13617 " try { x; } catch(e) { return true; }" | |
13618 " }" | |
13619 " return false;" | |
13620 "};" | |
13621 "f();"); | |
13622 CHECK_EQ(true, value->BooleanValue()); | |
13623 interceptor_call_count = 0; | |
13624 value = CompileRun( | |
13625 "function g() {" | |
13626 " for (var i = 0; i < 1000; i++) {" | |
13627 " try { x(42); } catch(e) { return true; }" | |
13628 " }" | |
13629 " return false;" | |
13630 "};" | |
13631 "g();"); | |
13632 CHECK_EQ(true, value->BooleanValue()); | |
13633 } | |
13634 | |
13635 | |
13636 static int interceptor_ic_exception_get_count = 0; | |
13637 | |
13638 static void InterceptorICExceptionGetter( | |
13639 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
13640 ApiTestFuzzer::Fuzz(); | |
13641 if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) { | |
13642 info.GetReturnValue().Set(call_ic_function3); | |
13643 } | |
13644 if (interceptor_ic_exception_get_count == 20) { | |
13645 info.GetIsolate()->ThrowException(v8_num(42)); | |
13646 return; | |
13647 } | |
13648 } | |
13649 | |
13650 | |
13651 // Test interceptor load/call IC where the interceptor throws an | |
13652 // exception once in a while. | |
13653 THREADED_TEST(InterceptorICGetterExceptions) { | |
13654 interceptor_ic_exception_get_count = 0; | |
13655 v8::Isolate* isolate = CcTest::isolate(); | |
13656 v8::HandleScope scope(isolate); | |
13657 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13658 templ->SetHandler( | |
13659 v8::NamedPropertyHandlerConfiguration(InterceptorICExceptionGetter)); | |
13660 LocalContext context(0, templ, v8::Handle<Value>()); | |
13661 call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run(); | |
13662 v8::Handle<Value> value = CompileRun( | |
13663 "function f() {" | |
13664 " for (var i = 0; i < 100; i++) {" | |
13665 " try { x; } catch(e) { return true; }" | |
13666 " }" | |
13667 " return false;" | |
13668 "};" | |
13669 "f();"); | |
13670 CHECK_EQ(true, value->BooleanValue()); | |
13671 interceptor_ic_exception_get_count = 0; | |
13672 value = CompileRun( | |
13673 "function f() {" | |
13674 " for (var i = 0; i < 100; i++) {" | |
13675 " try { x(42); } catch(e) { return true; }" | |
13676 " }" | |
13677 " return false;" | |
13678 "};" | |
13679 "f();"); | |
13680 CHECK_EQ(true, value->BooleanValue()); | |
13681 } | |
13682 | |
13683 | |
13684 static int interceptor_ic_exception_set_count = 0; | |
13685 | |
13686 static void InterceptorICExceptionSetter( | |
13687 Local<Name> key, Local<Value> value, | |
13688 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
13689 ApiTestFuzzer::Fuzz(); | |
13690 if (++interceptor_ic_exception_set_count > 20) { | |
13691 info.GetIsolate()->ThrowException(v8_num(42)); | |
13692 } | |
13693 } | |
13694 | |
13695 | |
13696 // Test interceptor store IC where the interceptor throws an exception | |
13697 // once in a while. | |
13698 THREADED_TEST(InterceptorICSetterExceptions) { | |
13699 interceptor_ic_exception_set_count = 0; | |
13700 v8::Isolate* isolate = CcTest::isolate(); | |
13701 v8::HandleScope scope(isolate); | |
13702 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13703 templ->SetHandler( | |
13704 v8::NamedPropertyHandlerConfiguration(0, InterceptorICExceptionSetter)); | |
13705 LocalContext context(0, templ, v8::Handle<Value>()); | |
13706 v8::Handle<Value> value = CompileRun( | |
13707 "function f() {" | |
13708 " for (var i = 0; i < 100; i++) {" | |
13709 " try { x = 42; } catch(e) { return true; }" | |
13710 " }" | |
13711 " return false;" | |
13712 "};" | |
13713 "f();"); | |
13714 CHECK_EQ(true, value->BooleanValue()); | |
13715 } | |
13716 | |
13717 | |
13718 // Test that we ignore null interceptors. | |
13719 THREADED_TEST(NullNamedInterceptor) { | |
13720 v8::Isolate* isolate = CcTest::isolate(); | |
13721 v8::HandleScope scope(isolate); | |
13722 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13723 templ->SetHandler(v8::NamedPropertyHandlerConfiguration( | |
13724 static_cast<v8::GenericNamedPropertyGetterCallback>(0))); | |
13725 LocalContext context; | |
13726 templ->Set(CcTest::isolate(), "x", v8_num(42)); | |
13727 v8::Handle<v8::Object> obj = templ->NewInstance(); | |
13728 context->Global()->Set(v8_str("obj"), obj); | |
13729 v8::Handle<Value> value = CompileRun("obj.x"); | |
13730 CHECK(value->IsInt32()); | |
13731 CHECK_EQ(42, value->Int32Value()); | |
13732 } | |
13733 | |
13734 | |
13735 // Test that we ignore null interceptors. | |
13736 THREADED_TEST(NullIndexedInterceptor) { | |
13737 v8::Isolate* isolate = CcTest::isolate(); | |
13738 v8::HandleScope scope(isolate); | |
13739 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
13740 templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( | |
13741 static_cast<v8::IndexedPropertyGetterCallback>(0))); | |
13742 LocalContext context; | |
13743 templ->Set(CcTest::isolate(), "42", v8_num(42)); | |
13744 v8::Handle<v8::Object> obj = templ->NewInstance(); | |
13745 context->Global()->Set(v8_str("obj"), obj); | |
13746 v8::Handle<Value> value = CompileRun("obj[42]"); | |
13747 CHECK(value->IsInt32()); | |
13748 CHECK_EQ(42, value->Int32Value()); | |
13749 } | |
13750 | |
13751 | |
13752 THREADED_TEST(NamedPropertyHandlerGetterAttributes) { | |
13753 v8::Isolate* isolate = CcTest::isolate(); | |
13754 v8::HandleScope scope(isolate); | |
13755 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | |
13756 templ->InstanceTemplate()->SetHandler( | |
13757 v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); | |
13758 LocalContext env; | |
13759 env->Global()->Set(v8_str("obj"), | |
13760 templ->GetFunction()->NewInstance()); | |
13761 ExpectTrue("obj.x === 42"); | |
13762 ExpectTrue("!obj.propertyIsEnumerable('x')"); | |
13763 } | |
13764 | |
13765 | |
13766 static void ThrowingGetter(Local<String> name, | 10910 static void ThrowingGetter(Local<String> name, |
13767 const v8::PropertyCallbackInfo<v8::Value>& info) { | 10911 const v8::PropertyCallbackInfo<v8::Value>& info) { |
13768 ApiTestFuzzer::Fuzz(); | 10912 ApiTestFuzzer::Fuzz(); |
13769 info.GetIsolate()->ThrowException(Handle<Value>()); | 10913 info.GetIsolate()->ThrowException(Handle<Value>()); |
13770 info.GetReturnValue().SetUndefined(); | 10914 info.GetReturnValue().SetUndefined(); |
13771 } | 10915 } |
13772 | 10916 |
13773 | 10917 |
13774 THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) { | 10918 THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) { |
13775 LocalContext context; | 10919 LocalContext context; |
(...skipping 7848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21624 | 18768 |
21625 Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); | 18769 Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); |
21626 CHECK(result5->Equals( | 18770 CHECK(result5->Equals( |
21627 object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype())); | 18771 object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype())); |
21628 | 18772 |
21629 Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); | 18773 Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); |
21630 CHECK(result6.IsEmpty()); | 18774 CHECK(result6.IsEmpty()); |
21631 } | 18775 } |
21632 | 18776 |
21633 | 18777 |
21634 THREADED_TEST(Regress125988) { | |
21635 v8::HandleScope scope(CcTest::isolate()); | |
21636 Handle<FunctionTemplate> intercept = FunctionTemplate::New(CcTest::isolate()); | |
21637 AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
21638 LocalContext env; | |
21639 env->Global()->Set(v8_str("Intercept"), intercept->GetFunction()); | |
21640 CompileRun("var a = new Object();" | |
21641 "var b = new Intercept();" | |
21642 "var c = new Object();" | |
21643 "c.__proto__ = b;" | |
21644 "b.__proto__ = a;" | |
21645 "a.x = 23;" | |
21646 "for (var i = 0; i < 3; i++) c.x;"); | |
21647 ExpectBoolean("c.hasOwnProperty('x')", false); | |
21648 ExpectInt32("c.x", 23); | |
21649 CompileRun("a.y = 42;" | |
21650 "for (var i = 0; i < 3; i++) c.x;"); | |
21651 ExpectBoolean("c.hasOwnProperty('x')", false); | |
21652 ExpectInt32("c.x", 23); | |
21653 ExpectBoolean("c.hasOwnProperty('y')", false); | |
21654 ExpectInt32("c.y", 42); | |
21655 } | |
21656 | |
21657 | |
21658 static void TestReceiver(Local<Value> expected_result, | 18778 static void TestReceiver(Local<Value> expected_result, |
21659 Local<Value> expected_receiver, | 18779 Local<Value> expected_receiver, |
21660 const char* code) { | 18780 const char* code) { |
21661 Local<Value> result = CompileRun(code); | 18781 Local<Value> result = CompileRun(code); |
21662 CHECK(result->IsObject()); | 18782 CHECK(result->IsObject()); |
21663 CHECK(expected_receiver->Equals(result.As<v8::Object>()->Get(1))); | 18783 CHECK(expected_receiver->Equals(result.As<v8::Object>()->Get(1))); |
21664 CHECK(expected_result->Equals(result.As<v8::Object>()->Get(0))); | 18784 CHECK(expected_result->Equals(result.As<v8::Object>()->Get(0))); |
21665 } | 18785 } |
21666 | 18786 |
21667 | 18787 |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22335 CheckInstanceCheckedAccessors(true); | 19455 CheckInstanceCheckedAccessors(true); |
22336 | 19456 |
22337 printf("Testing negative ...\n"); | 19457 printf("Testing negative ...\n"); |
22338 CompileRun("var obj = {};" | 19458 CompileRun("var obj = {};" |
22339 "obj.__proto__ = new f();"); | 19459 "obj.__proto__ = new f();"); |
22340 CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); | 19460 CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); |
22341 CheckInstanceCheckedAccessors(false); | 19461 CheckInstanceCheckedAccessors(false); |
22342 } | 19462 } |
22343 | 19463 |
22344 | 19464 |
| 19465 static void EmptyInterceptorGetter( |
| 19466 Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) {} |
| 19467 |
| 19468 |
| 19469 static void EmptyInterceptorSetter( |
| 19470 Local<String> name, Local<Value> value, |
| 19471 const v8::PropertyCallbackInfo<v8::Value>& info) {} |
| 19472 |
| 19473 |
22345 THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { | 19474 THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { |
22346 v8::internal::FLAG_allow_natives_syntax = true; | 19475 v8::internal::FLAG_allow_natives_syntax = true; |
22347 LocalContext context; | 19476 LocalContext context; |
22348 v8::HandleScope scope(context->GetIsolate()); | 19477 v8::HandleScope scope(context->GetIsolate()); |
22349 | 19478 |
22350 Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); | 19479 Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); |
22351 Local<ObjectTemplate> inst = templ->InstanceTemplate(); | 19480 Local<ObjectTemplate> inst = templ->InstanceTemplate(); |
22352 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); | 19481 templ->InstanceTemplate()->SetNamedPropertyHandler(EmptyInterceptorGetter, |
| 19482 EmptyInterceptorSetter); |
22353 inst->SetAccessor(v8_str("foo"), | 19483 inst->SetAccessor(v8_str("foo"), |
22354 InstanceCheckedGetter, InstanceCheckedSetter, | 19484 InstanceCheckedGetter, InstanceCheckedSetter, |
22355 Handle<Value>(), | 19485 Handle<Value>(), |
22356 v8::DEFAULT, | 19486 v8::DEFAULT, |
22357 v8::None, | 19487 v8::None, |
22358 v8::AccessorSignature::New(context->GetIsolate(), templ)); | 19488 v8::AccessorSignature::New(context->GetIsolate(), templ)); |
22359 context->Global()->Set(v8_str("f"), templ->GetFunction()); | 19489 context->Global()->Set(v8_str("f"), templ->GetFunction()); |
22360 | 19490 |
22361 printf("Testing positive ...\n"); | 19491 printf("Testing positive ...\n"); |
22362 CompileRun("var obj = new f();"); | 19492 CompileRun("var obj = new f();"); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22617 | 19747 |
22618 // Compile a try-finally clause where the finally block causes a GC | 19748 // Compile a try-finally clause where the finally block causes a GC |
22619 // while there still is a message pending for external reporting. | 19749 // while there still is a message pending for external reporting. |
22620 TryCatch try_catch; | 19750 TryCatch try_catch; |
22621 try_catch.SetVerbose(true); | 19751 try_catch.SetVerbose(true); |
22622 CompileRun("try { throw new Error(); } finally { gc(); }"); | 19752 CompileRun("try { throw new Error(); } finally { gc(); }"); |
22623 CHECK(try_catch.HasCaught()); | 19753 CHECK(try_catch.HasCaught()); |
22624 } | 19754 } |
22625 | 19755 |
22626 | 19756 |
22627 THREADED_TEST(Regress149912) { | |
22628 LocalContext context; | |
22629 v8::HandleScope scope(context->GetIsolate()); | |
22630 Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); | |
22631 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
22632 context->Global()->Set(v8_str("Bug"), templ->GetFunction()); | |
22633 CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();"); | |
22634 } | |
22635 | |
22636 | |
22637 THREADED_TEST(Regress157124) { | 19757 THREADED_TEST(Regress157124) { |
22638 LocalContext context; | 19758 LocalContext context; |
22639 v8::Isolate* isolate = context->GetIsolate(); | 19759 v8::Isolate* isolate = context->GetIsolate(); |
22640 v8::HandleScope scope(isolate); | 19760 v8::HandleScope scope(isolate); |
22641 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 19761 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
22642 Local<Object> obj = templ->NewInstance(); | 19762 Local<Object> obj = templ->NewInstance(); |
22643 obj->GetIdentityHash(); | 19763 obj->GetIdentityHash(); |
22644 obj->DeleteHiddenValue(v8_str("Bug")); | 19764 obj->DeleteHiddenValue(v8_str("Bug")); |
22645 } | 19765 } |
22646 | 19766 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22944 CheckCorrectThrow("%GetOwnPropertyNames(other, 0)"); | 20064 CheckCorrectThrow("%GetOwnPropertyNames(other, 0)"); |
22945 CheckCorrectThrow("%DefineAccessorPropertyUnchecked(" | 20065 CheckCorrectThrow("%DefineAccessorPropertyUnchecked(" |
22946 "other, 'x', null, null, 1)"); | 20066 "other, 'x', null, null, 1)"); |
22947 | 20067 |
22948 // Reset the failed access check callback so it does not influence | 20068 // Reset the failed access check callback so it does not influence |
22949 // the other tests. | 20069 // the other tests. |
22950 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); | 20070 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); |
22951 } | 20071 } |
22952 | 20072 |
22953 | 20073 |
22954 THREADED_TEST(Regress256330) { | |
22955 i::FLAG_allow_natives_syntax = true; | |
22956 LocalContext context; | |
22957 v8::HandleScope scope(context->GetIsolate()); | |
22958 Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); | |
22959 AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
22960 context->Global()->Set(v8_str("Bug"), templ->GetFunction()); | |
22961 CompileRun("\"use strict\"; var o = new Bug;" | |
22962 "function f(o) { o.x = 10; };" | |
22963 "f(o); f(o); f(o);" | |
22964 "%OptimizeFunctionOnNextCall(f);" | |
22965 "f(o);"); | |
22966 ExpectBoolean("%GetOptimizationStatus(f) != 2", true); | |
22967 } | |
22968 | |
22969 | |
22970 THREADED_TEST(CrankshaftInterceptorSetter) { | |
22971 i::FLAG_allow_natives_syntax = true; | |
22972 v8::HandleScope scope(CcTest::isolate()); | |
22973 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
22974 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
22975 LocalContext env; | |
22976 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
22977 CompileRun("var obj = new Obj;" | |
22978 // Initialize fields to avoid transitions later. | |
22979 "obj.age = 0;" | |
22980 "obj.accessor_age = 42;" | |
22981 "function setter(i) { this.accessor_age = i; };" | |
22982 "function getter() { return this.accessor_age; };" | |
22983 "function setAge(i) { obj.age = i; };" | |
22984 "Object.defineProperty(obj, 'age', { get:getter, set:setter });" | |
22985 "setAge(1);" | |
22986 "setAge(2);" | |
22987 "setAge(3);" | |
22988 "%OptimizeFunctionOnNextCall(setAge);" | |
22989 "setAge(4);"); | |
22990 // All stores went through the interceptor. | |
22991 ExpectInt32("obj.interceptor_age", 4); | |
22992 ExpectInt32("obj.accessor_age", 42); | |
22993 } | |
22994 | |
22995 | |
22996 THREADED_TEST(CrankshaftInterceptorGetter) { | |
22997 i::FLAG_allow_natives_syntax = true; | |
22998 v8::HandleScope scope(CcTest::isolate()); | |
22999 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
23000 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
23001 LocalContext env; | |
23002 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
23003 CompileRun("var obj = new Obj;" | |
23004 // Initialize fields to avoid transitions later. | |
23005 "obj.age = 1;" | |
23006 "obj.accessor_age = 42;" | |
23007 "function getter() { return this.accessor_age; };" | |
23008 "function getAge() { return obj.interceptor_age; };" | |
23009 "Object.defineProperty(obj, 'interceptor_age', { get:getter });" | |
23010 "getAge();" | |
23011 "getAge();" | |
23012 "getAge();" | |
23013 "%OptimizeFunctionOnNextCall(getAge);"); | |
23014 // Access through interceptor. | |
23015 ExpectInt32("getAge()", 1); | |
23016 } | |
23017 | |
23018 | |
23019 THREADED_TEST(CrankshaftInterceptorFieldRead) { | |
23020 i::FLAG_allow_natives_syntax = true; | |
23021 v8::HandleScope scope(CcTest::isolate()); | |
23022 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
23023 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
23024 LocalContext env; | |
23025 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
23026 CompileRun("var obj = new Obj;" | |
23027 "obj.__proto__.interceptor_age = 42;" | |
23028 "obj.age = 100;" | |
23029 "function getAge() { return obj.interceptor_age; };"); | |
23030 ExpectInt32("getAge();", 100); | |
23031 ExpectInt32("getAge();", 100); | |
23032 ExpectInt32("getAge();", 100); | |
23033 CompileRun("%OptimizeFunctionOnNextCall(getAge);"); | |
23034 // Access through interceptor. | |
23035 ExpectInt32("getAge();", 100); | |
23036 } | |
23037 | |
23038 | |
23039 THREADED_TEST(CrankshaftInterceptorFieldWrite) { | |
23040 i::FLAG_allow_natives_syntax = true; | |
23041 v8::HandleScope scope(CcTest::isolate()); | |
23042 Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); | |
23043 AddInterceptor(templ, InterceptorGetter, InterceptorSetter); | |
23044 LocalContext env; | |
23045 env->Global()->Set(v8_str("Obj"), templ->GetFunction()); | |
23046 CompileRun("var obj = new Obj;" | |
23047 "obj.age = 100000;" | |
23048 "function setAge(i) { obj.age = i };" | |
23049 "setAge(100);" | |
23050 "setAge(101);" | |
23051 "setAge(102);" | |
23052 "%OptimizeFunctionOnNextCall(setAge);" | |
23053 "setAge(103);"); | |
23054 ExpectInt32("obj.age", 100000); | |
23055 ExpectInt32("obj.interceptor_age", 103); | |
23056 } | |
23057 | |
23058 | |
23059 class RequestInterruptTestBase { | 20074 class RequestInterruptTestBase { |
23060 public: | 20075 public: |
23061 RequestInterruptTestBase() | 20076 RequestInterruptTestBase() |
23062 : env_(), | 20077 : env_(), |
23063 isolate_(env_->GetIsolate()), | 20078 isolate_(env_->GetIsolate()), |
23064 sem_(0), | 20079 sem_(0), |
23065 warmup_(20000), | 20080 warmup_(20000), |
23066 should_continue_(true) { | 20081 should_continue_(true) { |
23067 } | 20082 } |
23068 | 20083 |
(...skipping 1893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
24962 "bar2.js"); | 21977 "bar2.js"); |
24963 } | 21978 } |
24964 | 21979 |
24965 | 21980 |
24966 TEST(StreamingScriptWithSourceMappingURLInTheMiddle) { | 21981 TEST(StreamingScriptWithSourceMappingURLInTheMiddle) { |
24967 const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#", | 21982 const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#", |
24968 " sourceMappingURL=bar2.js\n", "foo();", NULL}; | 21983 " sourceMappingURL=bar2.js\n", "foo();", NULL}; |
24969 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL, | 21984 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL, |
24970 "bar2.js"); | 21985 "bar2.js"); |
24971 } | 21986 } |
OLD | NEW |