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