Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / src / accessors.cc
index 35cff1a..011372c 100644 (file)
@@ -1,89 +1,77 @@
 // Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
-#include "accessors.h"
-
-#include "compiler.h"
-#include "contexts.h"
-#include "deoptimizer.h"
-#include "execution.h"
-#include "factory.h"
-#include "frames-inl.h"
-#include "isolate.h"
-#include "list-inl.h"
-#include "property-details.h"
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/accessors.h"
+#include "src/api.h"
+#include "src/compiler.h"
+#include "src/contexts.h"
+#include "src/deoptimizer.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/frames-inl.h"
+#include "src/isolate.h"
+#include "src/list-inl.h"
+#include "src/property-details.h"
+#include "src/prototype.h"
 
 namespace v8 {
 namespace internal {
 
 
-template <class C>
-static C* FindInstanceOf(Isolate* isolate, Object* obj) {
-  for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) {
-    if (Is<C>(cur)) return C::cast(cur);
-  }
-  return NULL;
-}
-
-
-// Entry point that never should be called.
-MaybeObject* Accessors::IllegalSetter(Isolate* isolate,
-                                      JSObject*,
-                                      Object*,
-                                      void*) {
-  UNREACHABLE();
-  return NULL;
+Handle<AccessorInfo> Accessors::MakeAccessor(
+    Isolate* isolate,
+    Handle<Name> name,
+    AccessorNameGetterCallback getter,
+    AccessorNameSetterCallback setter,
+    PropertyAttributes attributes) {
+  Factory* factory = isolate->factory();
+  Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
+  info->set_property_attributes(attributes);
+  info->set_all_can_read(false);
+  info->set_all_can_write(false);
+  info->set_name(*name);
+  Handle<Object> get = v8::FromCData(isolate, getter);
+  Handle<Object> set = v8::FromCData(isolate, setter);
+  info->set_getter(*get);
+  info->set_setter(*set);
+  return info;
 }
 
 
-Object* Accessors::IllegalGetAccessor(Isolate* isolate,
-                                      Object* object,
-                                      void*) {
-  UNREACHABLE();
-  return object;
+Handle<ExecutableAccessorInfo> Accessors::CloneAccessor(
+    Isolate* isolate,
+    Handle<ExecutableAccessorInfo> accessor) {
+  Factory* factory = isolate->factory();
+  Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
+  info->set_name(accessor->name());
+  info->set_flag(accessor->flag());
+  info->set_expected_receiver_type(accessor->expected_receiver_type());
+  info->set_getter(accessor->getter());
+  info->set_setter(accessor->setter());
+  info->set_data(accessor->data());
+  return info;
 }
 
 
-MaybeObject* Accessors::ReadOnlySetAccessor(Isolate* isolate,
-                                            JSObject*,
-                                            Object* value,
-                                            void*) {
-  // According to ECMA-262, section 8.6.2.2, page 28, setting
-  // read-only properties must be silently ignored.
-  return value;
+template <class C>
+static C* FindInstanceOf(Isolate* isolate, Object* obj) {
+  for (PrototypeIterator iter(isolate, obj,
+                              PrototypeIterator::START_AT_RECEIVER);
+       !iter.IsAtEnd(); iter.Advance()) {
+    if (Is<C>(iter.GetCurrent())) return C::cast(iter.GetCurrent());
+  }
+  return NULL;
 }
 
 
-static V8_INLINE bool CheckForName(Handle<String> name,
-                                   String* property_name,
+static V8_INLINE bool CheckForName(Handle<Name> name,
+                                   Handle<String> property_name,
                                    int offset,
                                    int* object_offset) {
-  if (name->Equals(property_name)) {
+  if (Name::Equals(name, property_name)) {
     *object_offset = offset;
     return true;
   }
@@ -95,40 +83,40 @@ static V8_INLINE bool CheckForName(Handle<String> name,
 // If true, *object_offset contains offset of object field.
 template <class T>
 bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
-                                        Handle<String> name,
+                                        Handle<Name> name,
                                         int* object_offset) {
   Isolate* isolate = name->GetIsolate();
 
   if (type->Is(T::String())) {
-    return CheckForName(name, isolate->heap()->length_string(),
+    return CheckForName(name, isolate->factory()->length_string(),
                         String::kLengthOffset, object_offset);
   }
 
   if (!type->IsClass()) return false;
-  Handle<Map> map = type->AsClass();
+  Handle<Map> map = type->AsClass()->Map();
 
   switch (map->instance_type()) {
     case JS_ARRAY_TYPE:
       return
-        CheckForName(name, isolate->heap()->length_string(),
+        CheckForName(name, isolate->factory()->length_string(),
                      JSArray::kLengthOffset, object_offset);
     case JS_TYPED_ARRAY_TYPE:
       return
-        CheckForName(name, isolate->heap()->length_string(),
+        CheckForName(name, isolate->factory()->length_string(),
                      JSTypedArray::kLengthOffset, object_offset) ||
-        CheckForName(name, isolate->heap()->byte_length_string(),
+        CheckForName(name, isolate->factory()->byte_length_string(),
                      JSTypedArray::kByteLengthOffset, object_offset) ||
-        CheckForName(name, isolate->heap()->byte_offset_string(),
+        CheckForName(name, isolate->factory()->byte_offset_string(),
                      JSTypedArray::kByteOffsetOffset, object_offset);
     case JS_ARRAY_BUFFER_TYPE:
       return
-        CheckForName(name, isolate->heap()->byte_length_string(),
+        CheckForName(name, isolate->factory()->byte_length_string(),
                      JSArrayBuffer::kByteLengthOffset, object_offset);
     case JS_DATA_VIEW_TYPE:
       return
-        CheckForName(name, isolate->heap()->byte_length_string(),
+        CheckForName(name, isolate->factory()->byte_length_string(),
                      JSDataView::kByteLengthOffset, object_offset) ||
-        CheckForName(name, isolate->heap()->byte_offset_string(),
+        CheckForName(name, isolate->factory()->byte_offset_string(),
                      JSDataView::kByteOffsetOffset, object_offset);
     default:
       return false;
@@ -138,39 +126,88 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
 
 template
 bool Accessors::IsJSObjectFieldAccessor<Type>(Type* type,
-                                              Handle<String> name,
+                                              Handle<Name> name,
                                               int* object_offset);
 
 
 template
 bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
-                                                  Handle<String> name,
+                                                  Handle<Name> name,
                                                   int* object_offset);
 
 
+bool SetPropertyOnInstanceIfInherited(
+    Isolate* isolate, const v8::PropertyCallbackInfo<void>& info,
+    v8::Local<v8::Name> name, Handle<Object> value) {
+  Handle<Object> holder = Utils::OpenHandle(*info.Holder());
+  Handle<Object> receiver = Utils::OpenHandle(*info.This());
+  if (*holder == *receiver) return false;
+  if (receiver->IsJSObject()) {
+    Handle<JSObject> object = Handle<JSObject>::cast(receiver);
+    // This behaves sloppy since we lost the actual strict-mode.
+    // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like data
+    // properties.
+    if (!object->map()->is_extensible()) return true;
+    JSObject::SetOwnPropertyIgnoreAttributes(object, Utils::OpenHandle(*name),
+                                             value, NONE).Check();
+  }
+  return true;
+}
+
+
 //
-// Accessors::ArrayLength
+// Accessors::ArgumentsIterator
 //
 
 
-MaybeObject* Accessors::ArrayGetLength(Isolate* isolate,
-                                       Object* object,
-                                       void*) {
-  // Traverse the prototype chain until we reach an array.
-  JSArray* holder = FindInstanceOf<JSArray>(isolate, object);
-  return holder == NULL ? Smi::FromInt(0) : holder->length();
+void Accessors::ArgumentsIteratorGetter(
+    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* result = isolate->native_context()->array_values_iterator();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
+}
+
+
+void Accessors::ArgumentsIteratorSetter(
+    v8::Local<v8::Name> name, v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSObject> object = Utils::OpenHandle(*info.This());
+  Handle<Object> value = Utils::OpenHandle(*val);
+
+  if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
+
+  LookupIterator it(object, Utils::OpenHandle(*name));
+  CHECK_EQ(LookupIterator::ACCESSOR, it.state());
+  DCHECK(it.HolderIsReceiverOrHiddenPrototype());
+  Object::SetDataProperty(&it, value);
+}
+
+
+Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
+    Isolate* isolate, PropertyAttributes attributes) {
+  Handle<Name> name(isolate->native_context()->iterator_symbol(), isolate);
+  return MakeAccessor(isolate, name, &ArgumentsIteratorGetter,
+                      &ArgumentsIteratorSetter, attributes);
 }
 
 
+//
+// Accessors::ArrayLength
+//
+
+
 // The helper function will 'flatten' Number objects.
 Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
                                         Handle<Object> value) {
   if (value->IsNumber() || !value->IsJSValue()) return value;
   Handle<JSValue> wrapper = Handle<JSValue>::cast(value);
-  ASSERT(wrapper->GetIsolate()->context()->native_context()->number_function()->
+  DCHECK(wrapper->GetIsolate()->native_context()->number_function()->
       has_initial_map());
-  if (wrapper->map() ==
-      isolate->context()->native_context()->number_function()->initial_map()) {
+  if (wrapper->map() == isolate->number_function()->initial_map()) {
     return handle(wrapper->value(), isolate);
   }
 
@@ -178,174 +215,300 @@ Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
 }
 
 
-MaybeObject* Accessors::ArraySetLength(Isolate* isolate,
-                                       JSObject* object_raw,
-                                       Object* value_raw,
-                                       void*) {
+void Accessors::ArrayLengthGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
   HandleScope scope(isolate);
-  Handle<JSObject> object(object_raw, isolate);
-  Handle<Object> value(value_raw, isolate);
+  JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
+  Object* result = holder->length();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
+}
 
-  // This means one of the object's prototypes is a JSArray and the
-  // object does not have a 'length' property.  Calling SetProperty
-  // causes an infinite loop.
-  if (!object->IsJSArray()) {
-    Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(object,
-        isolate->factory()->length_string(), value, NONE);
-    RETURN_IF_EMPTY_HANDLE(isolate, result);
-    return *result;
+
+void Accessors::ArrayLengthSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSObject> object = Utils::OpenHandle(*info.This());
+  Handle<Object> value = Utils::OpenHandle(*val);
+  if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
+    return;
   }
 
   value = FlattenNumber(isolate, value);
 
   Handle<JSArray> array_handle = Handle<JSArray>::cast(object);
-
-  bool has_exception;
-  Handle<Object> uint32_v =
-      Execution::ToUint32(isolate, value, &has_exception);
-  if (has_exception) return Failure::Exception();
-  Handle<Object> number_v =
-      Execution::ToNumber(isolate, value, &has_exception);
-  if (has_exception) return Failure::Exception();
+  MaybeHandle<Object> maybe;
+  Handle<Object> uint32_v;
+  maybe = Execution::ToUint32(isolate, value);
+  if (!maybe.ToHandle(&uint32_v)) {
+    isolate->OptionalRescheduleException(false);
+    return;
+  }
+  Handle<Object> number_v;
+  maybe = Execution::ToNumber(isolate, value);
+  if (!maybe.ToHandle(&number_v)) {
+    isolate->OptionalRescheduleException(false);
+    return;
+  }
 
   if (uint32_v->Number() == number_v->Number()) {
-    Handle<Object> result = JSArray::SetElementsLength(array_handle, uint32_v);
-    RETURN_IF_EMPTY_HANDLE(isolate, result);
-    return *result;
+    maybe = JSArray::SetElementsLength(array_handle, uint32_v);
+    maybe.Check();
+    return;
+  }
+
+  Handle<Object> exception;
+  maybe = isolate->factory()->NewRangeError("invalid_array_length",
+                                            HandleVector<Object>(NULL, 0));
+  if (!maybe.ToHandle(&exception)) {
+    isolate->OptionalRescheduleException(false);
+    return;
   }
-  return isolate->Throw(
-      *isolate->factory()->NewRangeError("invalid_array_length",
-                                         HandleVector<Object>(NULL, 0)));
+
+  isolate->ScheduleThrow(*exception);
 }
 
 
-const AccessorDescriptor Accessors::ArrayLength = {
-  ArrayGetLength,
-  ArraySetLength,
-  0
-};
+Handle<AccessorInfo> Accessors::ArrayLengthInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->length_string(),
+                      &ArrayLengthGetter,
+                      &ArrayLengthSetter,
+                      attributes);
+}
+
 
 
 //
 // Accessors::StringLength
 //
 
+void Accessors::StringLengthGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+
+  // We have a slight impedance mismatch between the external API and the way we
+  // use callbacks internally: Externally, callbacks can only be used with
+  // v8::Object, but internally we have callbacks on entities which are higher
+  // in the hierarchy, in this case for String values.
 
-MaybeObject* Accessors::StringGetLength(Isolate* isolate,
-                                        Object* object,
-                                        void*) {
-  Object* value = object;
-  if (object->IsJSValue()) value = JSValue::cast(object)->value();
-  if (value->IsString()) return Smi::FromInt(String::cast(value)->length());
-  // If object is not a string we return 0 to be compatible with WebKit.
-  // Note: Firefox returns the length of ToString(object).
-  return Smi::FromInt(0);
+  Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
+  if (!value->IsString()) {
+    // Not a string value. That means that we either got a String wrapper or
+    // a Value with a String wrapper in its prototype chain.
+    value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
+  }
+  Object* result = Smi::FromInt(String::cast(value)->length());
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::StringLength = {
-  StringGetLength,
-  IllegalSetter,
-  0
-};
+void Accessors::StringLengthSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::StringLengthInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->length_string(),
+                      &StringLengthGetter,
+                      &StringLengthSetter,
+                      attributes);
+}
 
 
 //
-// Accessors::ScriptSource
+// Accessors::ScriptColumnOffset
 //
 
 
-MaybeObject* Accessors::ScriptGetSource(Isolate* isolate,
-                                        Object* object,
-                                        void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->source();
+void Accessors::ScriptColumnOffsetGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* res = Script::cast(JSValue::cast(object)->value())->column_offset();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptSource = {
-  ScriptGetSource,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptColumnOffsetSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("column_offset")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptColumnOffsetGetter,
+                      &ScriptColumnOffsetSetter,
+                      attributes);
+}
 
 
 //
-// Accessors::ScriptName
+// Accessors::ScriptId
 //
 
 
-MaybeObject* Accessors::ScriptGetName(Isolate* isolate,
-                                      Object* object,
-                                      void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->name();
+void Accessors::ScriptIdGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* id = Script::cast(JSValue::cast(object)->value())->id();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptName = {
-  ScriptGetName,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptIdSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptIdInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(
+      isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptIdGetter,
+                      &ScriptIdSetter,
+                      attributes);
+}
 
 
 //
-// Accessors::ScriptId
+// Accessors::ScriptName
 //
 
 
-MaybeObject* Accessors::ScriptGetId(Isolate* isolate, Object* object, void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->id();
+void Accessors::ScriptNameGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* source = Script::cast(JSValue::cast(object)->value())->name();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptId = {
-  ScriptGetId,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptNameSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptNameInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->name_string(),
+                      &ScriptNameGetter,
+                      &ScriptNameSetter,
+                      attributes);
+}
 
 
 //
-// Accessors::ScriptLineOffset
+// Accessors::ScriptSource
 //
 
 
-MaybeObject* Accessors::ScriptGetLineOffset(Isolate* isolate,
-                                            Object* object,
-                                            void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->line_offset();
+void Accessors::ScriptSourceGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* source = Script::cast(JSValue::cast(object)->value())->source();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptLineOffset = {
-  ScriptGetLineOffset,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptSourceSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptSourceInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->source_string(),
+                      &ScriptSourceGetter,
+                      &ScriptSourceSetter,
+                      attributes);
+}
 
 
 //
-// Accessors::ScriptColumnOffset
+// Accessors::ScriptLineOffset
 //
 
 
-MaybeObject* Accessors::ScriptGetColumnOffset(Isolate* isolate,
-                                              Object* object,
-                                              void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->column_offset();
+void Accessors::ScriptLineOffsetGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* res = Script::cast(JSValue::cast(object)->value())->line_offset();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptColumnOffset = {
-  ScriptGetColumnOffset,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptLineOffsetSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("line_offset")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptLineOffsetGetter,
+                      &ScriptLineOffsetSetter,
+                      attributes);
+}
 
 
 //
@@ -353,19 +516,36 @@ const AccessorDescriptor Accessors::ScriptColumnOffset = {
 //
 
 
-MaybeObject* Accessors::ScriptGetType(Isolate* isolate,
-                                      Object* object,
-                                      void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->type();
+void Accessors::ScriptTypeGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* res = Script::cast(JSValue::cast(object)->value())->type();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptType = {
-  ScriptGetType,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptTypeSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptTypeInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(
+      isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptTypeGetter,
+                      &ScriptTypeSetter,
+                      attributes);
+}
 
 
 //
@@ -373,19 +553,37 @@ const AccessorDescriptor Accessors::ScriptType = {
 //
 
 
-MaybeObject* Accessors::ScriptGetCompilationType(Isolate* isolate,
-                                                 Object* object,
-                                                 void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Smi::FromInt(Script::cast(script)->compilation_type());
+void Accessors::ScriptCompilationTypeGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* res = Smi::FromInt(
+      Script::cast(JSValue::cast(object)->value())->compilation_type());
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptCompilationType = {
-  ScriptGetCompilationType,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptCompilationTypeSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("compilation_type")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptCompilationTypeGetter,
+                      &ScriptCompilationTypeSetter,
+                      attributes);
+}
 
 
 //
@@ -393,29 +591,115 @@ const AccessorDescriptor Accessors::ScriptCompilationType = {
 //
 
 
-MaybeObject* Accessors::ScriptGetLineEnds(Isolate* isolate,
-                                          Object* object,
-                                          void*) {
-  JSValue* wrapper = JSValue::cast(object);
+void Accessors::ScriptLineEndsGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Script> script(Script::cast(wrapper->value()), isolate);
-  InitScriptLineEnds(script);
-  ASSERT(script->line_ends()->IsFixedArray());
+  Handle<Object> object = Utils::OpenHandle(*info.This());
+  Handle<Script> script(
+      Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+  Script::InitLineEnds(script);
+  DCHECK(script->line_ends()->IsFixedArray());
   Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
   // We do not want anyone to modify this array from JS.
-  ASSERT(*line_ends == isolate->heap()->empty_fixed_array() ||
+  DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
          line_ends->map() == isolate->heap()->fixed_cow_array_map());
   Handle<JSArray> js_array =
       isolate->factory()->NewJSArrayWithElements(line_ends);
-  return *js_array;
+  info.GetReturnValue().Set(Utils::ToLocal(js_array));
 }
 
 
-const AccessorDescriptor Accessors::ScriptLineEnds = {
-  ScriptGetLineEnds,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptLineEndsSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("line_ends")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptLineEndsGetter,
+                      &ScriptLineEndsSetter,
+                      attributes);
+}
+
+
+//
+// Accessors::ScriptSourceUrl
+//
+
+
+void Accessors::ScriptSourceUrlGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
+}
+
+
+void Accessors::ScriptSourceUrlSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->source_url_string(),
+                      &ScriptSourceUrlGetter,
+                      &ScriptSourceUrlSetter,
+                      attributes);
+}
+
+
+//
+// Accessors::ScriptSourceMappingUrl
+//
+
+
+void Accessors::ScriptSourceMappingUrlGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* url =
+      Script::cast(JSValue::cast(object)->value())->source_mapping_url();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
+}
+
+
+void Accessors::ScriptSourceMappingUrlSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->source_mapping_url_string(),
+                      &ScriptSourceMappingUrlGetter,
+                      &ScriptSourceMappingUrlSetter,
+                      attributes);
+}
 
 
 //
@@ -423,19 +707,36 @@ const AccessorDescriptor Accessors::ScriptLineEnds = {
 //
 
 
-MaybeObject* Accessors::ScriptGetContextData(Isolate* isolate,
-                                             Object* object,
-                                             void*) {
-  Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->context_data();
+void Accessors::ScriptContextDataGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
 }
 
 
-const AccessorDescriptor Accessors::ScriptContextData = {
-  ScriptGetContextData,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptContextDataSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("context_data")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptContextDataGetter,
+                      &ScriptContextDataSetter,
+                      attributes);
+}
 
 
 //
@@ -443,28 +744,46 @@ const AccessorDescriptor Accessors::ScriptContextData = {
 //
 
 
-MaybeObject* Accessors::ScriptGetEvalFromScript(Isolate* isolate,
-                                                Object* object,
-                                                void*) {
-  Object* script = JSValue::cast(object)->value();
-  if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
+void Accessors::ScriptEvalFromScriptGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<Object> object = Utils::OpenHandle(*info.This());
+  Handle<Script> script(
+      Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+  Handle<Object> result = isolate->factory()->undefined_value();
+  if (!script->eval_from_shared()->IsUndefined()) {
     Handle<SharedFunctionInfo> eval_from_shared(
-        SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared()));
-
+        SharedFunctionInfo::cast(script->eval_from_shared()));
     if (eval_from_shared->script()->IsScript()) {
       Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
-      return *GetScriptWrapper(eval_from_script);
+      result = Script::GetWrapper(eval_from_script);
     }
   }
-  return isolate->heap()->undefined_value();
+
+  info.GetReturnValue().Set(Utils::ToLocal(result));
 }
 
 
-const AccessorDescriptor Accessors::ScriptEvalFromScript = {
-  ScriptGetEvalFromScript,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptEvalFromScriptSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("eval_from_script")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptEvalFromScriptGetter,
+                      &ScriptEvalFromScriptSetter,
+                      attributes);
+}
 
 
 //
@@ -472,32 +791,45 @@ const AccessorDescriptor Accessors::ScriptEvalFromScript = {
 //
 
 
-MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Isolate* isolate,
-                                                        Object* object,
-                                                        void*) {
-  Script* raw_script = Script::cast(JSValue::cast(object)->value());
+void Accessors::ScriptEvalFromScriptPositionGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Script> script(raw_script);
-
-  // If this is not a script compiled through eval there is no eval position.
-  if (script->compilation_type() != Script::COMPILATION_TYPE_EVAL) {
-    return script->GetHeap()->undefined_value();
+  Handle<Object> object = Utils::OpenHandle(*info.This());
+  Handle<Script> script(
+      Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+  Handle<Object> result = isolate->factory()->undefined_value();
+  if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
+    Handle<Code> code(SharedFunctionInfo::cast(
+        script->eval_from_shared())->code());
+    result = Handle<Object>(
+        Smi::FromInt(code->SourcePosition(code->instruction_start() +
+                     script->eval_from_instructions_offset()->value())),
+        isolate);
   }
+  info.GetReturnValue().Set(Utils::ToLocal(result));
+}
 
-  // Get the function from where eval was called and find the source position
-  // from the instruction offset.
-  Handle<Code> code(SharedFunctionInfo::cast(
-      script->eval_from_shared())->code());
-  return Smi::FromInt(code->SourcePosition(code->instruction_start() +
-                      script->eval_from_instructions_offset()->value()));
+
+void Accessors::ScriptEvalFromScriptPositionSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
 }
 
 
-const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
-  ScriptGetEvalFromScriptPosition,
-  IllegalSetter,
-  0
-};
+Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("eval_from_script_position")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptEvalFromScriptPositionGetter,
+                      &ScriptEvalFromScriptPositionSetter,
+                      attributes);
+}
 
 
 //
@@ -505,100 +837,66 @@ const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
 //
 
 
-MaybeObject* Accessors::ScriptGetEvalFromFunctionName(Isolate* isolate,
-                                                      Object* object,
-                                                      void*) {
-  Object* script = JSValue::cast(object)->value();
-  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
-      Script::cast(script)->eval_from_shared()));
-
-
+void Accessors::ScriptEvalFromFunctionNameGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<Object> object = Utils::OpenHandle(*info.This());
+  Handle<Script> script(
+      Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+  Handle<Object> result;
+  Handle<SharedFunctionInfo> shared(
+      SharedFunctionInfo::cast(script->eval_from_shared()));
   // Find the name of the function calling eval.
   if (!shared->name()->IsUndefined()) {
-    return shared->name();
+    result = Handle<Object>(shared->name(), isolate);
   } else {
-    return shared->inferred_name();
+    result = Handle<Object>(shared->inferred_name(), isolate);
   }
+  info.GetReturnValue().Set(Utils::ToLocal(result));
 }
 
 
-const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
-  ScriptGetEvalFromFunctionName,
-  IllegalSetter,
-  0
-};
+void Accessors::ScriptEvalFromFunctionNameSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  Handle<String> name(isolate->factory()->InternalizeOneByteString(
+      STATIC_CHAR_VECTOR("eval_from_function_name")));
+  return MakeAccessor(isolate,
+                      name,
+                      &ScriptEvalFromFunctionNameGetter,
+                      &ScriptEvalFromFunctionNameSetter,
+                      attributes);
+}
 
 
 //
 // Accessors::FunctionPrototype
 //
 
-
-Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
-  CALL_HEAP_FUNCTION(function->GetIsolate(),
-                     Accessors::FunctionGetPrototype(function->GetIsolate(),
-                                                     *function,
-                                                     NULL),
-                     Object);
-}
-
-
-Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
-                                               Handle<Object> prototype) {
-  ASSERT(function->should_have_prototype());
-  CALL_HEAP_FUNCTION(function->GetIsolate(),
-                     Accessors::FunctionSetPrototype(function->GetIsolate(),
-                                                     *function,
-                                                     *prototype,
-                                                     NULL),
-                     Object);
-}
-
-
-MaybeObject* Accessors::FunctionGetPrototype(Isolate* isolate,
-                                             Object* object,
-                                             void*) {
-  JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
-  if (function_raw == NULL) return isolate->heap()->undefined_value();
-  while (!function_raw->should_have_prototype()) {
-    function_raw = FindInstanceOf<JSFunction>(isolate,
-                                              function_raw->GetPrototype());
-    // There has to be one because we hit the getter.
-    ASSERT(function_raw != NULL);
-  }
-
-  if (!function_raw->has_prototype()) {
-    HandleScope scope(isolate);
-    Handle<JSFunction> function(function_raw);
+static Handle<Object> GetFunctionPrototype(Isolate* isolate,
+                                           Handle<JSFunction> function) {
+  if (!function->has_prototype()) {
     Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
     JSFunction::SetPrototype(function, proto);
-    function_raw = *function;
   }
-  return function_raw->prototype();
+  return Handle<Object>(function->prototype(), isolate);
 }
 
 
-MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
-                                             JSObject* object_raw,
-                                             Object* value_raw,
-                                             void*) {
-  JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object_raw);
-  if (function_raw == NULL) return isolate->heap()->undefined_value();
-
-  HandleScope scope(isolate);
-  Handle<JSFunction> function(function_raw, isolate);
-  Handle<JSObject> object(object_raw, isolate);
-  Handle<Object> value(value_raw, isolate);
-  if (!function->should_have_prototype()) {
-    // Since we hit this accessor, object will have no prototype property.
-    Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(object,
-        isolate->factory()->prototype_string(), value, NONE);
-    RETURN_IF_EMPTY_HANDLE(isolate, result);
-    return *result;
-  }
-
+static Handle<Object> SetFunctionPrototype(Isolate* isolate,
+                                           Handle<JSFunction> function,
+                                           Handle<Object> value) {
   Handle<Object> old_value;
-  bool is_observed = *function == *object && function->map()->is_observed();
+  bool is_observed = function->map()->is_observed();
   if (is_observed) {
     if (function->has_prototype())
       old_value = handle(function->prototype(), isolate);
@@ -607,22 +905,66 @@ MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
   }
 
   JSFunction::SetPrototype(function, value);
-  ASSERT(function->prototype() == *value);
+  DCHECK(function->prototype() == *value);
 
   if (is_observed && !old_value->SameValue(*value)) {
     JSObject::EnqueueChangeRecord(
         function, "update", isolate->factory()->prototype_string(), old_value);
   }
 
-  return *function;
+  return function;
 }
 
 
-const AccessorDescriptor Accessors::FunctionPrototype = {
-  FunctionGetPrototype,
-  FunctionSetPrototype,
-  0
-};
+Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
+  return GetFunctionPrototype(function->GetIsolate(), function);
+}
+
+
+Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
+                                               Handle<Object> prototype) {
+  DCHECK(function->should_have_prototype());
+  Isolate* isolate = function->GetIsolate();
+  return SetFunctionPrototype(isolate, function, prototype);
+}
+
+
+void Accessors::FunctionPrototypeGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result = GetFunctionPrototype(isolate, function);
+  info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
+
+void Accessors::FunctionPrototypeSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<Object> value = Utils::OpenHandle(*val);
+  if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
+    return;
+  }
+  Handle<JSFunction> object =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  SetFunctionPrototype(isolate, object, value);
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->prototype_string(),
+                      &FunctionPrototypeGetter,
+                      &FunctionPrototypeSetter,
+                      attributes);
+}
 
 
 //
@@ -630,31 +972,49 @@ const AccessorDescriptor Accessors::FunctionPrototype = {
 //
 
 
-MaybeObject* Accessors::FunctionGetLength(Isolate* isolate,
-                                          Object* object,
-                                          void*) {
-  JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
-  if (function == NULL) return Smi::FromInt(0);
-  // Check if already compiled.
-  if (function->shared()->is_compiled()) {
-    return Smi::FromInt(function->shared()->length());
-  }
-  // If the function isn't compiled yet, the length is not computed correctly
-  // yet. Compile it now and return the right length.
+void Accessors::FunctionLengthGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<JSFunction> function_handle(function);
-  if (Compiler::EnsureCompiled(function_handle, KEEP_EXCEPTION)) {
-    return Smi::FromInt(function_handle->shared()->length());
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+
+  int length = 0;
+  if (function->shared()->is_compiled()) {
+    length = function->shared()->length();
+  } else {
+    // If the function isn't compiled yet, the length is not computed
+    // correctly yet. Compile it now and return the right length.
+    if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
+      length = function->shared()->length();
+    }
+    if (isolate->has_pending_exception()) {
+      isolate->OptionalRescheduleException(false);
+    }
   }
-  return Failure::Exception();
+  Handle<Object> result(Smi::FromInt(length), isolate);
+  info.GetReturnValue().Set(Utils::ToLocal(result));
 }
 
 
-const AccessorDescriptor Accessors::FunctionLength = {
-  FunctionGetLength,
-  ReadOnlySetAccessor,
-  0
-};
+void Accessors::FunctionLengthSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  // Function length is non writable, non configurable.
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionLengthInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->length_string(),
+                      &FunctionLengthGetter,
+                      &FunctionLengthSetter,
+                      attributes);
+}
 
 
 //
@@ -662,21 +1022,35 @@ const AccessorDescriptor Accessors::FunctionLength = {
 //
 
 
-MaybeObject* Accessors::FunctionGetName(Isolate* isolate,
-                                        Object* object,
-                                        void*) {
-  JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
-  return holder == NULL
-      ? isolate->heap()->undefined_value()
-      : holder->shared()->name();
+void Accessors::FunctionNameGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result(function->shared()->name(), isolate);
+  info.GetReturnValue().Set(Utils::ToLocal(result));
 }
 
 
-const AccessorDescriptor Accessors::FunctionName = {
-  FunctionGetName,
-  ReadOnlySetAccessor,
-  0
-};
+void Accessors::FunctionNameSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  // Function name is non writable, non configurable.
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionNameInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->name_string(),
+                      &FunctionNameGetter,
+                      &FunctionNameSetter,
+                      attributes);
+}
 
 
 //
@@ -684,16 +1058,7 @@ const AccessorDescriptor Accessors::FunctionName = {
 //
 
 
-Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
-  CALL_HEAP_FUNCTION(function->GetIsolate(),
-                     Accessors::FunctionGetArguments(function->GetIsolate(),
-                                                     *function,
-                                                     NULL),
-                     Object);
-}
-
-
-static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
+static Handle<Object> ArgumentsForInlinedFunction(
     JavaScriptFrame* frame,
     Handle<JSFunction> inlined_function,
     int inlined_frame_index) {
@@ -717,81 +1082,112 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
   arguments->set_elements(*array);
 
   // Return the freshly allocated arguments object.
-  return *arguments;
+  return arguments;
 }
 
 
-MaybeObject* Accessors::FunctionGetArguments(Isolate* isolate,
-                                             Object* object,
-                                             void*) {
-  HandleScope scope(isolate);
-  JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
-  if (holder == NULL) return isolate->heap()->undefined_value();
-  Handle<JSFunction> function(holder, isolate);
+static int FindFunctionInFrame(JavaScriptFrame* frame,
+                               Handle<JSFunction> function) {
+  DisallowHeapAllocation no_allocation;
+  List<JSFunction*> functions(2);
+  frame->GetFunctions(&functions);
+  for (int i = functions.length() - 1; i >= 0; i--) {
+    if (functions[i] == *function) return i;
+  }
+  return -1;
+}
+
+
+Handle<Object> GetFunctionArguments(Isolate* isolate,
+                                    Handle<JSFunction> function) {
+  if (function->shared()->native()) return isolate->factory()->null_value();
 
-  if (function->shared()->native()) return isolate->heap()->null_value();
   // Find the top invocation of the function by traversing frames.
-  List<JSFunction*> functions(2);
   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
     JavaScriptFrame* frame = it.frame();
-    frame->GetFunctions(&functions);
-    for (int i = functions.length() - 1; i >= 0; i--) {
-      // Skip all frames that aren't invocations of the given function.
-      if (functions[i] != *function) continue;
-
-      if (i > 0) {
-        // The function in question was inlined.  Inlined functions have the
-        // correct number of arguments and no allocated arguments object, so
-        // we can construct a fresh one by interpreting the function's
-        // deoptimization input data.
-        return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
-      }
+    int function_index = FindFunctionInFrame(frame, function);
+    if (function_index < 0) continue;
+
+    if (function_index > 0) {
+      // The function in question was inlined.  Inlined functions have the
+      // correct number of arguments and no allocated arguments object, so
+      // we can construct a fresh one by interpreting the function's
+      // deoptimization input data.
+      return ArgumentsForInlinedFunction(frame, function, function_index);
+    }
 
-      if (!frame->is_optimized()) {
-        // If there is an arguments variable in the stack, we return that.
-        Handle<ScopeInfo> scope_info(function->shared()->scope_info());
-        int index = scope_info->StackSlotIndex(
-            isolate->heap()->arguments_string());
-        if (index >= 0) {
-          Handle<Object> arguments(frame->GetExpression(index), isolate);
-          if (!arguments->IsArgumentsMarker()) return *arguments;
-        }
+    if (!frame->is_optimized()) {
+      // If there is an arguments variable in the stack, we return that.
+      Handle<ScopeInfo> scope_info(function->shared()->scope_info());
+      int index = scope_info->StackSlotIndex(
+          isolate->heap()->arguments_string());
+      if (index >= 0) {
+        Handle<Object> arguments(frame->GetExpression(index), isolate);
+        if (!arguments->IsArgumentsMarker()) return arguments;
       }
-
-      // If there is no arguments variable in the stack or we have an
-      // optimized frame, we find the frame that holds the actual arguments
-      // passed to the function.
-      it.AdvanceToArgumentsFrame();
-      frame = it.frame();
-
-      // Get the number of arguments and construct an arguments object
-      // mirror for the right frame.
-      const int length = frame->ComputeParametersCount();
-      Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
-          function, length);
-      Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
-
-      // Copy the parameters to the arguments object.
-      ASSERT(array->length() == length);
-      for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
-      arguments->set_elements(*array);
-
-      // Return the freshly allocated arguments object.
-      return *arguments;
     }
-    functions.Rewind(0);
+
+    // If there is no arguments variable in the stack or we have an
+    // optimized frame, we find the frame that holds the actual arguments
+    // passed to the function.
+    it.AdvanceToArgumentsFrame();
+    frame = it.frame();
+
+    // Get the number of arguments and construct an arguments object
+    // mirror for the right frame.
+    const int length = frame->ComputeParametersCount();
+    Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
+        function, length);
+    Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
+
+    // Copy the parameters to the arguments object.
+    DCHECK(array->length() == length);
+    for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
+    arguments->set_elements(*array);
+
+    // Return the freshly allocated arguments object.
+    return arguments;
   }
 
   // No frame corresponding to the given function found. Return null.
-  return isolate->heap()->null_value();
+  return isolate->factory()->null_value();
 }
 
 
-const AccessorDescriptor Accessors::FunctionArguments = {
-  FunctionGetArguments,
-  ReadOnlySetAccessor,
-  0
-};
+Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
+  return GetFunctionArguments(function->GetIsolate(), function);
+}
+
+
+void Accessors::FunctionArgumentsGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result = GetFunctionArguments(isolate, function);
+  info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
+
+void Accessors::FunctionArgumentsSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  // Function arguments is non writable, non configurable.
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->arguments_string(),
+                      &FunctionArgumentsGetter,
+                      &FunctionArgumentsSetter,
+                      attributes);
+}
 
 
 //
@@ -799,22 +1195,33 @@ const AccessorDescriptor Accessors::FunctionArguments = {
 //
 
 
+static inline bool AllowAccessToFunction(Context* current_context,
+                                         JSFunction* function) {
+  return current_context->HasSameSecurityTokenAs(function->context());
+}
+
+
 class FrameFunctionIterator {
  public:
   FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
-      : frame_iterator_(isolate),
+      : isolate_(isolate),
+        frame_iterator_(isolate),
         functions_(2),
         index_(0) {
     GetFunctions();
   }
   JSFunction* next() {
-    if (functions_.length() == 0) return NULL;
-    JSFunction* next_function = functions_[index_];
-    index_--;
-    if (index_ < 0) {
-      GetFunctions();
+    while (true) {
+      if (functions_.length() == 0) return NULL;
+      JSFunction* next_function = functions_[index_];
+      index_--;
+      if (index_ < 0) {
+        GetFunctions();
+      }
+      // Skip functions from other origins.
+      if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
+      return next_function;
     }
-    return next_function;
   }
 
   // Iterate through functions until the first occurence of 'function'.
@@ -835,39 +1242,34 @@ class FrameFunctionIterator {
     if (frame_iterator_.done()) return;
     JavaScriptFrame* frame = frame_iterator_.frame();
     frame->GetFunctions(&functions_);
-    ASSERT(functions_.length() > 0);
+    DCHECK(functions_.length() > 0);
     frame_iterator_.Advance();
     index_ = functions_.length() - 1;
   }
+  Isolate* isolate_;
   JavaScriptFrameIterator frame_iterator_;
   List<JSFunction*> functions_;
   int index_;
 };
 
 
-MaybeObject* Accessors::FunctionGetCaller(Isolate* isolate,
-                                          Object* object,
-                                          void*) {
-  HandleScope scope(isolate);
+MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
+                                   Handle<JSFunction> function) {
   DisallowHeapAllocation no_allocation;
-  JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
-  if (holder == NULL) return isolate->heap()->undefined_value();
-  if (holder->shared()->native()) return isolate->heap()->null_value();
-  Handle<JSFunction> function(holder, isolate);
-
   FrameFunctionIterator it(isolate, no_allocation);
-
+  if (function->shared()->native()) {
+    return MaybeHandle<JSFunction>();
+  }
   // Find the function from the frames.
   if (!it.Find(*function)) {
     // No frame corresponding to the given function found. Return null.
-    return isolate->heap()->null_value();
+    return MaybeHandle<JSFunction>();
   }
-
   // Find previously called non-toplevel function.
   JSFunction* caller;
   do {
     caller = it.next();
-    if (caller == NULL) return isolate->heap()->null_value();
+    if (caller == NULL) return MaybeHandle<JSFunction>();
   } while (caller->shared()->is_toplevel());
 
   // If caller is a built-in function and caller's caller is also built-in,
@@ -884,24 +1286,59 @@ MaybeObject* Accessors::FunctionGetCaller(Isolate* isolate,
   // allows us to make bound functions use the strict function map
   // and its associated throwing caller and arguments.
   if (caller->shared()->bound()) {
-    return isolate->heap()->null_value();
+    return MaybeHandle<JSFunction>();
   }
   // Censor if the caller is not a sloppy mode function.
   // Change from ES5, which used to throw, see:
   // https://bugs.ecmascript.org/show_bug.cgi?id=310
   if (caller->shared()->strict_mode() == STRICT) {
-    return isolate->heap()->null_value();
+    return MaybeHandle<JSFunction>();
+  }
+  // Don't return caller from another security context.
+  if (!AllowAccessToFunction(isolate->context(), caller)) {
+    return MaybeHandle<JSFunction>();
+  }
+  return Handle<JSFunction>(caller);
+}
+
+
+void Accessors::FunctionCallerGetter(
+    v8::Local<v8::Name> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result;
+  MaybeHandle<JSFunction> maybe_caller;
+  maybe_caller = FindCaller(isolate, function);
+  Handle<JSFunction> caller;
+  if (maybe_caller.ToHandle(&caller)) {
+    result = caller;
+  } else {
+    result = isolate->factory()->null_value();
   }
+  info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
 
-  return caller;
+void Accessors::FunctionCallerSetter(
+    v8::Local<v8::Name> name,
+    v8::Local<v8::Value> val,
+    const v8::PropertyCallbackInfo<void>& info) {
+  // Function caller is non writable, non configurable.
+  UNREACHABLE();
 }
 
 
-const AccessorDescriptor Accessors::FunctionCaller = {
-  FunctionGetCaller,
-  ReadOnlySetAccessor,
-  0
-};
+Handle<AccessorInfo> Accessors::FunctionCallerInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->caller_string(),
+                      &FunctionCallerGetter,
+                      &FunctionCallerSetter,
+                      attributes);
+}
 
 
 //
@@ -913,15 +1350,22 @@ static void ModuleGetExport(
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
   Context* context = Context::cast(instance->context());
-  ASSERT(context->IsModuleContext());
+  DCHECK(context->IsModuleContext());
   int slot = info.Data()->Int32Value();
   Object* value = context->get(slot);
   Isolate* isolate = instance->GetIsolate();
   if (value->IsTheHole()) {
     Handle<String> name = v8::Utils::OpenHandle(*property);
-    isolate->ScheduleThrow(
-        *isolate->factory()->NewReferenceError("not_defined",
-                                               HandleVector(&name, 1)));
+
+    Handle<Object> exception;
+    MaybeHandle<Object> maybe = isolate->factory()->NewReferenceError(
+        "not_defined", HandleVector(&name, 1));
+    if (!maybe.ToHandle(&exception)) {
+      isolate->OptionalRescheduleException(false);
+      return;
+    }
+
+    isolate->ScheduleThrow(*exception);
     return;
   }
   info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
@@ -934,15 +1378,21 @@ static void ModuleSetExport(
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
   Context* context = Context::cast(instance->context());
-  ASSERT(context->IsModuleContext());
+  DCHECK(context->IsModuleContext());
   int slot = info.Data()->Int32Value();
   Object* old_value = context->get(slot);
+  Isolate* isolate = context->GetIsolate();
   if (old_value->IsTheHole()) {
     Handle<String> name = v8::Utils::OpenHandle(*property);
-    Isolate* isolate = instance->GetIsolate();
-    isolate->ScheduleThrow(
-        *isolate->factory()->NewReferenceError("not_defined",
-                                               HandleVector(&name, 1)));
+    Handle<Object> exception;
+    MaybeHandle<Object> maybe = isolate->factory()->NewReferenceError(
+        "not_defined", HandleVector(&name, 1));
+    if (!maybe.ToHandle(&exception)) {
+      isolate->OptionalRescheduleException(false);
+      return;
+    }
+
+    isolate->ScheduleThrow(*exception);
     return;
   }
   context->set(slot, *v8::Utils::OpenHandle(*value));