LCOV - code coverage report
Current view: top level - src - accessors.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 289 325 88.9 %
Date: 2017-04-26 Functions: 63 69 91.3 %

          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/list-inl.h"
      15             : #include "src/messages.h"
      16             : #include "src/property-details.h"
      17             : #include "src/prototype.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22       53859 : Handle<AccessorInfo> Accessors::MakeAccessor(
      23             :     Isolate* isolate, Handle<Name> name, AccessorNameGetterCallback getter,
      24             :     AccessorNameBooleanSetterCallback setter, PropertyAttributes attributes) {
      25             :   Factory* factory = isolate->factory();
      26       53859 :   Handle<AccessorInfo> info = factory->NewAccessorInfo();
      27             :   info->set_property_attributes(attributes);
      28             :   info->set_all_can_read(false);
      29             :   info->set_all_can_write(false);
      30             :   info->set_is_special_data_property(true);
      31             :   info->set_is_sloppy(false);
      32             :   info->set_replace_on_access(false);
      33       53859 :   name = factory->InternalizeName(name);
      34       53859 :   info->set_name(*name);
      35       53859 :   Handle<Object> get = v8::FromCData(isolate, getter);
      36       53859 :   if (setter == nullptr) setter = &ReconfigureToDataProperty;
      37       53859 :   Handle<Object> set = v8::FromCData(isolate, setter);
      38       53859 :   info->set_getter(*get);
      39       53859 :   info->set_setter(*set);
      40       53859 :   Address redirected = info->redirected_getter();
      41       53859 :   if (redirected != nullptr) {
      42       52487 :     Handle<Object> js_get = v8::FromCData(isolate, redirected);
      43       52487 :     info->set_js_getter(*js_get);
      44             :   }
      45       53859 :   return info;
      46             : }
      47             : 
      48             : 
      49             : static V8_INLINE bool CheckForName(Handle<Name> name,
      50             :                                    Handle<String> property_name,
      51             :                                    int offset,
      52             :                                    int* object_offset) {
      53      329851 :   if (Name::Equals(name, property_name)) {
      54      246773 :     *object_offset = offset;
      55             :     return true;
      56             :   }
      57             :   return false;
      58             : }
      59             : 
      60             : 
      61             : // Returns true for properties that are accessors to object fields.
      62             : // If true, *object_offset contains offset of object field.
      63     1222505 : bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
      64             :                                         int* object_offset) {
      65             :   Isolate* isolate = name->GetIsolate();
      66             : 
      67     1222505 :   switch (map->instance_type()) {
      68             :     case JS_ARRAY_TYPE:
      69             :       return
      70             :         CheckForName(name, isolate->factory()->length_string(),
      71      267590 :                      JSArray::kLengthOffset, object_offset);
      72             :     default:
      73      954915 :       if (map->instance_type() < FIRST_NONSTRING_TYPE) {
      74             :         return CheckForName(name, isolate->factory()->length_string(),
      75       62261 :                             String::kLengthOffset, object_offset);
      76             :       }
      77             : 
      78             :       return false;
      79             :   }
      80             : }
      81             : 
      82             : 
      83             : namespace {
      84             : 
      85     1514402 : MUST_USE_RESULT MaybeHandle<Object> ReplaceAccessorWithDataProperty(
      86             :     Isolate* isolate, Handle<Object> receiver, Handle<JSObject> holder,
      87             :     Handle<Name> name, Handle<Object> value) {
      88             :   LookupIterator it(receiver, name, holder,
      89     1514402 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
      90             :   // Skip any access checks we might hit. This accessor should never hit in a
      91             :   // situation where the caller does not have access.
      92     1514404 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
      93           0 :     CHECK(it.HasAccess());
      94           0 :     it.Next();
      95             :   }
      96             :   DCHECK(holder.is_identical_to(it.GetHolder<JSObject>()));
      97     1514404 :   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
      98     1514404 :   it.ReconfigureDataProperty(value, it.property_attributes());
      99     1514402 :   return value;
     100             : }
     101             : 
     102             : }  // namespace
     103             : 
     104     1491626 : void Accessors::ReconfigureToDataProperty(
     105             :     v8::Local<v8::Name> key, v8::Local<v8::Value> val,
     106             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     107             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     108             :   HandleScope scope(isolate);
     109             :   Handle<Object> receiver = Utils::OpenHandle(*info.This());
     110             :   Handle<JSObject> holder =
     111     1491626 :       Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
     112     1491626 :   Handle<Name> name = Utils::OpenHandle(*key);
     113     1491626 :   Handle<Object> value = Utils::OpenHandle(*val);
     114             :   MaybeHandle<Object> result =
     115     1491626 :       ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value);
     116     1491633 :   if (result.is_null()) {
     117           0 :     isolate->OptionalRescheduleException(false);
     118             :   } else {
     119             :     info.GetReturnValue().Set(true);
     120             :   }
     121     1491629 : }
     122             : 
     123             : //
     124             : // Accessors::ArgumentsIterator
     125             : //
     126             : 
     127             : 
     128        9324 : void Accessors::ArgumentsIteratorGetter(
     129             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
     130             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     131             :   DisallowHeapAllocation no_allocation;
     132             :   HandleScope scope(isolate);
     133       18648 :   Object* result = isolate->native_context()->array_values_iterator();
     134             :   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
     135        9324 : }
     136             : 
     137             : 
     138          79 : Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
     139             :     Isolate* isolate, PropertyAttributes attributes) {
     140             :   Handle<Name> name = isolate->factory()->iterator_symbol();
     141             :   return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, nullptr,
     142          79 :                       attributes);
     143             : }
     144             : 
     145             : 
     146             : //
     147             : // Accessors::ArrayLength
     148             : //
     149             : 
     150             : 
     151      533389 : void Accessors::ArrayLengthGetter(
     152             :     v8::Local<v8::Name> name,
     153             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     154             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     155             :   RuntimeCallTimerScope timer(
     156      533389 :       isolate, &RuntimeCallStats::AccessorNameGetterCallback_ArrayLength);
     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      533389 : }
     163             : 
     164     1003395 : 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             :   HandleScope scope(isolate);
     169             : 
     170             :   DCHECK(Utils::OpenHandle(*name)->SameValue(isolate->heap()->length_string()));
     171             : 
     172             :   Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
     173             :   Handle<JSArray> array = Handle<JSArray>::cast(object);
     174     1003395 :   Handle<Object> length_obj = Utils::OpenHandle(*val);
     175             : 
     176     1003395 :   bool was_readonly = JSArray::HasReadOnlyLength(array);
     177             : 
     178     1003395 :   uint32_t length = 0;
     179     1003395 :   if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
     180         386 :     isolate->OptionalRescheduleException(false);
     181         386 :     return;
     182             :   }
     183             : 
     184     1003039 :   if (!was_readonly && V8_UNLIKELY(JSArray::HasReadOnlyLength(array)) &&
     185          30 :       length != array->length()->Number()) {
     186             :     // AnythingToArrayLength() may have called setter re-entrantly and modified
     187             :     // its property descriptor. Don't perform this check if "length" was
     188             :     // previously readonly, as this may have been called during
     189             :     // DefineOwnPropertyIgnoreAttributes().
     190          30 :     if (info.ShouldThrowOnError()) {
     191             :       Factory* factory = isolate->factory();
     192             :       isolate->Throw(*factory->NewTypeError(
     193             :           MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name),
     194          45 :           i::Object::TypeOf(isolate, object), object));
     195          15 :       isolate->OptionalRescheduleException(false);
     196             :     } else {
     197             :       info.GetReturnValue().Set(false);
     198             :     }
     199             :     return;
     200             :   }
     201             : 
     202     1002979 :   JSArray::SetLength(array, length);
     203             : 
     204     1002979 :   uint32_t actual_new_len = 0;
     205     1002979 :   CHECK(array->length()->ToArrayLength(&actual_new_len));
     206             :   // Fail if there were non-deletable elements.
     207     1002979 :   if (actual_new_len != length) {
     208         103 :     if (info.ShouldThrowOnError()) {
     209             :       Factory* factory = isolate->factory();
     210             :       isolate->Throw(*factory->NewTypeError(
     211             :           MessageTemplate::kStrictDeleteProperty,
     212          90 :           factory->NewNumberFromUint(actual_new_len - 1), array));
     213          45 :       isolate->OptionalRescheduleException(false);
     214             :     } else {
     215             :       info.GetReturnValue().Set(false);
     216             :     }
     217             :   } else {
     218             :     info.GetReturnValue().Set(true);
     219             :   }
     220             : }
     221             : 
     222             : 
     223         316 : Handle<AccessorInfo> Accessors::ArrayLengthInfo(
     224             :       Isolate* isolate, PropertyAttributes attributes) {
     225             :   return MakeAccessor(isolate,
     226             :                       isolate->factory()->length_string(),
     227             :                       &ArrayLengthGetter,
     228             :                       &ArrayLengthSetter,
     229         316 :                       attributes);
     230             : }
     231             : 
     232             : //
     233             : // Accessors::ModuleNamespaceEntry
     234             : //
     235             : 
     236         853 : void Accessors::ModuleNamespaceEntryGetter(
     237             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
     238             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     239             :   HandleScope scope(isolate);
     240             :   JSModuleNamespace* holder =
     241             :       JSModuleNamespace::cast(*Utils::OpenHandle(*info.Holder()));
     242             :   Handle<Object> result;
     243         853 :   if (!holder->GetExport(Handle<String>::cast(Utils::OpenHandle(*name)))
     244        1706 :            .ToHandle(&result)) {
     245         105 :     isolate->OptionalRescheduleException(false);
     246             :   } else {
     247             :     info.GetReturnValue().Set(Utils::ToLocal(result));
     248             :   }
     249         853 : }
     250             : 
     251          15 : void Accessors::ModuleNamespaceEntrySetter(
     252             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
     253             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     254             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     255             :   HandleScope scope(isolate);
     256             :   Factory* factory = isolate->factory();
     257             :   Handle<JSModuleNamespace> holder =
     258             :       Handle<JSModuleNamespace>::cast(Utils::OpenHandle(*info.Holder()));
     259             : 
     260          15 :   if (info.ShouldThrowOnError()) {
     261             :     isolate->Throw(*factory->NewTypeError(
     262             :         MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name),
     263           0 :         i::Object::TypeOf(isolate, holder), holder));
     264           0 :     isolate->OptionalRescheduleException(false);
     265             :   } else {
     266             :     info.GetReturnValue().Set(false);
     267             :   }
     268          15 : }
     269             : 
     270         611 : Handle<AccessorInfo> Accessors::ModuleNamespaceEntryInfo(
     271             :     Isolate* isolate, Handle<String> name, PropertyAttributes attributes) {
     272             :   return MakeAccessor(isolate, name, &ModuleNamespaceEntryGetter,
     273         611 :                       &ModuleNamespaceEntrySetter, attributes);
     274             : }
     275             : 
     276             : 
     277             : //
     278             : // Accessors::StringLength
     279             : //
     280             : 
     281       47285 : void Accessors::StringLengthGetter(
     282             :     v8::Local<v8::Name> name,
     283             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     284             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     285             :   RuntimeCallTimerScope timer(
     286       47285 :       isolate, &RuntimeCallStats::AccessorNameGetterCallback_StringLength);
     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       47285 :   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       47285 : }
     304             : 
     305             : 
     306          79 : Handle<AccessorInfo> Accessors::StringLengthInfo(
     307             :       Isolate* isolate, PropertyAttributes attributes) {
     308             :   return MakeAccessor(isolate, isolate->factory()->length_string(),
     309          79 :                       &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          79 : Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
     332             :       Isolate* isolate, PropertyAttributes attributes) {
     333             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     334          79 :       STATIC_CHAR_VECTOR("column_offset")));
     335             :   return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, nullptr,
     336          79 :                       attributes);
     337             : }
     338             : 
     339             : 
     340             : //
     341             : // Accessors::ScriptId
     342             : //
     343             : 
     344             : 
     345      717059 : 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      717059 : }
     355             : 
     356             : 
     357          79 : Handle<AccessorInfo> Accessors::ScriptIdInfo(
     358             :       Isolate* isolate, PropertyAttributes attributes) {
     359             :   Handle<String> name(
     360          79 :       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
     361          79 :   return MakeAccessor(isolate, name, &ScriptIdGetter, nullptr, attributes);
     362             : }
     363             : 
     364             : 
     365             : //
     366             : // Accessors::ScriptName
     367             : //
     368             : 
     369             : 
     370        3602 : 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        3602 : }
     380             : 
     381             : 
     382          79 : Handle<AccessorInfo> Accessors::ScriptNameInfo(
     383             :       Isolate* isolate, PropertyAttributes attributes) {
     384             :   return MakeAccessor(isolate, isolate->factory()->name_string(),
     385          79 :                       &ScriptNameGetter, nullptr, attributes);
     386             : }
     387             : 
     388             : 
     389             : //
     390             : // Accessors::ScriptSource
     391             : //
     392             : 
     393             : 
     394        2748 : 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        2748 : }
     404             : 
     405             : 
     406          79 : Handle<AccessorInfo> Accessors::ScriptSourceInfo(
     407             :       Isolate* isolate, PropertyAttributes attributes) {
     408             :   return MakeAccessor(isolate, isolate->factory()->source_string(),
     409          79 :                       &ScriptSourceGetter, nullptr, attributes);
     410             : }
     411             : 
     412             : 
     413             : //
     414             : // Accessors::ScriptLineOffset
     415             : //
     416             : 
     417             : 
     418        7608 : 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        7608 : }
     429             : 
     430             : 
     431          79 : Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
     432             :       Isolate* isolate, PropertyAttributes attributes) {
     433             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     434          79 :       STATIC_CHAR_VECTOR("line_offset")));
     435             :   return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, nullptr,
     436          79 :                       attributes);
     437             : }
     438             : 
     439             : 
     440             : //
     441             : // Accessors::ScriptType
     442             : //
     443             : 
     444             : 
     445         321 : 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         321 : }
     456             : 
     457             : 
     458          79 : Handle<AccessorInfo> Accessors::ScriptTypeInfo(
     459             :       Isolate* isolate, PropertyAttributes attributes) {
     460             :   Handle<String> name(
     461          79 :       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
     462          79 :   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          79 : Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
     485             :       Isolate* isolate, PropertyAttributes attributes) {
     486             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     487          79 :       STATIC_CHAR_VECTOR("compilation_type")));
     488             :   return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, nullptr,
     489          79 :                       attributes);
     490             : }
     491             : 
     492             : 
     493             : //
     494             : // Accessors::ScriptSourceUrl
     495             : //
     496             : 
     497             : 
     498        4548 : 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        4548 : }
     508             : 
     509             : 
     510          79 : Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
     511             :       Isolate* isolate, PropertyAttributes attributes) {
     512             :   return MakeAccessor(isolate, isolate->factory()->source_url_string(),
     513          79 :                       &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          79 : Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
     536             :       Isolate* isolate, PropertyAttributes attributes) {
     537             :   return MakeAccessor(isolate, isolate->factory()->source_mapping_url_string(),
     538          79 :                       &ScriptSourceMappingUrlGetter, nullptr, attributes);
     539             : }
     540             : 
     541             : 
     542             : //
     543             : // Accessors::ScriptGetContextData
     544             : //
     545             : 
     546             : 
     547      516638 : 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      516638 : }
     557             : 
     558             : 
     559          79 : Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
     560             :       Isolate* isolate, PropertyAttributes attributes) {
     561             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     562          79 :       STATIC_CHAR_VECTOR("context_data")));
     563             :   return MakeAccessor(isolate, name, &ScriptContextDataGetter, nullptr,
     564          79 :                       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          79 : Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
     596             :       Isolate* isolate, PropertyAttributes attributes) {
     597             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     598          79 :       STATIC_CHAR_VECTOR("eval_from_script")));
     599             :   return MakeAccessor(isolate, name, &ScriptEvalFromScriptGetter, nullptr,
     600          79 :                       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          79 : Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
     626             :       Isolate* isolate, PropertyAttributes attributes) {
     627             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     628          79 :       STATIC_CHAR_VECTOR("eval_from_script_position")));
     629             :   return MakeAccessor(isolate, name, &ScriptEvalFromScriptPositionGetter,
     630          79 :                       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           0 :     if (!shared->name()->IsUndefined(isolate)) {
     653             :       result = Handle<Object>(shared->name(), isolate);
     654             :     } else {
     655           0 :       result = Handle<Object>(shared->inferred_name(), isolate);
     656             :     }
     657             :   }
     658             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     659           0 : }
     660             : 
     661             : 
     662          79 : Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
     663             :       Isolate* isolate, PropertyAttributes attributes) {
     664             :   Handle<String> name(isolate->factory()->InternalizeOneByteString(
     665          79 :       STATIC_CHAR_VECTOR("eval_from_function_name")));
     666             :   return MakeAccessor(isolate, name, &ScriptEvalFromFunctionNameGetter, nullptr,
     667          79 :                       attributes);
     668             : }
     669             : 
     670             : 
     671             : //
     672             : // Accessors::FunctionPrototype
     673             : //
     674             : 
     675      210768 : static Handle<Object> GetFunctionPrototype(Isolate* isolate,
     676             :                                            Handle<JSFunction> function) {
     677      210768 :   if (!function->has_prototype()) {
     678      119781 :     Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
     679      119781 :     JSFunction::SetPrototype(function, proto);
     680             :   }
     681      421536 :   return Handle<Object>(function->prototype(), isolate);
     682             : }
     683             : 
     684      210768 : void Accessors::FunctionPrototypeGetter(
     685             :     v8::Local<v8::Name> name,
     686             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     687             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     688             :   RuntimeCallTimerScope timer(
     689      210768 :       isolate, &RuntimeCallStats::AccessorNameGetterCallback_FunctionPrototype);
     690             :   HandleScope scope(isolate);
     691             :   Handle<JSFunction> function =
     692      210768 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     693      210768 :   Handle<Object> result = GetFunctionPrototype(isolate, function);
     694             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     695      210768 : }
     696             : 
     697      408301 : void Accessors::FunctionPrototypeSetter(
     698             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
     699             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
     700             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     701             :   HandleScope scope(isolate);
     702      408301 :   Handle<Object> value = Utils::OpenHandle(*val);
     703             :   Handle<JSFunction> object =
     704      408301 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     705      408301 :   JSFunction::SetPrototype(object, value);
     706             :   info.GetReturnValue().Set(true);
     707      408301 : }
     708             : 
     709             : 
     710         407 : Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
     711             :       Isolate* isolate, PropertyAttributes attributes) {
     712             :   return MakeAccessor(isolate,
     713             :                       isolate->factory()->prototype_string(),
     714             :                       &FunctionPrototypeGetter,
     715             :                       &FunctionPrototypeSetter,
     716         407 :                       attributes);
     717             : }
     718             : 
     719             : 
     720             : //
     721             : // Accessors::FunctionLength
     722             : //
     723             : 
     724             : 
     725       23870 : void Accessors::FunctionLengthGetter(
     726             :     v8::Local<v8::Name> name,
     727             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     728             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     729             :   HandleScope scope(isolate);
     730             :   Handle<JSFunction> function =
     731       23870 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     732             :   Handle<Object> result;
     733       47740 :   if (!JSFunction::GetLength(isolate, function).ToHandle(&result)) {
     734             :     result = handle(Smi::kZero, isolate);
     735         292 :     isolate->OptionalRescheduleException(false);
     736             :   }
     737             : 
     738             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     739       23870 : }
     740             : 
     741         644 : Handle<AccessorInfo> Accessors::FunctionLengthInfo(
     742             :       Isolate* isolate, PropertyAttributes attributes) {
     743             :   return MakeAccessor(isolate, isolate->factory()->length_string(),
     744             :                       &FunctionLengthGetter, &ReconfigureToDataProperty,
     745         644 :                       attributes);
     746             : }
     747             : 
     748             : 
     749             : //
     750             : // Accessors::FunctionName
     751             : //
     752             : 
     753             : 
     754      117513 : void Accessors::FunctionNameGetter(
     755             :     v8::Local<v8::Name> name,
     756             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     757             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     758             :   HandleScope scope(isolate);
     759             :   Handle<JSFunction> function =
     760      117513 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     761      117513 :   Handle<Object> result = JSFunction::GetName(isolate, function);
     762             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     763      117513 : }
     764             : 
     765       47713 : Handle<AccessorInfo> Accessors::FunctionNameInfo(
     766             :       Isolate* isolate, PropertyAttributes attributes) {
     767             :   return MakeAccessor(isolate, isolate->factory()->name_string(),
     768             :                       &FunctionNameGetter, &ReconfigureToDataProperty,
     769       47713 :                       attributes);
     770             : }
     771             : 
     772             : 
     773             : //
     774             : // Accessors::FunctionArguments
     775             : //
     776             : 
     777             : 
     778       13597 : static Handle<Object> ArgumentsForInlinedFunction(
     779             :     JavaScriptFrame* frame,
     780             :     Handle<JSFunction> inlined_function,
     781             :     int inlined_frame_index) {
     782             :   Isolate* isolate = inlined_function->GetIsolate();
     783             :   Factory* factory = isolate->factory();
     784             : 
     785       13597 :   TranslatedState translated_values(frame);
     786       13597 :   translated_values.Prepare(false, frame->fp());
     787             : 
     788       13597 :   int argument_count = 0;
     789             :   TranslatedFrame* translated_frame =
     790             :       translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
     791       13597 :                                                          &argument_count);
     792             :   TranslatedFrame::iterator iter = translated_frame->begin();
     793             : 
     794             :   // Skip the function.
     795             :   iter++;
     796             : 
     797             :   // Skip the receiver.
     798             :   iter++;
     799       13597 :   argument_count--;
     800             : 
     801             :   Handle<JSObject> arguments =
     802       13597 :       factory->NewArgumentsObject(inlined_function, argument_count);
     803       13597 :   Handle<FixedArray> array = factory->NewFixedArray(argument_count);
     804             :   bool should_deoptimize = false;
     805       48862 :   for (int i = 0; i < argument_count; ++i) {
     806             :     // If we materialize any object, we should deoptimize the frame because we
     807             :     // might alias an object that was eliminated by escape analysis.
     808       70520 :     should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
     809       35265 :     Handle<Object> value = iter->GetValue();
     810       35265 :     array->set(i, *value);
     811             :     iter++;
     812             :   }
     813       13597 :   arguments->set_elements(*array);
     814             : 
     815       13597 :   if (should_deoptimize) {
     816         111 :     translated_values.StoreMaterializedValuesAndDeopt(frame);
     817             :   }
     818             : 
     819             :   // Return the freshly allocated arguments object.
     820       27194 :   return arguments;
     821             : }
     822             : 
     823             : 
     824      336870 : static int FindFunctionInFrame(JavaScriptFrame* frame,
     825             :                                Handle<JSFunction> function) {
     826             :   DisallowHeapAllocation no_allocation;
     827             :   List<FrameSummary> frames(2);
     828      336870 :   frame->Summarize(&frames);
     829      605278 :   for (int i = frames.length() - 1; i >= 0; i--) {
     830      732386 :     if (*frames[i].AsJavaScript().function() == *function) return i;
     831             :   }
     832             :   return -1;
     833             : }
     834             : 
     835             : 
     836             : namespace {
     837             : 
     838       99738 : Handle<Object> GetFunctionArguments(Isolate* isolate,
     839             :                                     Handle<JSFunction> function) {
     840             :   // Find the top invocation of the function by traversing frames.
     841      677646 :   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
     842             :     JavaScriptFrame* frame = it.frame();
     843      336870 :     int function_index = FindFunctionInFrame(frame, function);
     844      575955 :     if (function_index < 0) continue;
     845             : 
     846       97785 :     if (function_index > 0) {
     847             :       // The function in question was inlined.  Inlined functions have the
     848             :       // correct number of arguments and no allocated arguments object, so
     849             :       // we can construct a fresh one by interpreting the function's
     850             :       // deoptimization input data.
     851      111382 :       return ArgumentsForInlinedFunction(frame, function, function_index);
     852             :     }
     853             : 
     854             :     // Find the frame that holds the actual arguments passed to the function.
     855       84188 :     it.AdvanceToArgumentsFrame();
     856             :     frame = it.frame();
     857             : 
     858             :     // Get the number of arguments and construct an arguments object
     859             :     // mirror for the right frame.
     860       84188 :     const int length = frame->ComputeParametersCount();
     861             :     Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
     862       84188 :         function, length);
     863       84188 :     Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
     864             : 
     865             :     // Copy the parameters to the arguments object.
     866             :     DCHECK(array->length() == length);
     867      270112 :     for (int i = 0; i < length; i++) {
     868      185924 :       Object* value = frame->GetParameter(i);
     869      185924 :       if (value->IsTheHole(isolate)) {
     870             :         // Generators currently use holes as dummy arguments when resuming.  We
     871             :         // must not leak those.
     872             :         DCHECK(IsResumableFunction(function->shared()->kind()));
     873         224 :         value = isolate->heap()->undefined_value();
     874             :       }
     875      185924 :       array->set(i, value);
     876             :     }
     877       84188 :     arguments->set_elements(*array);
     878             : 
     879             :     // Return the freshly allocated arguments object.
     880       84188 :     return arguments;
     881             :   }
     882             : 
     883             :   // No frame corresponding to the given function found. Return null.
     884        1953 :   return isolate->factory()->null_value();
     885             : }
     886             : 
     887             : }  // namespace
     888             : 
     889             : 
     890       15293 : Handle<JSObject> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
     891             :   Handle<Object> arguments =
     892       15293 :       GetFunctionArguments(function->GetIsolate(), function);
     893       15293 :   CHECK(arguments->IsJSObject());
     894       15293 :   return Handle<JSObject>::cast(arguments);
     895             : }
     896             : 
     897             : 
     898       88398 : void Accessors::FunctionArgumentsGetter(
     899             :     v8::Local<v8::Name> name,
     900             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
     901             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
     902             :   HandleScope scope(isolate);
     903             :   Handle<JSFunction> function =
     904             :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
     905             :   Handle<Object> result =
     906             :       function->shared()->native()
     907             :           ? Handle<Object>::cast(isolate->factory()->null_value())
     908      172843 :           : GetFunctionArguments(isolate, function);
     909             :   info.GetReturnValue().Set(Utils::ToLocal(result));
     910       88398 : }
     911             : 
     912             : 
     913         328 : Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
     914             :       Isolate* isolate, PropertyAttributes attributes) {
     915             :   return MakeAccessor(isolate, isolate->factory()->arguments_string(),
     916         328 :                       &FunctionArgumentsGetter, nullptr, attributes);
     917             : }
     918             : 
     919             : 
     920             : //
     921             : // Accessors::FunctionCaller
     922             : //
     923             : 
     924             : 
     925             : static inline bool AllowAccessToFunction(Context* current_context,
     926             :                                          JSFunction* function) {
     927       30613 :   return current_context->HasSameSecurityTokenAs(function->context());
     928             : }
     929             : 
     930             : 
     931             : class FrameFunctionIterator {
     932             :  public:
     933        9872 :   FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
     934       19744 :       : isolate_(isolate), frame_iterator_(isolate), frames_(2), index_(0) {
     935        9872 :     GetFrames();
     936        9872 :   }
     937       29145 :   JSFunction* next() {
     938             :     while (true) {
     939       56297 :       if (frames_.length() == 0) return NULL;
     940       27107 :       JSFunction* next_function = *frames_[index_].AsJavaScript().function();
     941       27107 :       index_--;
     942       27107 :       if (index_ < 0) {
     943       24822 :         GetFrames();
     944             :       }
     945             :       // Skip functions from other origins.
     946       54214 :       if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
     947             :       return next_function;
     948             :     }
     949             :   }
     950             : 
     951             :   // Iterate through functions until the first occurence of 'function'.
     952             :   // Returns true if 'function' is found, and false if the iterator ends
     953             :   // without finding it.
     954             :   bool Find(JSFunction* function) {
     955             :     JSFunction* next_function;
     956       17798 :     do {
     957       21766 :       next_function = next();
     958       21766 :       if (next_function == function) return true;
     959             :     } while (next_function != NULL);
     960             :     return false;
     961             :   }
     962             : 
     963             :  private:
     964       34694 :   void GetFrames() {
     965       32536 :     frames_.Rewind(0);
     966       69388 :     if (frame_iterator_.done()) return;
     967             :     JavaScriptFrame* frame = frame_iterator_.frame();
     968       32536 :     frame->Summarize(&frames_);
     969             :     DCHECK(frames_.length() > 0);
     970       32536 :     frame_iterator_.Advance();
     971       32536 :     index_ = frames_.length() - 1;
     972             :   }
     973             :   Isolate* isolate_;
     974             :   JavaScriptFrameIterator frame_iterator_;
     975             :   List<FrameSummary> frames_;
     976             :   int index_;
     977             : };
     978             : 
     979             : 
     980       13378 : MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
     981             :                                    Handle<JSFunction> function) {
     982             :   DisallowHeapAllocation no_allocation;
     983        9872 :   FrameFunctionIterator it(isolate, no_allocation);
     984        9872 :   if (function->shared()->native()) {
     985             :     return MaybeHandle<JSFunction>();
     986             :   }
     987             :   // Find the function from the frames.
     988        5934 :   if (!it.Find(*function)) {
     989             :     // No frame corresponding to the given function found. Return null.
     990             :     return MaybeHandle<JSFunction>();
     991             :   }
     992             :   // Find previously called non-toplevel function.
     993             :   JSFunction* caller;
     994        7086 :   do {
     995        7203 :     caller = it.next();
     996        7203 :     if (caller == NULL) return MaybeHandle<JSFunction>();
     997             :   } while (caller->shared()->is_toplevel());
     998             : 
     999             :   // If caller is not user code and caller's caller is also not user code,
    1000             :   // use that instead.
    1001             :   JSFunction* potential_caller = caller;
    1002        8054 :   while (potential_caller != NULL &&
    1003        4027 :          !potential_caller->shared()->IsUserJavaScript()) {
    1004             :     caller = potential_caller;
    1005         176 :     potential_caller = it.next();
    1006             :   }
    1007        3851 :   if (!caller->shared()->native() && potential_caller != NULL) {
    1008             :     caller = potential_caller;
    1009             :   }
    1010             :   // Censor if the caller is not a sloppy mode function.
    1011             :   // Change from ES5, which used to throw, see:
    1012             :   // https://bugs.ecmascript.org/show_bug.cgi?id=310
    1013        3851 :   if (is_strict(caller->shared()->language_mode())) {
    1014             :     return MaybeHandle<JSFunction>();
    1015             :   }
    1016             :   // Don't return caller from another security context.
    1017        3506 :   if (!AllowAccessToFunction(isolate->context(), caller)) {
    1018             :     return MaybeHandle<JSFunction>();
    1019             :   }
    1020             :   return Handle<JSFunction>(caller);
    1021             : }
    1022             : 
    1023             : 
    1024        9872 : void Accessors::FunctionCallerGetter(
    1025             :     v8::Local<v8::Name> name,
    1026             :     const v8::PropertyCallbackInfo<v8::Value>& info) {
    1027             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1028             :   HandleScope scope(isolate);
    1029             :   Handle<JSFunction> function =
    1030        9872 :       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
    1031             :   Handle<Object> result;
    1032             :   MaybeHandle<JSFunction> maybe_caller;
    1033        9872 :   maybe_caller = FindCaller(isolate, function);
    1034             :   Handle<JSFunction> caller;
    1035        9872 :   if (maybe_caller.ToHandle(&caller)) {
    1036             :     result = caller;
    1037             :   } else {
    1038             :     result = isolate->factory()->null_value();
    1039             :   }
    1040             :   info.GetReturnValue().Set(Utils::ToLocal(result));
    1041        9872 : }
    1042             : 
    1043             : 
    1044         328 : Handle<AccessorInfo> Accessors::FunctionCallerInfo(
    1045             :       Isolate* isolate, PropertyAttributes attributes) {
    1046             :   return MakeAccessor(isolate, isolate->factory()->caller_string(),
    1047         328 :                       &FunctionCallerGetter, nullptr, attributes);
    1048             : }
    1049             : 
    1050             : 
    1051             : //
    1052             : // Accessors::BoundFunctionLength
    1053             : //
    1054             : 
    1055         521 : void Accessors::BoundFunctionLengthGetter(
    1056             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
    1057             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1058             :   RuntimeCallTimerScope timer(
    1059             :       isolate,
    1060         521 :       &RuntimeCallStats::AccessorNameGetterCallback_BoundFunctionLength);
    1061             :   HandleScope scope(isolate);
    1062             :   Handle<JSBoundFunction> function =
    1063             :       Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
    1064             : 
    1065             :   Handle<Smi> target_length;
    1066             :   Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
    1067             :                             isolate);
    1068        1042 :   if (!JSFunction::GetLength(isolate, target).ToHandle(&target_length)) {
    1069             :     target_length = handle(Smi::kZero, isolate);
    1070           0 :     isolate->OptionalRescheduleException(false);
    1071         521 :     return;
    1072             :   }
    1073             : 
    1074             :   int bound_length = function->bound_arguments()->length();
    1075         521 :   int length = Max(0, target_length->value() - bound_length);
    1076             : 
    1077             :   Handle<Object> result(Smi::FromInt(length), isolate);
    1078             :   info.GetReturnValue().Set(Utils::ToLocal(result));
    1079             : }
    1080             : 
    1081          79 : Handle<AccessorInfo> Accessors::BoundFunctionLengthInfo(
    1082             :     Isolate* isolate, PropertyAttributes attributes) {
    1083             :   return MakeAccessor(isolate, isolate->factory()->length_string(),
    1084             :                       &BoundFunctionLengthGetter, &ReconfigureToDataProperty,
    1085          79 :                       attributes);
    1086             : }
    1087             : 
    1088             : //
    1089             : // Accessors::BoundFunctionName
    1090             : //
    1091             : 
    1092         341 : void Accessors::BoundFunctionNameGetter(
    1093             :     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
    1094             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1095             :   RuntimeCallTimerScope timer(
    1096         341 :       isolate, &RuntimeCallStats::AccessorNameGetterCallback_BoundFunctionName);
    1097             :   HandleScope scope(isolate);
    1098             :   Handle<JSBoundFunction> function =
    1099         341 :       Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
    1100             :   Handle<Object> result;
    1101         682 :   if (!JSBoundFunction::GetName(isolate, function).ToHandle(&result)) {
    1102           0 :     isolate->OptionalRescheduleException(false);
    1103         341 :     return;
    1104             :   }
    1105             :   info.GetReturnValue().Set(Utils::ToLocal(result));
    1106             : }
    1107             : 
    1108          79 : Handle<AccessorInfo> Accessors::BoundFunctionNameInfo(
    1109             :     Isolate* isolate, PropertyAttributes attributes) {
    1110             :   return MakeAccessor(isolate, isolate->factory()->name_string(),
    1111             :                       &BoundFunctionNameGetter, &ReconfigureToDataProperty,
    1112          79 :                       attributes);
    1113             : }
    1114             : 
    1115             : //
    1116             : // Accessors::ErrorStack
    1117             : //
    1118             : 
    1119             : namespace {
    1120             : 
    1121       22899 : MaybeHandle<JSReceiver> ClearInternalStackTrace(Isolate* isolate,
    1122             :                                                 Handle<JSObject> error) {
    1123       45798 :   RETURN_ON_EXCEPTION(
    1124             :       isolate,
    1125             :       JSReceiver::SetProperty(error, isolate->factory()->stack_trace_symbol(),
    1126             :                               isolate->factory()->undefined_value(), STRICT),
    1127             :       JSReceiver);
    1128             :   return error;
    1129             : }
    1130             : 
    1131       22801 : bool IsAccessor(Handle<Object> receiver, Handle<Name> name,
    1132             :                 Handle<JSObject> holder) {
    1133             :   LookupIterator it(receiver, name, holder,
    1134       22801 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    1135             :   // Skip any access checks we might hit. This accessor should never hit in a
    1136             :   // situation where the caller does not have access.
    1137       22801 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    1138           0 :     CHECK(it.HasAccess());
    1139           0 :     it.Next();
    1140             :   }
    1141       22801 :   return (it.state() == LookupIterator::ACCESSOR);
    1142             : }
    1143             : 
    1144             : }  // namespace
    1145             : 
    1146       22946 : void Accessors::ErrorStackGetter(
    1147             :     v8::Local<v8::Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
    1148             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1149             :   HandleScope scope(isolate);
    1150             :   Handle<JSObject> holder =
    1151             :       Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
    1152             : 
    1153             :   // Retrieve the structured stack trace.
    1154             : 
    1155             :   Handle<Object> stack_trace;
    1156             :   Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol();
    1157             :   MaybeHandle<Object> maybe_stack_trace =
    1158       22946 :       JSObject::GetProperty(holder, stack_trace_symbol);
    1159       45892 :   if (!maybe_stack_trace.ToHandle(&stack_trace) ||
    1160             :       stack_trace->IsUndefined(isolate)) {
    1161             :     Handle<Object> result = isolate->factory()->undefined_value();
    1162             :     info.GetReturnValue().Set(Utils::ToLocal(result));
    1163             :     return;
    1164             :   }
    1165             : 
    1166             :   // Format it, clear the internal structured trace and reconfigure as a data
    1167             :   // property.
    1168             : 
    1169             :   Handle<Object> formatted_stack_trace;
    1170       22846 :   if (!ErrorUtils::FormatStackTrace(isolate, holder, stack_trace)
    1171       45692 :            .ToHandle(&formatted_stack_trace)) {
    1172          45 :     isolate->OptionalRescheduleException(false);
    1173          45 :     return;
    1174             :   }
    1175             : 
    1176       45602 :   MaybeHandle<Object> result = ClearInternalStackTrace(isolate, holder);
    1177       22801 :   if (result.is_null()) {
    1178           0 :     isolate->OptionalRescheduleException(false);
    1179           0 :     return;
    1180             :   }
    1181             : 
    1182             :   // If stack is still an accessor (this could have changed in the meantime
    1183             :   // since FormatStackTrace can execute arbitrary JS), replace it with a data
    1184             :   // property.
    1185             :   Handle<Object> receiver =
    1186       22801 :       Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
    1187       22801 :   Handle<Name> name = Utils::OpenHandle(*key);
    1188       22801 :   if (IsAccessor(receiver, name, holder)) {
    1189             :     result = ReplaceAccessorWithDataProperty(isolate, receiver, holder, name,
    1190       22771 :                                              formatted_stack_trace);
    1191       22771 :     if (result.is_null()) {
    1192           0 :       isolate->OptionalRescheduleException(false);
    1193           0 :       return;
    1194             :     }
    1195             :   } else {
    1196             :     // The stack property has been modified in the meantime.
    1197          60 :     if (!JSObject::GetProperty(holder, name).ToHandle(&formatted_stack_trace)) {
    1198           0 :       isolate->OptionalRescheduleException(false);
    1199           0 :       return;
    1200             :     }
    1201             :   }
    1202             : 
    1203             :   v8::Local<v8::Value> value = Utils::ToLocal(formatted_stack_trace);
    1204             :   info.GetReturnValue().Set(value);
    1205             : }
    1206             : 
    1207          98 : void Accessors::ErrorStackSetter(
    1208             :     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
    1209             :     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
    1210             :   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    1211             :   HandleScope scope(isolate);
    1212             :   Handle<JSObject> obj = Handle<JSObject>::cast(
    1213             :       Utils::OpenHandle(*v8::Local<v8::Value>(info.This())));
    1214             : 
    1215             :   // Clear internal properties to avoid memory leaks.
    1216             :   Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol();
    1217         196 :   if (JSReceiver::HasOwnProperty(obj, stack_trace_symbol).FromMaybe(false)) {
    1218          98 :     ClearInternalStackTrace(isolate, obj);
    1219             :   }
    1220             : 
    1221          98 :   Accessors::ReconfigureToDataProperty(name, val, info);
    1222          98 : }
    1223             : 
    1224         790 : Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate,
    1225             :                                                PropertyAttributes attributes) {
    1226             :   Handle<AccessorInfo> info =
    1227             :       MakeAccessor(isolate, isolate->factory()->stack_string(),
    1228         790 :                    &ErrorStackGetter, &ErrorStackSetter, attributes);
    1229         790 :   return info;
    1230             : }
    1231             : 
    1232             : }  // namespace internal
    1233             : }  // namespace v8

Generated by: LCOV version 1.10