| 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 |