LCOV - code coverage report
Current view: top level - src - accessors.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 318 355 89.6 %
Date: 2017-10-20 Functions: 66 72 91.7 %

          Line data    Source code
       1             : // Copyright 2012 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 "src/accessors.h"
       6             : 
       7             : #include "src/api.h"
       8             : #include "src/contexts.h"
       9             : #include "src/deoptimizer.h"
      10             : #include "src/execution.h"
      11             : #include "src/factory.h"
      12             : #include "src/frames-inl.h"
      13             : #include "src/isolate-inl.h"
      14             : #include "src/messages.h"
      15             : #include "src/property-details.h"
      16             : #include "src/prototype.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : 
      21      105969 : Handle<AccessorInfo> Accessors::MakeAccessor(
      22             :     Isolate* isolate, Handle<Name> name, AccessorNameGetterCallback getter,
      23             :     AccessorNameBooleanSetterCallback setter, PropertyAttributes attributes) {
      24             :   Factory* factory = isolate->factory();
      25      105969 :   Handle<AccessorInfo> info = factory->NewAccessorInfo();
      26      105969 :   info->set_property_attributes(attributes);
      27      105969 :   info->set_all_can_read(false);
      28      105969 :   info->set_all_can_write(false);
      29      105969 :   info->set_is_special_data_property(true);
      30      105969 :   info->set_is_sloppy(false);
      31      105969 :   info->set_replace_on_access(false);
      32      105969 :   name = factory->InternalizeName(name);
      33      105969 :   info->set_name(*name);
      34      105969 :   Handle<Object> get = v8::FromCData(isolate, getter);
      35      105969 :   if (setter == nullptr) setter = &ReconfigureToDataProperty;
      36      105969 :   Handle<Object> set = v8::FromCData(isolate, setter);
      37      105969 :   info->set_getter(*get);
      38      105969 :   info->set_setter(*set);
      39      105969 :   Address redirected = info->redirected_getter();
      40      105969 :   if (redirected != nullptr) {
      41      104793 :     Handle<Object> js_get = v8::FromCData(isolate, redirected);
      42      104793 :     info->set_js_getter(*js_get);
      43             :   }
      44      105969 :   return info;
      45             : }
      46             : 
      47             : 
      48             : static V8_INLINE bool CheckForName(Handle<Name> name,
      49             :                                    Handle<String> property_name,
      50             :                                    int offset,
      51             :                                    int* object_offset) {
      52      105545 :   if (Name::Equals(name, property_name)) {
      53       96946 :     *object_offset = offset;
      54             :     return true;
      55             :   }
      56             :   return false;
      57             : }
      58             : 
      59             : 
      60             : // Returns true for properties that are accessors to object fields.
      61             : // If true, *object_offset contains offset of object field.
      62      284933 : bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
      63             :                                         int* object_offset) {
      64             :   Isolate* isolate = name->GetIsolate();
      65             : 
      66      284933 :   switch (map->instance_type()) {
      67             :     case JS_ARRAY_TYPE:
      68             :       return
      69             :         CheckForName(name, isolate->factory()->length_string(),
      70      101255 :                      JSArray::kLengthOffset, object_offset);
      71             :     default:
      72      183678 :       if (map->instance_type() < FIRST_NONSTRING_TYPE) {
      73             :         return CheckForName(name, isolate->factory()->length_string(),
      74        4290 :                             String::kLengthOffset, object_offset);
      75             :       }
      76             : 
      77             :       return false;
      78             :   }
      79             : }
      80             : 
      81             : 
      82             : namespace {
      83             : 
      84       12729 : MUST_USE_RESULT MaybeHandle<Object> ReplaceAccessorWithDataProperty(
      85             :     Isolate* isolate, Handle<Object> receiver, Handle<JSObject> holder,
      86             :     Handle<Name> name, Handle<Object> value) {
      87             :   LookupIterator it(receiver, name, holder,
      88       12729 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
      89             :   // Skip any access checks we might hit. This accessor should never hit in a
      90             :   // situation where the caller does not have access.
      91       12729 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
      92           0 :     CHECK(it.HasAccess());
      93           0 :     it.Next();
      94             :   }
      95             :   DCHECK(holder.is_identical_to(it.GetHolder<JSObject>()));
      96       12729 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
      97       12729 :   it.ReconfigureDataProperty(value, it.property_attributes());
      98       12729 :   return value;
      99             : }
     100             : 
     101             : }  // namespace
     102             : 
     103        1564 : void Accessors::ReconfigureToDataProperty(
     104             :     v8::Local<v8::Name> key, v8::Local<v8::Value> val,
     105             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     106             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     107             :   RuntimeCallTimerScope stats_scope(
     108        1564 :       isolate, &RuntimeCallStats::ReconfigureToDataProperty);
     109             :   HandleScope scope(isolate);
     110             :   Handle<Object> receiver = Utils::OpenHandle(*info.This());
     111             :   Handle<JSObject> holder =
     112        1564 :       Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
     113        1564 :   Handle<Name> name = Utils::OpenHandle(*key);
     114        1564 :   Handle<Object> value = Utils::OpenHandle(*val);
     115             :   MaybeHandle<Object> result =
     116        1564 :       ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value);
     117        1564 :   if (result.is_null()) {
     118           0 :     isolate->OptionalRescheduleException(false);
     119             :   } else {
     120             :     info.GetReturnValue().Set(true);
     121             :   }
     122        1564 : }
     123             : 
     124             : //
     125             : // Accessors::ArgumentsIterator
     126             : //
     127             : 
     128             : 
     129        5943 : void Accessors::ArgumentsIteratorGetter(
     130             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
     131             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     132             :   DisallowHeapAllocation no_allocation;
     133             :   HandleScope scope(isolate);
     134       11886 :   Object* result = isolate->native_context()->array_values_iterator();
     135             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
     136        5943 : }
     137             : 
     138             : 
     139          61 : Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
     140             :     Isolate* isolate, PropertyAttributes attributes) {
     141             :   Handle<Name> name = isolate->factory()->iterator_symbol();
     142             :   return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, nullptr,
     143          61 :                       attributes);
     144             : }
     145             : 
     146             : 
     147             : //
     148             : // Accessors::ArrayLength
     149             : //
     150             : 
     151             : 
     152      195736 : void Accessors::ArrayLengthGetter(
     153             :     v8::Local<v8::Name> name,
     154             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     155             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     156      195736 :   RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::ArrayLengthGetter);
     157             :   DisallowHeapAllocation no_allocation;
     158             :   HandleScope scope(isolate);
     159             :   JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
     160             :   Object* result = holder->length();
     161             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
     162      195736 : }
     163             : 
     164      526792 : void Accessors::ArrayLengthSetter(
     165             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
     166             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     167             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     168      526792 :   RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::ArrayLengthSetter);
     169             :   HandleScope scope(isolate);
     170             : 
     171             :   DCHECK(Utils::OpenHandle(*name)->SameValue(isolate->heap()->length_string()));
     172             : 
     173             :   Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
     174             :   Handle<JSArray> array = Handle<JSArray>::cast(object);
     175      526792 :   Handle<Object> length_obj = Utils::OpenHandle(*val);
     176             : 
     177      526792 :   bool was_readonly = JSArray::HasReadOnlyLength(array);
     178             : 
     179      526792 :   uint32_t length = 0;
     180      526792 :   if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
     181         256 :     isolate->OptionalRescheduleException(false);
     182         256 :     return;
     183             :   }
     184             : 
     185      526556 :   if (!was_readonly && V8_UNLIKELY(JSArray::HasReadOnlyLength(array)) &&
     186          20 :       length != array->length()->Number()) {
     187             :     // AnythingToArrayLength() may have called setter re-entrantly and modified
     188             :     // its property descriptor. Don't perform this check if "length" was
     189             :     // previously readonly, as this may have been called during
     190             :     // DefineOwnPropertyIgnoreAttributes().
     191          20 :     if (info.ShouldThrowOnError()) {
     192             :       Factory* factory = isolate->factory();
     193             :       isolate->Throw(*factory->NewTypeError(
     194             :           MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name),
     195          30 :           i::Object::TypeOf(isolate, object), object));
     196          10 :       isolate->OptionalRescheduleException(false);
     197             :     } else {
     198             :       info.GetReturnValue().Set(false);
     199             :     }
     200             :     return;
     201             :   }
     202             : 
     203      526516 :   JSArray::SetLength(array, length);
     204             : 
     205      526516 :   uint32_t actual_new_len = 0;
     206      526516 :   CHECK(array->length()->ToArrayLength(&actual_new_len));
     207             :   // Fail if there were non-deletable elements.
     208      526516 :   if (actual_new_len != length) {
     209          68 :     if (info.ShouldThrowOnError()) {
     210             :       Factory* factory = isolate->factory();
     211             :       isolate->Throw(*factory->NewTypeError(
     212             :           MessageTemplate::kStrictDeleteProperty,
     213          60 :           factory->NewNumberFromUint(actual_new_len - 1), array));
     214          30 :       isolate->OptionalRescheduleException(false);
     215             :     } else {
     216             :       info.GetReturnValue().Set(false);
     217             :     }
     218             :   } else {
     219             :     info.GetReturnValue().Set(true);
     220             :   }
     221             : }
     222             : 
     223             : 
     224         183 : Handle<AccessorInfo> Accessors::ArrayLengthInfo(
     225             :       Isolate* isolate, PropertyAttributes attributes) {
     226             :   return MakeAccessor(isolate,
     227             :                       isolate->factory()->length_string(),
     228             :                       &ArrayLengthGetter,
     229             :                       &ArrayLengthSetter,
     230         183 :                       attributes);
     231             : }
     232             : 
     233             : //
     234             : // Accessors::ModuleNamespaceEntry
     235             : //
     236             : 
     237       30320 : void Accessors::ModuleNamespaceEntryGetter(
     238             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
     239             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     240             :   HandleScope scope(isolate);
     241             :   JSModuleNamespace* holder =
     242             :       JSModuleNamespace::cast(*Utils::OpenHandle(*info.Holder()));
     243             :   Handle<Object> result;
     244       30320 :   if (!holder->GetExport(Handle<String>::cast(Utils::OpenHandle(*name)))
     245       60640 :            .ToHandle(&result)) {
     246          70 :     isolate->OptionalRescheduleException(false);
     247             :   } else {
     248             :     info.GetReturnValue().Set(Utils::ToLocal(result));
     249             :   }
     250       30320 : }
     251             : 
     252          20 : void Accessors::ModuleNamespaceEntrySetter(
     253             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
     254             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     255             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     256             :   HandleScope scope(isolate);
     257             :   Factory* factory = isolate->factory();
     258             :   Handle<JSModuleNamespace> holder =
     259             :       Handle<JSModuleNamespace>::cast(Utils::OpenHandle(*info.Holder()));
     260             : 
     261          20 :   if (info.ShouldThrowOnError()) {
     262             :     isolate->Throw(*factory->NewTypeError(
     263             :         MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name),
     264           0 :         i::Object::TypeOf(isolate, holder), holder));
     265           0 :     isolate->OptionalRescheduleException(false);
     266             :   } else {
     267             :     info.GetReturnValue().Set(false);
     268             :   }
     269          20 : }
     270             : 
     271       30140 : Handle<AccessorInfo> Accessors::ModuleNamespaceEntryInfo(
     272             :     Isolate* isolate, Handle<String> name, PropertyAttributes attributes) {
     273             :   return MakeAccessor(isolate, name, &ModuleNamespaceEntryGetter,
     274       30140 :                       &ModuleNamespaceEntrySetter, attributes);
     275             : }
     276             : 
     277             : 
     278             : //
     279             : // Accessors::StringLength
     280             : //
     281             : 
     282       30159 : void Accessors::StringLengthGetter(
     283             :     v8::Local<v8::Name> name,
     284             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     285             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     286       30159 :   RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::StringLengthGetter);
     287             :   DisallowHeapAllocation no_allocation;
     288             :   HandleScope scope(isolate);
     289             : 
     290             :   // We have a slight impedance mismatch between the external API and the way we
     291             :   // use callbacks internally: Externally, callbacks can only be used with
     292             :   // v8::Object, but internally we have callbacks on entities which are higher
     293             :   // in the hierarchy, in this case for String values.
     294             : 
     295             :   Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
     296       30159 :   if (!value->IsString()) {
     297             :     // Not a string value. That means that we either got a String wrapper or
     298             :     // a Value with a String wrapper in its prototype chain.
     299             :     value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
     300             :   }
     301             :   Object* result = Smi::FromInt(String::cast(value)->length());
     302             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
     303       30159 : }
     304             : 
     305             : 
     306          61 : Handle<AccessorInfo> Accessors::StringLengthInfo(
     307             :       Isolate* isolate, PropertyAttributes attributes) {
     308             :   return MakeAccessor(isolate, isolate->factory()->length_string(),
     309          61 :                       &StringLengthGetter, nullptr, attributes);
     310             : }
     311             : 
     312             : 
     313             : //
     314             : // Accessors::ScriptColumnOffset
     315             : //
     316             : 
     317             : 
     318           0 : void Accessors::ScriptColumnOffsetGetter(
     319             :     v8::Local<v8::Name> name,
     320             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     321             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     322             :   DisallowHeapAllocation no_allocation;
     323             :   HandleScope scope(isolate);
     324             :   Object* object = *Utils::OpenHandle(*info.Holder());
     325             :   Object* res = Smi::FromInt(
     326             :       Script::cast(JSValue::cast(object)->value())->column_offset());
     327             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
     328           0 : }
     329             : 
     330             : 
     331          61 : Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
     332             :       Isolate* isolate, PropertyAttributes attributes) {
     333             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     334          61 :       STATIC_CHAR_VECTOR("column_offset")));
     335             :   return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, nullptr,
     336          61 :                       attributes);
     337             : }
     338             : 
     339             : 
     340             : //
     341             : // Accessors::ScriptId
     342             : //
     343             : 
     344             : 
     345        3070 : void Accessors::ScriptIdGetter(
     346             :     v8::Local<v8::Name> name,
     347             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     348             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     349             :   DisallowHeapAllocation no_allocation;
     350             :   HandleScope scope(isolate);
     351             :   Object* object = *Utils::OpenHandle(*info.Holder());
     352             :   Object* id = Smi::FromInt(Script::cast(JSValue::cast(object)->value())->id());
     353             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
     354        3070 : }
     355             : 
     356             : 
     357          61 : Handle<AccessorInfo> Accessors::ScriptIdInfo(
     358             :       Isolate* isolate, PropertyAttributes attributes) {
     359             :   Handle<String> name(
     360          61 :       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
     361          61 :   return MakeAccessor(isolate, name, &ScriptIdGetter, nullptr, attributes);
     362             : }
     363             : 
     364             : 
     365             : //
     366             : // Accessors::ScriptName
     367             : //
     368             : 
     369             : 
     370        2104 : void Accessors::ScriptNameGetter(
     371             :     v8::Local<v8::Name> name,
     372             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     373             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     374             :   DisallowHeapAllocation no_allocation;
     375             :   HandleScope scope(isolate);
     376             :   Object* object = *Utils::OpenHandle(*info.Holder());
     377             :   Object* source = Script::cast(JSValue::cast(object)->value())->name();
     378             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
     379        2104 : }
     380             : 
     381             : 
     382          61 : Handle<AccessorInfo> Accessors::ScriptNameInfo(
     383             :       Isolate* isolate, PropertyAttributes attributes) {
     384             :   return MakeAccessor(isolate, isolate->factory()->name_string(),
     385          61 :                       &ScriptNameGetter, nullptr, attributes);
     386             : }
     387             : 
     388             : 
     389             : //
     390             : // Accessors::ScriptSource
     391             : //
     392             : 
     393             : 
     394        2513 : void Accessors::ScriptSourceGetter(
     395             :     v8::Local<v8::Name> name,
     396             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     397             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     398             :   DisallowHeapAllocation no_allocation;
     399             :   HandleScope scope(isolate);
     400             :   Object* object = *Utils::OpenHandle(*info.Holder());
     401             :   Object* source = Script::cast(JSValue::cast(object)->value())->source();
     402             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
     403        2513 : }
     404             : 
     405             : 
     406          61 : Handle<AccessorInfo> Accessors::ScriptSourceInfo(
     407             :       Isolate* isolate, PropertyAttributes attributes) {
     408             :   return MakeAccessor(isolate, isolate->factory()->source_string(),
     409          61 :                       &ScriptSourceGetter, nullptr, attributes);
     410             : }
     411             : 
     412             : 
     413             : //
     414             : // Accessors::ScriptLineOffset
     415             : //
     416             : 
     417             : 
     418        4840 : void Accessors::ScriptLineOffsetGetter(
     419             :     v8::Local<v8::Name> name,
     420             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     421             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     422             :   DisallowHeapAllocation no_allocation;
     423             :   HandleScope scope(isolate);
     424             :   Object* object = *Utils::OpenHandle(*info.Holder());
     425             :   Object* res =
     426             :       Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
     427             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
     428        4840 : }
     429             : 
     430             : 
     431          61 : Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
     432             :       Isolate* isolate, PropertyAttributes attributes) {
     433             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     434          61 :       STATIC_CHAR_VECTOR("line_offset")));
     435             :   return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, nullptr,
     436          61 :                       attributes);
     437             : }
     438             : 
     439             : 
     440             : //
     441             : // Accessors::ScriptType
     442             : //
     443             : 
     444             : 
     445         210 : void Accessors::ScriptTypeGetter(
     446             :     v8::Local<v8::Name> name,
     447             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     448             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     449             :   DisallowHeapAllocation no_allocation;
     450             :   HandleScope scope(isolate);
     451             :   Object* object = *Utils::OpenHandle(*info.Holder());
     452             :   Object* res =
     453             :       Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
     454             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
     455         210 : }
     456             : 
     457             : 
     458          61 : Handle<AccessorInfo> Accessors::ScriptTypeInfo(
     459             :       Isolate* isolate, PropertyAttributes attributes) {
     460             :   Handle<String> name(
     461          61 :       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
     462          61 :   return MakeAccessor(isolate, name, &ScriptTypeGetter, nullptr, attributes);
     463             : }
     464             : 
     465             : 
     466             : //
     467             : // Accessors::ScriptCompilationType
     468             : //
     469             : 
     470             : 
     471           0 : void Accessors::ScriptCompilationTypeGetter(
     472             :     v8::Local<v8::Name> name,
     473             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     474             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     475             :   DisallowHeapAllocation no_allocation;
     476             :   HandleScope scope(isolate);
     477             :   Object* object = *Utils::OpenHandle(*info.Holder());
     478             :   Object* res = Smi::FromInt(
     479           0 :       Script::cast(JSValue::cast(object)->value())->compilation_type());
     480             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
     481           0 : }
     482             : 
     483             : 
     484          61 : Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
     485             :       Isolate* isolate, PropertyAttributes attributes) {
     486             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     487          61 :       STATIC_CHAR_VECTOR("compilation_type")));
     488             :   return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, nullptr,
     489          61 :                       attributes);
     490             : }
     491             : 
     492             : 
     493             : //
     494             : // Accessors::ScriptSourceUrl
     495             : //
     496             : 
     497             : 
     498        2480 : void Accessors::ScriptSourceUrlGetter(
     499             :     v8::Local<v8::Name> name,
     500             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     501             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     502             :   DisallowHeapAllocation no_allocation;
     503             :   HandleScope scope(isolate);
     504             :   Object* object = *Utils::OpenHandle(*info.Holder());
     505             :   Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
     506             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
     507        2480 : }
     508             : 
     509             : 
     510          61 : Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
     511             :       Isolate* isolate, PropertyAttributes attributes) {
     512             :   return MakeAccessor(isolate, isolate->factory()->source_url_string(),
     513          61 :                       &ScriptSourceUrlGetter, nullptr, attributes);
     514             : }
     515             : 
     516             : 
     517             : //
     518             : // Accessors::ScriptSourceMappingUrl
     519             : //
     520             : 
     521             : 
     522           0 : void Accessors::ScriptSourceMappingUrlGetter(
     523             :     v8::Local<v8::Name> name,
     524             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     525             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     526             :   DisallowHeapAllocation no_allocation;
     527             :   HandleScope scope(isolate);
     528             :   Object* object = *Utils::OpenHandle(*info.Holder());
     529             :   Object* url =
     530             :       Script::cast(JSValue::cast(object)->value())->source_mapping_url();
     531             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
     532           0 : }
     533             : 
     534             : 
     535          61 : Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
     536             :       Isolate* isolate, PropertyAttributes attributes) {
     537             :   return MakeAccessor(isolate, isolate->factory()->source_mapping_url_string(),
     538          61 :                       &ScriptSourceMappingUrlGetter, nullptr, attributes);
     539             : }
     540             : 
     541             : 
     542             : //
     543             : // Accessors::ScriptGetContextData
     544             : //
     545             : 
     546             : 
     547        3572 : void Accessors::ScriptContextDataGetter(
     548             :     v8::Local<v8::Name> name,
     549             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     550             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     551             :   DisallowHeapAllocation no_allocation;
     552             :   HandleScope scope(isolate);
     553             :   Object* object = *Utils::OpenHandle(*info.Holder());
     554             :   Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
     555             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
     556        3572 : }
     557             : 
     558             : 
     559          61 : Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
     560             :       Isolate* isolate, PropertyAttributes attributes) {
     561             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     562          61 :       STATIC_CHAR_VECTOR("context_data")));
     563             :   return MakeAccessor(isolate, name, &ScriptContextDataGetter, nullptr,
     564          61 :                       attributes);
     565             : }
     566             : 
     567             : 
     568             : //
     569             : // Accessors::ScriptGetEvalFromScript
     570             : //
     571             : 
     572             : 
     573           0 : void Accessors::ScriptEvalFromScriptGetter(
     574             :     v8::Local<v8::Name> name,
     575             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     576             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     577             :   HandleScope scope(isolate);
     578             :   Handle<Object> object = Utils::OpenHandle(*info.Holder());
     579             :   Handle<Script> script(
     580             :       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
     581             :   Handle<Object> result = isolate->factory()->undefined_value();
     582           0 :   if (!script->eval_from_shared()->IsUndefined(isolate)) {
     583             :     Handle<SharedFunctionInfo> eval_from_shared(
     584             :         SharedFunctionInfo::cast(script->eval_from_shared()));
     585           0 :     if (eval_from_shared->script()->IsScript()) {
     586             :       Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
     587           0 :       result = Script::GetWrapper(eval_from_script);
     588             :     }
     589             :   }
     590             : 
     591             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     592           0 : }
     593             : 
     594             : 
     595          61 : Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
     596             :       Isolate* isolate, PropertyAttributes attributes) {
     597             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     598          61 :       STATIC_CHAR_VECTOR("eval_from_script")));
     599             :   return MakeAccessor(isolate, name, &ScriptEvalFromScriptGetter, nullptr,
     600          61 :                       attributes);
     601             : }
     602             : 
     603             : 
     604             : //
     605             : // Accessors::ScriptGetEvalFromScriptPosition
     606             : //
     607             : 
     608             : 
     609           0 : void Accessors::ScriptEvalFromScriptPositionGetter(
     610             :     v8::Local<v8::Name> name,
     611             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     612             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     613             :   HandleScope scope(isolate);
     614             :   Handle<Object> object = Utils::OpenHandle(*info.Holder());
     615             :   Handle<Script> script(
     616             :       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
     617             :   Handle<Object> result = isolate->factory()->undefined_value();
     618           0 :   if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
     619           0 :     result = Handle<Object>(Smi::FromInt(script->GetEvalPosition()), isolate);
     620             :   }
     621             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     622           0 : }
     623             : 
     624             : 
     625          61 : Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
     626             :       Isolate* isolate, PropertyAttributes attributes) {
     627             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     628          61 :       STATIC_CHAR_VECTOR("eval_from_script_position")));
     629             :   return MakeAccessor(isolate, name, &ScriptEvalFromScriptPositionGetter,
     630          61 :                       nullptr, attributes);
     631             : }
     632             : 
     633             : 
     634             : //
     635             : // Accessors::ScriptGetEvalFromFunctionName
     636             : //
     637             : 
     638             : 
     639           0 : void Accessors::ScriptEvalFromFunctionNameGetter(
     640             :     v8::Local<v8::Name> name,
     641             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     642             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     643             :   HandleScope scope(isolate);
     644             :   Handle<Object> object = Utils::OpenHandle(*info.Holder());
     645             :   Handle<Script> script(
     646             :       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
     647             :   Handle<Object> result = isolate->factory()->undefined_value();
     648           0 :   if (!script->eval_from_shared()->IsUndefined(isolate)) {
     649             :     Handle<SharedFunctionInfo> shared(
     650             :         SharedFunctionInfo::cast(script->eval_from_shared()));
     651             :     // Find the name of the function calling eval.
     652             :     result = Handle<Object>(shared->name(), isolate);
     653             :   }
     654             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     655           0 : }
     656             : 
     657             : 
     658          61 : Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
     659             :       Isolate* isolate, PropertyAttributes attributes) {
     660             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     661          61 :       STATIC_CHAR_VECTOR("eval_from_function_name")));
     662             :   return MakeAccessor(isolate, name, &ScriptEvalFromFunctionNameGetter, nullptr,
     663          61 :                       attributes);
     664             : }
     665             : 
     666             : 
     667             : //
     668             : // Accessors::FunctionPrototype
     669             : //
     670             : 
     671      251883 : static Handle<Object> GetFunctionPrototype(Isolate* isolate,
     672             :                                            Handle<JSFunction> function) {
     673      251883 :   if (!function->has_prototype()) {
     674       86847 :     Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
     675       86847 :     JSFunction::SetPrototype(function, proto);
     676             :   }
     677      503766 :   return Handle<Object>(function->prototype(), isolate);
     678             : }
     679             : 
     680      251883 : void Accessors::FunctionPrototypeGetter(
     681             :     v8::Local<v8::Name> name,
     682             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     683             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     684             :   RuntimeCallTimerScope timer(isolate,
     685      251883 :                               &RuntimeCallStats::FunctionPrototypeGetter);
     686             :   HandleScope scope(isolate);
     687             :   Handle<JSFunction> function =
     688      251883 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     689      251883 :   Handle<Object> result = GetFunctionPrototype(isolate, function);
     690             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     691      251883 : }
     692             : 
     693      332928 : void Accessors::FunctionPrototypeSetter(
     694             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
     695             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     696             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     697             :   RuntimeCallTimerScope timer(isolate,
     698      332928 :                               &RuntimeCallStats::FunctionPrototypeSetter);
     699             :   HandleScope scope(isolate);
     700      332928 :   Handle<Object> value = Utils::OpenHandle(*val);
     701             :   Handle<JSFunction> object =
     702      332928 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     703      332928 :   JSFunction::SetPrototype(object, value);
     704             :   info.GetReturnValue().Set(true);
     705      332928 : }
     706             : 
     707             : 
     708         549 : Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
     709             :       Isolate* isolate, PropertyAttributes attributes) {
     710             :   return MakeAccessor(isolate,
     711             :                       isolate->factory()->prototype_string(),
     712             :                       &FunctionPrototypeGetter,
     713             :                       &FunctionPrototypeSetter,
     714         549 :                       attributes);
     715             : }
     716             : 
     717             : 
     718             : //
     719             : // Accessors::FunctionLength
     720             : //
     721             : 
     722             : 
     723       17234 : void Accessors::FunctionLengthGetter(
     724             :     v8::Local<v8::Name> name,
     725             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     726             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     727             :   HandleScope scope(isolate);
     728             :   Handle<JSFunction> function =
     729       17234 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     730             :   int length = 0;
     731       34468 :   if (!JSFunction::GetLength(isolate, function).To(&length)) {
     732         285 :     isolate->OptionalRescheduleException(false);
     733             :   }
     734             :   Handle<Object> result(Smi::FromInt(length), isolate);
     735             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     736       17234 : }
     737             : 
     738         915 : Handle<AccessorInfo> Accessors::FunctionLengthInfo(
     739             :       Isolate* isolate, PropertyAttributes attributes) {
     740             :   return MakeAccessor(isolate, isolate->factory()->length_string(),
     741             :                       &FunctionLengthGetter, &ReconfigureToDataProperty,
     742         915 :                       attributes);
     743             : }
     744             : 
     745             : 
     746             : //
     747             : // Accessors::FunctionName
     748             : //
     749             : 
     750             : 
     751       69088 : void Accessors::FunctionNameGetter(
     752             :     v8::Local<v8::Name> name,
     753             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     754             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     755             :   HandleScope scope(isolate);
     756             :   Handle<JSFunction> function =
     757       69088 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     758       69088 :   Handle<Object> result = JSFunction::GetName(isolate, function);
     759             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     760       69088 : }
     761             : 
     762       70563 : Handle<AccessorInfo> Accessors::FunctionNameInfo(
     763             :       Isolate* isolate, PropertyAttributes attributes) {
     764             :   return MakeAccessor(isolate, isolate->factory()->name_string(),
     765             :                       &FunctionNameGetter, &ReconfigureToDataProperty,
     766       70563 :                       attributes);
     767             : }
     768             : 
     769             : 
     770             : //
     771             : // Accessors::FunctionArguments
     772             : //
     773             : 
     774             : 
     775        2517 : static Handle<Object> ArgumentsForInlinedFunction(
     776             :     JavaScriptFrame* frame,
     777             :     Handle<JSFunction> inlined_function,
     778             :     int inlined_frame_index) {
     779             :   Isolate* isolate = inlined_function->GetIsolate();
     780             :   Factory* factory = isolate->factory();
     781             : 
     782        2517 :   TranslatedState translated_values(frame);
     783        2517 :   translated_values.Prepare(frame->fp());
     784             : 
     785        2517 :   int argument_count = 0;
     786             :   TranslatedFrame* translated_frame =
     787             :       translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
     788        2517 :                                                          &argument_count);
     789             :   TranslatedFrame::iterator iter = translated_frame->begin();
     790             : 
     791             :   // Skip the function.
     792             :   iter++;
     793             : 
     794             :   // Skip the receiver.
     795             :   iter++;
     796        2517 :   argument_count--;
     797             : 
     798             :   Handle<JSObject> arguments =
     799        2517 :       factory->NewArgumentsObject(inlined_function, argument_count);
     800        2517 :   Handle<FixedArray> array = factory->NewFixedArray(argument_count);
     801             :   bool should_deoptimize = false;
     802        9667 :   for (int i = 0; i < argument_count; ++i) {
     803             :     // If we materialize any object, we should deoptimize the frame because we
     804             :     // might alias an object that was eliminated by escape analysis.
     805       14286 :     should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
     806        7150 :     Handle<Object> value = iter->GetValue();
     807        7150 :     array->set(i, *value);
     808             :     iter++;
     809             :   }
     810        2517 :   arguments->set_elements(*array);
     811             : 
     812        2517 :   if (should_deoptimize) {
     813         146 :     translated_values.StoreMaterializedValuesAndDeopt(frame);
     814             :   }
     815             : 
     816             :   // Return the freshly allocated arguments object.
     817        5034 :   return arguments;
     818             : }
     819             : 
     820             : 
     821      202427 : static int FindFunctionInFrame(JavaScriptFrame* frame,
     822             :                                Handle<JSFunction> function) {
     823             :   std::vector<FrameSummary> frames;
     824      202427 :   frame->Summarize(&frames);
     825      757103 :   for (size_t i = frames.size(); i != 0; i--) {
     826      426080 :     if (*frames[i - 1].AsJavaScript().function() == *function) {
     827       63218 :       return static_cast<int>(i) - 1;
     828             :     }
     829             :   }
     830      202427 :   return -1;
     831             : }
     832             : 
     833             : 
     834             : namespace {
     835             : 
     836       64244 : Handle<Object> GetFunctionArguments(Isolate* isolate,
     837             :                                     Handle<JSFunction> function) {
     838             :   // Find the top invocation of the function by traversing frames.
     839      406906 :   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
     840             :     JavaScriptFrame* frame = it.frame();
     841      202427 :     int function_index = FindFunctionInFrame(frame, function);
     842      341636 :     if (function_index < 0) continue;
     843             : 
     844       63218 :     if (function_index > 0) {
     845             :       // The function in question was inlined.  Inlined functions have the
     846             :       // correct number of arguments and no allocated arguments object, so
     847             :       // we can construct a fresh one by interpreting the function's
     848             :       // deoptimization input data.
     849       65735 :       return ArgumentsForInlinedFunction(frame, function, function_index);
     850             :     }
     851             : 
     852             :     // Find the frame that holds the actual arguments passed to the function.
     853       60701 :     if (it.frame()->has_adapted_arguments()) {
     854             :       it.AdvanceOneFrame();
     855             :       DCHECK(it.frame()->is_arguments_adaptor());
     856             :     }
     857             :     frame = it.frame();
     858             : 
     859             :     // Get the number of arguments and construct an arguments object
     860             :     // mirror for the right frame.
     861       60701 :     const int length = frame->ComputeParametersCount();
     862             :     Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
     863       60701 :         function, length);
     864       60701 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
     865             : 
     866             :     // Copy the parameters to the arguments object.
     867             :     DCHECK(array->length() == length);
     868      195889 :     for (int i = 0; i < length; i++) {
     869      135188 :       Object* value = frame->GetParameter(i);
     870      135188 :       if (value->IsTheHole(isolate)) {
     871             :         // Generators currently use holes as dummy arguments when resuming.  We
     872             :         // must not leak those.
     873             :         DCHECK(IsResumableFunction(function->shared()->kind()));
     874          88 :         value = isolate->heap()->undefined_value();
     875             :       }
     876      135188 :       array->set(i, value);
     877             :     }
     878       60701 :     arguments->set_elements(*array);
     879             : 
     880             :     // Return the freshly allocated arguments object.
     881       60701 :     return arguments;
     882             :   }
     883             : 
     884             :   // No frame corresponding to the given function found. Return null.
     885        1026 :   return isolate->factory()->null_value();
     886             : }
     887             : 
     888             : }  // namespace
     889             : 
     890             : 
     891       10114 : Handle<JSObject> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
     892             :   Handle<Object> arguments =
     893       10114 :       GetFunctionArguments(function->GetIsolate(), function);
     894       10114 :   CHECK(arguments->IsJSObject());
     895       10114 :   return Handle<JSObject>::cast(arguments);
     896             : }
     897             : 
     898             : 
     899       54130 : void Accessors::FunctionArgumentsGetter(
     900             :     v8::Local<v8::Name> name,
     901             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     902             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     903             :   HandleScope scope(isolate);
     904             :   Handle<JSFunction> function =
     905             :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     906             :   Handle<Object> result =
     907             :       function->shared()->native()
     908             :           ? Handle<Object>::cast(isolate->factory()->null_value())
     909      108260 :           : GetFunctionArguments(isolate, function);
     910             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     911       54130 : }
     912             : 
     913             : 
     914         305 : Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
     915             :       Isolate* isolate, PropertyAttributes attributes) {
     916             :   return MakeAccessor(isolate, isolate->factory()->arguments_string(),
     917         305 :                       &FunctionArgumentsGetter, nullptr, attributes);
     918             : }
     919             : 
     920             : 
     921             : //
     922             : // Accessors::FunctionCaller
     923             : //
     924             : 
     925             : 
     926             : static inline bool AllowAccessToFunction(Context* current_context,
     927             :                                          JSFunction* function) {
     928       17879 :   return current_context->HasSameSecurityTokenAs(function->context());
     929             : }
     930             : 
     931             : 
     932        3787 : class FrameFunctionIterator {
     933             :  public:
     934        3787 :   explicit FrameFunctionIterator(Isolate* isolate)
     935       11361 :       : isolate_(isolate), frame_iterator_(isolate), inlined_frame_index_(-1) {
     936             :     GetFrames();
     937        3787 :   }
     938             : 
     939             :   // Iterate through functions until the first occurrence of 'function'.
     940             :   // Returns true if one is found, and false if the iterator ends before.
     941        3787 :   bool Find(Handle<JSFunction> function) {
     942       10662 :     do {
     943       23432 :       if (!next().ToHandle(&function_)) return false;
     944             :     } while (!function_.is_identical_to(function));
     945             :     return true;
     946             :   }
     947             : 
     948             :   // Iterate through functions until the next non-toplevel one is found.
     949             :   // Returns true if one is found, and false if the iterator ends before.
     950        2733 :   bool FindNextNonTopLevel() {
     951        4811 :     do {
     952        9778 :       if (!next().ToHandle(&function_)) return false;
     953             :     } while (function_->shared()->is_toplevel());
     954             :     return true;
     955             :   }
     956             : 
     957             :   // Iterate through function until the first native or user-provided function
     958             :   // is found. Functions not defined in user-provided scripts are not visible
     959             :   // unless directly exposed, in which case the native flag is set on them.
     960             :   // Returns true if one is found, and false if the iterator ends before.
     961        2655 :   bool FindFirstNativeOrUserJavaScript() {
     962        7926 :     while (!function_->shared()->native() &&
     963        2586 :            !function_->shared()->IsUserJavaScript()) {
     964          60 :       if (!next().ToHandle(&function_)) return false;
     965             :     }
     966             :     return true;
     967             :   }
     968             : 
     969             :   // In case of inlined frames the function could have been materialized from
     970             :   // deoptimization information. If that is the case we need to make sure that
     971             :   // subsequent call will see the same function, since we are about to hand out
     972             :   // the value to JavaScript. Make sure to store the materialized value and
     973             :   // trigger a deoptimization of the underlying frame.
     974        2655 :   Handle<JSFunction> MaterializeFunction() {
     975        2655 :     if (inlined_frame_index_ == 0) return function_;
     976             : 
     977             :     JavaScriptFrame* frame = frame_iterator_.frame();
     978          36 :     TranslatedState translated_values(frame);
     979          36 :     translated_values.Prepare(frame->fp());
     980             : 
     981             :     TranslatedFrame* translated_frame =
     982          36 :         translated_values.GetFrameFromJSFrameIndex(inlined_frame_index_);
     983             :     TranslatedFrame::iterator iter = translated_frame->begin();
     984             : 
     985             :     // First value is the function.
     986          36 :     bool should_deoptimize = iter->IsMaterializedObject();
     987          36 :     Handle<Object> value = iter->GetValue();
     988          36 :     if (should_deoptimize) {
     989          21 :       translated_values.StoreMaterializedValuesAndDeopt(frame);
     990             :     }
     991             : 
     992             :     return Handle<JSFunction>::cast(value);
     993             :   }
     994             : 
     995             :  private:
     996       16635 :   MaybeHandle<JSFunction> next() {
     997             :     while (true) {
     998       16665 :       inlined_frame_index_--;
     999       16665 :       if (inlined_frame_index_ == -1) {
    1000        9889 :         if (!frame_iterator_.done()) {
    1001        9889 :           frame_iterator_.Advance();
    1002       15533 :           frames_.clear();
    1003             :           GetFrames();
    1004             :         }
    1005        9889 :         if (inlined_frame_index_ == -1) return MaybeHandle<JSFunction>();
    1006        8757 :         inlined_frame_index_--;
    1007             :       }
    1008             :       Handle<JSFunction> next_function =
    1009       15533 :           frames_[inlined_frame_index_].AsJavaScript().function();
    1010             :       // Skip functions from other origins.
    1011       31066 :       if (!AllowAccessToFunction(isolate_->context(), *next_function)) continue;
    1012       15503 :       return next_function;
    1013             :     }
    1014             :   }
    1015             :   void GetFrames() {
    1016             :     DCHECK_EQ(-1, inlined_frame_index_);
    1017       13676 :     if (frame_iterator_.done()) return;
    1018             :     JavaScriptFrame* frame = frame_iterator_.frame();
    1019       12544 :     frame->Summarize(&frames_);
    1020       12544 :     inlined_frame_index_ = static_cast<int>(frames_.size());
    1021             :     DCHECK_LT(0, inlined_frame_index_);
    1022             :   }
    1023             :   Isolate* isolate_;
    1024             :   Handle<JSFunction> function_;
    1025             :   JavaScriptFrameIterator frame_iterator_;
    1026             :   std::vector<FrameSummary> frames_;
    1027             :   int inlined_frame_index_;
    1028             : };
    1029             : 
    1030             : 
    1031        6133 : MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
    1032             :                                    Handle<JSFunction> function) {
    1033        3787 :   FrameFunctionIterator it(isolate);
    1034        3787 :   if (function->shared()->native()) {
    1035           0 :     return MaybeHandle<JSFunction>();
    1036             :   }
    1037             :   // Find the function from the frames. Return null in case no frame
    1038             :   // corresponding to the given function was found.
    1039        3787 :   if (!it.Find(function)) {
    1040        1054 :     return MaybeHandle<JSFunction>();
    1041             :   }
    1042             :   // Find previously called non-toplevel function.
    1043        2733 :   if (!it.FindNextNonTopLevel()) {
    1044          78 :     return MaybeHandle<JSFunction>();
    1045             :   }
    1046             :   // Find the first user-land JavaScript function (or the entry point into
    1047             :   // native JavaScript builtins in case such a builtin was the caller).
    1048        2655 :   if (!it.FindFirstNativeOrUserJavaScript()) {
    1049           0 :     return MaybeHandle<JSFunction>();
    1050             :   }
    1051             : 
    1052             :   // Materialize the function that the iterator is currently sitting on. Note
    1053             :   // that this might trigger deoptimization in case the function was actually
    1054             :   // materialized. Identity of the function must be preserved because we are
    1055             :   // going to return it to JavaScript after this point.
    1056        2655 :   Handle<JSFunction> caller = it.MaterializeFunction();
    1057             : 
    1058             :   // Censor if the caller is not a sloppy mode function.
    1059             :   // Change from ES5, which used to throw, see:
    1060             :   // https://bugs.ecmascript.org/show_bug.cgi?id=310
    1061        2655 :   if (is_strict(caller->shared()->language_mode())) {
    1062         309 :     return MaybeHandle<JSFunction>();
    1063             :   }
    1064             :   // Don't return caller from another security context.
    1065        2346 :   if (!AllowAccessToFunction(isolate->context(), *caller)) {
    1066           0 :     return MaybeHandle<JSFunction>();
    1067             :   }
    1068        2346 :   return caller;
    1069             : }
    1070             : 
    1071             : 
    1072        3787 : void Accessors::FunctionCallerGetter(
    1073             :     v8::Local<v8::Name> name,
    1074             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
    1075             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1076             :   HandleScope scope(isolate);
    1077             :   Handle<JSFunction> function =
    1078        3787 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
    1079             :   Handle<Object> result;
    1080             :   MaybeHandle<JSFunction> maybe_caller;
    1081        3787 :   maybe_caller = FindCaller(isolate, function);
    1082             :   Handle<JSFunction> caller;
    1083        3787 :   if (maybe_caller.ToHandle(&caller)) {
    1084             :     result = caller;
    1085             :   } else {
    1086             :     result = isolate->factory()->null_value();
    1087             :   }
    1088             :   info.GetReturnValue().Set(Utils::ToLocal(result));
    1089        3787 : }
    1090             : 
    1091             : 
    1092         305 : Handle<AccessorInfo> Accessors::FunctionCallerInfo(
    1093             :       Isolate* isolate, PropertyAttributes attributes) {
    1094             :   return MakeAccessor(isolate, isolate->factory()->caller_string(),
    1095         305 :                       &FunctionCallerGetter, nullptr, attributes);
    1096             : }
    1097             : 
    1098             : 
    1099             : //
    1100             : // Accessors::BoundFunctionLength
    1101             : //
    1102             : 
    1103         342 : void Accessors::BoundFunctionLengthGetter(
    1104             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
    1105             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1106             :   RuntimeCallTimerScope timer(isolate,
    1107         342 :                               &RuntimeCallStats::BoundFunctionLengthGetter);
    1108             :   HandleScope scope(isolate);
    1109             :   Handle<JSBoundFunction> function =
    1110         342 :       Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
    1111             : 
    1112             :   int length = 0;
    1113         684 :   if (!JSBoundFunction::GetLength(isolate, function).To(&length)) {
    1114           0 :     isolate->OptionalRescheduleException(false);
    1115         342 :     return;
    1116             :   }
    1117             :   Handle<Object> result(Smi::FromInt(length), isolate);
    1118             :   info.GetReturnValue().Set(Utils::ToLocal(result));
    1119             : }
    1120             : 
    1121          61 : Handle<AccessorInfo> Accessors::BoundFunctionLengthInfo(
    1122             :     Isolate* isolate, PropertyAttributes attributes) {
    1123             :   return MakeAccessor(isolate, isolate->factory()->length_string(),
    1124             :                       &BoundFunctionLengthGetter, &ReconfigureToDataProperty,
    1125          61 :                       attributes);
    1126             : }
    1127             : 
    1128             : //
    1129             : // Accessors::BoundFunctionName
    1130             : //
    1131             : 
    1132          82 : void Accessors::BoundFunctionNameGetter(
    1133             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
    1134             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1135             :   RuntimeCallTimerScope timer(isolate,
    1136          82 :                               &RuntimeCallStats::BoundFunctionNameGetter);
    1137             :   HandleScope scope(isolate);
    1138             :   Handle<JSBoundFunction> function =
    1139          82 :       Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
    1140             :   Handle<Object> result;
    1141         164 :   if (!JSBoundFunction::GetName(isolate, function).ToHandle(&result)) {
    1142           0 :     isolate->OptionalRescheduleException(false);
    1143          82 :     return;
    1144             :   }
    1145             :   info.GetReturnValue().Set(Utils::ToLocal(result));
    1146             : }
    1147             : 
    1148          61 : Handle<AccessorInfo> Accessors::BoundFunctionNameInfo(
    1149             :     Isolate* isolate, PropertyAttributes attributes) {
    1150             :   return MakeAccessor(isolate, isolate->factory()->name_string(),
    1151             :                       &BoundFunctionNameGetter, &ReconfigureToDataProperty,
    1152          61 :                       attributes);
    1153             : }
    1154             : 
    1155             : //
    1156             : // Accessors::ErrorStack
    1157             : //
    1158             : 
    1159             : namespace {
    1160             : 
    1161       12119 : MaybeHandle<JSReceiver> ClearInternalStackTrace(Isolate* isolate,
    1162             :                                                 Handle<JSObject> error) {
    1163       24238 :   RETURN_ON_EXCEPTION(
    1164             :       isolate,
    1165             :       JSReceiver::SetProperty(error, isolate->factory()->stack_trace_symbol(),
    1166             :                               isolate->factory()->undefined_value(),
    1167             :                               LanguageMode::kStrict),
    1168             :       JSReceiver);
    1169       12119 :   return error;
    1170             : }
    1171             : 
    1172       12041 : bool IsAccessor(Handle<Object> receiver, Handle<Name> name,
    1173             :                 Handle<JSObject> holder) {
    1174             :   LookupIterator it(receiver, name, holder,
    1175       12041 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    1176             :   // Skip any access checks we might hit. This accessor should never hit in a
    1177             :   // situation where the caller does not have access.
    1178       12041 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    1179           0 :     CHECK(it.HasAccess());
    1180           0 :     it.Next();
    1181             :   }
    1182       12041 :   return (it.state() == LookupIterator::ACCESSOR);
    1183             : }
    1184             : 
    1185             : }  // namespace
    1186             : 
    1187       12245 : void Accessors::ErrorStackGetter(
    1188             :     v8::Local<v8::Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
    1189             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1190             :   HandleScope scope(isolate);
    1191             :   Handle<JSObject> holder =
    1192             :       Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
    1193             : 
    1194             :   // Retrieve the structured stack trace.
    1195             : 
    1196             :   Handle<Object> stack_trace;
    1197             :   Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol();
    1198             :   MaybeHandle<Object> maybe_stack_trace =
    1199       12245 :       JSObject::GetProperty(holder, stack_trace_symbol);
    1200       24490 :   if (!maybe_stack_trace.ToHandle(&stack_trace) ||
    1201             :       stack_trace->IsUndefined(isolate)) {
    1202             :     Handle<Object> result = isolate->factory()->undefined_value();
    1203             :     info.GetReturnValue().Set(Utils::ToLocal(result));
    1204             :     return;
    1205             :   }
    1206             : 
    1207             :   // Format it, clear the internal structured trace and reconfigure as a data
    1208             :   // property.
    1209             : 
    1210             :   Handle<Object> formatted_stack_trace;
    1211       12157 :   if (!ErrorUtils::FormatStackTrace(isolate, holder, stack_trace)
    1212       24314 :            .ToHandle(&formatted_stack_trace)) {
    1213         116 :     isolate->OptionalRescheduleException(false);
    1214         116 :     return;
    1215             :   }
    1216             : 
    1217       12041 :   MaybeHandle<Object> result = ClearInternalStackTrace(isolate, holder);
    1218       12041 :   if (result.is_null()) {
    1219           0 :     isolate->OptionalRescheduleException(false);
    1220           0 :     return;
    1221             :   }
    1222             : 
    1223             :   // If stack is still an accessor (this could have changed in the meantime
    1224             :   // since FormatStackTrace can execute arbitrary JS), replace it with a data
    1225             :   // property.
    1226             :   Handle<Object> receiver =
    1227       12041 :       Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
    1228       12041 :   Handle<Name> name = Utils::OpenHandle(*key);
    1229       12041 :   if (IsAccessor(receiver, name, holder)) {
    1230             :     result = ReplaceAccessorWithDataProperty(isolate, receiver, holder, name,
    1231       11165 :                                              formatted_stack_trace);
    1232       11165 :     if (result.is_null()) {
    1233           0 :       isolate->OptionalRescheduleException(false);
    1234           0 :       return;
    1235             :     }
    1236             :   } else {
    1237             :     // The stack property has been modified in the meantime.
    1238        1752 :     if (!JSObject::GetProperty(holder, name).ToHandle(&formatted_stack_trace)) {
    1239           0 :       isolate->OptionalRescheduleException(false);
    1240           0 :       return;
    1241             :     }
    1242             :   }
    1243             : 
    1244             :   v8::Local<v8::Value> value = Utils::ToLocal(formatted_stack_trace);
    1245             :   info.GetReturnValue().Set(value);
    1246             : }
    1247             : 
    1248          78 : void Accessors::ErrorStackSetter(
    1249             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
    1250             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
    1251             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1252             :   HandleScope scope(isolate);
    1253             :   Handle<JSObject> obj = Handle<JSObject>::cast(
    1254             :       Utils::OpenHandle(*v8::Local<v8::Value>(info.This())));
    1255             : 
    1256             :   // Clear internal properties to avoid memory leaks.
    1257             :   Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol();
    1258         156 :   if (JSReceiver::HasOwnProperty(obj, stack_trace_symbol).FromMaybe(false)) {
    1259          78 :     ClearInternalStackTrace(isolate, obj);
    1260             :   }
    1261             : 
    1262          78 :   Accessors::ReconfigureToDataProperty(name, val, info);
    1263          78 : }
    1264             : 
    1265         790 : Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate,
    1266             :                                                PropertyAttributes attributes) {
    1267             :   Handle<AccessorInfo> info =
    1268             :       MakeAccessor(isolate, isolate->factory()->stack_string(),
    1269         790 :                    &ErrorStackGetter, &ErrorStackSetter, attributes);
    1270         790 :   return info;
    1271             : }
    1272             : 
    1273             : }  // namespace internal
    1274             : }  // namespace v8

Generated by: LCOV version 1.10