Upgrade to 3.29
Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.
Bug: 17370214
Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/src/accessors.cc b/src/accessors.cc
index 8048738..011372c 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -1,76 +1,197 @@
// 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.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include "v8.h"
-#include "accessors.h"
+#include "src/v8.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"
+#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* FindInPrototypeChain(Object* obj, bool* found_it) {
- ASSERT(!*found_it);
- Heap* heap = HEAP;
- while (!Is<C>(obj)) {
- if (obj == heap->null_value()) return NULL;
- obj = obj->GetPrototype();
- }
- *found_it = true;
- return C::cast(obj);
+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;
}
-// Entry point that never should be called.
-MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) {
- UNREACHABLE();
+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;
+}
+
+
+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;
}
-Object* Accessors::IllegalGetAccessor(Object* object, void*) {
- UNREACHABLE();
- return object;
+static V8_INLINE bool CheckForName(Handle<Name> name,
+ Handle<String> property_name,
+ int offset,
+ int* object_offset) {
+ if (Name::Equals(name, property_name)) {
+ *object_offset = offset;
+ return true;
+ }
+ return false;
}
-MaybeObject* Accessors::ReadOnlySetAccessor(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;
+// Returns true for properties that are accessors to object fields.
+// If true, *object_offset contains offset of object field.
+template <class T>
+bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
+ Handle<Name> name,
+ int* object_offset) {
+ Isolate* isolate = name->GetIsolate();
+
+ if (type->Is(T::String())) {
+ return CheckForName(name, isolate->factory()->length_string(),
+ String::kLengthOffset, object_offset);
+ }
+
+ if (!type->IsClass()) return false;
+ Handle<Map> map = type->AsClass()->Map();
+
+ switch (map->instance_type()) {
+ case JS_ARRAY_TYPE:
+ return
+ CheckForName(name, isolate->factory()->length_string(),
+ JSArray::kLengthOffset, object_offset);
+ case JS_TYPED_ARRAY_TYPE:
+ return
+ CheckForName(name, isolate->factory()->length_string(),
+ JSTypedArray::kLengthOffset, object_offset) ||
+ CheckForName(name, isolate->factory()->byte_length_string(),
+ JSTypedArray::kByteLengthOffset, object_offset) ||
+ CheckForName(name, isolate->factory()->byte_offset_string(),
+ JSTypedArray::kByteOffsetOffset, object_offset);
+ case JS_ARRAY_BUFFER_TYPE:
+ return
+ CheckForName(name, isolate->factory()->byte_length_string(),
+ JSArrayBuffer::kByteLengthOffset, object_offset);
+ case JS_DATA_VIEW_TYPE:
+ return
+ CheckForName(name, isolate->factory()->byte_length_string(),
+ JSDataView::kByteLengthOffset, object_offset) ||
+ CheckForName(name, isolate->factory()->byte_offset_string(),
+ JSDataView::kByteOffsetOffset, object_offset);
+ default:
+ return false;
+ }
+}
+
+
+template
+bool Accessors::IsJSObjectFieldAccessor<Type>(Type* type,
+ Handle<Name> name,
+ int* object_offset);
+
+
+template
+bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
+ 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::ArgumentsIterator
+//
+
+
+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);
}
@@ -79,198 +200,315 @@
//
-MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
- // Traverse the prototype chain until we reach an array.
- bool found_it = false;
- JSArray* holder = FindInPrototypeChain<JSArray>(object, &found_it);
- if (!found_it) return Smi::FromInt(0);
- return holder->length();
-}
-
-
// The helper function will 'flatten' Number objects.
-Object* Accessors::FlattenNumber(Object* value) {
+Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
+ Handle<Object> value) {
if (value->IsNumber() || !value->IsJSValue()) return value;
- JSValue* wrapper = JSValue::cast(value);
- ASSERT(Isolate::Current()->context()->global_context()->number_function()->
+ Handle<JSValue> wrapper = Handle<JSValue>::cast(value);
+ DCHECK(wrapper->GetIsolate()->native_context()->number_function()->
has_initial_map());
- Map* number_map = Isolate::Current()->context()->global_context()->
- number_function()->initial_map();
- if (wrapper->map() == number_map) return wrapper->value();
+ if (wrapper->map() == isolate->number_function()->initial_map()) {
+ return handle(wrapper->value(), isolate);
+ }
+
return value;
}
-MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) {
- Isolate* isolate = object->GetIsolate();
-
- // 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()) {
- return object->SetLocalPropertyIgnoreAttributes(
- isolate->heap()->length_symbol(), value, NONE);
- }
-
- value = FlattenNumber(value);
-
- // Need to call methods that may trigger GC.
+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);
-
- // Protect raw pointers.
- Handle<JSObject> object_handle(object, isolate);
- Handle<Object> value_handle(value, isolate);
-
- bool has_exception;
- Handle<Object> uint32_v = Execution::ToUint32(value_handle, &has_exception);
- if (has_exception) return Failure::Exception();
- Handle<Object> number_v = Execution::ToNumber(value_handle, &has_exception);
- if (has_exception) return Failure::Exception();
-
- if (uint32_v->Number() == number_v->Number()) {
- return Handle<JSArray>::cast(object_handle)->SetElementsLength(*uint32_v);
- }
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_length",
- HandleVector<Object>(NULL, 0)));
+ JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
+ Object* result = holder->length();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
}
-const AccessorDescriptor Accessors::ArrayLength = {
- ArrayGetLength,
- ArraySetLength,
- 0
-};
+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);
+ 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()) {
+ 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;
+ }
+
+ isolate->ScheduleThrow(*exception);
+}
+
+
+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);
-MaybeObject* Accessors::StringGetLength(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);
+ // 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.
+
+ 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
-};
-
-
-//
-// Accessors::ScriptSource
-//
-
-
-MaybeObject* Accessors::ScriptGetSource(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->source();
+void Accessors::StringLengthSetter(
+ v8::Local<v8::Name> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::ScriptSource = {
- ScriptGetSource,
- IllegalSetter,
- 0
-};
-
-
-//
-// Accessors::ScriptName
-//
-
-
-MaybeObject* Accessors::ScriptGetName(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->name();
+Handle<AccessorInfo> Accessors::StringLengthInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->length_string(),
+ &StringLengthGetter,
+ &StringLengthSetter,
+ attributes);
}
-const AccessorDescriptor Accessors::ScriptName = {
- ScriptGetName,
- IllegalSetter,
- 0
-};
-
-
-//
-// Accessors::ScriptId
-//
-
-
-MaybeObject* Accessors::ScriptGetId(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->id();
-}
-
-
-const AccessorDescriptor Accessors::ScriptId = {
- ScriptGetId,
- IllegalSetter,
- 0
-};
-
-
-//
-// Accessors::ScriptLineOffset
-//
-
-
-MaybeObject* Accessors::ScriptGetLineOffset(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->line_offset();
-}
-
-
-const AccessorDescriptor Accessors::ScriptLineOffset = {
- ScriptGetLineOffset,
- IllegalSetter,
- 0
-};
-
-
//
// Accessors::ScriptColumnOffset
//
-MaybeObject* Accessors::ScriptGetColumnOffset(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->column_offset();
+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::ScriptColumnOffset = {
- ScriptGetColumnOffset,
- IllegalSetter,
- 0
-};
-
-
-//
-// Accessors::ScriptData
-//
-
-
-MaybeObject* Accessors::ScriptGetData(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->data();
+void Accessors::ScriptColumnOffsetSetter(
+ v8::Local<v8::Name> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::ScriptData = {
- ScriptGetData,
- IllegalSetter,
- 0
-};
+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::ScriptId
+//
+
+
+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)));
+}
+
+
+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::ScriptName
+//
+
+
+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)));
+}
+
+
+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::ScriptSource
+//
+
+
+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)));
+}
+
+
+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::ScriptLineOffset
+//
+
+
+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)));
+}
+
+
+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);
+}
//
@@ -278,17 +516,36 @@
//
-MaybeObject* Accessors::ScriptGetType(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);
+}
//
@@ -296,17 +553,37 @@
//
-MaybeObject* Accessors::ScriptGetCompilationType(Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return 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);
+}
//
@@ -314,28 +591,115 @@
//
-MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) {
- JSValue* wrapper = JSValue::cast(object);
- Isolate* isolate = wrapper->GetIsolate();
+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);
+}
//
@@ -343,17 +707,36 @@
//
-MaybeObject* Accessors::ScriptGetContextData(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);
+}
//
@@ -361,26 +744,46 @@
//
-MaybeObject* Accessors::ScriptGetEvalFromScript(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 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);
+}
//
@@ -388,30 +791,45 @@
//
-MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) {
- HandleScope scope;
- Handle<Script> script(Script::cast(JSValue::cast(object)->value()));
-
- // If this is not a script compiled through eval there is no eval position.
- int compilation_type = Smi::cast(script->compilation_type())->value();
- if (compilation_type != Script::COMPILATION_TYPE_EVAL) {
- return HEAP->undefined_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<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);
}
-
- // 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()));
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
- ScriptGetEvalFromScriptPosition,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptEvalFromScriptPositionSetter(
+ v8::Local<v8::Name> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+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);
+}
//
@@ -419,88 +837,134 @@
//
-MaybeObject* Accessors::ScriptGetEvalFromFunctionName(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
//
-
-MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
- Heap* heap = Isolate::Current()->heap();
- bool found_it = false;
- JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return heap->undefined_value();
- while (!function->should_have_prototype()) {
- found_it = false;
- function = FindInPrototypeChain<JSFunction>(object->GetPrototype(),
- &found_it);
- // There has to be one because we hit the getter.
- ASSERT(found_it);
- }
-
+static Handle<Object> GetFunctionPrototype(Isolate* isolate,
+ Handle<JSFunction> function) {
if (!function->has_prototype()) {
- Object* prototype;
- { MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function);
- if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
- }
- Object* result;
- { MaybeObject* maybe_result = function->SetPrototype(prototype);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
+ JSFunction::SetPrototype(function, proto);
}
- return function->prototype();
+ return Handle<Object>(function->prototype(), isolate);
}
-MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
- Object* value,
- void*) {
- Heap* heap = object->GetHeap();
- bool found_it = false;
- JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return heap->undefined_value();
- if (!function->should_have_prototype()) {
- // Since we hit this accessor, object will have no prototype property.
- return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(),
- value,
- NONE);
+static Handle<Object> SetFunctionPrototype(Isolate* isolate,
+ Handle<JSFunction> function,
+ Handle<Object> value) {
+ Handle<Object> old_value;
+ bool is_observed = function->map()->is_observed();
+ if (is_observed) {
+ if (function->has_prototype())
+ old_value = handle(function->prototype(), isolate);
+ else
+ old_value = isolate->factory()->NewFunctionPrototype(function);
}
- Object* prototype;
- { MaybeObject* maybe_prototype = function->SetPrototype(value);
- if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
+ JSFunction::SetPrototype(function, value);
+ DCHECK(function->prototype() == *value);
+
+ if (is_observed && !old_value->SameValue(*value)) {
+ JSObject::EnqueueChangeRecord(
+ function, "update", isolate->factory()->prototype_string(), old_value);
}
- ASSERT(function->prototype() == value);
+
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);
+}
//
@@ -508,31 +972,49 @@
//
-MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
- bool found_it = false;
- JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return Smi::FromInt(0);
- // Check if already compiled.
- if (!function->shared()->is_compiled()) {
+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<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.
- HandleScope scope;
- Handle<JSFunction> handle(function);
- if (!JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
- return Failure::Exception();
+ if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
+ length = function->shared()->length();
}
- return Smi::FromInt(handle->shared()->length());
- } else {
- return Smi::FromInt(function->shared()->length());
+ if (isolate->has_pending_exception()) {
+ isolate->OptionalRescheduleException(false);
+ }
}
+ 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);
+}
//
@@ -540,19 +1022,35 @@
//
-MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
- bool found_it = false;
- JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return HEAP->undefined_value();
- return 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);
+}
//
@@ -560,103 +1058,136 @@
//
-static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
+static Handle<Object> ArgumentsForInlinedFunction(
JavaScriptFrame* frame,
Handle<JSFunction> inlined_function,
int inlined_frame_index) {
- Factory* factory = Isolate::Current()->factory();
- Vector<SlotRef> args_slots =
- SlotRef::ComputeSlotMappingForArguments(
- frame,
- inlined_frame_index,
- inlined_function->shared()->formal_parameter_count());
- int args_count = args_slots.length();
+ Isolate* isolate = inlined_function->GetIsolate();
+ Factory* factory = isolate->factory();
+ SlotRefValueBuilder slot_refs(
+ frame,
+ inlined_frame_index,
+ inlined_function->shared()->formal_parameter_count());
+
+ int args_count = slot_refs.args_length();
Handle<JSObject> arguments =
factory->NewArgumentsObject(inlined_function, args_count);
Handle<FixedArray> array = factory->NewFixedArray(args_count);
+ slot_refs.Prepare(isolate);
for (int i = 0; i < args_count; ++i) {
- Handle<Object> value = args_slots[i].GetValue();
+ Handle<Object> value = slot_refs.GetNext(isolate, 0);
array->set(i, *value);
}
+ slot_refs.Finish(isolate);
arguments->set_elements(*array);
- args_slots.Dispose();
// Return the freshly allocated arguments object.
- return *arguments;
+ return arguments;
}
-MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
- Isolate* isolate = Isolate::Current();
- HandleScope scope(isolate);
- bool found_it = false;
- JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return isolate->heap()->undefined_value();
- Handle<JSFunction> function(holder, isolate);
-
- if (function->shared()->native()) return isolate->heap()->null_value();
- // Find the top invocation of the function by traversing frames.
+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();
+
+ // Find the top invocation of the function by traversing frames.
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;
+ int function_index = FindFunctionInFrame(frame, function);
+ if (function_index < 0) 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);
- }
-
- 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_symbol());
- 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;
+ 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);
}
- functions.Rewind(0);
+
+ 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.
+ 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);
+}
//
@@ -664,35 +1195,33 @@
//
-static MaybeObject* CheckNonStrictCallerOrThrow(
- Isolate* isolate,
- JSFunction* caller) {
- DisableAssertNoAllocation enable_allocation;
- if (!caller->shared()->is_classic_mode()) {
- return isolate->Throw(
- *isolate->factory()->NewTypeError("strict_caller",
- HandleVector<Object>(NULL, 0)));
- }
- return caller;
+static inline bool AllowAccessToFunction(Context* current_context,
+ JSFunction* function) {
+ return current_context->HasSameSecurityTokenAs(function->context());
}
class FrameFunctionIterator {
public:
- FrameFunctionIterator(Isolate* isolate, const AssertNoAllocation& promise)
- : frame_iterator_(isolate),
+ FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
+ : 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'.
@@ -713,39 +1242,34 @@
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(Object* object, void*) {
- Isolate* isolate = Isolate::Current();
- HandleScope scope(isolate);
- AssertNoAllocation no_alloc;
- bool found_it = false;
- JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
- if (!found_it) return isolate->heap()->undefined_value();
- if (holder->shared()->native()) return isolate->heap()->null_value();
- Handle<JSFunction> function(holder, isolate);
-
- FrameFunctionIterator it(isolate, no_alloc);
-
+MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
+ Handle<JSFunction> function) {
+ DisallowHeapAllocation no_allocation;
+ 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,
@@ -755,51 +1279,144 @@
caller = potential_caller;
potential_caller = it.next();
}
+ if (!caller->shared()->native() && potential_caller != NULL) {
+ caller = potential_caller;
+ }
// If caller is bound, return null. This is compatible with JSC, and
// 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>();
}
- return CheckNonStrictCallerOrThrow(isolate, caller);
+ // 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 MaybeHandle<JSFunction>();
+ }
+ // Don't return caller from another security context.
+ if (!AllowAccessToFunction(isolate->context(), caller)) {
+ return MaybeHandle<JSFunction>();
+ }
+ return Handle<JSFunction>(caller);
}
-const AccessorDescriptor Accessors::FunctionCaller = {
- FunctionGetCaller,
- ReadOnlySetAccessor,
- 0
-};
+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));
+}
+
+
+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();
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionCallerInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->caller_string(),
+ &FunctionCallerGetter,
+ &FunctionCallerSetter,
+ attributes);
+}
//
-// Accessors::ObjectPrototype
+// Accessors::MakeModuleExport
//
+static void ModuleGetExport(
+ v8::Local<v8::String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
+ Context* context = Context::cast(instance->context());
+ 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);
-MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
- Object* current = receiver->GetPrototype();
- while (current->IsJSObject() &&
- JSObject::cast(current)->map()->is_hidden_prototype()) {
- current = current->GetPrototype();
+ 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;
}
- return current;
+ info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
}
-MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver,
- Object* value,
- void*) {
- const bool skip_hidden_prototypes = true;
- // To be consistent with other Set functions, return the value.
- return receiver->SetPrototype(value, skip_hidden_prototypes);
+static void ModuleSetExport(
+ v8::Local<v8::String> property,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
+ Context* context = Context::cast(instance->context());
+ 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);
+ 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));
}
-const AccessorDescriptor Accessors::ObjectPrototype = {
- ObjectGetPrototype,
- ObjectSetPrototype,
- 0
-};
+Handle<AccessorInfo> Accessors::MakeModuleExport(
+ Handle<String> name,
+ int index,
+ PropertyAttributes attributes) {
+ Isolate* isolate = name->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
+ info->set_property_attributes(attributes);
+ info->set_all_can_read(true);
+ info->set_all_can_write(true);
+ info->set_name(*name);
+ info->set_data(Smi::FromInt(index));
+ Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
+ Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
+ info->set_getter(*getter);
+ if (!(attributes & ReadOnly)) info->set_setter(*setter);
+ return info;
+}
+
} } // namespace v8::internal