Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: test/cctest/test-api.cc

Issue 900033003: split interceptor tests off of test-api (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/test-api.h ('k') | test/cctest/test-api-interceptors.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « test/cctest/test-api.h ('k') | test/cctest/test-api-interceptors.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698