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