update V8 to TOT snapshot branch
diff --git a/src/objects.cc b/src/objects.cc
index a8328ac..99532ac 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -219,7 +219,7 @@
LookupResult* result,
String* name,
PropertyAttributes* attributes) {
- if (result->IsValid()) {
+ if (result->IsProperty()) {
switch (result->type()) {
case CALLBACKS: {
// Only allow API accessors.
@@ -242,7 +242,7 @@
// Search ALL_CAN_READ accessors in prototype chain.
LookupResult r;
result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
- if (r.IsValid()) {
+ if (r.IsProperty()) {
return GetPropertyWithFailedAccessCheck(receiver,
&r,
name,
@@ -255,16 +255,16 @@
// No access check in GetPropertyAttributeWithInterceptor.
LookupResult r;
result->holder()->LookupRealNamedProperty(name, &r);
- if (r.IsValid()) {
+ if (r.IsProperty()) {
return GetPropertyWithFailedAccessCheck(receiver,
&r,
name,
attributes);
}
- }
- default: {
break;
}
+ default:
+ UNREACHABLE();
}
}
@@ -280,7 +280,7 @@
LookupResult* result,
String* name,
bool continue_search) {
- if (result->IsValid()) {
+ if (result->IsProperty()) {
switch (result->type()) {
case CALLBACKS: {
// Only allow API accessors.
@@ -301,7 +301,7 @@
// Search ALL_CAN_READ accessors in prototype chain.
LookupResult r;
result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
- if (r.IsValid()) {
+ if (r.IsProperty()) {
return GetPropertyAttributeWithFailedAccessCheck(receiver,
&r,
name,
@@ -319,7 +319,7 @@
} else {
result->holder()->LocalLookupRealNamedProperty(name, &r);
}
- if (r.IsValid()) {
+ if (r.IsProperty()) {
return GetPropertyAttributeWithFailedAccessCheck(receiver,
&r,
name,
@@ -328,9 +328,8 @@
break;
}
- default: {
- break;
- }
+ default:
+ UNREACHABLE();
}
}
@@ -456,7 +455,7 @@
// holder will always be the interceptor holder and the search may
// only continue with a current object just after the interceptor
// holder in the prototype chain.
- Object* last = result->IsValid() ? result->holder() : Heap::null_value();
+ Object* last = result->IsProperty() ? result->holder() : Heap::null_value();
for (Object* current = this; true; current = current->GetPrototype()) {
if (current->IsAccessCheckNeeded()) {
// Check if we're allowed to read from the current object. Note
@@ -1408,8 +1407,12 @@
// Check local property, ignore interceptor.
LookupResult result;
LocalLookupRealNamedProperty(name, &result);
- if (result.IsValid()) return SetProperty(&result, name, value, attributes);
- // Add real property.
+ if (result.IsFound()) {
+ // An existing property, a map transition or a null descriptor was
+ // found. Use set property to handle all these cases.
+ return SetProperty(&result, name, value, attributes);
+ }
+ // Add a new real property.
return AddProperty(name, value, attributes);
}
@@ -1641,8 +1644,8 @@
pt != Heap::null_value();
pt = pt->GetPrototype()) {
JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
- if (result->IsValid()) {
- if (!result->IsTransitionType() && result->IsReadOnly()) {
+ if (result->IsProperty()) {
+ if (result->IsReadOnly()) {
result->NotFound();
return;
}
@@ -1703,7 +1706,11 @@
if (HasFastProperties()) {
LookupInDescriptor(name, result);
- if (result->IsValid()) {
+ if (result->IsFound()) {
+ // A property, a map transition or a null descriptor was found.
+ // We return all of these result types because
+ // LocalLookupRealNamedProperty is used when setting properties
+ // where map transitions and null descriptors are handled.
ASSERT(result->holder() == this && result->type() != NORMAL);
// Disallow caching for uninitialized constants. These can only
// occur as fields.
@@ -1752,16 +1759,7 @@
pt != Heap::null_value();
pt = JSObject::cast(pt)->GetPrototype()) {
JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
- if (result->IsValid()) {
- switch (result->type()) {
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case CALLBACKS:
- return;
- default: break;
- }
- }
+ if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
}
result->NotFound();
}
@@ -1847,14 +1845,15 @@
// accessor that wants to handle the property.
LookupResult accessor_result;
LookupCallbackSetterInPrototypes(name, &accessor_result);
- if (accessor_result.IsValid()) {
+ if (accessor_result.IsProperty()) {
return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
name,
value,
accessor_result.holder());
}
}
- if (result->IsNotFound()) {
+ if (!result->IsFound()) {
+ // Neither properties nor transitions found.
return AddProperty(name, value, attributes);
}
if (result->IsReadOnly() && result->IsProperty()) return value;
@@ -1913,15 +1912,12 @@
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
AssertNoContextChange ncc;
- // ADDED TO CLONE
- LookupResult result_struct;
- LocalLookup(name, &result_struct);
- LookupResult* result = &result_struct;
- // END ADDED TO CLONE
+ LookupResult result;
+ LocalLookup(name, &result);
// Check access rights if needed.
if (IsAccessCheckNeeded()
- && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
- return SetPropertyWithFailedAccessCheck(result, name, value);
+ && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
+ return SetPropertyWithFailedAccessCheck(&result, name, value);
}
if (IsJSGlobalProxy()) {
@@ -1935,28 +1931,31 @@
}
// Check for accessor in prototype chain removed here in clone.
- if (result->IsNotFound()) {
+ if (!result.IsFound()) {
+ // Neither properties nor transitions found.
return AddProperty(name, value, attributes);
}
+ PropertyDetails details = PropertyDetails(attributes, NORMAL);
+
// Check of IsReadOnly removed from here in clone.
- switch (result->type()) {
+ switch (result.type()) {
case NORMAL:
- return SetNormalizedProperty(result, value);
+ return SetNormalizedProperty(name, value, details);
case FIELD:
- return FastPropertyAtPut(result->GetFieldIndex(), value);
+ return FastPropertyAtPut(result.GetFieldIndex(), value);
case MAP_TRANSITION:
- if (attributes == result->GetAttributes()) {
+ if (attributes == result.GetAttributes()) {
// Only use map transition if the attributes match.
- return AddFastPropertyUsingMap(result->GetTransitionMap(),
+ return AddFastPropertyUsingMap(result.GetTransitionMap(),
name,
value);
}
return ConvertDescriptorToField(name, value, attributes);
case CONSTANT_FUNCTION:
// Only replace the function if necessary.
- if (value == result->GetConstantFunction()) return value;
+ if (value == result.GetConstantFunction()) return value;
// Preserve the attributes of this existing property.
- attributes = result->GetAttributes();
+ attributes = result.GetAttributes();
return ConvertDescriptorToField(name, value, attributes);
case CALLBACKS:
case INTERCEPTOR:
@@ -2072,7 +2071,7 @@
name,
continue_search);
}
- if (result->IsValid()) {
+ if (result->IsProperty()) {
switch (result->type()) {
case NORMAL: // fall through
case FIELD:
@@ -2082,13 +2081,8 @@
case INTERCEPTOR:
return result->holder()->
GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- return ABSENT;
default:
UNREACHABLE();
- break;
}
}
return ABSENT;
@@ -2261,7 +2255,7 @@
// Check local property, ignore interceptor.
LookupResult result;
LocalLookupRealNamedProperty(name, &result);
- if (!result.IsValid()) return Heap::true_value();
+ if (!result.IsProperty()) return Heap::true_value();
// Normalize object if needed.
Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
@@ -2445,7 +2439,7 @@
} else {
LookupResult result;
LocalLookup(name, &result);
- if (!result.IsValid()) return Heap::true_value();
+ if (!result.IsProperty()) return Heap::true_value();
// Ignore attributes if forcing a deletion.
if (result.IsDontDelete() && mode != FORCE_DELETION) {
return Heap::false_value();
@@ -2675,7 +2669,7 @@
current != Heap::null_value();
current = JSObject::cast(current)->GetPrototype()) {
JSObject::cast(current)->LocalLookup(name, result);
- if (result->IsValid() && !result->IsTransitionType()) return;
+ if (result->IsProperty()) return;
}
result->NotFound();
}
@@ -2687,7 +2681,7 @@
current != Heap::null_value();
current = JSObject::cast(current)->GetPrototype()) {
JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
- if (result->IsValid() && result->type() == CALLBACKS) return;
+ if (result->IsProperty() && result->type() == CALLBACKS) return;
}
result->NotFound();
}
@@ -2717,7 +2711,7 @@
// cause security problems.
LookupResult callback_result;
LookupCallback(name, &callback_result);
- if (callback_result.IsValid()) {
+ if (callback_result.IsFound()) {
Object* obj = callback_result.GetCallbackObject();
if (obj->IsAccessorInfo() &&
AccessorInfo::cast(obj)->prohibits_overwriting()) {
@@ -2768,11 +2762,16 @@
// Lookup the name.
LookupResult result;
LocalLookup(name, &result);
- if (result.IsValid()) {
+ if (result.IsProperty()) {
if (result.IsReadOnly()) return Heap::undefined_value();
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
if (obj->IsFixedArray()) {
+ // The object might be in fast mode even though it has
+ // a getter/setter.
+ Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+ if (ok->IsFailure()) return ok;
+
PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
SetNormalizedProperty(name, obj, details);
return obj;
@@ -2885,7 +2884,7 @@
obj = JSObject::cast(obj)->GetPrototype()) {
LookupResult result;
JSObject::cast(obj)->LocalLookup(name, &result);
- if (result.IsValid()) {
+ if (result.IsProperty()) {
if (result.IsReadOnly()) return Heap::undefined_value();
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
@@ -4753,6 +4752,40 @@
}
+bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
+ // Check the basic conditions for generating inline constructor code.
+ if (!FLAG_inline_new
+ || !has_only_simple_this_property_assignments()
+ || this_property_assignments_count() == 0) {
+ return false;
+ }
+
+ // If the prototype is null inline constructors cause no problems.
+ if (!prototype->IsJSObject()) {
+ ASSERT(prototype->IsNull());
+ return true;
+ }
+
+ // Traverse the proposed prototype chain looking for setters for properties of
+ // the same names as are set by the inline constructor.
+ for (Object* obj = prototype;
+ obj != Heap::null_value();
+ obj = obj->GetPrototype()) {
+ JSObject* js_object = JSObject::cast(obj);
+ for (int i = 0; i < this_property_assignments_count(); i++) {
+ LookupResult result;
+ String* name = GetThisPropertyAssignmentName(i);
+ js_object->LocalLookupRealNamedProperty(name, &result);
+ if (result.IsProperty() && result.type() == CALLBACKS) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
void SharedFunctionInfo::SetThisPropertyAssignmentsInfo(
bool only_simple_this_property_assignments,
FixedArray* assignments) {
@@ -4808,7 +4841,6 @@
}
-
// Support function for printing the source code to a StringStream
// without any allocation in the heap.
void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
@@ -5286,6 +5318,48 @@
}
+Object* JSObject::SetPrototype(Object* value,
+ bool skip_hidden_prototypes) {
+ // Silently ignore the change if value is not a JSObject or null.
+ // SpiderMonkey behaves this way.
+ if (!value->IsJSObject() && !value->IsNull()) return value;
+
+ // Before we can set the prototype we need to be sure
+ // prototype cycles are prevented.
+ // It is sufficient to validate that the receiver is not in the new prototype
+ // chain.
+ for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) {
+ if (JSObject::cast(pt) == this) {
+ // Cycle detected.
+ HandleScope scope;
+ return Top::Throw(*Factory::NewError("cyclic_proto",
+ HandleVector<Object>(NULL, 0)));
+ }
+ }
+
+ JSObject* real_receiver = this;
+
+ if (skip_hidden_prototypes) {
+ // Find the first object in the chain whose prototype object is not
+ // hidden and set the new prototype on that object.
+ Object* current_proto = real_receiver->GetPrototype();
+ while (current_proto->IsJSObject() &&
+ JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
+ real_receiver = JSObject::cast(current_proto);
+ current_proto = current_proto->GetPrototype();
+ }
+ }
+
+ // Set the new prototype of the object.
+ Object* new_map = real_receiver->map()->CopyDropTransitions();
+ if (new_map->IsFailure()) return new_map;
+ Map::cast(new_map)->set_prototype(value);
+ real_receiver->set_map(Map::cast(new_map));
+
+ return value;
+}
+
+
bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
switch (GetElementsKind()) {
case FAST_ELEMENTS: {
@@ -6103,7 +6177,9 @@
// Check local property in holder, ignore interceptor.
LookupResult result;
LocalLookupRealNamedProperty(name, &result);
- if (result.IsValid()) return GetProperty(receiver, &result, name, attributes);
+ if (result.IsProperty()) {
+ return GetProperty(receiver, &result, name, attributes);
+ }
// Continue searching via the prototype chain.
Object* pt = GetPrototype();
*attributes = ABSENT;
@@ -6119,8 +6195,10 @@
// Check local property in holder, ignore interceptor.
LookupResult result;
LocalLookupRealNamedProperty(name, &result);
- if (!result.IsValid()) return Heap::undefined_value();
- return GetProperty(receiver, &result, name, attributes);
+ if (result.IsProperty()) {
+ return GetProperty(receiver, &result, name, attributes);
+ }
+ return Heap::undefined_value();
}
@@ -6172,24 +6250,7 @@
LookupResult result;
LocalLookupRealNamedProperty(key, &result);
- if (result.IsValid()) {
- switch (result.type()) {
- case NORMAL: // fall through.
- case FIELD: // fall through.
- case CALLBACKS: // fall through.
- case CONSTANT_FUNCTION:
- return true;
- case INTERCEPTOR:
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- return false;
- default:
- UNREACHABLE();
- }
- }
-
- return false;
+ return result.IsProperty() && (result.type() != INTERCEPTOR);
}
@@ -6251,7 +6312,7 @@
LookupResult result;
LocalLookupRealNamedProperty(key, &result);
- return result.IsValid() && (result.type() == CALLBACKS);
+ return result.IsProperty() && (result.type() == CALLBACKS);
}