OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 | 1900 |
1901 void EmptyInterceptorGetter(Local<String> name, | 1901 void EmptyInterceptorGetter(Local<String> name, |
1902 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1902 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1903 } | 1903 } |
1904 | 1904 |
1905 void EmptyInterceptorSetter(Local<String> name, | 1905 void EmptyInterceptorSetter(Local<String> name, |
1906 Local<Value> value, | 1906 Local<Value> value, |
1907 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1907 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1908 } | 1908 } |
1909 | 1909 |
| 1910 void EmptyGenericInterceptorGetter(Local<Name> name, |
| 1911 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1912 } |
| 1913 |
| 1914 void EmptyGenericInterceptorSetter(Local<Name> name, |
| 1915 Local<Value> value, |
| 1916 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1917 } |
| 1918 |
1910 void InterceptorGetter(Local<String> name, | 1919 void InterceptorGetter(Local<String> name, |
1911 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1920 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1912 // Intercept names that start with 'interceptor_'. | 1921 // Intercept names that start with 'interceptor_'. |
1913 String::Utf8Value utf8(name); | 1922 String::Utf8Value utf8(name); |
1914 char* name_str = *utf8; | 1923 char* name_str = *utf8; |
1915 char prefix[] = "interceptor_"; | 1924 char prefix[] = "interceptor_"; |
1916 int i; | 1925 int i; |
1917 for (i = 0; name_str[i] && prefix[i]; ++i) { | 1926 for (i = 0; name_str[i] && prefix[i]; ++i) { |
1918 if (name_str[i] != prefix[i]) return; | 1927 if (name_str[i] != prefix[i]) return; |
1919 } | 1928 } |
(...skipping 15 matching lines...) Expand all Loading... |
1935 } | 1944 } |
1936 if (!prefix[i]) return; | 1945 if (!prefix[i]) return; |
1937 | 1946 |
1938 if (value->IsInt32() && value->Int32Value() < 10000) { | 1947 if (value->IsInt32() && value->Int32Value() < 10000) { |
1939 Handle<Object> self = Handle<Object>::Cast(info.This()); | 1948 Handle<Object> self = Handle<Object>::Cast(info.This()); |
1940 self->SetHiddenValue(name, value); | 1949 self->SetHiddenValue(name, value); |
1941 info.GetReturnValue().Set(value); | 1950 info.GetReturnValue().Set(value); |
1942 } | 1951 } |
1943 } | 1952 } |
1944 | 1953 |
| 1954 void GenericInterceptorGetter(Local<Name> generic_name, |
| 1955 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1956 Local<String> str; |
| 1957 if (generic_name->IsSymbol()) { |
| 1958 Local<Value> name = Local<Symbol>::Cast(generic_name)->Name(); |
| 1959 if (name->IsUndefined()) return; |
| 1960 str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name)); |
| 1961 } else { |
| 1962 Local<String> name = Local<String>::Cast(generic_name); |
| 1963 String::Utf8Value utf8(name); |
| 1964 char* name_str = *utf8; |
| 1965 if (*name_str == '_') return; |
| 1966 str = String::Concat(v8_str("_str_"), name); |
| 1967 } |
| 1968 |
| 1969 Handle<Object> self = Handle<Object>::Cast(info.This()); |
| 1970 info.GetReturnValue().Set(self->Get(str)); |
| 1971 } |
| 1972 |
| 1973 void GenericInterceptorSetter(Local<Name> generic_name, |
| 1974 Local<Value> value, |
| 1975 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1976 Local<String> str; |
| 1977 if (generic_name->IsSymbol()) { |
| 1978 Local<Value> name = Local<Symbol>::Cast(generic_name)->Name(); |
| 1979 if (name->IsUndefined()) return; |
| 1980 str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name)); |
| 1981 } else { |
| 1982 Local<String> name = Local<String>::Cast(generic_name); |
| 1983 String::Utf8Value utf8(name); |
| 1984 char* name_str = *utf8; |
| 1985 if (*name_str == '_') return; |
| 1986 str = String::Concat(v8_str("_str_"), name); |
| 1987 } |
| 1988 |
| 1989 Handle<Object> self = Handle<Object>::Cast(info.This()); |
| 1990 self->Set(str, value); |
| 1991 info.GetReturnValue().Set(value); |
| 1992 } |
| 1993 |
1945 void AddAccessor(Handle<FunctionTemplate> templ, | 1994 void AddAccessor(Handle<FunctionTemplate> templ, |
1946 Handle<String> name, | 1995 Handle<String> name, |
1947 v8::AccessorGetterCallback getter, | 1996 v8::AccessorGetterCallback getter, |
1948 v8::AccessorSetterCallback setter) { | 1997 v8::AccessorSetterCallback setter) { |
1949 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); | 1998 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); |
1950 } | 1999 } |
1951 | 2000 |
1952 void AddInterceptor(Handle<FunctionTemplate> templ, | 2001 void AddInterceptor(Handle<FunctionTemplate> templ, |
1953 v8::NamedPropertyGetterCallback getter, | 2002 v8::NamedPropertyGetterCallback getter, |
1954 v8::NamedPropertySetterCallback setter) { | 2003 v8::NamedPropertySetterCallback setter) { |
1955 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); | 2004 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); |
1956 } | 2005 } |
1957 | 2006 |
1958 | 2007 |
1959 void AddAccessor(Handle<FunctionTemplate> templ, | 2008 void AddAccessor(Handle<FunctionTemplate> templ, |
1960 Handle<Name> name, | 2009 Handle<Name> name, |
1961 v8::AccessorNameGetterCallback getter, | 2010 v8::AccessorNameGetterCallback getter, |
1962 v8::AccessorNameSetterCallback setter) { | 2011 v8::AccessorNameSetterCallback setter) { |
1963 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); | 2012 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); |
1964 } | 2013 } |
1965 | 2014 |
| 2015 void AddGenericInterceptor(Handle<FunctionTemplate> templ, |
| 2016 v8::GenericNamedPropertyGetterCallback getter, |
| 2017 v8::GenericNamedPropertySetterCallback setter) { |
| 2018 templ->InstanceTemplate()->SetGenericNamedPropertyHandler(getter, setter); |
| 2019 } |
| 2020 |
1966 | 2021 |
1967 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { | 2022 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { |
1968 v8::HandleScope scope(CcTest::isolate()); | 2023 v8::HandleScope scope(CcTest::isolate()); |
1969 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); | 2024 Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); |
1970 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); | 2025 Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); |
1971 child->Inherit(parent); | 2026 child->Inherit(parent); |
1972 AddAccessor(parent, v8_str("age"), | 2027 AddAccessor(parent, v8_str("age"), |
1973 SimpleAccessorGetter, SimpleAccessorSetter); | 2028 SimpleAccessorGetter, SimpleAccessorSetter); |
1974 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | 2029 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
1975 LocalContext env; | 2030 LocalContext env; |
1976 env->Global()->Set(v8_str("Child"), child->GetFunction()); | 2031 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
1977 CompileRun("var child = new Child;" | 2032 CompileRun("var child = new Child;" |
1978 "child.age = 10;"); | 2033 "child.age = 10;"); |
1979 ExpectBoolean("child.hasOwnProperty('age')", false); | 2034 ExpectBoolean("child.hasOwnProperty('age')", false); |
1980 ExpectInt32("child.age", 10); | 2035 ExpectInt32("child.age", 10); |
1981 ExpectInt32("child.accessor_age", 10); | 2036 ExpectInt32("child.accessor_age", 10); |
1982 } | 2037 } |
1983 | 2038 |
1984 | 2039 |
| 2040 THREADED_TEST(LegacyInterceptorDoesNotSeeSymbols) { |
| 2041 LocalContext env; |
| 2042 v8::Isolate* isolate = CcTest::isolate(); |
| 2043 v8::HandleScope scope(isolate); |
| 2044 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); |
| 2045 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); |
| 2046 v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age")); |
| 2047 |
| 2048 child->Inherit(parent); |
| 2049 AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter); |
| 2050 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 2051 |
| 2052 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 2053 env->Global()->Set(v8_str("age"), age); |
| 2054 CompileRun("var child = new Child;" |
| 2055 "child[age] = 10;"); |
| 2056 ExpectInt32("child[age]", 10); |
| 2057 ExpectBoolean("child.hasOwnProperty('age')", false); |
| 2058 ExpectBoolean("child.hasOwnProperty('accessor_age')", true); |
| 2059 } |
| 2060 |
| 2061 |
| 2062 THREADED_TEST(GenericInterceptorDoesSeeSymbols) { |
| 2063 LocalContext env; |
| 2064 v8::Isolate* isolate = CcTest::isolate(); |
| 2065 v8::HandleScope scope(isolate); |
| 2066 Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); |
| 2067 Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); |
| 2068 v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age")); |
| 2069 v8::Local<v8::Symbol> anon = v8::Symbol::New(isolate); |
| 2070 |
| 2071 child->Inherit(parent); |
| 2072 AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter); |
| 2073 AddGenericInterceptor( |
| 2074 child, GenericInterceptorGetter, GenericInterceptorSetter); |
| 2075 |
| 2076 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 2077 env->Global()->Set(v8_str("age"), age); |
| 2078 env->Global()->Set(v8_str("anon"), anon); |
| 2079 CompileRun("var child = new Child;" |
| 2080 "child[age] = 10;"); |
| 2081 ExpectInt32("child[age]", 10); |
| 2082 ExpectInt32("child._sym_age", 10); |
| 2083 |
| 2084 // Check that it also sees strings. |
| 2085 CompileRun("child.foo = 47"); |
| 2086 ExpectInt32("child.foo", 47); |
| 2087 ExpectInt32("child._str_foo", 47); |
| 2088 |
| 2089 // Check that the interceptor can punt (in this case, on anonymous symbols). |
| 2090 CompileRun("child[anon] = 31337"); |
| 2091 ExpectInt32("child[anon]", 31337); |
| 2092 } |
| 2093 |
| 2094 |
1985 THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { | 2095 THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { |
1986 v8::Isolate* isolate = CcTest::isolate(); | 2096 v8::Isolate* isolate = CcTest::isolate(); |
1987 v8::HandleScope scope(isolate); | 2097 v8::HandleScope scope(isolate); |
1988 LocalContext env; | 2098 LocalContext env; |
1989 v8::Local<v8::Value> res = CompileRun("var a = []; a;"); | 2099 v8::Local<v8::Value> res = CompileRun("var a = []; a;"); |
1990 i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res))); | 2100 i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res))); |
1991 CHECK(a->map()->instance_descriptors()->IsFixedArray()); | 2101 CHECK(a->map()->instance_descriptors()->IsFixedArray()); |
1992 CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); | 2102 CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); |
1993 CompileRun("Object.defineProperty(a, 'length', { writable: false });"); | 2103 CompileRun("Object.defineProperty(a, 'length', { writable: false });"); |
1994 CHECK_EQ(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); | 2104 CHECK_EQ(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); |
(...skipping 20915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22910 desc = x->GetOwnPropertyDescriptor(v8_str("p1")); | 23020 desc = x->GetOwnPropertyDescriptor(v8_str("p1")); |
22911 Local<Function> set = | 23021 Local<Function> set = |
22912 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set"))); | 23022 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set"))); |
22913 Local<Function> get = | 23023 Local<Function> get = |
22914 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get"))); | 23024 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get"))); |
22915 CHECK_EQ(v8_num(13), get->Call(x, 0, NULL)); | 23025 CHECK_EQ(v8_num(13), get->Call(x, 0, NULL)); |
22916 Handle<Value> args[] = { v8_num(14) }; | 23026 Handle<Value> args[] = { v8_num(14) }; |
22917 set->Call(x, 1, args); | 23027 set->Call(x, 1, args); |
22918 CHECK_EQ(v8_num(14), get->Call(x, 0, NULL)); | 23028 CHECK_EQ(v8_num(14), get->Call(x, 0, NULL)); |
22919 } | 23029 } |
OLD | NEW |