PR-URL: https://github.com/iojs/io.js/pull/952
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Rod Vagg <rod@vagg.org>
This commit is contained in:
Ben Noordhuis 2015-02-25 11:41:56 +01:00
Родитель 739fda16a9
Коммит 78f4837926
22 изменённых файлов: 368 добавлений и 87 удалений

17
deps/v8/include/v8.h поставляемый
Просмотреть файл

@ -3899,6 +3899,9 @@ class V8_EXPORT FunctionTemplate : public Template {
};
enum class PropertyHandlerFlags { kNone = 0, kAllCanRead = 1 };
struct NamedPropertyHandlerConfiguration {
NamedPropertyHandlerConfiguration(
/** Note: getter is required **/
@ -3907,13 +3910,15 @@ struct NamedPropertyHandlerConfiguration {
GenericNamedPropertyQueryCallback query = 0,
GenericNamedPropertyDeleterCallback deleter = 0,
GenericNamedPropertyEnumeratorCallback enumerator = 0,
Handle<Value> data = Handle<Value>())
Handle<Value> data = Handle<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
data(data) {}
data(data),
flags(flags) {}
GenericNamedPropertyGetterCallback getter;
GenericNamedPropertySetterCallback setter;
@ -3921,6 +3926,7 @@ struct NamedPropertyHandlerConfiguration {
GenericNamedPropertyDeleterCallback deleter;
GenericNamedPropertyEnumeratorCallback enumerator;
Handle<Value> data;
PropertyHandlerFlags flags;
};
@ -3932,13 +3938,15 @@ struct IndexedPropertyHandlerConfiguration {
IndexedPropertyQueryCallback query = 0,
IndexedPropertyDeleterCallback deleter = 0,
IndexedPropertyEnumeratorCallback enumerator = 0,
Handle<Value> data = Handle<Value>())
Handle<Value> data = Handle<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
data(data) {}
data(data),
flags(flags) {}
IndexedPropertyGetterCallback getter;
IndexedPropertySetterCallback setter;
@ -3946,6 +3954,7 @@ struct IndexedPropertyHandlerConfiguration {
IndexedPropertyDeleterCallback deleter;
IndexedPropertyEnumeratorCallback enumerator;
Handle<Value> data;
PropertyHandlerFlags flags;
};

35
deps/v8/src/api.cc поставляемый
Просмотреть файл

@ -1306,12 +1306,10 @@ void ObjectTemplate::SetAccessor(v8::Handle<Name> name,
template <typename Getter, typename Setter, typename Query, typename Deleter,
typename Enumerator>
static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
Getter getter, Setter setter,
Query query, Deleter remover,
Enumerator enumerator,
Handle<Value> data,
bool can_intercept_symbols) {
static void ObjectTemplateSetNamedPropertyHandler(
ObjectTemplate* templ, Getter getter, Setter setter, Query query,
Deleter remover, Enumerator enumerator, Handle<Value> data,
bool can_intercept_symbols, PropertyHandlerFlags flags) {
i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
@ -1319,10 +1317,8 @@ static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
i::FunctionTemplateInfo* constructor =
i::FunctionTemplateInfo::cast(Utils::OpenHandle(templ)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
i::Handle<i::InterceptorInfo> obj =
i::Handle<i::InterceptorInfo>::cast(struct_obj);
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
@ -1331,6 +1327,8 @@ static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
obj->set_flags(0);
obj->set_can_intercept_symbols(can_intercept_symbols);
obj->set_all_can_read(static_cast<int>(flags) &
static_cast<int>(PropertyHandlerFlags::kAllCanRead));
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@ -1345,15 +1343,16 @@ void ObjectTemplate::SetNamedPropertyHandler(
NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
NamedPropertyEnumeratorCallback enumerator, Handle<Value> data) {
ObjectTemplateSetNamedPropertyHandler(this, getter, setter, query, remover,
enumerator, data, false);
enumerator, data, false,
PropertyHandlerFlags::kNone);
}
void ObjectTemplate::SetHandler(
const NamedPropertyHandlerConfiguration& config) {
ObjectTemplateSetNamedPropertyHandler(this, config.getter, config.setter,
config.query, config.deleter,
config.enumerator, config.data, true);
ObjectTemplateSetNamedPropertyHandler(
this, config.getter, config.setter, config.query, config.deleter,
config.enumerator, config.data, true, config.flags);
}
@ -1409,10 +1408,8 @@ void ObjectTemplate::SetHandler(
i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
Utils::OpenHandle(this)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
i::Handle<i::InterceptorInfo> obj =
i::Handle<i::InterceptorInfo>::cast(struct_obj);
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
@ -1422,6 +1419,8 @@ void ObjectTemplate::SetHandler(
SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
}
obj->set_flags(0);
obj->set_all_can_read(static_cast<int>(config.flags) &
static_cast<int>(PropertyHandlerFlags::kAllCanRead));
v8::Local<v8::Value> data = config.data;
if (data.IsEmpty()) {

1
deps/v8/src/flags.cc поставляемый
Просмотреть файл

@ -556,6 +556,7 @@ uint32_t FlagList::Hash() {
for (size_t i = 0; i < num_flags; ++i) {
Flag* current = &flags[i];
if (!current->IsDefault()) {
modified_args_as_string << i;
modified_args_as_string << *current;
}
}

4
deps/v8/src/generator.js поставляемый
Просмотреть файл

@ -97,7 +97,7 @@ function SetUpGenerators() {
%AddNamedProperty(GeneratorObjectPrototype, symbolIterator,
GeneratorObjectIterator, DONT_ENUM | DONT_DELETE | READ_ONLY);
%AddNamedProperty(GeneratorObjectPrototype, "constructor",
GeneratorFunctionPrototype, DONT_ENUM | DONT_DELETE | READ_ONLY);
GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
%AddNamedProperty(GeneratorObjectPrototype,
symbolToStringTag, "Generator", DONT_ENUM | READ_ONLY);
%InternalSetPrototype(GeneratorFunctionPrototype, $Function.prototype);
@ -105,7 +105,7 @@ function SetUpGenerators() {
symbolToStringTag, "GeneratorFunction", DONT_ENUM | READ_ONLY);
%SetCode(GeneratorFunctionPrototype, GeneratorFunctionPrototypeConstructor);
%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
GeneratorFunction, DONT_ENUM | DONT_DELETE | READ_ONLY);
GeneratorFunction, DONT_ENUM | READ_ONLY);
%InternalSetPrototype(GeneratorFunction, $Function);
%SetCode(GeneratorFunction, GeneratorFunctionConstructor);
}

2
deps/v8/src/globals.h поставляемый
Просмотреть файл

@ -84,7 +84,7 @@ namespace internal {
// Determine whether double field unboxing feature is enabled.
#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64)
#define V8_DOUBLE_FIELDS_UNBOXING 1
#define V8_DOUBLE_FIELDS_UNBOXING 0
#else
#define V8_DOUBLE_FIELDS_UNBOXING 0
#endif

5
deps/v8/src/heap/mark-compact.cc поставляемый
Просмотреть файл

@ -3052,6 +3052,11 @@ void MarkCompactCollector::EvacuatePages() {
// have an emergency page and the space still has room for that.
if (space->HasEmergencyMemory() && space->CanExpand()) {
EvacuateLiveObjectsFromPage(p);
// Unlink the page from the list of pages here. We must not iterate
// over that page later (e.g. when scan on scavenge pages are
// processed). The page itself will be freed later and is still
// reachable from the evacuation candidates list.
p->Unlink();
} else {
// Without room for expansion evacuation is not guaranteed to succeed.
// Pessimistically abandon unevacuated pages.

7
deps/v8/src/heap/spaces.cc поставляемый
Просмотреть файл

@ -1142,7 +1142,12 @@ void PagedSpace::ReleasePage(Page* page) {
allocation_info_.set_limit(NULL);
}
page->Unlink();
// If page is still in a list, unlink it from that list.
if (page->next_chunk() != NULL) {
DCHECK(page->prev_chunk() != NULL);
page->Unlink();
}
if (page->IsFlagSet(MemoryChunk::CONTAINS_ONLY_DATA)) {
heap()->isolate()->memory_allocator()->Free(page);
} else {

2
deps/v8/src/ic/ic.cc поставляемый
Просмотреть файл

@ -2924,7 +2924,7 @@ RUNTIME_FUNCTION(LoadElementWithInterceptor) {
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
JSObject::GetElementWithInterceptor(receiver, receiver, index));
JSObject::GetElementWithInterceptor(receiver, receiver, index, true));
return *result;
}

1
deps/v8/src/objects-inl.h поставляемый
Просмотреть файл

@ -5517,6 +5517,7 @@ ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
kCanInterceptSymbolsBit)
BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)

121
deps/v8/src/objects.cc поставляемый
Просмотреть файл

@ -572,12 +572,19 @@ MaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
static bool FindAllCanReadHolder(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
// Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
// which have already been checked.
DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
it->state() == LookupIterator::INTERCEPTOR);
for (it->Next(); it->IsFound(); it->Next()) {
if (it->state() == LookupIterator::ACCESSOR) {
Handle<Object> accessors = it->GetAccessors();
auto accessors = it->GetAccessors();
if (accessors->IsAccessorInfo()) {
if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
}
} else if (it->state() == LookupIterator::INTERCEPTOR) {
auto holder = it->GetHolder<JSObject>();
if (holder->GetNamedInterceptor()->all_can_read()) return true;
}
}
return false;
@ -587,10 +594,18 @@ static bool FindAllCanReadHolder(LookupIterator* it) {
MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
LookupIterator* it) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
if (FindAllCanReadHolder(it)) {
return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
it->GetHolder<JSObject>(),
it->GetAccessors());
while (FindAllCanReadHolder(it)) {
if (it->state() == LookupIterator::ACCESSOR) {
return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
it->GetHolder<JSObject>(),
it->GetAccessors());
}
DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
auto receiver = Handle<JSObject>::cast(it->GetReceiver());
auto result = GetPropertyWithInterceptor(it->GetHolder<JSObject>(),
receiver, it->name());
if (it->isolate()->has_scheduled_exception()) break;
if (!result.is_null()) return result;
}
it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
@ -601,8 +616,16 @@ MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
LookupIterator* it) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
if (FindAllCanReadHolder(it))
return maybe(it->property_details().attributes());
while (FindAllCanReadHolder(it)) {
if (it->state() == LookupIterator::ACCESSOR) {
return maybe(it->property_details().attributes());
}
DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
auto result = GetPropertyAttributesWithInterceptor(
it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
if (it->isolate()->has_scheduled_exception()) break;
if (result.has_value && result.value != ABSENT) return result;
}
it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
Maybe<PropertyAttributes>());
@ -736,6 +759,65 @@ Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
}
static MaybeHandle<JSObject> FindIndexedAllCanReadHolder(
Isolate* isolate, Handle<JSObject> js_object,
PrototypeIterator::WhereToStart where_to_start) {
for (PrototypeIterator iter(isolate, js_object, where_to_start);
!iter.IsAtEnd(); iter.Advance()) {
auto curr = PrototypeIterator::GetCurrent(iter);
if (!curr->IsJSObject()) break;
auto obj = Handle<JSObject>::cast(curr);
if (!obj->HasIndexedInterceptor()) continue;
if (obj->GetIndexedInterceptor()->all_can_read()) return obj;
}
return MaybeHandle<JSObject>();
}
MaybeHandle<Object> JSObject::GetElementWithFailedAccessCheck(
Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
uint32_t index) {
Handle<JSObject> holder = object;
PrototypeIterator::WhereToStart where_to_start =
PrototypeIterator::START_AT_RECEIVER;
while (true) {
auto all_can_read_holder =
FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
if (!all_can_read_holder.ToHandle(&holder)) break;
auto result =
JSObject::GetElementWithInterceptor(holder, receiver, index, false);
if (isolate->has_scheduled_exception()) break;
if (!result.is_null()) return result;
where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
}
isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
Maybe<PropertyAttributes> JSObject::GetElementAttributesWithFailedAccessCheck(
Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
uint32_t index) {
Handle<JSObject> holder = object;
PrototypeIterator::WhereToStart where_to_start =
PrototypeIterator::START_AT_RECEIVER;
while (true) {
auto all_can_read_holder =
FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
if (!all_can_read_holder.ToHandle(&holder)) break;
auto result =
JSObject::GetElementAttributeFromInterceptor(object, receiver, index);
if (isolate->has_scheduled_exception()) break;
if (result.has_value && result.value != ABSENT) return result;
where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
}
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
return maybe(ABSENT);
}
MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
Handle<Object> object,
Handle<Object> receiver,
@ -768,14 +850,14 @@ MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
// Check access rights if needed.
if (js_object->IsAccessCheckNeeded()) {
if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
return JSObject::GetElementWithFailedAccessCheck(isolate, js_object,
receiver, index);
}
}
if (js_object->HasIndexedInterceptor()) {
return JSObject::GetElementWithInterceptor(js_object, receiver, index);
return JSObject::GetElementWithInterceptor(js_object, receiver, index,
true);
}
if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
@ -4184,9 +4266,8 @@ Maybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver(
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
return maybe(ABSENT);
return GetElementAttributesWithFailedAccessCheck(isolate, object,
receiver, index);
}
}
@ -13383,10 +13464,10 @@ MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
}
MaybeHandle<Object> JSObject::GetElementWithInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
uint32_t index) {
MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
Handle<Object> receiver,
uint32_t index,
bool check_prototype) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing
@ -13411,6 +13492,8 @@ MaybeHandle<Object> JSObject::GetElementWithInterceptor(
}
}
if (!check_prototype) return MaybeHandle<Object>();
ElementsAccessor* handler = object->GetElementsAccessor();
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(

17
deps/v8/src/objects.h поставляемый
Просмотреть файл

@ -1971,9 +1971,8 @@ class JSObject: public JSReceiver {
// Returns the index'th element.
// The undefined object if index is out of bounds.
MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
uint32_t index);
Handle<JSObject> object, Handle<Object> receiver, uint32_t index,
bool check_prototype);
enum SetFastElementsCapacitySmiMode {
kAllowSmiElements,
@ -2336,6 +2335,14 @@ class JSObject: public JSReceiver {
Handle<Object> value,
StrictMode strict_mode,
bool check_prototype = true);
MUST_USE_RESULT static MaybeHandle<Object> GetElementWithFailedAccessCheck(
Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
uint32_t index);
MUST_USE_RESULT static Maybe<PropertyAttributes>
GetElementAttributesWithFailedAccessCheck(Isolate* isolate,
Handle<JSObject> object,
Handle<Object> receiver,
uint32_t index);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
@ -7062,8 +7069,6 @@ class SharedFunctionInfo: public HeapObject {
static const int kUniqueIdOffset = kFeedbackVectorOffset + kPointerSize;
static const int kLastPointerFieldOffset = kUniqueIdOffset;
#else
// Just to not break the postmortem support with conditional offsets
static const int kUniqueIdOffset = kFeedbackVectorOffset;
static const int kLastPointerFieldOffset = kFeedbackVectorOffset;
#endif
@ -10642,6 +10647,7 @@ class InterceptorInfo: public Struct {
DECL_ACCESSORS(enumerator, Object)
DECL_ACCESSORS(data, Object)
DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
DECL_BOOLEAN_ACCESSORS(all_can_read)
inline int flags() const;
inline void set_flags(int flags);
@ -10662,6 +10668,7 @@ class InterceptorInfo: public Struct {
static const int kSize = kFlagsOffset + kPointerSize;
static const int kCanInterceptSymbolsBit = 0;
static const int kAllCanReadBit = 1;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);

3
deps/v8/src/runtime/runtime-debug.cc поставляемый
Просмотреть файл

@ -246,7 +246,8 @@ RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
isolate, result,
JSObject::GetElementWithInterceptor(obj, obj, index, true));
return *result;
}

2
deps/v8/src/runtime/runtime-regexp.cc поставляемый
Просмотреть файл

@ -278,7 +278,7 @@ void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
}
void FindOneByteStringIndices(Vector<const uint8_t> subject, char pattern,
void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern,
ZoneList<int>* indices, unsigned int limit,
Zone* zone) {
DCHECK(limit > 0);

65
deps/v8/src/serialize.cc поставляемый
Просмотреть файл

@ -2054,6 +2054,10 @@ void Serializer::Pad() {
for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) {
sink_->Put(kNop, "Padding");
}
// Pad up to pointer size for checksum.
while (!IsAligned(sink_->Position(), kPointerAlignment)) {
sink_->Put(kNop, "Padding");
}
}
@ -2394,6 +2398,41 @@ Vector<const byte> SnapshotData::Payload() const {
}
class Checksum {
public:
explicit Checksum(Vector<const byte> payload) {
// Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit.
uintptr_t a = 1;
uintptr_t b = 0;
const uintptr_t* cur = reinterpret_cast<const uintptr_t*>(payload.start());
DCHECK(IsAligned(payload.length(), kIntptrSize));
const uintptr_t* end = cur + payload.length() / kIntptrSize;
while (cur < end) {
// Unsigned overflow expected and intended.
a += *cur++;
b += a;
}
#if V8_HOST_ARCH_64_BIT
a ^= a >> 32;
b ^= b >> 32;
#endif // V8_HOST_ARCH_64_BIT
a_ = static_cast<uint32_t>(a);
b_ = static_cast<uint32_t>(b);
}
bool Check(uint32_t a, uint32_t b) const { return a == a_ && b == b_; }
uint32_t a() const { return a_; }
uint32_t b() const { return b_; }
private:
uint32_t a_;
uint32_t b_;
DISALLOW_COPY_AND_ASSIGN(Checksum);
};
SerializedCodeData::SerializedCodeData(const List<byte>& payload,
const CodeSerializer& cs) {
DisallowHeapAllocation no_gc;
@ -2412,12 +2451,20 @@ SerializedCodeData::SerializedCodeData(const List<byte>& payload,
AllocateData(size);
// Set header values.
SetHeaderValue(kCheckSumOffset, CheckSum(cs.source()));
SetHeaderValue(kVersionHashOffset, Version::Hash());
SetHeaderValue(kSourceHashOffset, SourceHash(cs.source()));
SetHeaderValue(kCpuFeaturesOffset,
static_cast<uint32_t>(CpuFeatures::SupportedFeatures()));
SetHeaderValue(kFlagHashOffset, FlagList::Hash());
SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings());
SetHeaderValue(kReservationsOffset, reservations.length());
SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
SetHeaderValue(kPayloadLengthOffset, payload.length());
Checksum checksum(payload.ToConstVector());
SetHeaderValue(kChecksum1Offset, checksum.a());
SetHeaderValue(kChecksum2Offset, checksum.b());
// Copy reservation chunk sizes.
CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
reservation_size);
@ -2432,14 +2479,14 @@ SerializedCodeData::SerializedCodeData(const List<byte>& payload,
}
bool SerializedCodeData::IsSane(String* source) {
return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
Payload().length() >= SharedFunctionInfo::kSize;
}
int SerializedCodeData::CheckSum(String* string) {
return Version::Hash() ^ string->length();
bool SerializedCodeData::IsSane(String* source) const {
return GetHeaderValue(kVersionHashOffset) == Version::Hash() &&
GetHeaderValue(kSourceHashOffset) == SourceHash(source) &&
GetHeaderValue(kCpuFeaturesOffset) ==
static_cast<uint32_t>(CpuFeatures::SupportedFeatures()) &&
GetHeaderValue(kFlagHashOffset) == FlagList::Hash() &&
Checksum(Payload()).Check(GetHeaderValue(kChecksum1Offset),
GetHeaderValue(kChecksum2Offset));
}

44
deps/v8/src/serialize.h поставляемый
Просмотреть файл

@ -481,12 +481,14 @@ class SerializedData {
class IsLastChunkBits : public BitField<bool, 31, 1> {};
protected:
void SetHeaderValue(int offset, int value) {
reinterpret_cast<int*>(data_)[offset] = value;
void SetHeaderValue(int offset, uint32_t value) {
memcpy(reinterpret_cast<uint32_t*>(data_) + offset, &value, sizeof(value));
}
int GetHeaderValue(int offset) const {
return reinterpret_cast<const int*>(data_)[offset];
uint32_t GetHeaderValue(int offset) const {
uint32_t value;
memcpy(&value, reinterpret_cast<int*>(data_) + offset, sizeof(value));
return value;
}
void AllocateData(int size);
@ -920,22 +922,32 @@ class SerializedCodeData : public SerializedData {
explicit SerializedCodeData(ScriptData* data)
: SerializedData(const_cast<byte*>(data->data()), data->length()) {}
bool IsSane(String* source);
bool IsSane(String* source) const;
int CheckSum(String* source);
static uint32_t SourceHash(String* source) { return source->length(); }
// The data header consists of int-sized entries:
// [0] version hash
// [1] number of internalized strings
// [2] number of code stub keys
// [3] number of reservation size entries
// [4] payload length
static const int kCheckSumOffset = 0;
static const int kNumInternalizedStringsOffset = 1;
static const int kReservationsOffset = 2;
static const int kNumCodeStubKeysOffset = 3;
static const int kPayloadLengthOffset = 4;
static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
// [1] source hash
// [2] cpu features
// [3] flag hash
// [4] number of internalized strings
// [5] number of code stub keys
// [6] number of reservation size entries
// [7] payload length
// [8] checksum 1
// [9] checksum 2
static const int kVersionHashOffset = 0;
static const int kSourceHashOffset = 1;
static const int kCpuFeaturesOffset = 2;
static const int kFlagHashOffset = 3;
static const int kNumInternalizedStringsOffset = 4;
static const int kReservationsOffset = 5;
static const int kNumCodeStubKeysOffset = 6;
static const int kPayloadLengthOffset = 7;
static const int kChecksum1Offset = 8;
static const int kChecksum2Offset = 9;
static const int kHeaderSize = (kChecksum2Offset + 1) * kIntSize;
};
} } // namespace v8::internal

2
deps/v8/src/version.cc поставляемый
Просмотреть файл

@ -35,7 +35,7 @@
#define MAJOR_VERSION 4
#define MINOR_VERSION 1
#define BUILD_NUMBER 0
#define PATCH_LEVEL 14
#define PATCH_LEVEL 21
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0

5
deps/v8/src/version.h поставляемый
Просмотреть файл

@ -18,8 +18,9 @@ class Version {
static int GetBuild() { return build_; }
static int GetPatch() { return patch_; }
static bool IsCandidate() { return candidate_; }
static int Hash() {
return static_cast<int>(base::hash_combine(major_, minor_, build_, patch_));
static uint32_t Hash() {
return static_cast<uint32_t>(
base::hash_combine(major_, minor_, build_, patch_));
}
// Calculate the V8 version string.

2
deps/v8/test/cctest/test-api.cc поставляемый
Просмотреть файл

@ -24540,7 +24540,7 @@ TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit2) {
void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
const char* garbage = "garbage garbage garbage garbage.";
const char* garbage = "garbage garbage garbage garbage garbage garbage";
const uint8_t* data = reinterpret_cast<const uint8_t*>(garbage);
int length = 16;
v8::ScriptCompiler::CachedData* cached_data =

50
deps/v8/test/cctest/test-serialize.cc поставляемый
Просмотреть файл

@ -1156,6 +1156,56 @@ TEST(SerializeToplevelIsolates) {
}
TEST(SerializeToplevelFlagChange) {
FLAG_serialize_toplevel = true;
const char* source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache;
v8::Isolate* isolate1 = v8::Isolate::New();
{
v8::Isolate::Scope iscope(isolate1);
v8::HandleScope scope(isolate1);
v8::Local<v8::Context> context = v8::Context::New(isolate1);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(source);
v8::ScriptOrigin origin(v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin);
v8::Local<v8::UnboundScript> script = v8::ScriptCompiler::CompileUnbound(
isolate1, &source, v8::ScriptCompiler::kProduceCodeCache);
const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
CHECK(data);
// Persist cached data.
uint8_t* buffer = NewArray<uint8_t>(data->length);
MemCopy(buffer, data->data, data->length);
cache = new v8::ScriptCompiler::CachedData(
buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
CHECK(result->ToString(isolate1)->Equals(v8_str("abcdef")));
}
isolate1->Dispose();
v8::Isolate* isolate2 = v8::Isolate::New();
FLAG_allow_natives_syntax = true; // Flag change should trigger cache reject.
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(source);
v8::ScriptOrigin origin(v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::ScriptCompiler::CompileUnbound(isolate2, &source,
v8::ScriptCompiler::kConsumeCodeCache);
CHECK(cache->rejected);
}
isolate2->Dispose();
}
TEST(SerializeWithHarmonyScoping) {
FLAG_serialize_toplevel = true;
FLAG_harmony_scoping = true;

15
deps/v8/test/mjsunit/es6/regress/regress-3902.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function* g() {}
assertTrue(Object.getOwnPropertyDescriptor(g.__proto__, "constructor").configurable);
assertTrue(Object.getOwnPropertyDescriptor(g.prototype.__proto__, "constructor").configurable);
function FakeGeneratorFunctionConstructor() {}
Object.defineProperty(g.__proto__, "constructor", {value: FakeGeneratorFunctionConstructor});
assertSame(g.__proto__.constructor, FakeGeneratorFunctionConstructor);
function FakeGeneratorObjectConstructor() {}
Object.defineProperty(g.prototype.__proto__, "constructor", {value: FakeGeneratorObjectConstructor});
assertSame(g.prototype.__proto__.constructor, FakeGeneratorObjectConstructor);

41
deps/v8/test/mjsunit/regress/regress-430201.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,41 @@
// Copyright 2010 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.
// Flags: --allow-natives-syntax --expose-gc
var array_1 = [];
%SetFlags("--stress-compaction");
for (var a = 0; a < 10000; a++) { array_1[a * 100] = 0; }
gc();
gc();
var array_2 = [];
for (var i = 0; i < 321361; i++) {
array_2[i] = String.fromCharCode(i)[0];
}

14
deps/v8/tools/gen-postmortem-metadata.py поставляемый
Просмотреть файл

@ -70,6 +70,8 @@ consts_misc = [
{ 'name': 'ExternalStringTag', 'value': 'kExternalStringTag' },
{ 'name': 'SlicedStringTag', 'value': 'kSlicedStringTag' },
{ 'name': 'FailureTag', 'value': 'kFailureTag' },
{ 'name': 'FailureTagMask', 'value': 'kFailureTagMask' },
{ 'name': 'HeapObjectTag', 'value': 'kHeapObjectTag' },
{ 'name': 'HeapObjectTagMask', 'value': 'kHeapObjectTagMask' },
{ 'name': 'SmiTag', 'value': 'kSmiTag' },
@ -92,6 +94,8 @@ consts_misc = [
'value': 'DescriptorArray::kFirstIndex' },
{ 'name': 'prop_type_field',
'value': 'FIELD' },
{ 'name': 'prop_type_first_phantom',
'value': 'TRANSITION' },
{ 'name': 'prop_type_mask',
'value': 'PropertyDetails::TypeField::kMask' },
{ 'name': 'prop_index_mask',
@ -116,9 +120,9 @@ consts_misc = [
'value': 'DICTIONARY_ELEMENTS' },
{ 'name': 'bit_field2_elements_kind_mask',
'value': 'Map::ElementsKindBits::kMask' },
'value': 'Map::kElementsKindMask' },
{ 'name': 'bit_field2_elements_kind_shift',
'value': 'Map::ElementsKindBits::kShift' },
'value': 'Map::kElementsKindShift' },
{ 'name': 'bit_field3_dictionary_map_shift',
'value': 'Map::DictionaryMap::kShift' },
@ -192,9 +196,9 @@ header = '''
* This file is generated by %s. Do not edit directly.
*/
#include "src/v8.h"
#include "src/frames.h"
#include "src/frames-inl.h" /* for architecture-specific frame constants */
#include "v8.h"
#include "frames.h"
#include "frames-inl.h" /* for architecture-specific frame constants */
using namespace v8::internal;