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 
     23 Handle<AccessorInfo> Accessors::MakeAccessor(
     24     Isolate* isolate,
     25     Handle<Name> name,
     26     AccessorNameGetterCallback getter,
     27     AccessorNameSetterCallback setter,
     28     PropertyAttributes attributes) {
     29   Factory* factory = isolate->factory();
     30   Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
     31   info->set_property_attributes(attributes);
     32   info->set_all_can_read(false);
     33   info->set_all_can_write(false);
     34   info->set_is_special_data_property(true);
     35   info->set_name(*name);
     36   Handle<Object> get = v8::FromCData(isolate, getter);
     37   Handle<Object> set = v8::FromCData(isolate, setter);
     38   info->set_getter(*get);
     39   info->set_setter(*set);
     40   return info;
     41 }
     42 
     43 
     44 Handle<ExecutableAccessorInfo> Accessors::CloneAccessor(
     45     Isolate* isolate,
     46     Handle<ExecutableAccessorInfo> accessor) {
     47   Factory* factory = isolate->factory();
     48   Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
     49   info->set_name(accessor->name());
     50   info->set_flag(accessor->flag());
     51   info->set_expected_receiver_type(accessor->expected_receiver_type());
     52   info->set_getter(accessor->getter());
     53   info->set_setter(accessor->setter());
     54   info->set_data(accessor->data());
     55   return info;
     56 }
     57 
     58 
     59 static V8_INLINE bool CheckForName(Handle<Name> name,
     60                                    Handle<String> property_name,
     61                                    int offset,
     62                                    int* object_offset) {
     63   if (Name::Equals(name, property_name)) {
     64     *object_offset = offset;
     65     return true;
     66   }
     67   return false;
     68 }
     69 
     70 
     71 // Returns true for properties that are accessors to object fields.
     72 // If true, *object_offset contains offset of object field.
     73 bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
     74                                         int* object_offset) {
     75   Isolate* isolate = name->GetIsolate();
     76 
     77   switch (map->instance_type()) {
     78     case JS_ARRAY_TYPE:
     79       return
     80         CheckForName(name, isolate->factory()->length_string(),
     81                      JSArray::kLengthOffset, object_offset);
     82     case JS_ARRAY_BUFFER_TYPE:
     83       return CheckForName(name, isolate->factory()->byte_length_string(),
     84                           JSArrayBuffer::kByteLengthOffset, object_offset);
     85     default:
     86       if (map->instance_type() < FIRST_NONSTRING_TYPE) {
     87         return CheckForName(name, isolate->factory()->length_string(),
     88                             String::kLengthOffset, object_offset);
     89       }
     90 
     91       return false;
     92   }
     93 }
     94 
     95 
     96 bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
     97                                                  Handle<Name> name,
     98                                                  int* object_offset) {
     99   Isolate* isolate = name->GetIsolate();
    100 
    101   switch (map->instance_type()) {
    102     case JS_TYPED_ARRAY_TYPE: {
    103       if (!CheckForName(name, isolate->factory()->length_string(),
    104                         JSTypedArray::kLengthOffset, object_offset) &&
    105           !CheckForName(name, isolate->factory()->byte_length_string(),
    106                         JSTypedArray::kByteLengthOffset, object_offset) &&
    107           !CheckForName(name, isolate->factory()->byte_offset_string(),
    108                         JSTypedArray::kByteOffsetOffset, object_offset)) {
    109         return false;
    110       }
    111 
    112       if (map->is_dictionary_map()) return false;
    113 
    114       // Check if the property is overridden on the instance.
    115       DescriptorArray* descriptors = map->instance_descriptors();
    116       int descriptor = descriptors->SearchWithCache(*name, *map);
    117       if (descriptor != DescriptorArray::kNotFound) return false;
    118 
    119       Handle<Object> proto = Handle<Object>(map->prototype(), isolate);
    120       if (!proto->IsJSReceiver()) return false;
    121 
    122       // Check if the property is defined in the prototype chain.
    123       LookupIterator it(proto, name);
    124       if (!it.IsFound()) return false;
    125 
    126       Object* original_proto =
    127           JSFunction::cast(map->GetConstructor())->prototype();
    128 
    129       // Property is not configurable. It is enough to verify that
    130       // the holder is the same.
    131       return *it.GetHolder<Object>() == original_proto;
    132     }
    133     case JS_DATA_VIEW_TYPE:
    134       return CheckForName(name, isolate->factory()->byte_length_string(),
    135                           JSDataView::kByteLengthOffset, object_offset) ||
    136              CheckForName(name, isolate->factory()->byte_offset_string(),
    137                           JSDataView::kByteOffsetOffset, object_offset);
    138     default:
    139       return false;
    140   }
    141 }
    142 
    143 
    144 //
    145 // Accessors::ArgumentsIterator
    146 //
    147 
    148 
    149 void Accessors::ArgumentsIteratorGetter(
    150     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
    151   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    152   DisallowHeapAllocation no_allocation;
    153   HandleScope scope(isolate);
    154   Object* result = isolate->native_context()->array_values_iterator();
    155   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
    156 }
    157 
    158 
    159 void Accessors::ArgumentsIteratorSetter(
    160     v8::Local<v8::Name> name, v8::Local<v8::Value> val,
    161     const v8::PropertyCallbackInfo<void>& info) {
    162   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    163   HandleScope scope(isolate);
    164   Handle<JSObject> object_handle =
    165       Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
    166   Handle<Object> value_handle = Utils::OpenHandle(*val);
    167   Handle<Name> name_handle = Utils::OpenHandle(*name);
    168 
    169   if (JSObject::DefinePropertyOrElementIgnoreAttributes(
    170           object_handle, name_handle, value_handle, NONE)
    171           .is_null()) {
    172     isolate->OptionalRescheduleException(false);
    173   }
    174 }
    175 
    176 
    177 Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
    178     Isolate* isolate, PropertyAttributes attributes) {
    179   Handle<Name> name = isolate->factory()->iterator_symbol();
    180   return MakeAccessor(isolate, name, &ArgumentsIteratorGetter,
    181                       &ArgumentsIteratorSetter, attributes);
    182 }
    183 
    184 
    185 //
    186 // Accessors::ArrayLength
    187 //
    188 
    189 
    190 void Accessors::ArrayLengthGetter(
    191     v8::Local<v8::Name> name,
    192     const v8::PropertyCallbackInfo<v8::Value>& info) {
    193   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    194   DisallowHeapAllocation no_allocation;
    195   HandleScope scope(isolate);
    196   JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
    197   Object* result = holder->length();
    198   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
    199 }
    200 
    201 
    202 void Accessors::ArrayLengthSetter(
    203     v8::Local<v8::Name> name,
    204     v8::Local<v8::Value> val,
    205     const v8::PropertyCallbackInfo<void>& info) {
    206   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    207   HandleScope scope(isolate);
    208 
    209   Handle<JSReceiver> object = Utils::OpenHandle(*info.This());
    210   Handle<JSArray> array = Handle<JSArray>::cast(object);
    211   Handle<Object> length_obj = Utils::OpenHandle(*val);
    212 
    213   uint32_t length = 0;
    214   if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
    215     isolate->OptionalRescheduleException(false);
    216     return;
    217   }
    218 
    219   if (JSArray::ObservableSetLength(array, length).is_null()) {
    220     isolate->OptionalRescheduleException(false);
    221   }
    222 }
    223 
    224 
    225 Handle<AccessorInfo> Accessors::ArrayLengthInfo(
    226       Isolate* isolate, PropertyAttributes attributes) {
    227   return MakeAccessor(isolate,
    228                       isolate->factory()->length_string(),
    229                       &ArrayLengthGetter,
    230                       &ArrayLengthSetter,
    231                       attributes);
    232 }
    233 
    234 
    235 //
    236 // Accessors::StringLength
    237 //
    238 
    239 void Accessors::StringLengthGetter(
    240     v8::Local<v8::Name> name,
    241     const v8::PropertyCallbackInfo<v8::Value>& info) {
    242   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    243   DisallowHeapAllocation no_allocation;
    244   HandleScope scope(isolate);
    245 
    246   // We have a slight impedance mismatch between the external API and the way we
    247   // use callbacks internally: Externally, callbacks can only be used with
    248   // v8::Object, but internally we have callbacks on entities which are higher
    249   // in the hierarchy, in this case for String values.
    250 
    251   Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
    252   if (!value->IsString()) {
    253     // Not a string value. That means that we either got a String wrapper or
    254     // a Value with a String wrapper in its prototype chain.
    255     value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
    256   }
    257   Object* result = Smi::FromInt(String::cast(value)->length());
    258   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
    259 }
    260 
    261 
    262 void Accessors::StringLengthSetter(
    263     v8::Local<v8::Name> name,
    264     v8::Local<v8::Value> value,
    265     const v8::PropertyCallbackInfo<void>& info) {
    266   UNREACHABLE();
    267 }
    268 
    269 
    270 Handle<AccessorInfo> Accessors::StringLengthInfo(
    271       Isolate* isolate, PropertyAttributes attributes) {
    272   return MakeAccessor(isolate,
    273                       isolate->factory()->length_string(),
    274                       &StringLengthGetter,
    275                       &StringLengthSetter,
    276                       attributes);
    277 }
    278 
    279 
    280 //
    281 // Accessors::ScriptColumnOffset
    282 //
    283 
    284 
    285 void Accessors::ScriptColumnOffsetGetter(
    286     v8::Local<v8::Name> name,
    287     const v8::PropertyCallbackInfo<v8::Value>& info) {
    288   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    289   DisallowHeapAllocation no_allocation;
    290   HandleScope scope(isolate);
    291   Object* object = *Utils::OpenHandle(*info.This());
    292   Object* res = Smi::FromInt(
    293       Script::cast(JSValue::cast(object)->value())->column_offset());
    294   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
    295 }
    296 
    297 
    298 void Accessors::ScriptColumnOffsetSetter(
    299     v8::Local<v8::Name> name,
    300     v8::Local<v8::Value> value,
    301     const v8::PropertyCallbackInfo<void>& info) {
    302   UNREACHABLE();
    303 }
    304 
    305 
    306 Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
    307       Isolate* isolate, PropertyAttributes attributes) {
    308   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    309       STATIC_CHAR_VECTOR("column_offset")));
    310   return MakeAccessor(isolate,
    311                       name,
    312                       &ScriptColumnOffsetGetter,
    313                       &ScriptColumnOffsetSetter,
    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.This());
    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 void Accessors::ScriptIdSetter(
    336     v8::Local<v8::Name> name,
    337     v8::Local<v8::Value> value,
    338     const v8::PropertyCallbackInfo<void>& info) {
    339   UNREACHABLE();
    340 }
    341 
    342 
    343 Handle<AccessorInfo> Accessors::ScriptIdInfo(
    344       Isolate* isolate, PropertyAttributes attributes) {
    345   Handle<String> name(
    346       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
    347   return MakeAccessor(isolate,
    348                       name,
    349                       &ScriptIdGetter,
    350                       &ScriptIdSetter,
    351                       attributes);
    352 }
    353 
    354 
    355 //
    356 // Accessors::ScriptName
    357 //
    358 
    359 
    360 void Accessors::ScriptNameGetter(
    361     v8::Local<v8::Name> name,
    362     const v8::PropertyCallbackInfo<v8::Value>& info) {
    363   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    364   DisallowHeapAllocation no_allocation;
    365   HandleScope scope(isolate);
    366   Object* object = *Utils::OpenHandle(*info.This());
    367   Object* source = Script::cast(JSValue::cast(object)->value())->name();
    368   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
    369 }
    370 
    371 
    372 void Accessors::ScriptNameSetter(
    373     v8::Local<v8::Name> name,
    374     v8::Local<v8::Value> value,
    375     const v8::PropertyCallbackInfo<void>& info) {
    376   UNREACHABLE();
    377 }
    378 
    379 
    380 Handle<AccessorInfo> Accessors::ScriptNameInfo(
    381       Isolate* isolate, PropertyAttributes attributes) {
    382   return MakeAccessor(isolate,
    383                       isolate->factory()->name_string(),
    384                       &ScriptNameGetter,
    385                       &ScriptNameSetter,
    386                       attributes);
    387 }
    388 
    389 
    390 //
    391 // Accessors::ScriptSource
    392 //
    393 
    394 
    395 void Accessors::ScriptSourceGetter(
    396     v8::Local<v8::Name> name,
    397     const v8::PropertyCallbackInfo<v8::Value>& info) {
    398   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    399   DisallowHeapAllocation no_allocation;
    400   HandleScope scope(isolate);
    401   Object* object = *Utils::OpenHandle(*info.This());
    402   Object* source = Script::cast(JSValue::cast(object)->value())->source();
    403   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
    404 }
    405 
    406 
    407 void Accessors::ScriptSourceSetter(
    408     v8::Local<v8::Name> name,
    409     v8::Local<v8::Value> value,
    410     const v8::PropertyCallbackInfo<void>& info) {
    411   UNREACHABLE();
    412 }
    413 
    414 
    415 Handle<AccessorInfo> Accessors::ScriptSourceInfo(
    416       Isolate* isolate, PropertyAttributes attributes) {
    417   return MakeAccessor(isolate,
    418                       isolate->factory()->source_string(),
    419                       &ScriptSourceGetter,
    420                       &ScriptSourceSetter,
    421                       attributes);
    422 }
    423 
    424 
    425 //
    426 // Accessors::ScriptLineOffset
    427 //
    428 
    429 
    430 void Accessors::ScriptLineOffsetGetter(
    431     v8::Local<v8::Name> name,
    432     const v8::PropertyCallbackInfo<v8::Value>& info) {
    433   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    434   DisallowHeapAllocation no_allocation;
    435   HandleScope scope(isolate);
    436   Object* object = *Utils::OpenHandle(*info.This());
    437   Object* res =
    438       Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
    439   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
    440 }
    441 
    442 
    443 void Accessors::ScriptLineOffsetSetter(
    444     v8::Local<v8::Name> name,
    445     v8::Local<v8::Value> value,
    446     const v8::PropertyCallbackInfo<void>& info) {
    447   UNREACHABLE();
    448 }
    449 
    450 
    451 Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
    452       Isolate* isolate, PropertyAttributes attributes) {
    453   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    454       STATIC_CHAR_VECTOR("line_offset")));
    455   return MakeAccessor(isolate,
    456                       name,
    457                       &ScriptLineOffsetGetter,
    458                       &ScriptLineOffsetSetter,
    459                       attributes);
    460 }
    461 
    462 
    463 //
    464 // Accessors::ScriptType
    465 //
    466 
    467 
    468 void Accessors::ScriptTypeGetter(
    469     v8::Local<v8::Name> name,
    470     const v8::PropertyCallbackInfo<v8::Value>& info) {
    471   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    472   DisallowHeapAllocation no_allocation;
    473   HandleScope scope(isolate);
    474   Object* object = *Utils::OpenHandle(*info.This());
    475   Object* res =
    476       Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
    477   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
    478 }
    479 
    480 
    481 void Accessors::ScriptTypeSetter(
    482     v8::Local<v8::Name> name,
    483     v8::Local<v8::Value> value,
    484     const v8::PropertyCallbackInfo<void>& info) {
    485   UNREACHABLE();
    486 }
    487 
    488 
    489 Handle<AccessorInfo> Accessors::ScriptTypeInfo(
    490       Isolate* isolate, PropertyAttributes attributes) {
    491   Handle<String> name(
    492       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
    493   return MakeAccessor(isolate,
    494                       name,
    495                       &ScriptTypeGetter,
    496                       &ScriptTypeSetter,
    497                       attributes);
    498 }
    499 
    500 
    501 //
    502 // Accessors::ScriptCompilationType
    503 //
    504 
    505 
    506 void Accessors::ScriptCompilationTypeGetter(
    507     v8::Local<v8::Name> name,
    508     const v8::PropertyCallbackInfo<v8::Value>& info) {
    509   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    510   DisallowHeapAllocation no_allocation;
    511   HandleScope scope(isolate);
    512   Object* object = *Utils::OpenHandle(*info.This());
    513   Object* res = Smi::FromInt(
    514       Script::cast(JSValue::cast(object)->value())->compilation_type());
    515   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
    516 }
    517 
    518 
    519 void Accessors::ScriptCompilationTypeSetter(
    520     v8::Local<v8::Name> name,
    521     v8::Local<v8::Value> value,
    522     const v8::PropertyCallbackInfo<void>& info) {
    523   UNREACHABLE();
    524 }
    525 
    526 
    527 Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
    528       Isolate* isolate, PropertyAttributes attributes) {
    529   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    530       STATIC_CHAR_VECTOR("compilation_type")));
    531   return MakeAccessor(isolate,
    532                       name,
    533                       &ScriptCompilationTypeGetter,
    534                       &ScriptCompilationTypeSetter,
    535                       attributes);
    536 }
    537 
    538 
    539 //
    540 // Accessors::ScriptGetLineEnds
    541 //
    542 
    543 
    544 void Accessors::ScriptLineEndsGetter(
    545     v8::Local<v8::Name> name,
    546     const v8::PropertyCallbackInfo<v8::Value>& info) {
    547   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    548   HandleScope scope(isolate);
    549   Handle<Object> object = Utils::OpenHandle(*info.This());
    550   Handle<Script> script(
    551       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
    552   Script::InitLineEnds(script);
    553   DCHECK(script->line_ends()->IsFixedArray());
    554   Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
    555   // We do not want anyone to modify this array from JS.
    556   DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
    557          line_ends->map() == isolate->heap()->fixed_cow_array_map());
    558   Handle<JSArray> js_array =
    559       isolate->factory()->NewJSArrayWithElements(line_ends);
    560   info.GetReturnValue().Set(Utils::ToLocal(js_array));
    561 }
    562 
    563 
    564 void Accessors::ScriptLineEndsSetter(
    565     v8::Local<v8::Name> name,
    566     v8::Local<v8::Value> value,
    567     const v8::PropertyCallbackInfo<void>& info) {
    568   UNREACHABLE();
    569 }
    570 
    571 
    572 Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
    573       Isolate* isolate, PropertyAttributes attributes) {
    574   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    575       STATIC_CHAR_VECTOR("line_ends")));
    576   return MakeAccessor(isolate,
    577                       name,
    578                       &ScriptLineEndsGetter,
    579                       &ScriptLineEndsSetter,
    580                       attributes);
    581 }
    582 
    583 
    584 //
    585 // Accessors::ScriptSourceUrl
    586 //
    587 
    588 
    589 void Accessors::ScriptSourceUrlGetter(
    590     v8::Local<v8::Name> name,
    591     const v8::PropertyCallbackInfo<v8::Value>& info) {
    592   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    593   DisallowHeapAllocation no_allocation;
    594   HandleScope scope(isolate);
    595   Object* object = *Utils::OpenHandle(*info.This());
    596   Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
    597   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
    598 }
    599 
    600 
    601 void Accessors::ScriptSourceUrlSetter(
    602     v8::Local<v8::Name> name,
    603     v8::Local<v8::Value> value,
    604     const v8::PropertyCallbackInfo<void>& info) {
    605   UNREACHABLE();
    606 }
    607 
    608 
    609 Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
    610       Isolate* isolate, PropertyAttributes attributes) {
    611   return MakeAccessor(isolate,
    612                       isolate->factory()->source_url_string(),
    613                       &ScriptSourceUrlGetter,
    614                       &ScriptSourceUrlSetter,
    615                       attributes);
    616 }
    617 
    618 
    619 //
    620 // Accessors::ScriptSourceMappingUrl
    621 //
    622 
    623 
    624 void Accessors::ScriptSourceMappingUrlGetter(
    625     v8::Local<v8::Name> name,
    626     const v8::PropertyCallbackInfo<v8::Value>& info) {
    627   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    628   DisallowHeapAllocation no_allocation;
    629   HandleScope scope(isolate);
    630   Object* object = *Utils::OpenHandle(*info.This());
    631   Object* url =
    632       Script::cast(JSValue::cast(object)->value())->source_mapping_url();
    633   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
    634 }
    635 
    636 
    637 void Accessors::ScriptSourceMappingUrlSetter(
    638     v8::Local<v8::Name> name,
    639     v8::Local<v8::Value> value,
    640     const v8::PropertyCallbackInfo<void>& info) {
    641   UNREACHABLE();
    642 }
    643 
    644 
    645 Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
    646       Isolate* isolate, PropertyAttributes attributes) {
    647   return MakeAccessor(isolate,
    648                       isolate->factory()->source_mapping_url_string(),
    649                       &ScriptSourceMappingUrlGetter,
    650                       &ScriptSourceMappingUrlSetter,
    651                       attributes);
    652 }
    653 
    654 
    655 //
    656 // Accessors::ScriptIsEmbedderDebugScript
    657 //
    658 
    659 
    660 void Accessors::ScriptIsEmbedderDebugScriptGetter(
    661     v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
    662   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    663   DisallowHeapAllocation no_allocation;
    664   HandleScope scope(isolate);
    665   Object* object = *Utils::OpenHandle(*info.This());
    666   bool is_embedder_debug_script = Script::cast(JSValue::cast(object)->value())
    667                                       ->origin_options()
    668                                       .IsEmbedderDebugScript();
    669   Object* res = *isolate->factory()->ToBoolean(is_embedder_debug_script);
    670   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
    671 }
    672 
    673 
    674 void Accessors::ScriptIsEmbedderDebugScriptSetter(
    675     v8::Local<v8::Name> name, v8::Local<v8::Value> value,
    676     const v8::PropertyCallbackInfo<void>& info) {
    677   UNREACHABLE();
    678 }
    679 
    680 
    681 Handle<AccessorInfo> Accessors::ScriptIsEmbedderDebugScriptInfo(
    682     Isolate* isolate, PropertyAttributes attributes) {
    683   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    684       STATIC_CHAR_VECTOR("is_debugger_script")));
    685   return MakeAccessor(isolate, name, &ScriptIsEmbedderDebugScriptGetter,
    686                       &ScriptIsEmbedderDebugScriptSetter, attributes);
    687 }
    688 
    689 
    690 //
    691 // Accessors::ScriptGetContextData
    692 //
    693 
    694 
    695 void Accessors::ScriptContextDataGetter(
    696     v8::Local<v8::Name> name,
    697     const v8::PropertyCallbackInfo<v8::Value>& info) {
    698   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    699   DisallowHeapAllocation no_allocation;
    700   HandleScope scope(isolate);
    701   Object* object = *Utils::OpenHandle(*info.This());
    702   Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
    703   info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
    704 }
    705 
    706 
    707 void Accessors::ScriptContextDataSetter(
    708     v8::Local<v8::Name> name,
    709     v8::Local<v8::Value> value,
    710     const v8::PropertyCallbackInfo<void>& info) {
    711   UNREACHABLE();
    712 }
    713 
    714 
    715 Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
    716       Isolate* isolate, PropertyAttributes attributes) {
    717   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    718       STATIC_CHAR_VECTOR("context_data")));
    719   return MakeAccessor(isolate,
    720                       name,
    721                       &ScriptContextDataGetter,
    722                       &ScriptContextDataSetter,
    723                       attributes);
    724 }
    725 
    726 
    727 //
    728 // Accessors::ScriptGetEvalFromScript
    729 //
    730 
    731 
    732 void Accessors::ScriptEvalFromScriptGetter(
    733     v8::Local<v8::Name> name,
    734     const v8::PropertyCallbackInfo<v8::Value>& info) {
    735   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    736   HandleScope scope(isolate);
    737   Handle<Object> object = Utils::OpenHandle(*info.This());
    738   Handle<Script> script(
    739       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
    740   Handle<Object> result = isolate->factory()->undefined_value();
    741   if (!script->eval_from_shared()->IsUndefined()) {
    742     Handle<SharedFunctionInfo> eval_from_shared(
    743         SharedFunctionInfo::cast(script->eval_from_shared()));
    744     if (eval_from_shared->script()->IsScript()) {
    745       Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
    746       result = Script::GetWrapper(eval_from_script);
    747     }
    748   }
    749 
    750   info.GetReturnValue().Set(Utils::ToLocal(result));
    751 }
    752 
    753 
    754 void Accessors::ScriptEvalFromScriptSetter(
    755     v8::Local<v8::Name> name,
    756     v8::Local<v8::Value> value,
    757     const v8::PropertyCallbackInfo<void>& info) {
    758   UNREACHABLE();
    759 }
    760 
    761 
    762 Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
    763       Isolate* isolate, PropertyAttributes attributes) {
    764   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    765       STATIC_CHAR_VECTOR("eval_from_script")));
    766   return MakeAccessor(isolate,
    767                       name,
    768                       &ScriptEvalFromScriptGetter,
    769                       &ScriptEvalFromScriptSetter,
    770                       attributes);
    771 }
    772 
    773 
    774 //
    775 // Accessors::ScriptGetEvalFromScriptPosition
    776 //
    777 
    778 
    779 void Accessors::ScriptEvalFromScriptPositionGetter(
    780     v8::Local<v8::Name> name,
    781     const v8::PropertyCallbackInfo<v8::Value>& info) {
    782   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    783   HandleScope scope(isolate);
    784   Handle<Object> object = Utils::OpenHandle(*info.This());
    785   Handle<Script> script(
    786       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
    787   Handle<Object> result = isolate->factory()->undefined_value();
    788   if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
    789     Handle<Code> code(SharedFunctionInfo::cast(
    790         script->eval_from_shared())->code());
    791     result = Handle<Object>(Smi::FromInt(code->SourcePosition(
    792                                 code->instruction_start() +
    793                                 script->eval_from_instructions_offset())),
    794                             isolate);
    795   }
    796   info.GetReturnValue().Set(Utils::ToLocal(result));
    797 }
    798 
    799 
    800 void Accessors::ScriptEvalFromScriptPositionSetter(
    801     v8::Local<v8::Name> name,
    802     v8::Local<v8::Value> value,
    803     const v8::PropertyCallbackInfo<void>& info) {
    804   UNREACHABLE();
    805 }
    806 
    807 
    808 Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
    809       Isolate* isolate, PropertyAttributes attributes) {
    810   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    811       STATIC_CHAR_VECTOR("eval_from_script_position")));
    812   return MakeAccessor(isolate,
    813                       name,
    814                       &ScriptEvalFromScriptPositionGetter,
    815                       &ScriptEvalFromScriptPositionSetter,
    816                       attributes);
    817 }
    818 
    819 
    820 //
    821 // Accessors::ScriptGetEvalFromFunctionName
    822 //
    823 
    824 
    825 void Accessors::ScriptEvalFromFunctionNameGetter(
    826     v8::Local<v8::Name> name,
    827     const v8::PropertyCallbackInfo<v8::Value>& info) {
    828   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    829   HandleScope scope(isolate);
    830   Handle<Object> object = Utils::OpenHandle(*info.This());
    831   Handle<Script> script(
    832       Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
    833   Handle<Object> result;
    834   Handle<SharedFunctionInfo> shared(
    835       SharedFunctionInfo::cast(script->eval_from_shared()));
    836   // Find the name of the function calling eval.
    837   if (!shared->name()->IsUndefined()) {
    838     result = Handle<Object>(shared->name(), isolate);
    839   } else {
    840     result = Handle<Object>(shared->inferred_name(), isolate);
    841   }
    842   info.GetReturnValue().Set(Utils::ToLocal(result));
    843 }
    844 
    845 
    846 void Accessors::ScriptEvalFromFunctionNameSetter(
    847     v8::Local<v8::Name> name,
    848     v8::Local<v8::Value> value,
    849     const v8::PropertyCallbackInfo<void>& info) {
    850   UNREACHABLE();
    851 }
    852 
    853 
    854 Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
    855       Isolate* isolate, PropertyAttributes attributes) {
    856   Handle<String> name(isolate->factory()->InternalizeOneByteString(
    857       STATIC_CHAR_VECTOR("eval_from_function_name")));
    858   return MakeAccessor(isolate,
    859                       name,
    860                       &ScriptEvalFromFunctionNameGetter,
    861                       &ScriptEvalFromFunctionNameSetter,
    862                       attributes);
    863 }
    864 
    865 
    866 //
    867 // Accessors::FunctionPrototype
    868 //
    869 
    870 static Handle<Object> GetFunctionPrototype(Isolate* isolate,
    871                                            Handle<JSFunction> function) {
    872   if (!function->has_prototype()) {
    873     Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
    874     JSFunction::SetPrototype(function, proto);
    875   }
    876   return Handle<Object>(function->prototype(), isolate);
    877 }
    878 
    879 
    880 MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
    881     Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
    882   Handle<Object> old_value;
    883   bool is_observed = function->map()->is_observed();
    884   if (is_observed) {
    885     if (function->has_prototype())
    886       old_value = handle(function->prototype(), isolate);
    887     else
    888       old_value = isolate->factory()->NewFunctionPrototype(function);
    889   }
    890 
    891   JSFunction::SetPrototype(function, value);
    892   DCHECK(function->prototype() == *value);
    893 
    894   if (is_observed && !old_value->SameValue(*value)) {
    895     MaybeHandle<Object> result = JSObject::EnqueueChangeRecord(
    896         function, "update", isolate->factory()->prototype_string(), old_value);
    897     if (result.is_null()) return MaybeHandle<Object>();
    898   }
    899 
    900   return function;
    901 }
    902 
    903 
    904 MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
    905                                                     Handle<Object> prototype) {
    906   DCHECK(function->IsConstructor());
    907   Isolate* isolate = function->GetIsolate();
    908   return SetFunctionPrototype(isolate, function, prototype);
    909 }
    910 
    911 
    912 void Accessors::FunctionPrototypeGetter(
    913     v8::Local<v8::Name> name,
    914     const v8::PropertyCallbackInfo<v8::Value>& info) {
    915   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    916   HandleScope scope(isolate);
    917   Handle<JSFunction> function =
    918       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
    919   Handle<Object> result = GetFunctionPrototype(isolate, function);
    920   info.GetReturnValue().Set(Utils::ToLocal(result));
    921 }
    922 
    923 
    924 void Accessors::FunctionPrototypeSetter(
    925     v8::Local<v8::Name> name,
    926     v8::Local<v8::Value> val,
    927     const v8::PropertyCallbackInfo<void>& info) {
    928   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    929   HandleScope scope(isolate);
    930   Handle<Object> value = Utils::OpenHandle(*val);
    931   Handle<JSFunction> object =
    932       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
    933   if (SetFunctionPrototype(isolate, object, value).is_null()) {
    934     isolate->OptionalRescheduleException(false);
    935   }
    936 }
    937 
    938 
    939 Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
    940       Isolate* isolate, PropertyAttributes attributes) {
    941   return MakeAccessor(isolate,
    942                       isolate->factory()->prototype_string(),
    943                       &FunctionPrototypeGetter,
    944                       &FunctionPrototypeSetter,
    945                       attributes);
    946 }
    947 
    948 
    949 //
    950 // Accessors::FunctionLength
    951 //
    952 
    953 
    954 void Accessors::FunctionLengthGetter(
    955     v8::Local<v8::Name> name,
    956     const v8::PropertyCallbackInfo<v8::Value>& info) {
    957   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
    958   HandleScope scope(isolate);
    959   Handle<JSFunction> function =
    960       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
    961 
    962   int length = 0;
    963   if (function->shared()->is_compiled()) {
    964     length = function->shared()->length();
    965   } else {
    966     // If the function isn't compiled yet, the length is not computed
    967     // correctly yet. Compile it now and return the right length.
    968     if (Compiler::Compile(function, KEEP_EXCEPTION)) {
    969       length = function->shared()->length();
    970     }
    971     if (isolate->has_pending_exception()) {
    972       isolate->OptionalRescheduleException(false);
    973     }
    974   }
    975   Handle<Object> result(Smi::FromInt(length), isolate);
    976   info.GetReturnValue().Set(Utils::ToLocal(result));
    977 }
    978 
    979 
    980 MUST_USE_RESULT static MaybeHandle<Object> ReplaceAccessorWithDataProperty(
    981     Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
    982     Handle<Object> value, bool is_observed, Handle<Object> old_value) {
    983   LookupIterator it(object, name);
    984   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
    985   DCHECK(it.HolderIsReceiverOrHiddenPrototype());
    986   it.ReconfigureDataProperty(value, it.property_details().attributes());
    987 
    988   if (is_observed && !old_value->SameValue(*value)) {
    989     return JSObject::EnqueueChangeRecord(object, "update", name, old_value);
    990   }
    991 
    992   return value;
    993 }
    994 
    995 
    996 MUST_USE_RESULT static MaybeHandle<Object> SetFunctionLength(
    997     Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
    998   Handle<Object> old_value;
    999   bool is_observed = function->map()->is_observed();
   1000   if (is_observed) {
   1001     old_value = handle(Smi::FromInt(function->shared()->length()), isolate);
   1002   }
   1003 
   1004   return ReplaceAccessorWithDataProperty(isolate, function,
   1005                                          isolate->factory()->length_string(),
   1006                                          value, is_observed, old_value);
   1007 }
   1008 
   1009 
   1010 void Accessors::FunctionLengthSetter(
   1011     v8::Local<v8::Name> name,
   1012     v8::Local<v8::Value> val,
   1013     const v8::PropertyCallbackInfo<void>& info) {
   1014   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   1015   HandleScope scope(isolate);
   1016   Handle<Object> value = Utils::OpenHandle(*val);
   1017 
   1018   Handle<JSFunction> object =
   1019       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   1020   if (SetFunctionLength(isolate, object, value).is_null()) {
   1021     isolate->OptionalRescheduleException(false);
   1022   }
   1023 }
   1024 
   1025 
   1026 Handle<AccessorInfo> Accessors::FunctionLengthInfo(
   1027       Isolate* isolate, PropertyAttributes attributes) {
   1028   return MakeAccessor(isolate,
   1029                       isolate->factory()->length_string(),
   1030                       &FunctionLengthGetter,
   1031                       &FunctionLengthSetter,
   1032                       attributes);
   1033 }
   1034 
   1035 
   1036 //
   1037 // Accessors::FunctionName
   1038 //
   1039 
   1040 
   1041 void Accessors::FunctionNameGetter(
   1042     v8::Local<v8::Name> name,
   1043     const v8::PropertyCallbackInfo<v8::Value>& info) {
   1044   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   1045   HandleScope scope(isolate);
   1046   Handle<JSFunction> function =
   1047       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   1048   Handle<Object> result;
   1049   if (function->shared()->name_should_print_as_anonymous()) {
   1050     result = isolate->factory()->anonymous_string();
   1051   } else {
   1052     result = handle(function->shared()->name(), isolate);
   1053   }
   1054   info.GetReturnValue().Set(Utils::ToLocal(result));
   1055 }
   1056 
   1057 
   1058 MUST_USE_RESULT static MaybeHandle<Object> SetFunctionName(
   1059     Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
   1060   Handle<Object> old_value;
   1061   bool is_observed = function->map()->is_observed();
   1062   if (is_observed) {
   1063     old_value = handle(function->shared()->name(), isolate);
   1064   }
   1065 
   1066   return ReplaceAccessorWithDataProperty(isolate, function,
   1067                                          isolate->factory()->name_string(),
   1068                                          value, is_observed, old_value);
   1069 }
   1070 
   1071 
   1072 void Accessors::FunctionNameSetter(
   1073     v8::Local<v8::Name> name,
   1074     v8::Local<v8::Value> val,
   1075     const v8::PropertyCallbackInfo<void>& info) {
   1076   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   1077   HandleScope scope(isolate);
   1078   Handle<Object> value = Utils::OpenHandle(*val);
   1079 
   1080   Handle<JSFunction> object =
   1081       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   1082   if (SetFunctionName(isolate, object, value).is_null()) {
   1083     isolate->OptionalRescheduleException(false);
   1084   }
   1085 }
   1086 
   1087 
   1088 Handle<AccessorInfo> Accessors::FunctionNameInfo(
   1089       Isolate* isolate, PropertyAttributes attributes) {
   1090   return MakeAccessor(isolate,
   1091                       isolate->factory()->name_string(),
   1092                       &FunctionNameGetter,
   1093                       &FunctionNameSetter,
   1094                       attributes);
   1095 }
   1096 
   1097 
   1098 //
   1099 // Accessors::FunctionArguments
   1100 //
   1101 
   1102 
   1103 static Handle<Object> ArgumentsForInlinedFunction(
   1104     JavaScriptFrame* frame,
   1105     Handle<JSFunction> inlined_function,
   1106     int inlined_frame_index) {
   1107   Isolate* isolate = inlined_function->GetIsolate();
   1108   Factory* factory = isolate->factory();
   1109 
   1110   TranslatedState translated_values(frame);
   1111   translated_values.Prepare(false, frame->fp());
   1112 
   1113   int argument_count = 0;
   1114   TranslatedFrame* translated_frame =
   1115       translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
   1116                                                          &argument_count);
   1117   TranslatedFrame::iterator iter = translated_frame->begin();
   1118 
   1119   // Skip the function.
   1120   iter++;
   1121 
   1122   // Skip the receiver.
   1123   iter++;
   1124   argument_count--;
   1125 
   1126   Handle<JSObject> arguments =
   1127       factory->NewArgumentsObject(inlined_function, argument_count);
   1128   Handle<FixedArray> array = factory->NewFixedArray(argument_count);
   1129   bool should_deoptimize = false;
   1130   for (int i = 0; i < argument_count; ++i) {
   1131     // If we materialize any object, we should deopt because we might alias
   1132     // an object that was eliminated by escape analysis.
   1133     should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
   1134     Handle<Object> value = iter->GetValue();
   1135     array->set(i, *value);
   1136     iter++;
   1137   }
   1138   arguments->set_elements(*array);
   1139 
   1140   if (should_deoptimize) {
   1141     translated_values.StoreMaterializedValuesAndDeopt();
   1142   }
   1143 
   1144   // Return the freshly allocated arguments object.
   1145   return arguments;
   1146 }
   1147 
   1148 
   1149 static int FindFunctionInFrame(JavaScriptFrame* frame,
   1150                                Handle<JSFunction> function) {
   1151   DisallowHeapAllocation no_allocation;
   1152   List<JSFunction*> functions(2);
   1153   frame->GetFunctions(&functions);
   1154   for (int i = functions.length() - 1; i >= 0; i--) {
   1155     if (functions[i] == *function) return i;
   1156   }
   1157   return -1;
   1158 }
   1159 
   1160 
   1161 Handle<Object> GetFunctionArguments(Isolate* isolate,
   1162                                     Handle<JSFunction> function) {
   1163   if (function->shared()->native()) return isolate->factory()->null_value();
   1164 
   1165   // Find the top invocation of the function by traversing frames.
   1166   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
   1167     JavaScriptFrame* frame = it.frame();
   1168     int function_index = FindFunctionInFrame(frame, function);
   1169     if (function_index < 0) continue;
   1170 
   1171     if (function_index > 0) {
   1172       // The function in question was inlined.  Inlined functions have the
   1173       // correct number of arguments and no allocated arguments object, so
   1174       // we can construct a fresh one by interpreting the function's
   1175       // deoptimization input data.
   1176       return ArgumentsForInlinedFunction(frame, function, function_index);
   1177     }
   1178 
   1179     // Find the frame that holds the actual arguments passed to the function.
   1180     it.AdvanceToArgumentsFrame();
   1181     frame = it.frame();
   1182 
   1183     // Get the number of arguments and construct an arguments object
   1184     // mirror for the right frame.
   1185     const int length = frame->ComputeParametersCount();
   1186     Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
   1187         function, length);
   1188     Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
   1189 
   1190     // Copy the parameters to the arguments object.
   1191     DCHECK(array->length() == length);
   1192     for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
   1193     arguments->set_elements(*array);
   1194 
   1195     // Return the freshly allocated arguments object.
   1196     return arguments;
   1197   }
   1198 
   1199   // No frame corresponding to the given function found. Return null.
   1200   return isolate->factory()->null_value();
   1201 }
   1202 
   1203 
   1204 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
   1205   return GetFunctionArguments(function->GetIsolate(), function);
   1206 }
   1207 
   1208 
   1209 void Accessors::FunctionArgumentsGetter(
   1210     v8::Local<v8::Name> name,
   1211     const v8::PropertyCallbackInfo<v8::Value>& info) {
   1212   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   1213   HandleScope scope(isolate);
   1214   Handle<JSFunction> function =
   1215       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   1216   Handle<Object> result = GetFunctionArguments(isolate, function);
   1217   info.GetReturnValue().Set(Utils::ToLocal(result));
   1218 }
   1219 
   1220 
   1221 void Accessors::FunctionArgumentsSetter(
   1222     v8::Local<v8::Name> name,
   1223     v8::Local<v8::Value> val,
   1224     const v8::PropertyCallbackInfo<void>& info) {
   1225   // Function arguments is non writable, non configurable.
   1226   UNREACHABLE();
   1227 }
   1228 
   1229 
   1230 Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
   1231       Isolate* isolate, PropertyAttributes attributes) {
   1232   return MakeAccessor(isolate,
   1233                       isolate->factory()->arguments_string(),
   1234                       &FunctionArgumentsGetter,
   1235                       &FunctionArgumentsSetter,
   1236                       attributes);
   1237 }
   1238 
   1239 
   1240 //
   1241 // Accessors::FunctionCaller
   1242 //
   1243 
   1244 
   1245 static inline bool AllowAccessToFunction(Context* current_context,
   1246                                          JSFunction* function) {
   1247   return current_context->HasSameSecurityTokenAs(function->context());
   1248 }
   1249 
   1250 
   1251 class FrameFunctionIterator {
   1252  public:
   1253   FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
   1254       : isolate_(isolate),
   1255         frame_iterator_(isolate),
   1256         functions_(2),
   1257         index_(0) {
   1258     GetFunctions();
   1259   }
   1260   JSFunction* next() {
   1261     while (true) {
   1262       if (functions_.length() == 0) return NULL;
   1263       JSFunction* next_function = functions_[index_];
   1264       index_--;
   1265       if (index_ < 0) {
   1266         GetFunctions();
   1267       }
   1268       // Skip functions from other origins.
   1269       if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
   1270       return next_function;
   1271     }
   1272   }
   1273 
   1274   // Iterate through functions until the first occurence of 'function'.
   1275   // Returns true if 'function' is found, and false if the iterator ends
   1276   // without finding it.
   1277   bool Find(JSFunction* function) {
   1278     JSFunction* next_function;
   1279     do {
   1280       next_function = next();
   1281       if (next_function == function) return true;
   1282     } while (next_function != NULL);
   1283     return false;
   1284   }
   1285 
   1286  private:
   1287   void GetFunctions() {
   1288     functions_.Rewind(0);
   1289     if (frame_iterator_.done()) return;
   1290     JavaScriptFrame* frame = frame_iterator_.frame();
   1291     frame->GetFunctions(&functions_);
   1292     DCHECK(functions_.length() > 0);
   1293     frame_iterator_.Advance();
   1294     index_ = functions_.length() - 1;
   1295   }
   1296   Isolate* isolate_;
   1297   JavaScriptFrameIterator frame_iterator_;
   1298   List<JSFunction*> functions_;
   1299   int index_;
   1300 };
   1301 
   1302 
   1303 MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
   1304                                    Handle<JSFunction> function) {
   1305   DisallowHeapAllocation no_allocation;
   1306   FrameFunctionIterator it(isolate, no_allocation);
   1307   if (function->shared()->native()) {
   1308     return MaybeHandle<JSFunction>();
   1309   }
   1310   // Find the function from the frames.
   1311   if (!it.Find(*function)) {
   1312     // No frame corresponding to the given function found. Return null.
   1313     return MaybeHandle<JSFunction>();
   1314   }
   1315   // Find previously called non-toplevel function.
   1316   JSFunction* caller;
   1317   do {
   1318     caller = it.next();
   1319     if (caller == NULL) return MaybeHandle<JSFunction>();
   1320   } while (caller->shared()->is_toplevel());
   1321 
   1322   // If caller is a built-in function and caller's caller is also built-in,
   1323   // use that instead.
   1324   JSFunction* potential_caller = caller;
   1325   while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) {
   1326     caller = potential_caller;
   1327     potential_caller = it.next();
   1328   }
   1329   if (!caller->shared()->native() && potential_caller != NULL) {
   1330     caller = potential_caller;
   1331   }
   1332   // Censor if the caller is not a sloppy mode function.
   1333   // Change from ES5, which used to throw, see:
   1334   // https://bugs.ecmascript.org/show_bug.cgi?id=310
   1335   if (is_strict(caller->shared()->language_mode())) {
   1336     return MaybeHandle<JSFunction>();
   1337   }
   1338   // Don't return caller from another security context.
   1339   if (!AllowAccessToFunction(isolate->context(), caller)) {
   1340     return MaybeHandle<JSFunction>();
   1341   }
   1342   return Handle<JSFunction>(caller);
   1343 }
   1344 
   1345 
   1346 void Accessors::FunctionCallerGetter(
   1347     v8::Local<v8::Name> name,
   1348     const v8::PropertyCallbackInfo<v8::Value>& info) {
   1349   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   1350   HandleScope scope(isolate);
   1351   Handle<JSFunction> function =
   1352       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   1353   Handle<Object> result;
   1354   MaybeHandle<JSFunction> maybe_caller;
   1355   maybe_caller = FindCaller(isolate, function);
   1356   Handle<JSFunction> caller;
   1357   if (maybe_caller.ToHandle(&caller)) {
   1358     result = caller;
   1359   } else {
   1360     result = isolate->factory()->null_value();
   1361   }
   1362   info.GetReturnValue().Set(Utils::ToLocal(result));
   1363 }
   1364 
   1365 
   1366 void Accessors::FunctionCallerSetter(
   1367     v8::Local<v8::Name> name,
   1368     v8::Local<v8::Value> val,
   1369     const v8::PropertyCallbackInfo<void>& info) {
   1370   // Function caller is non writable, non configurable.
   1371   UNREACHABLE();
   1372 }
   1373 
   1374 
   1375 Handle<AccessorInfo> Accessors::FunctionCallerInfo(
   1376       Isolate* isolate, PropertyAttributes attributes) {
   1377   return MakeAccessor(isolate,
   1378                       isolate->factory()->caller_string(),
   1379                       &FunctionCallerGetter,
   1380                       &FunctionCallerSetter,
   1381                       attributes);
   1382 }
   1383 
   1384 
   1385 //
   1386 // Accessors::MakeModuleExport
   1387 //
   1388 
   1389 static void ModuleGetExport(
   1390     v8::Local<v8::String> property,
   1391     const v8::PropertyCallbackInfo<v8::Value>& info) {
   1392   JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
   1393   Context* context = Context::cast(instance->context());
   1394   DCHECK(context->IsModuleContext());
   1395   Isolate* isolate = instance->GetIsolate();
   1396   int slot = info.Data()
   1397                  ->Int32Value(info.GetIsolate()->GetCurrentContext())
   1398                  .FromMaybe(-1);
   1399   if (slot < 0 || slot >= context->length()) {
   1400     Handle<String> name = v8::Utils::OpenHandle(*property);
   1401 
   1402     Handle<Object> exception = isolate->factory()->NewReferenceError(
   1403         MessageTemplate::kNotDefined, name);
   1404     isolate->ScheduleThrow(*exception);
   1405     return;
   1406   }
   1407   Object* value = context->get(slot);
   1408   if (value->IsTheHole()) {
   1409     Handle<String> name = v8::Utils::OpenHandle(*property);
   1410 
   1411     Handle<Object> exception = isolate->factory()->NewReferenceError(
   1412         MessageTemplate::kNotDefined, name);
   1413     isolate->ScheduleThrow(*exception);
   1414     return;
   1415   }
   1416   info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
   1417 }
   1418 
   1419 
   1420 static void ModuleSetExport(
   1421     v8::Local<v8::String> property,
   1422     v8::Local<v8::Value> value,
   1423     const v8::PropertyCallbackInfo<v8::Value>& info) {
   1424   JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
   1425   Context* context = Context::cast(instance->context());
   1426   DCHECK(context->IsModuleContext());
   1427   Isolate* isolate = instance->GetIsolate();
   1428   int slot = info.Data()
   1429                  ->Int32Value(info.GetIsolate()->GetCurrentContext())
   1430                  .FromMaybe(-1);
   1431   if (slot < 0 || slot >= context->length()) {
   1432     Handle<String> name = v8::Utils::OpenHandle(*property);
   1433     Handle<Object> exception = isolate->factory()->NewReferenceError(
   1434         MessageTemplate::kNotDefined, name);
   1435     isolate->ScheduleThrow(*exception);
   1436     return;
   1437   }
   1438   Object* old_value = context->get(slot);
   1439   if (old_value->IsTheHole()) {
   1440     Handle<String> name = v8::Utils::OpenHandle(*property);
   1441     Handle<Object> exception = isolate->factory()->NewReferenceError(
   1442         MessageTemplate::kNotDefined, name);
   1443     isolate->ScheduleThrow(*exception);
   1444     return;
   1445   }
   1446   context->set(slot, *v8::Utils::OpenHandle(*value));
   1447 }
   1448 
   1449 
   1450 Handle<AccessorInfo> Accessors::MakeModuleExport(
   1451     Handle<String> name,
   1452     int index,
   1453     PropertyAttributes attributes) {
   1454   Isolate* isolate = name->GetIsolate();
   1455   Factory* factory = isolate->factory();
   1456   Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
   1457   info->set_property_attributes(attributes);
   1458   info->set_all_can_read(true);
   1459   info->set_all_can_write(true);
   1460   info->set_name(*name);
   1461   info->set_data(Smi::FromInt(index));
   1462   Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
   1463   Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
   1464   info->set_getter(*getter);
   1465   if (!(attributes & ReadOnly)) info->set_setter(*setter);
   1466   return info;
   1467 }
   1468 
   1469 
   1470 }  // namespace internal
   1471 }  // namespace v8
   1472