LCOV - code coverage report
Current view: top level - test/unittests/api - v8-object-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 72 111 64.9 %
Date: 2017-10-20 Functions: 18 25 72.0 %

          Line data    Source code
       1             : // Copyright 2017 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 "include/v8.h"
       6             : #include "src/api.h"
       7             : #include "src/objects-inl.h"
       8             : #include "test/unittests/test-utils.h"
       9             : #include "testing/gtest/include/gtest/gtest.h"
      10             : 
      11             : namespace v8 {
      12             : namespace {
      13             : 
      14             : using ObjectTest = TestWithContext;
      15             : 
      16           0 : void accessor_name_getter_callback(Local<Name>,
      17           0 :                                    const PropertyCallbackInfo<Value>&) {}
      18             : 
      19       13159 : TEST_F(ObjectTest, SetAccessorWhenUnconfigurablePropAlreadyDefined) {
      20           1 :   TryCatch try_catch(isolate());
      21             : 
      22           1 :   Local<Object> global = context()->Global();
      23             :   Local<String> property_name =
      24             :       String::NewFromUtf8(isolate(), "foo", NewStringType::kNormal)
      25           1 :           .ToLocalChecked();
      26             : 
      27           2 :   PropertyDescriptor prop_desc;
      28           1 :   prop_desc.set_configurable(false);
      29           2 :   global->DefineProperty(context(), property_name, prop_desc).ToChecked();
      30             : 
      31             :   Maybe<bool> result = global->SetAccessor(context(), property_name,
      32           1 :                                            accessor_name_getter_callback);
      33           2 :   ASSERT_TRUE(result.IsJust());
      34           2 :   ASSERT_FALSE(result.FromJust());
      35           3 :   ASSERT_FALSE(try_catch.HasCaught());
      36             : }
      37             : 
      38             : using LapContextTest = TestWithIsolate;
      39             : 
      40             : // TODO(yukishiino): Enable this unittest once
      41             : // PropertyAccessInfo::accessor_holder() gets supported.  Currently we're using
      42             : // PropertyAccessInfo::holder(), which doesn't return the accessor holder.
      43       13155 : TEST_F(LapContextTest, DISABLED_CurrentContextInLazyAccessorOnPrototype) {
      44             :   // The receiver object is created in |receiver_context|, but its prototype
      45             :   // object is created in |prototype_context|, and the property is accessed
      46             :   // from |caller_context|.
      47           0 :   Local<Context> receiver_context = Context::New(isolate());
      48           0 :   Local<Context> prototype_context = Context::New(isolate());
      49           0 :   Local<Context> caller_context = Context::New(isolate());
      50             : 
      51             :   static int call_count;  // The number of calls of the accessor callback.
      52           0 :   call_count = 0;
      53             : 
      54           0 :   Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
      55           0 :   Local<Signature> signature = Signature::New(isolate(), function_template);
      56             :   Local<String> property_key =
      57             :       String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
      58           0 :           .ToLocalChecked();
      59             :   Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
      60             :       isolate(),
      61           0 :       [](const FunctionCallbackInfo<Value>& info) {
      62           0 :         ++call_count;
      63             :         Local<Context> prototype_context = *reinterpret_cast<Local<Context>*>(
      64           0 :             info.Data().As<External>()->Value());
      65           0 :         EXPECT_EQ(prototype_context, info.GetIsolate()->GetCurrentContext());
      66           0 :       },
      67           0 :       External::New(isolate(), &prototype_context), signature);
      68           0 :   function_template->PrototypeTemplate()->SetAccessorProperty(
      69           0 :       property_key, get_or_set, get_or_set);
      70             : 
      71             :   // |object| is created in |receiver_context|, and |prototype| is created
      72             :   // in |prototype_context|.  And then, object.__proto__ = prototype.
      73             :   Local<Function> interface_for_receiver =
      74           0 :       function_template->GetFunction(receiver_context).ToLocalChecked();
      75             :   Local<Function> interface_for_prototype =
      76           0 :       function_template->GetFunction(prototype_context).ToLocalChecked();
      77             :   Local<String> prototype_key =
      78             :       String::NewFromUtf8(isolate(), "prototype", NewStringType::kNormal)
      79           0 :           .ToLocalChecked();
      80             :   Local<Object> prototype =
      81           0 :       interface_for_prototype->Get(caller_context, prototype_key)
      82           0 :           .ToLocalChecked()
      83             :           .As<Object>();
      84             :   Local<Object> object =
      85             :       interface_for_receiver->NewInstance(receiver_context).ToLocalChecked();
      86           0 :   object->SetPrototype(caller_context, prototype).ToChecked();
      87           0 :   EXPECT_EQ(receiver_context, object->CreationContext());
      88           0 :   EXPECT_EQ(prototype_context, prototype->CreationContext());
      89             : 
      90           0 :   EXPECT_EQ(0, call_count);
      91           0 :   object->Get(caller_context, property_key).ToLocalChecked();
      92           0 :   EXPECT_EQ(1, call_count);
      93           0 :   object->Set(caller_context, property_key, Null(isolate())).ToChecked();
      94           0 :   EXPECT_EQ(2, call_count);
      95             : 
      96             :   // Test with a compiled version.
      97             :   Local<String> object_key =
      98             :       String::NewFromUtf8(isolate(), "object", NewStringType::kNormal)
      99           0 :           .ToLocalChecked();
     100           0 :   caller_context->Global()->Set(caller_context, object_key, object).ToChecked();
     101             :   const char script[] =
     102             :       "function f() { object.property; object.property = 0; } "
     103             :       "f(); f(); "
     104             :       "%OptimizeFunctionOnNextCall(f); "
     105           0 :       "f();";
     106             :   Context::Scope scope(caller_context);
     107           0 :   internal::FLAG_allow_natives_syntax = true;
     108             :   Script::Compile(
     109             :       caller_context,
     110             :       String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
     111           0 :           .ToLocalChecked())
     112           0 :       .ToLocalChecked()
     113             :       ->Run(caller_context)
     114           0 :       .ToLocalChecked();
     115           0 :   EXPECT_EQ(8, call_count);
     116           0 : }
     117             : 
     118       13159 : TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPlatformObject) {
     119           1 :   Local<Context> receiver_context = Context::New(isolate());
     120           1 :   Local<Context> caller_context = Context::New(isolate());
     121             : 
     122             :   static int call_count;  // The number of calls of the accessor callback.
     123           1 :   call_count = 0;
     124             : 
     125           1 :   Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
     126           1 :   Local<Signature> signature = Signature::New(isolate(), function_template);
     127             :   Local<String> property_key =
     128             :       String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
     129           1 :           .ToLocalChecked();
     130             :   Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
     131             :       isolate(),
     132          32 :       [](const FunctionCallbackInfo<Value>& info) {
     133           8 :         ++call_count;
     134             :         Local<Context> receiver_context = *reinterpret_cast<Local<Context>*>(
     135           8 :             info.Data().As<External>()->Value());
     136          16 :         EXPECT_EQ(receiver_context, info.GetIsolate()->GetCurrentContext());
     137          16 :       },
     138           2 :       External::New(isolate(), &receiver_context), signature);
     139           2 :   function_template->InstanceTemplate()->SetAccessorProperty(
     140           2 :       property_key, get_or_set, get_or_set);
     141             : 
     142             :   Local<Function> interface =
     143           1 :       function_template->GetFunction(receiver_context).ToLocalChecked();
     144             :   Local<Object> object =
     145             :       interface->NewInstance(receiver_context).ToLocalChecked();
     146             : 
     147           2 :   EXPECT_EQ(0, call_count);
     148           2 :   object->Get(caller_context, property_key).ToLocalChecked();
     149           2 :   EXPECT_EQ(1, call_count);
     150           2 :   object->Set(caller_context, property_key, Null(isolate())).ToChecked();
     151           2 :   EXPECT_EQ(2, call_count);
     152             : 
     153             :   // Test with a compiled version.
     154             :   Local<String> object_key =
     155             :       String::NewFromUtf8(isolate(), "object", NewStringType::kNormal)
     156           1 :           .ToLocalChecked();
     157           3 :   caller_context->Global()->Set(caller_context, object_key, object).ToChecked();
     158             :   const char script[] =
     159             :       "function f() { object.property; object.property = 0; } "
     160             :       "f(); f(); "
     161             :       "%OptimizeFunctionOnNextCall(f); "
     162           1 :       "f();";
     163             :   Context::Scope scope(caller_context);
     164           1 :   internal::FLAG_allow_natives_syntax = true;
     165             :   Script::Compile(
     166             :       caller_context,
     167             :       String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
     168           1 :           .ToLocalChecked())
     169           1 :       .ToLocalChecked()
     170             :       ->Run(caller_context)
     171           1 :       .ToLocalChecked();
     172           2 :   EXPECT_EQ(8, call_count);
     173           1 : }
     174             : 
     175       13159 : TEST_F(LapContextTest, CurrentContextInLazyAccessorOnInterface) {
     176           1 :   Local<Context> interface_context = Context::New(isolate());
     177           1 :   Local<Context> caller_context = Context::New(isolate());
     178             : 
     179             :   static int call_count;  // The number of calls of the accessor callback.
     180           1 :   call_count = 0;
     181             : 
     182           1 :   Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
     183             :   Local<String> property_key =
     184             :       String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
     185           1 :           .ToLocalChecked();
     186             :   Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
     187             :       isolate(),
     188          32 :       [](const FunctionCallbackInfo<Value>& info) {
     189           8 :         ++call_count;
     190             :         Local<Context> interface_context = *reinterpret_cast<Local<Context>*>(
     191           8 :             info.Data().As<External>()->Value());
     192          16 :         EXPECT_EQ(interface_context, info.GetIsolate()->GetCurrentContext());
     193          16 :       },
     194           2 :       External::New(isolate(), &interface_context), Local<Signature>());
     195           1 :   function_template->SetAccessorProperty(property_key, get_or_set, get_or_set);
     196             : 
     197             :   Local<Function> interface =
     198           1 :       function_template->GetFunction(interface_context).ToLocalChecked();
     199             : 
     200           2 :   EXPECT_EQ(0, call_count);
     201           2 :   interface->Get(caller_context, property_key).ToLocalChecked();
     202           2 :   EXPECT_EQ(1, call_count);
     203           2 :   interface->Set(caller_context, property_key, Null(isolate())).ToChecked();
     204           2 :   EXPECT_EQ(2, call_count);
     205             : 
     206             :   // Test with a compiled version.
     207             :   Local<String> interface_key =
     208             :       String::NewFromUtf8(isolate(), "Interface", NewStringType::kNormal)
     209           1 :           .ToLocalChecked();
     210             :   caller_context->Global()
     211           2 :       ->Set(caller_context, interface_key, interface)
     212           2 :       .ToChecked();
     213             :   const char script[] =
     214             :       "function f() { Interface.property; Interface.property = 0; } "
     215             :       "f(); f(); "
     216             :       "%OptimizeFunctionOnNextCall(f); "
     217           1 :       "f();";
     218             :   Context::Scope scope(caller_context);
     219           1 :   internal::FLAG_allow_natives_syntax = true;
     220             :   Script::Compile(
     221             :       caller_context,
     222             :       String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
     223           1 :           .ToLocalChecked())
     224           1 :       .ToLocalChecked()
     225             :       ->Run(caller_context)
     226           1 :       .ToLocalChecked();
     227           2 :   EXPECT_EQ(8, call_count);
     228           1 : }
     229             : 
     230             : }  // namespace
     231        7893 : }  // namespace v8

Generated by: LCOV version 1.10