| Index: test/cctest/test-api-accessors.cc
|
| diff --git a/test/cctest/test-api-accessors.cc b/test/cctest/test-api-accessors.cc
|
| index cda16cdbcbce8c27997dbc4b3be0153e9f3ce569..e9773e918df6284be78e0473b585617bd46aa2f1 100644
|
| --- a/test/cctest/test-api-accessors.cc
|
| +++ b/test/cctest/test-api-accessors.cc
|
| @@ -4,9 +4,9 @@
|
|
|
| #include "test/cctest/cctest.h"
|
|
|
| -#include "include/v8.h"
|
| #include "include/v8-experimental.h"
|
| -
|
| +#include "include/v8.h"
|
| +#include "src/api.h"
|
|
|
| namespace i = v8::internal;
|
|
|
| @@ -111,3 +111,139 @@ TEST(FastAccessors) {
|
| "}",
|
| 31415);
|
| }
|
| +
|
| +// The goal is to avoid the callback.
|
| +static void UnreachableCallback(
|
| + const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| + UNREACHABLE();
|
| +}
|
| +
|
| +TEST(CachedAccessor) {
|
| + // Crankshaft support for fast accessors is not implemented; crankshafted
|
| + // code uses the slow accessor which breaks this test's expectations.
|
| + v8::internal::FLAG_always_opt = false;
|
| + LocalContext env;
|
| + v8::Isolate* isolate = env->GetIsolate();
|
| + v8::HandleScope scope(isolate);
|
| +
|
| + // Create 'foo' class, with a hidden property.
|
| + v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate);
|
| +
|
| + v8::Local<v8::Private> priv =
|
| + v8::Private::ForApi(isolate, v8_str("Foo#draft"));
|
| +
|
| + foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache(
|
| + isolate, UnreachableCallback,
|
| + priv, v8::Local<v8::Value>()));
|
| +
|
| + // Create 'obj', instance of 'foo'.
|
| + v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked();
|
| +
|
| + // Install the private property on the instance.
|
| + CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
|
| + v8::Undefined(isolate))
|
| + .FromJust());
|
| +
|
| + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
|
| +
|
| + // Access cached accessor.
|
| + ExpectUndefined("obj.draft");
|
| +
|
| + // Set hidden property.
|
| + CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
|
| + v8_str("Shhh, I'm private!"))
|
| + .FromJust());
|
| +
|
| + ExpectString("obj.draft", "Shhh, I'm private!");
|
| +
|
| + // Stress the accessor to use the IC.
|
| + ExpectString(
|
| + "var result = '';"
|
| + "for (var i = 0; i < 10; ++i) { "
|
| + " result = obj.draft; "
|
| + "} "
|
| + "result; ",
|
| + "Shhh, I'm private!");
|
| +}
|
| +
|
| +TEST(CachedAccessorCrankshaft) {
|
| + i::FLAG_allow_natives_syntax = true;
|
| + // v8::internal::FLAG_always_opt = false;
|
| + LocalContext env;
|
| + v8::Isolate* isolate = env->GetIsolate();
|
| + v8::HandleScope scope(isolate);
|
| +
|
| + // Create 'foo' class, with a hidden property.
|
| + v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate);
|
| + v8::Local<v8::Private> priv =
|
| + v8::Private::ForApi(isolate, v8_str("Foo#draft"));
|
| +
|
| + // Install the private property on the template.
|
| + // foo->SetPrivate(priv, v8::Undefined(isolate));
|
| +
|
| + foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache(
|
| + isolate, UnreachableCallback,
|
| + priv, v8::Local<v8::Value>()));
|
| +
|
| + // Create 'obj', instance of 'foo'.
|
| + v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked();
|
| +
|
| + // Install the private property on the instance.
|
| + CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
|
| + v8::Undefined(isolate))
|
| + .FromJust());
|
| +
|
| + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
|
| +
|
| + // Access surrogate accessor.
|
| + ExpectUndefined("obj.draft");
|
| +
|
| + // Set hidden property.
|
| + CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123))
|
| + .FromJust());
|
| +
|
| + // Test ICs.
|
| + CompileRun(
|
| + "function f() {"
|
| + " var x;"
|
| + " for (var i = 0; i < 100; i++) {"
|
| + " x = obj.draft;"
|
| + " }"
|
| + " return x;"
|
| + "}");
|
| +
|
| + ExpectInt32("f()", 123);
|
| +
|
| + // Reset hidden property.
|
| + CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
|
| + .FromJust());
|
| +
|
| + // Test Crankshaft.
|
| + CompileRun("%OptimizeFunctionOnNextCall(f);");
|
| +
|
| + ExpectInt32("f()", 456);
|
| +
|
| + CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
|
| + .FromJust());
|
| + // Test non-global ICs.
|
| + CompileRun(
|
| + "function g() {"
|
| + " var x = obj;"
|
| + " var r = 0;"
|
| + " for (var i = 0; i < 100; i++) {"
|
| + " r = x.draft;"
|
| + " }"
|
| + " return r;"
|
| + "}");
|
| +
|
| + ExpectInt32("g()", 456);
|
| +
|
| + // Reset hidden property.
|
| + CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789))
|
| + .FromJust());
|
| +
|
| + // Test non-global access in Crankshaft.
|
| + CompileRun("%OptimizeFunctionOnNextCall(g);");
|
| +
|
| + ExpectInt32("g()", 789);
|
| +}
|
|
|