| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index 00585bfa45cd5649ad9b6b5d66998eb8531f1edf..c22ca40a8578feaa9fd1abeb1bd76dac37a981a0 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -1828,7 +1828,17 @@ void InterceptorGetter(Local<String> name,
|
| void InterceptorSetter(Local<String> name,
|
| Local<Value> value,
|
| const v8::PropertyCallbackInfo<v8::Value>& info) {
|
| - // Intercept accesses that set certain integer values.
|
| + // Intercept accesses that set certain integer values, for which the name does
|
| + // not start with 'accessor_'.
|
| + String::Utf8Value utf8(name);
|
| + char* name_str = *utf8;
|
| + char prefix[] = "accessor_";
|
| + int i;
|
| + for (i = 0; name_str[i] && prefix[i]; ++i) {
|
| + if (name_str[i] != prefix[i]) break;
|
| + }
|
| + if (!prefix[i]) return;
|
| +
|
| if (value->IsInt32() && value->Int32Value() < 10000) {
|
| Handle<Object> self = info.This();
|
| self->SetHiddenValue(name, value);
|
| @@ -20320,4 +20330,93 @@ THREADED_TEST(Regress256330) {
|
| ExpectBoolean("%GetOptimizationStatus(f) != 2", true);
|
| }
|
|
|
| +
|
| +THREADED_TEST(CrankshaftInterceptorSetter) {
|
| + i::FLAG_allow_natives_syntax = true;
|
| + v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| + Handle<FunctionTemplate> templ = FunctionTemplate::New();
|
| + AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
|
| + LocalContext env;
|
| + env->Global()->Set(v8_str("Obj"), templ->GetFunction());
|
| + CompileRun("var obj = new Obj;"
|
| + // Initialize fields to avoid transitions later.
|
| + "obj.age = 0;"
|
| + "obj.accessor_age = 42;"
|
| + "function setter(i) { this.accessor_age = i; };"
|
| + "function getter() { return this.accessor_age; };"
|
| + "function setAge(i) { obj.age = i; };"
|
| + "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
|
| + "setAge(1);"
|
| + "setAge(2);"
|
| + "setAge(3);"
|
| + "%OptimizeFunctionOnNextCall(setAge);"
|
| + "setAge(4);");
|
| + // All stores went through the interceptor.
|
| + ExpectInt32("obj.interceptor_age", 4);
|
| + ExpectInt32("obj.accessor_age", 42);
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(CrankshaftInterceptorGetter) {
|
| + i::FLAG_allow_natives_syntax = true;
|
| + v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| + Handle<FunctionTemplate> templ = FunctionTemplate::New();
|
| + AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
|
| + LocalContext env;
|
| + env->Global()->Set(v8_str("Obj"), templ->GetFunction());
|
| + CompileRun("var obj = new Obj;"
|
| + // Initialize fields to avoid transitions later.
|
| + "obj.age = 1;"
|
| + "obj.accessor_age = 42;"
|
| + "function getter() { return this.accessor_age; };"
|
| + "function getAge() { return obj.interceptor_age; };"
|
| + "Object.defineProperty(obj, 'interceptor_age', { get:getter });"
|
| + "getAge();"
|
| + "getAge();"
|
| + "getAge();"
|
| + "%OptimizeFunctionOnNextCall(getAge);");
|
| + // Access through interceptor.
|
| + ExpectInt32("getAge()", 1);
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(CrankshaftInterceptorFieldRead) {
|
| + i::FLAG_allow_natives_syntax = true;
|
| + v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| + Handle<FunctionTemplate> templ = FunctionTemplate::New();
|
| + AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
|
| + LocalContext env;
|
| + env->Global()->Set(v8_str("Obj"), templ->GetFunction());
|
| + CompileRun("var obj = new Obj;"
|
| + "obj.__proto__.interceptor_age = 42;"
|
| + "obj.age = 100;"
|
| + "function getAge() { return obj.interceptor_age; };");
|
| + ExpectInt32("getAge();", 100);
|
| + ExpectInt32("getAge();", 100);
|
| + ExpectInt32("getAge();", 100);
|
| + CompileRun("%OptimizeFunctionOnNextCall(getAge);");
|
| + // Access through interceptor.
|
| + ExpectInt32("getAge();", 100);
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(CrankshaftInterceptorFieldWrite) {
|
| + i::FLAG_allow_natives_syntax = true;
|
| + v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| + Handle<FunctionTemplate> templ = FunctionTemplate::New();
|
| + AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
|
| + LocalContext env;
|
| + env->Global()->Set(v8_str("Obj"), templ->GetFunction());
|
| + CompileRun("var obj = new Obj;"
|
| + "obj.age = 100000;"
|
| + "function setAge(i) { obj.age = i };"
|
| + "setAge(100);"
|
| + "setAge(101);"
|
| + "setAge(102);"
|
| + "%OptimizeFunctionOnNextCall(setAge);"
|
| + "setAge(103);");
|
| + ExpectInt32("obj.age", 100000);
|
| + ExpectInt32("obj.interceptor_age", 103);
|
| +}
|
| +
|
| #endif // V8_OS_POSIX
|
|
|