LCOV - code coverage report
Current view: top level - test/cctest - test-api-accessors.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 72 76 94.7 %
Date: 2017-10-20 Functions: 6 8 75.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "test/cctest/cctest.h"
       6             : 
       7             : #include "include/v8.h"
       8             : #include "src/api.h"
       9             : #include "src/objects-inl.h"
      10             : 
      11             : namespace i = v8::internal;
      12             : 
      13             : // The goal is to avoid the callback.
      14           0 : static void UnreachableCallback(
      15             :     const v8::FunctionCallbackInfo<v8::Value>& info) {
      16           0 :   UNREACHABLE();
      17             : }
      18             : 
      19       23724 : TEST(CachedAccessor) {
      20             :   // Crankshaft support for fast accessors is not implemented; crankshafted
      21             :   // code uses the slow accessor which breaks this test's expectations.
      22           6 :   v8::internal::FLAG_always_opt = false;
      23           6 :   LocalContext env;
      24           6 :   v8::Isolate* isolate = env->GetIsolate();
      25          12 :   v8::HandleScope scope(isolate);
      26             : 
      27             :   // Create 'foo' class, with a hidden property.
      28           6 :   v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate);
      29             : 
      30             :   v8::Local<v8::Private> priv =
      31           6 :       v8::Private::ForApi(isolate, v8_str("Foo#draft"));
      32             : 
      33             :   foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache(
      34             :                                                 isolate, UnreachableCallback,
      35          12 :                                                 priv, v8::Local<v8::Value>()));
      36             : 
      37             :   // Create 'obj', instance of 'foo'.
      38           6 :   v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked();
      39             : 
      40             :   // Install the private property on the instance.
      41          12 :   CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
      42             :                         v8::Undefined(isolate))
      43             :             .FromJust());
      44             : 
      45          30 :   CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
      46             : 
      47             :   // Access cached accessor.
      48           6 :   ExpectUndefined("obj.draft");
      49             : 
      50             :   // Set hidden property.
      51          18 :   CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
      52             :                         v8_str("Shhh, I'm private!"))
      53             :             .FromJust());
      54             : 
      55           6 :   ExpectString("obj.draft", "Shhh, I'm private!");
      56             : 
      57             :   // Stress the accessor to use the IC.
      58             :   ExpectString(
      59             :       "var result = '';"
      60             :       "for (var i = 0; i < 10; ++i) { "
      61             :       "  result = obj.draft; "
      62             :       "} "
      63             :       "result; ",
      64          12 :       "Shhh, I'm private!");
      65           6 : }
      66             : 
      67       23724 : TEST(CachedAccessorCrankshaft) {
      68           6 :   i::FLAG_allow_natives_syntax = true;
      69             :   // v8::internal::FLAG_always_opt = false;
      70           6 :   LocalContext env;
      71           6 :   v8::Isolate* isolate = env->GetIsolate();
      72          12 :   v8::HandleScope scope(isolate);
      73             : 
      74             :   // Create 'foo' class, with a hidden property.
      75           6 :   v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate);
      76             :   v8::Local<v8::Private> priv =
      77           6 :       v8::Private::ForApi(isolate, v8_str("Foo#draft"));
      78             : 
      79             :   // Install the private property on the template.
      80             :   // foo->SetPrivate(priv, v8::Undefined(isolate));
      81             : 
      82             :   foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache(
      83             :                                                 isolate, UnreachableCallback,
      84          12 :                                                 priv, v8::Local<v8::Value>()));
      85             : 
      86             :   // Create 'obj', instance of 'foo'.
      87           6 :   v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked();
      88             : 
      89             :   // Install the private property on the instance.
      90          12 :   CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
      91             :                         v8::Undefined(isolate))
      92             :             .FromJust());
      93             : 
      94          30 :   CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust());
      95             : 
      96             :   // Access surrogate accessor.
      97           6 :   ExpectUndefined("obj.draft");
      98             : 
      99             :   // Set hidden property.
     100          18 :   CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123))
     101             :             .FromJust());
     102             : 
     103             :   // Test ICs.
     104             :   CompileRun(
     105             :       "function f() {"
     106             :       "  var x;"
     107             :       "  for (var i = 0; i < 100; i++) {"
     108             :       "    x = obj.draft;"
     109             :       "  }"
     110             :       "  return x;"
     111             :       "}");
     112             : 
     113           6 :   ExpectInt32("f()", 123);
     114             : 
     115             :   // Reset hidden property.
     116          18 :   CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
     117             :             .FromJust());
     118             : 
     119             :   // Test Crankshaft.
     120             :   CompileRun("%OptimizeFunctionOnNextCall(f);");
     121             : 
     122           6 :   ExpectInt32("f()", 456);
     123             : 
     124          18 :   CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
     125             :             .FromJust());
     126             :   // Test non-global ICs.
     127             :   CompileRun(
     128             :       "function g() {"
     129             :       "  var x = obj;"
     130             :       "  var r = 0;"
     131             :       "  for (var i = 0; i < 100; i++) {"
     132             :       "    r = x.draft;"
     133             :       "  }"
     134             :       "  return r;"
     135             :       "}");
     136             : 
     137           6 :   ExpectInt32("g()", 456);
     138             : 
     139             :   // Reset hidden property.
     140          18 :   CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789))
     141             :             .FromJust());
     142             : 
     143             :   // Test non-global access in Crankshaft.
     144             :   CompileRun("%OptimizeFunctionOnNextCall(g);");
     145             : 
     146          12 :   ExpectInt32("g()", 789);
     147           6 : }
     148             : 
     149       23724 : TEST(CachedAccessorOnGlobalObject) {
     150           6 :   i::FLAG_allow_natives_syntax = true;
     151           6 :   LocalContext env;
     152           6 :   v8::Isolate* isolate = env->GetIsolate();
     153          12 :   v8::HandleScope scope(isolate);
     154             : 
     155             :   v8::Local<v8::FunctionTemplate> templ =
     156           6 :       v8::FunctionTemplate::New(CcTest::isolate());
     157           6 :   v8::Local<v8::ObjectTemplate> object_template = templ->InstanceTemplate();
     158             :   v8::Local<v8::Private> priv =
     159           6 :       v8::Private::ForApi(isolate, v8_str("Foo#draft"));
     160             : 
     161             :   object_template->SetAccessorProperty(
     162             :       v8_str("draft"),
     163             :       v8::FunctionTemplate::NewWithCache(isolate, UnreachableCallback, priv,
     164          12 :                                          v8::Local<v8::Value>()));
     165             : 
     166             :   v8::Local<v8::Context> ctx =
     167           6 :       v8::Context::New(CcTest::isolate(), nullptr, object_template);
     168           6 :   v8::Local<v8::Object> obj = ctx->Global();
     169             : 
     170             :   // Install the private property on the instance.
     171          12 :   CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
     172             :                         v8::Undefined(isolate))
     173             :             .FromJust());
     174             : 
     175             :   {
     176             :     v8::Context::Scope context_scope(ctx);
     177             : 
     178             :     // Access surrogate accessor.
     179           6 :     ExpectUndefined("draft");
     180             : 
     181             :     // Set hidden property.
     182          18 :     CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123))
     183             :               .FromJust());
     184             : 
     185             :     // Test ICs.
     186             :     CompileRun(
     187             :         "function f() {"
     188             :         "  var x;"
     189             :         "  for (var i = 0; i < 100; i++) {"
     190             :         "    x = draft;"
     191             :         "  }"
     192             :         "  return x;"
     193             :         "}");
     194             : 
     195           6 :     ExpectInt32("f()", 123);
     196             : 
     197             :     // Reset hidden property.
     198          18 :     CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
     199             :               .FromJust());
     200             : 
     201             :     // Test Crankshaft.
     202             :     CompileRun("%OptimizeFunctionOnNextCall(f);");
     203             : 
     204           6 :     ExpectInt32("f()", 456);
     205             : 
     206          18 :     CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
     207             :               .FromJust());
     208             :     // Test non-global ICs.
     209             :     CompileRun(
     210             :         "var x = this;"
     211             :         "function g() {"
     212             :         "  var r = 0;"
     213             :         "  for (var i = 0; i < 100; i++) {"
     214             :         "    r = x.draft;"
     215             :         "  }"
     216             :         "  return r;"
     217             :         "}");
     218             : 
     219           6 :     ExpectInt32("g()", 456);
     220             : 
     221             :     // Reset hidden property.
     222          18 :     CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789))
     223             :               .FromJust());
     224             : 
     225             :     // Test non-global access in Crankshaft.
     226             :     CompileRun("%OptimizeFunctionOnNextCall(g);");
     227             : 
     228           6 :     ExpectInt32("g()", 789);
     229           6 :   }
     230           6 : }
     231             : 
     232             : namespace {
     233             : 
     234           0 : static void Setter(v8::Local<v8::String> name, v8::Local<v8::Value> value,
     235           0 :                    const v8::PropertyCallbackInfo<void>& info) {}
     236             : }
     237             : 
     238             : // Re-declaration of non-configurable accessors should throw.
     239       23724 : TEST(RedeclareAccessor) {
     240           6 :   v8::HandleScope scope(CcTest::isolate());
     241          12 :   LocalContext env;
     242             : 
     243             :   v8::Local<v8::FunctionTemplate> templ =
     244           6 :       v8::FunctionTemplate::New(CcTest::isolate());
     245             : 
     246           6 :   v8::Local<v8::ObjectTemplate> object_template = templ->InstanceTemplate();
     247             :   object_template->SetAccessor(
     248             :       v8_str("foo"), nullptr, Setter, v8::Local<v8::Value>(),
     249          12 :       v8::AccessControl::DEFAULT, v8::PropertyAttribute::DontDelete);
     250             : 
     251             :   v8::Local<v8::Context> ctx =
     252           6 :       v8::Context::New(CcTest::isolate(), nullptr, object_template);
     253             : 
     254             :   // Declare function.
     255           6 :   v8::Local<v8::String> code = v8_str("function foo() {};");
     256             : 
     257          12 :   v8::TryCatch try_catch(CcTest::isolate());
     258          12 :   v8::Script::Compile(ctx, code).ToLocalChecked()->Run(ctx).IsEmpty();
     259          12 :   CHECK(try_catch.HasCaught());
     260       71160 : }

Generated by: LCOV version 1.10