LCOV - code coverage report
Current view: top level - test/cctest - test-accessors.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 394 394 100.0 %
Date: 2017-10-20 Functions: 48 48 100.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #include <stdlib.h>
      29             : 
      30             : #include "src/v8.h"
      31             : 
      32             : #include "src/api.h"
      33             : #include "src/frames-inl.h"
      34             : #include "src/string-stream.h"
      35             : #include "test/cctest/cctest.h"
      36             : 
      37             : using ::v8::ObjectTemplate;
      38             : using ::v8::Value;
      39             : using ::v8::Context;
      40             : using ::v8::Local;
      41             : using ::v8::Name;
      42             : using ::v8::String;
      43             : using ::v8::Script;
      44             : using ::v8::Function;
      45             : using ::v8::Extension;
      46             : 
      47           6 : static void handle_property(Local<String> name,
      48             :                             const v8::PropertyCallbackInfo<v8::Value>& info) {
      49           6 :   ApiTestFuzzer::Fuzz();
      50           6 :   info.GetReturnValue().Set(v8_num(900));
      51           6 : }
      52             : 
      53           6 : static void handle_property_2(Local<String> name,
      54             :                               const v8::PropertyCallbackInfo<v8::Value>& info) {
      55           6 :   ApiTestFuzzer::Fuzz();
      56           6 :   info.GetReturnValue().Set(v8_num(902));
      57           6 : }
      58             : 
      59             : 
      60         183 : static void handle_property(const v8::FunctionCallbackInfo<v8::Value>& info) {
      61          61 :   ApiTestFuzzer::Fuzz();
      62          61 :   CHECK_EQ(0, info.Length());
      63          61 :   info.GetReturnValue().Set(v8_num(907));
      64          61 : }
      65             : 
      66             : 
      67       23724 : THREADED_TEST(PropertyHandler) {
      68           6 :   LocalContext env;
      69           6 :   v8::Isolate* isolate = env->GetIsolate();
      70          12 :   v8::HandleScope scope(isolate);
      71           6 :   Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
      72          12 :   fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property);
      73             :   Local<v8::FunctionTemplate> getter_templ =
      74           6 :       v8::FunctionTemplate::New(isolate, handle_property);
      75           6 :   getter_templ->SetLength(0);
      76             :   fun_templ->
      77          18 :       InstanceTemplate()->SetAccessorProperty(v8_str("bar"), getter_templ);
      78          12 :   fun_templ->InstanceTemplate()->
      79          18 :       SetNativeDataProperty(v8_str("instance_foo"), handle_property);
      80           6 :   fun_templ->SetNativeDataProperty(v8_str("object_foo"), handle_property_2);
      81           6 :   Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked();
      82          30 :   CHECK(env->Global()->Set(env.local(), v8_str("Fun"), fun).FromJust());
      83             :   Local<Script> getter;
      84             :   Local<Script> setter;
      85             :   // check function instance accessors
      86             :   getter = v8_compile("var obj = new Fun(); obj.instance_foo;");
      87          18 :   CHECK_EQ(900, getter->Run(env.local())
      88             :                     .ToLocalChecked()
      89             :                     ->Int32Value(env.local())
      90             :                     .FromJust());
      91             :   setter = v8_compile("obj.instance_foo = 901;");
      92          18 :   CHECK_EQ(901, setter->Run(env.local())
      93             :                     .ToLocalChecked()
      94             :                     ->Int32Value(env.local())
      95             :                     .FromJust());
      96             :   getter = v8_compile("obj.bar;");
      97          18 :   CHECK_EQ(907, getter->Run(env.local())
      98             :                     .ToLocalChecked()
      99             :                     ->Int32Value(env.local())
     100             :                     .FromJust());
     101             :   setter = v8_compile("obj.bar = 908;");
     102          18 :   CHECK_EQ(908, setter->Run(env.local())
     103             :                     .ToLocalChecked()
     104             :                     ->Int32Value(env.local())
     105             :                     .FromJust());
     106             :   // check function static accessors
     107             :   getter = v8_compile("Fun.object_foo;");
     108          18 :   CHECK_EQ(902, getter->Run(env.local())
     109             :                     .ToLocalChecked()
     110             :                     ->Int32Value(env.local())
     111             :                     .FromJust());
     112             :   setter = v8_compile("Fun.object_foo = 903;");
     113          18 :   CHECK_EQ(903, setter->Run(env.local())
     114             :                     .ToLocalChecked()
     115             :                     ->Int32Value(env.local())
     116           6 :                     .FromJust());
     117           6 : }
     118             : 
     119             : 
     120          12 : static void GetIntValue(Local<String> property,
     121             :                         const v8::PropertyCallbackInfo<v8::Value>& info) {
     122          12 :   ApiTestFuzzer::Fuzz();
     123             :   int* value =
     124          12 :       static_cast<int*>(v8::Local<v8::External>::Cast(info.Data())->Value());
     125          12 :   info.GetReturnValue().Set(v8_num(*value));
     126          12 : }
     127             : 
     128             : 
     129          12 : static void SetIntValue(Local<String> property,
     130             :                         Local<Value> value,
     131             :                         const v8::PropertyCallbackInfo<void>& info) {
     132             :   int* field =
     133          12 :       static_cast<int*>(v8::Local<v8::External>::Cast(info.Data())->Value());
     134          36 :   *field = value->Int32Value(info.GetIsolate()->GetCurrentContext()).FromJust();
     135          12 : }
     136             : 
     137             : int foo, bar, baz;
     138             : 
     139       23724 : THREADED_TEST(GlobalVariableAccess) {
     140           6 :   foo = 0;
     141           6 :   bar = -4;
     142           6 :   baz = 10;
     143           6 :   v8::Isolate* isolate = CcTest::isolate();
     144           6 :   v8::HandleScope scope(isolate);
     145           6 :   v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
     146             :   templ->InstanceTemplate()->SetAccessor(
     147             :       v8_str("foo"), GetIntValue, SetIntValue,
     148          18 :       v8::External::New(isolate, &foo));
     149             :   templ->InstanceTemplate()->SetAccessor(
     150             :       v8_str("bar"), GetIntValue, SetIntValue,
     151          18 :       v8::External::New(isolate, &bar));
     152             :   templ->InstanceTemplate()->SetAccessor(
     153             :       v8_str("baz"), GetIntValue, SetIntValue,
     154          18 :       v8::External::New(isolate, &baz));
     155          12 :   LocalContext env(0, templ->InstanceTemplate());
     156          12 :   v8_compile("foo = (++bar) + baz")->Run(env.local()).ToLocalChecked();
     157           6 :   CHECK_EQ(-3, bar);
     158          12 :   CHECK_EQ(7, foo);
     159           6 : }
     160             : 
     161             : 
     162             : static int x_register[2] = {0, 0};
     163             : static v8::Local<v8::Object> x_receiver;
     164             : static v8::Local<v8::Object> x_holder;
     165             : 
     166             : template<class Info>
     167         600 : static void XGetter(const Info& info, int offset) {
     168         240 :   ApiTestFuzzer::Fuzz();
     169         240 :   v8::Isolate* isolate = CcTest::isolate();
     170         240 :   CHECK_EQ(isolate, info.GetIsolate());
     171         720 :   CHECK(
     172             :       x_receiver->Equals(isolate->GetCurrentContext(), info.This()).FromJust());
     173         240 :   info.GetReturnValue().Set(v8_num(x_register[offset]));
     174         240 : }
     175             : 
     176             : 
     177         120 : static void XGetter(Local<String> name,
     178             :                     const v8::PropertyCallbackInfo<v8::Value>& info) {
     179         360 :   CHECK(x_holder->Equals(info.GetIsolate()->GetCurrentContext(), info.Holder())
     180             :             .FromJust());
     181         120 :   XGetter(info, 0);
     182         120 : }
     183             : 
     184             : 
     185         120 : static void XGetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
     186         360 :   CHECK(
     187             :       x_receiver->Equals(info.GetIsolate()->GetCurrentContext(), info.Holder())
     188             :           .FromJust());
     189         120 :   XGetter(info, 1);
     190         120 : }
     191             : 
     192             : 
     193             : template<class Info>
     194         840 : static void XSetter(Local<Value> value, const Info& info, int offset) {
     195         240 :   v8::Isolate* isolate = CcTest::isolate();
     196         240 :   CHECK_EQ(isolate, info.GetIsolate());
     197         720 :   CHECK(x_holder->Equals(info.GetIsolate()->GetCurrentContext(), info.This())
     198             :             .FromJust());
     199         720 :   CHECK(x_holder->Equals(info.GetIsolate()->GetCurrentContext(), info.Holder())
     200             :             .FromJust());
     201         720 :   x_register[offset] =
     202             :       value->Int32Value(info.GetIsolate()->GetCurrentContext()).FromJust();
     203         240 :   info.GetReturnValue().Set(v8_num(-1));
     204         240 : }
     205             : 
     206             : 
     207         120 : static void XSetter(Local<String> name,
     208             :                     Local<Value> value,
     209             :                     const v8::PropertyCallbackInfo<void>& info) {
     210         120 :   XSetter(value, info, 0);
     211         120 : }
     212             : 
     213             : 
     214         120 : static void XSetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
     215         120 :   CHECK_EQ(1, info.Length());
     216         120 :   XSetter(info[0], info, 1);
     217         120 : }
     218             : 
     219             : 
     220       23724 : THREADED_TEST(AccessorIC) {
     221           6 :   LocalContext context;
     222           6 :   v8::Isolate* isolate = context->GetIsolate();
     223          12 :   v8::HandleScope scope(isolate);
     224           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     225           6 :   obj->SetAccessor(v8_str("x0"), XGetter, XSetter);
     226             :   obj->SetAccessorProperty(v8_str("x1"),
     227             :                            v8::FunctionTemplate::New(isolate, XGetter),
     228          18 :                            v8::FunctionTemplate::New(isolate, XSetter));
     229          12 :   x_holder = obj->NewInstance(context.local()).ToLocalChecked();
     230          30 :   CHECK(context->Global()
     231             :             ->Set(context.local(), v8_str("holder"), x_holder)
     232             :             .FromJust());
     233           6 :   x_receiver = v8::Object::New(isolate);
     234          30 :   CHECK(context->Global()
     235             :             ->Set(context.local(), v8_str("obj"), x_receiver)
     236             :             .FromJust());
     237             :   v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(
     238             :       CompileRun("obj.__proto__ = holder;"
     239             :                  "var result = [];"
     240             :                  "var key_0 = 'x0';"
     241             :                  "var key_1 = 'x1';"
     242             :                  "for (var j = 0; j < 10; j++) {"
     243             :                  "  var i = 4*j;"
     244             :                  "  result.push(holder.x0 = i);"
     245             :                  "  result.push(obj.x0);"
     246             :                  "  result.push(holder.x1 = i + 1);"
     247             :                  "  result.push(obj.x1);"
     248             :                  "  result.push(holder[key_0] = i + 2);"
     249             :                  "  result.push(obj[key_0]);"
     250             :                  "  result.push(holder[key_1] = i + 3);"
     251             :                  "  result.push(obj[key_1]);"
     252             :                  "}"
     253             :                  "result"));
     254           6 :   CHECK_EQ(80u, array->Length());
     255         480 :   for (int i = 0; i < 80; i++) {
     256             :     v8::Local<Value> entry =
     257        1440 :         array->Get(context.local(), v8::Integer::New(isolate, i))
     258         960 :             .ToLocalChecked();
     259        1440 :     CHECK(v8::Integer::New(isolate, i / 2)
     260             :               ->Equals(context.local(), entry)
     261             :               .FromJust());
     262           6 :   }
     263           6 : }
     264             : 
     265             : 
     266             : template <int C>
     267       12000 : static void HandleAllocatingGetter(
     268             :     Local<String> name,
     269             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     270       12000 :   ApiTestFuzzer::Fuzz();
     271     6162000 :   for (int i = 0; i < C; i++) {
     272             :     v8::String::NewFromUtf8(info.GetIsolate(), "foo",
     273             :                             v8::NewStringType::kNormal)
     274     6150000 :         .ToLocalChecked();
     275             :   }
     276             :   info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "foo",
     277             :                                                     v8::NewStringType::kNormal)
     278       12000 :                                 .ToLocalChecked());
     279       12000 : }
     280             : 
     281             : 
     282       23724 : THREADED_TEST(HandleScopePop) {
     283           6 :   LocalContext context;
     284           6 :   v8::Isolate* isolate = context->GetIsolate();
     285          12 :   v8::HandleScope scope(isolate);
     286           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     287           6 :   obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>);
     288           6 :   obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>);
     289             :   v8::Local<v8::Object> inst =
     290           6 :       obj->NewInstance(context.local()).ToLocalChecked();
     291          30 :   CHECK(
     292             :       context->Global()->Set(context.local(), v8_str("obj"), inst).FromJust());
     293             :   int count_before =
     294           6 :       i::HandleScope::NumberOfHandles(reinterpret_cast<i::Isolate*>(isolate));
     295             :   {
     296           6 :     v8::HandleScope scope(isolate);
     297             :     CompileRun(
     298             :         "for (var i = 0; i < 1000; i++) {"
     299             :         "  obj.one;"
     300             :         "  obj.many;"
     301           6 :         "}");
     302             :   }
     303             :   int count_after =
     304           6 :       i::HandleScope::NumberOfHandles(reinterpret_cast<i::Isolate*>(isolate));
     305          12 :   CHECK_EQ(count_before, count_after);
     306           6 : }
     307             : 
     308         264 : static void CheckAccessorArgsCorrect(
     309             :     Local<String> name,
     310             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     311         264 :   CHECK(info.GetIsolate() == CcTest::isolate());
     312         264 :   CHECK(info.This() == info.Holder());
     313        1056 :   CHECK(info.Data()
     314             :             ->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("data"))
     315             :             .FromJust());
     316         264 :   ApiTestFuzzer::Fuzz();
     317         264 :   CHECK(info.GetIsolate() == CcTest::isolate());
     318         264 :   CHECK(info.This() == info.Holder());
     319        1056 :   CHECK(info.Data()
     320             :             ->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("data"))
     321             :             .FromJust());
     322         264 :   CcTest::CollectAllGarbage();
     323         264 :   CHECK(info.GetIsolate() == CcTest::isolate());
     324         264 :   CHECK(info.This() == info.Holder());
     325        1056 :   CHECK(info.Data()
     326             :             ->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("data"))
     327             :             .FromJust());
     328             :   info.GetReturnValue().Set(17);
     329         264 : }
     330             : 
     331             : 
     332       23724 : THREADED_TEST(DirectCall) {
     333           6 :   LocalContext context;
     334           6 :   v8::Isolate* isolate = context->GetIsolate();
     335          12 :   v8::HandleScope scope(isolate);
     336           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     337             :   obj->SetAccessor(v8_str("xxx"), CheckAccessorArgsCorrect, nullptr,
     338          12 :                    v8_str("data"));
     339             :   v8::Local<v8::Object> inst =
     340           6 :       obj->NewInstance(context.local()).ToLocalChecked();
     341          30 :   CHECK(
     342             :       context->Global()->Set(context.local(), v8_str("obj"), inst).FromJust());
     343             :   Local<Script> scr =
     344           6 :       v8::Script::Compile(context.local(), v8_str("obj.xxx")).ToLocalChecked();
     345          60 :   for (int i = 0; i < 10; i++) {
     346          60 :     Local<Value> result = scr->Run(context.local()).ToLocalChecked();
     347          60 :     CHECK(!result.IsEmpty());
     348         120 :     CHECK_EQ(17, result->Int32Value(context.local()).FromJust());
     349           6 :   }
     350           6 : }
     351             : 
     352          72 : static void EmptyGetter(Local<String> name,
     353             :                         const v8::PropertyCallbackInfo<v8::Value>& info) {
     354          72 :   CheckAccessorArgsCorrect(name, info);
     355          72 :   ApiTestFuzzer::Fuzz();
     356          72 :   CheckAccessorArgsCorrect(name, info);
     357             :   info.GetReturnValue().Set(v8::Local<v8::Value>());
     358          72 : }
     359             : 
     360             : 
     361       23724 : THREADED_TEST(EmptyResult) {
     362           6 :   LocalContext context;
     363           6 :   v8::Isolate* isolate = context->GetIsolate();
     364          12 :   v8::HandleScope scope(isolate);
     365           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     366          12 :   obj->SetAccessor(v8_str("xxx"), EmptyGetter, nullptr, v8_str("data"));
     367             :   v8::Local<v8::Object> inst =
     368           6 :       obj->NewInstance(context.local()).ToLocalChecked();
     369          30 :   CHECK(
     370             :       context->Global()->Set(context.local(), v8_str("obj"), inst).FromJust());
     371             :   Local<Script> scr =
     372           6 :       v8::Script::Compile(context.local(), v8_str("obj.xxx")).ToLocalChecked();
     373          60 :   for (int i = 0; i < 10; i++) {
     374          60 :     Local<Value> result = scr->Run(context.local()).ToLocalChecked();
     375          60 :     CHECK(result == v8::Undefined(isolate));
     376           6 :   }
     377           6 : }
     378             : 
     379             : 
     380       23724 : THREADED_TEST(NoReuseRegress) {
     381             :   // Check that the IC generated for the one test doesn't get reused
     382             :   // for the other.
     383           6 :   v8::Isolate* isolate = CcTest::isolate();
     384           6 :   v8::HandleScope scope(isolate);
     385             :   {
     386           6 :     v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     387          12 :     obj->SetAccessor(v8_str("xxx"), EmptyGetter, nullptr, v8_str("data"));
     388           6 :     LocalContext context;
     389             :     v8::Local<v8::Object> inst =
     390           6 :         obj->NewInstance(context.local()).ToLocalChecked();
     391          30 :     CHECK(context->Global()
     392             :               ->Set(context.local(), v8_str("obj"), inst)
     393             :               .FromJust());
     394           6 :     Local<Script> scr = v8::Script::Compile(context.local(), v8_str("obj.xxx"))
     395           6 :                             .ToLocalChecked();
     396          12 :     for (int i = 0; i < 2; i++) {
     397          12 :       Local<Value> result = scr->Run(context.local()).ToLocalChecked();
     398          12 :       CHECK(result == v8::Undefined(isolate));
     399           6 :     }
     400             :   }
     401             :   {
     402           6 :     v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     403             :     obj->SetAccessor(v8_str("xxx"), CheckAccessorArgsCorrect, nullptr,
     404          12 :                      v8_str("data"));
     405           6 :     LocalContext context;
     406             :     v8::Local<v8::Object> inst =
     407           6 :         obj->NewInstance(context.local()).ToLocalChecked();
     408          30 :     CHECK(context->Global()
     409             :               ->Set(context.local(), v8_str("obj"), inst)
     410             :               .FromJust());
     411           6 :     Local<Script> scr = v8::Script::Compile(context.local(), v8_str("obj.xxx"))
     412           6 :                             .ToLocalChecked();
     413          60 :     for (int i = 0; i < 10; i++) {
     414          60 :       Local<Value> result = scr->Run(context.local()).ToLocalChecked();
     415          60 :       CHECK(!result.IsEmpty());
     416         120 :       CHECK_EQ(17, result->Int32Value(context.local()).FromJust());
     417           6 :     }
     418           6 :   }
     419           6 : }
     420             : 
     421          30 : static void ThrowingGetAccessor(
     422             :     Local<String> name,
     423             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     424          30 :   ApiTestFuzzer::Fuzz();
     425          60 :   info.GetIsolate()->ThrowException(v8_str("g"));
     426          30 : }
     427             : 
     428             : 
     429          30 : static void ThrowingSetAccessor(Local<String> name,
     430             :                                 Local<Value> value,
     431             :                                 const v8::PropertyCallbackInfo<void>& info) {
     432          30 :   info.GetIsolate()->ThrowException(value);
     433          30 : }
     434             : 
     435             : 
     436       23724 : THREADED_TEST(Regress1054726) {
     437           6 :   LocalContext env;
     438           6 :   v8::Isolate* isolate = env->GetIsolate();
     439          12 :   v8::HandleScope scope(isolate);
     440           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     441             :   obj->SetAccessor(v8_str("x"),
     442             :                    ThrowingGetAccessor,
     443             :                    ThrowingSetAccessor,
     444           6 :                    Local<Value>());
     445             : 
     446          36 :   CHECK(env->Global()
     447             :             ->Set(env.local(), v8_str("obj"),
     448             :                   obj->NewInstance(env.local()).ToLocalChecked())
     449             :             .FromJust());
     450             : 
     451             :   // Use the throwing property setter/getter in a loop to force
     452             :   // the accessor ICs to be initialized.
     453             :   v8::Local<Value> result;
     454             :   result = Script::Compile(env.local(),
     455             :                            v8_str("var result = '';"
     456             :                                   "for (var i = 0; i < 5; i++) {"
     457             :                                   "  try { obj.x; } catch (e) { result += e; }"
     458           6 :                                   "}; result"))
     459           6 :                .ToLocalChecked()
     460           6 :                ->Run(env.local())
     461          12 :                .ToLocalChecked();
     462          18 :   CHECK(v8_str("ggggg")->Equals(env.local(), result).FromJust());
     463             : 
     464             :   result =
     465             :       Script::Compile(env.local(),
     466             :                       v8_str("var result = '';"
     467             :                              "for (var i = 0; i < 5; i++) {"
     468             :                              "  try { obj.x = i; } catch (e) { result += e; }"
     469           6 :                              "}; result"))
     470           6 :           .ToLocalChecked()
     471           6 :           ->Run(env.local())
     472          12 :           .ToLocalChecked();
     473          24 :   CHECK(v8_str("01234")->Equals(env.local(), result).FromJust());
     474           6 : }
     475             : 
     476             : 
     477       12288 : static void AllocGetter(Local<String> name,
     478             :                         const v8::PropertyCallbackInfo<v8::Value>& info) {
     479       12288 :   ApiTestFuzzer::Fuzz();
     480       12288 :   info.GetReturnValue().Set(v8::Array::New(info.GetIsolate(), 1000));
     481       12288 : }
     482             : 
     483             : 
     484       23724 : THREADED_TEST(Gc) {
     485           6 :   LocalContext env;
     486           6 :   v8::Isolate* isolate = env->GetIsolate();
     487          12 :   v8::HandleScope scope(isolate);
     488           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     489           6 :   obj->SetAccessor(v8_str("xxx"), AllocGetter);
     490          36 :   CHECK(env->Global()
     491             :             ->Set(env.local(), v8_str("obj"),
     492             :                   obj->NewInstance(env.local()).ToLocalChecked())
     493             :             .FromJust());
     494             :   Script::Compile(env.local(), v8_str("var last = [];"
     495             :                                       "for (var i = 0; i < 2048; i++) {"
     496             :                                       "  var result = obj.xxx;"
     497             :                                       "  result[0] = last;"
     498             :                                       "  last = result;"
     499           6 :                                       "}"))
     500           6 :       .ToLocalChecked()
     501           6 :       ->Run(env.local())
     502          12 :       .ToLocalChecked();
     503           6 : }
     504             : 
     505             : 
     506         600 : static void StackCheck(Local<String> name,
     507             :                        const v8::PropertyCallbackInfo<v8::Value>& info) {
     508         600 :   i::StackFrameIterator iter(reinterpret_cast<i::Isolate*>(info.GetIsolate()));
     509        4100 :   for (int i = 0; !iter.done(); i++) {
     510             :     i::StackFrame* frame = iter.frame();
     511        3500 :     CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT));
     512        3500 :     i::Code* code = frame->LookupCode();
     513        3500 :     CHECK(code->IsCode());
     514             :     i::Address pc = frame->pc();
     515        3500 :     CHECK(code->contains(pc));
     516        3500 :     iter.Advance();
     517             :   }
     518         600 : }
     519             : 
     520             : 
     521       23724 : THREADED_TEST(StackIteration) {
     522           6 :   LocalContext env;
     523           6 :   v8::Isolate* isolate = env->GetIsolate();
     524          12 :   v8::HandleScope scope(isolate);
     525           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     526             :   i::StringStream::ClearMentionedObjectCache(
     527           6 :       reinterpret_cast<i::Isolate*>(isolate));
     528           6 :   obj->SetAccessor(v8_str("xxx"), StackCheck);
     529          36 :   CHECK(env->Global()
     530             :             ->Set(env.local(), v8_str("obj"),
     531             :                   obj->NewInstance(env.local()).ToLocalChecked())
     532             :             .FromJust());
     533             :   Script::Compile(env.local(), v8_str("function foo() {"
     534             :                                       "  return obj.xxx;"
     535             :                                       "}"
     536             :                                       "for (var i = 0; i < 100; i++) {"
     537             :                                       "  foo();"
     538           6 :                                       "}"))
     539           6 :       .ToLocalChecked()
     540           6 :       ->Run(env.local())
     541          12 :       .ToLocalChecked();
     542           6 : }
     543             : 
     544             : 
     545          24 : static void AllocateHandles(Local<String> name,
     546             :                             const v8::PropertyCallbackInfo<v8::Value>& info) {
     547       24576 :   for (int i = 0; i < i::kHandleBlockSize + 1; i++) {
     548             :     v8::Local<v8::Value>::New(info.GetIsolate(), name);
     549             :   }
     550          24 :   info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 100));
     551          24 : }
     552             : 
     553             : 
     554       23724 : THREADED_TEST(HandleScopeSegment) {
     555             :   // Check that we can return values past popping of handle scope
     556             :   // segments.
     557           6 :   LocalContext env;
     558           6 :   v8::Isolate* isolate = env->GetIsolate();
     559          12 :   v8::HandleScope scope(isolate);
     560           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     561           6 :   obj->SetAccessor(v8_str("xxx"), AllocateHandles);
     562          36 :   CHECK(env->Global()
     563             :             ->Set(env.local(), v8_str("obj"),
     564             :                   obj->NewInstance(env.local()).ToLocalChecked())
     565             :             .FromJust());
     566             :   v8::Local<v8::Value> result =
     567             :       Script::Compile(env.local(), v8_str("var result;"
     568             :                                           "for (var i = 0; i < 4; i++)"
     569             :                                           "  result = obj.xxx;"
     570           6 :                                           "result;"))
     571           6 :           .ToLocalChecked()
     572           6 :           ->Run(env.local())
     573           6 :           .ToLocalChecked();
     574          18 :   CHECK_EQ(100, result->Int32Value(env.local()).FromJust());
     575           6 : }
     576             : 
     577             : 
     578           6 : void JSONStringifyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
     579           6 :   v8::Local<v8::Array> array = v8::Array::New(info.GetIsolate(), 1);
     580          24 :   CHECK(array->Set(info.GetIsolate()->GetCurrentContext(), 0, v8_str("regress"))
     581             :             .FromJust());
     582             :   info.GetReturnValue().Set(array);
     583           6 : }
     584             : 
     585             : 
     586           6 : void JSONStringifyGetter(Local<Name> name,
     587             :                          const v8::PropertyCallbackInfo<v8::Value>& info) {
     588           6 :   info.GetReturnValue().Set(v8_str("crbug-161028"));
     589           6 : }
     590             : 
     591             : 
     592       23724 : THREADED_TEST(JSONStringifyNamedInterceptorObject) {
     593           6 :   LocalContext env;
     594           6 :   v8::Isolate* isolate = env->GetIsolate();
     595          12 :   v8::HandleScope scope(isolate);
     596             : 
     597           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     598             :   obj->SetHandler(v8::NamedPropertyHandlerConfiguration(
     599           6 :       JSONStringifyGetter, nullptr, nullptr, nullptr, JSONStringifyEnumerator));
     600          36 :   CHECK(env->Global()
     601             :             ->Set(env.local(), v8_str("obj"),
     602             :                   obj->NewInstance(env.local()).ToLocalChecked())
     603             :             .FromJust());
     604           6 :   v8::Local<v8::String> expected = v8_str("{\"regress\":\"crbug-161028\"}");
     605          18 :   CHECK(CompileRun("JSON.stringify(obj)")
     606             :             ->Equals(env.local(), expected)
     607           6 :             .FromJust());
     608           6 : }
     609             : 
     610             : 
     611             : static v8::Local<v8::Context> expected_current_context;
     612             : 
     613             : 
     614         120 : static void check_contexts(const v8::FunctionCallbackInfo<v8::Value>& info) {
     615          60 :   ApiTestFuzzer::Fuzz();
     616         120 :   CHECK(expected_current_context == info.GetIsolate()->GetCurrentContext());
     617          60 : }
     618             : 
     619             : 
     620       23724 : THREADED_TEST(AccessorPropertyCrossContext) {
     621           6 :   LocalContext env;
     622           6 :   v8::Isolate* isolate = env->GetIsolate();
     623          12 :   v8::HandleScope scope(isolate);
     624             :   v8::Local<v8::Function> fun =
     625          12 :       v8::Function::New(env.local(), check_contexts).ToLocalChecked();
     626          12 :   LocalContext switch_context;
     627          30 :   CHECK(switch_context->Global()
     628             :             ->Set(switch_context.local(), v8_str("fun"), fun)
     629             :             .FromJust());
     630          12 :   v8::TryCatch try_catch(isolate);
     631           6 :   expected_current_context = env.local();
     632             :   CompileRun(
     633             :       "var o = Object.create(null, { n: { get:fun } });"
     634             :       "for (var i = 0; i < 10; i++) o.n;");
     635          12 :   CHECK(!try_catch.HasCaught());
     636           6 : }
     637             : 
     638             : 
     639       23724 : THREADED_TEST(GlobalObjectAccessor) {
     640           6 :   LocalContext env;
     641           6 :   v8::Isolate* isolate = env->GetIsolate();
     642          12 :   v8::HandleScope scope(isolate);
     643             :   CompileRun(
     644             :       "var set_value = 1;"
     645             :       "Object.defineProperty(this.__proto__, 'x', {"
     646             :       "    get : function() { return this; },"
     647             :       "    set : function() { set_value = this; }"
     648             :       "});"
     649             :       "function getter() { return x; }"
     650             :       "function setter() { x = 1; }"
     651             :       "for (var i = 0; i < 4; i++) { getter(); setter(); }");
     652           6 :   CHECK(v8::Utils::OpenHandle(*CompileRun("getter()"))->IsJSGlobalProxy());
     653          12 :   CHECK(v8::Utils::OpenHandle(*CompileRun("set_value"))->IsJSGlobalProxy());
     654           6 : }
     655             : 
     656             : 
     657          12 : static void EmptyGetter(Local<Name> name,
     658             :                         const v8::PropertyCallbackInfo<v8::Value>& info) {
     659          12 :   ApiTestFuzzer::Fuzz();
     660          12 : }
     661             : 
     662             : 
     663           6 : static void OneProperty(Local<String> name,
     664             :                         const v8::PropertyCallbackInfo<v8::Value>& info) {
     665           6 :   ApiTestFuzzer::Fuzz();
     666           6 :   info.GetReturnValue().Set(v8_num(1));
     667           6 : }
     668             : 
     669             : 
     670       23724 : THREADED_TEST(Regress433458) {
     671           6 :   LocalContext env;
     672           6 :   v8::Isolate* isolate = env->GetIsolate();
     673          12 :   v8::HandleScope scope(isolate);
     674           6 :   v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
     675           6 :   obj->SetHandler(v8::NamedPropertyHandlerConfiguration(EmptyGetter));
     676           6 :   obj->SetNativeDataProperty(v8_str("prop"), OneProperty);
     677          36 :   CHECK(env->Global()
     678             :             ->Set(env.local(), v8_str("obj"),
     679             :                   obj->NewInstance(env.local()).ToLocalChecked())
     680             :             .FromJust());
     681             :   CompileRun(
     682             :       "Object.defineProperty(obj, 'prop', { writable: false });"
     683           6 :       "Object.defineProperty(obj, 'prop', { writable: true });");
     684           6 : }
     685             : 
     686             : 
     687             : static bool security_check_value = false;
     688             : 
     689         125 : static bool SecurityTestCallback(Local<v8::Context> accessing_context,
     690             :                                  Local<v8::Object> accessed_object,
     691             :                                  Local<v8::Value> data) {
     692         125 :   return security_check_value;
     693             : }
     694             : 
     695             : 
     696       23723 : TEST(PrototypeGetterAccessCheck) {
     697           5 :   i::FLAG_allow_natives_syntax = true;
     698           5 :   LocalContext env;
     699           5 :   v8::Isolate* isolate = env->GetIsolate();
     700          10 :   v8::HandleScope scope(isolate);
     701           5 :   auto fun_templ = v8::FunctionTemplate::New(isolate);
     702           5 :   auto getter_templ = v8::FunctionTemplate::New(isolate, handle_property);
     703           5 :   getter_templ->SetAcceptAnyReceiver(false);
     704          10 :   fun_templ->InstanceTemplate()->SetAccessorProperty(v8_str("foo"),
     705          15 :                                                      getter_templ);
     706           5 :   auto obj_templ = v8::ObjectTemplate::New(isolate);
     707           5 :   obj_templ->SetAccessCheckCallback(SecurityTestCallback);
     708          30 :   CHECK(env->Global()
     709             :             ->Set(env.local(), v8_str("Fun"),
     710             :                   fun_templ->GetFunction(env.local()).ToLocalChecked())
     711             :             .FromJust());
     712          30 :   CHECK(env->Global()
     713             :             ->Set(env.local(), v8_str("obj"),
     714             :                   obj_templ->NewInstance(env.local()).ToLocalChecked())
     715             :             .FromJust());
     716          30 :   CHECK(env->Global()
     717             :             ->Set(env.local(), v8_str("obj2"),
     718             :                   obj_templ->NewInstance(env.local()).ToLocalChecked())
     719             :             .FromJust());
     720             : 
     721           5 :   security_check_value = true;
     722             :   CompileRun("var proto = new Fun();");
     723             :   CompileRun("obj.__proto__ = proto;");
     724           5 :   ExpectInt32("proto.foo", 907);
     725             : 
     726             :   // Test direct.
     727           5 :   security_check_value = true;
     728           5 :   ExpectInt32("obj.foo", 907);
     729           5 :   security_check_value = false;
     730             :   {
     731           5 :     v8::TryCatch try_catch(isolate);
     732             :     CompileRun("obj.foo");
     733           5 :     CHECK(try_catch.HasCaught());
     734             :   }
     735             : 
     736             :   // Test through call.
     737           5 :   security_check_value = true;
     738           5 :   ExpectInt32("proto.__lookupGetter__('foo').call(obj)", 907);
     739           5 :   security_check_value = false;
     740             :   {
     741           5 :     v8::TryCatch try_catch(isolate);
     742             :     CompileRun("proto.__lookupGetter__('foo').call(obj)");
     743           5 :     CHECK(try_catch.HasCaught());
     744             :   }
     745             : 
     746             :   // Test ics.
     747             :   CompileRun(
     748             :       "function f() {"
     749             :       "   var x;"
     750             :       "  for (var i = 0; i < 4; i++) {"
     751             :       "    x = obj.foo;"
     752             :       "  }"
     753             :       "  return x;"
     754             :       "}");
     755             : 
     756           5 :   security_check_value = true;
     757           5 :   ExpectInt32("f()", 907);
     758           5 :   security_check_value = false;
     759             :   {
     760           5 :     v8::TryCatch try_catch(isolate);
     761             :     CompileRun("f();");
     762           5 :     CHECK(try_catch.HasCaught());
     763             :   }
     764             : 
     765             :   // Test crankshaft.
     766             :   CompileRun("%OptimizeFunctionOnNextCall(f);");
     767             : 
     768           5 :   security_check_value = true;
     769           5 :   ExpectInt32("f()", 907);
     770           5 :   security_check_value = false;
     771             :   {
     772           5 :     v8::TryCatch try_catch(isolate);
     773             :     CompileRun("f();");
     774           5 :     CHECK(try_catch.HasCaught());
     775           5 :   }
     776           5 : }
     777             : 
     778          15 : static void CheckReceiver(Local<String> name,
     779             :                           const v8::PropertyCallbackInfo<v8::Value>& info) {
     780          15 :   CHECK(info.This()->IsObject());
     781          15 : }
     782             : 
     783       23723 : TEST(Regress609134) {
     784           5 :   LocalContext env;
     785           5 :   v8::Isolate* isolate = env->GetIsolate();
     786          10 :   v8::HandleScope scope(isolate);
     787           5 :   auto fun_templ = v8::FunctionTemplate::New(isolate);
     788          10 :   fun_templ->InstanceTemplate()->SetNativeDataProperty(v8_str("foo"),
     789          15 :                                                        CheckReceiver);
     790             : 
     791          30 :   CHECK(env->Global()
     792             :             ->Set(env.local(), v8_str("Fun"),
     793             :                   fun_templ->GetFunction(env.local()).ToLocalChecked())
     794             :             .FromJust());
     795             : 
     796             :   CompileRun(
     797             :       "var f = new Fun();"
     798             :       "Number.prototype.__proto__ = f;"
     799             :       "var a = 42;"
     800           5 :       "for (var i = 0; i<3; i++) { a.foo; }");
     801       71159 : }

Generated by: LCOV version 1.10