Remove special ExecutableAccessorInfo handling based on flag
This additionally removes special "prototype" handling for O.o, since it's broken; and added test. BUG= R=mvstanton@chromium.org Review URL: https://codereview.chromium.org/368853003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22171 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ec349cbfed
commit
2350d46146
@ -4219,8 +4219,7 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
|
|||||||
ValueType value_type,
|
ValueType value_type,
|
||||||
StoreMode mode,
|
StoreMode mode,
|
||||||
ExtensibilityCheck extensibility_check,
|
ExtensibilityCheck extensibility_check,
|
||||||
StoreFromKeyed store_from_keyed,
|
StoreFromKeyed store_from_keyed) {
|
||||||
ExecutableAccessorInfoHandling handling) {
|
|
||||||
Isolate* isolate = object->GetIsolate();
|
Isolate* isolate = object->GetIsolate();
|
||||||
|
|
||||||
// Make sure that the top context does not change when doing callbacks or
|
// Make sure that the top context does not change when doing callbacks or
|
||||||
@ -4275,8 +4274,6 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
|
|||||||
old_attributes = lookup.GetAttributes();
|
old_attributes = lookup.GetAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool executed_set_prototype = false;
|
|
||||||
|
|
||||||
// Check of IsReadOnly removed from here in clone.
|
// Check of IsReadOnly removed from here in clone.
|
||||||
if (lookup.IsTransition()) {
|
if (lookup.IsTransition()) {
|
||||||
Handle<Object> result;
|
Handle<Object> result;
|
||||||
@ -4300,11 +4297,9 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
|
|||||||
SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
|
SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CALLBACKS:
|
case CALLBACKS: {
|
||||||
{
|
|
||||||
Handle<Object> callback(lookup.GetCallbackObject(), isolate);
|
Handle<Object> callback(lookup.GetCallbackObject(), isolate);
|
||||||
if (callback->IsExecutableAccessorInfo() &&
|
if (callback->IsExecutableAccessorInfo()) {
|
||||||
handling == DONT_FORCE_FIELD) {
|
|
||||||
Handle<Object> result;
|
Handle<Object> result;
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(
|
ASSIGN_RETURN_ON_EXCEPTION(
|
||||||
isolate, result,
|
isolate, result,
|
||||||
@ -4316,31 +4311,29 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
|
|||||||
STRICT),
|
STRICT),
|
||||||
Object);
|
Object);
|
||||||
|
|
||||||
if (attributes != lookup.GetAttributes()) {
|
if (attributes == lookup.GetAttributes()) return result;
|
||||||
Handle<ExecutableAccessorInfo> new_data =
|
|
||||||
Accessors::CloneAccessor(
|
Handle<ExecutableAccessorInfo> new_data =
|
||||||
isolate, Handle<ExecutableAccessorInfo>::cast(callback));
|
Accessors::CloneAccessor(
|
||||||
new_data->set_property_attributes(attributes);
|
isolate, Handle<ExecutableAccessorInfo>::cast(callback));
|
||||||
if (attributes & READ_ONLY) {
|
new_data->set_property_attributes(attributes);
|
||||||
// This way we don't have to introduce a lookup to the setter,
|
// This way we don't have to introduce a lookup to the setter, simply
|
||||||
// simply make it unavailable to reflect the attributes.
|
// make it unavailable to reflect the attributes.
|
||||||
new_data->clear_setter();
|
if (attributes & READ_ONLY) new_data->clear_setter();
|
||||||
}
|
SetPropertyCallback(object, name, new_data, attributes);
|
||||||
|
|
||||||
SetPropertyCallback(object, name, new_data, attributes);
|
|
||||||
}
|
|
||||||
if (is_observed) {
|
if (is_observed) {
|
||||||
// If we are setting the prototype of a function and are observed,
|
Handle<Object> new_value =
|
||||||
// don't send change records because the prototype handles that
|
Object::GetPropertyOrElement(object, name).ToHandleChecked();
|
||||||
// itself.
|
if (old_value->SameValue(*new_value)) {
|
||||||
executed_set_prototype = object->IsJSFunction() &&
|
old_value = isolate->factory()->the_hole_value();
|
||||||
String::Equals(isolate->factory()->prototype_string(),
|
}
|
||||||
Handle<String>::cast(name)) &&
|
EnqueueChangeRecord(object, "reconfigure", name, old_value);
|
||||||
Handle<JSFunction>::cast(object)->should_have_prototype();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ConvertAndSetOwnProperty(&lookup, name, value, attributes);
|
return result;
|
||||||
}
|
}
|
||||||
|
ConvertAndSetOwnProperty(&lookup, name, value, attributes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NONEXISTENT:
|
case NONEXISTENT:
|
||||||
@ -4350,7 +4343,7 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_observed && !executed_set_prototype) {
|
if (is_observed) {
|
||||||
if (lookup.IsTransition()) {
|
if (lookup.IsTransition()) {
|
||||||
EnqueueChangeRecord(object, "add", name, old_value);
|
EnqueueChangeRecord(object, "add", name, old_value);
|
||||||
} else if (old_value->IsTheHole()) {
|
} else if (old_value->IsTheHole()) {
|
||||||
|
@ -2148,13 +2148,6 @@ class JSObject: public JSReceiver {
|
|||||||
StrictMode strict_mode,
|
StrictMode strict_mode,
|
||||||
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
|
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
|
||||||
|
|
||||||
// SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
|
|
||||||
// grant an exemption to ExecutableAccessor callbacks in some cases.
|
|
||||||
enum ExecutableAccessorInfoHandling {
|
|
||||||
DEFAULT_HANDLING,
|
|
||||||
DONT_FORCE_FIELD
|
|
||||||
};
|
|
||||||
|
|
||||||
MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
|
MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
|
||||||
Handle<JSObject> object,
|
Handle<JSObject> object,
|
||||||
Handle<Name> key,
|
Handle<Name> key,
|
||||||
@ -2163,8 +2156,7 @@ class JSObject: public JSReceiver {
|
|||||||
ValueType value_type = OPTIMAL_REPRESENTATION,
|
ValueType value_type = OPTIMAL_REPRESENTATION,
|
||||||
StoreMode mode = ALLOW_AS_CONSTANT,
|
StoreMode mode = ALLOW_AS_CONSTANT,
|
||||||
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
|
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
|
||||||
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
|
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
|
||||||
ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
|
|
||||||
|
|
||||||
static void AddProperty(Handle<JSObject> object,
|
static void AddProperty(Handle<JSObject> object,
|
||||||
Handle<Name> key,
|
Handle<Name> key,
|
||||||
|
@ -5092,12 +5092,7 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
|
|||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||||
isolate, result,
|
isolate, result,
|
||||||
JSObject::SetOwnPropertyIgnoreAttributes(
|
JSObject::SetOwnPropertyIgnoreAttributes(
|
||||||
js_object, name, obj_value, attr,
|
js_object, name, obj_value, attr));
|
||||||
Object::OPTIMAL_REPRESENTATION,
|
|
||||||
ALLOW_AS_CONSTANT,
|
|
||||||
JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
|
|
||||||
JSReceiver::MAY_BE_STORE_FROM_KEYED,
|
|
||||||
JSObject::DONT_FORCE_FIELD));
|
|
||||||
return *result;
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15338,12 +15338,11 @@ TEST(ForceSet) {
|
|||||||
CHECK_EQ(3, global->Get(access_property)->Int32Value());
|
CHECK_EQ(3, global->Get(access_property)->Int32Value());
|
||||||
CHECK_EQ(1, force_set_set_count);
|
CHECK_EQ(1, force_set_set_count);
|
||||||
CHECK_EQ(2, force_set_get_count);
|
CHECK_EQ(2, force_set_get_count);
|
||||||
// Forcing the property to be set should override the accessor without
|
// Forcing the property to be set should call the accessor
|
||||||
// calling it
|
|
||||||
global->ForceSet(access_property, v8::Int32::New(isolate, 8));
|
global->ForceSet(access_property, v8::Int32::New(isolate, 8));
|
||||||
CHECK_EQ(8, global->Get(access_property)->Int32Value());
|
CHECK_EQ(3, global->Get(access_property)->Int32Value());
|
||||||
CHECK_EQ(1, force_set_set_count);
|
CHECK_EQ(2, force_set_set_count);
|
||||||
CHECK_EQ(2, force_set_get_count);
|
CHECK_EQ(3, force_set_get_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1136,7 +1136,8 @@ var objects = [
|
|||||||
// createProxy(Proxy.create, null),
|
// createProxy(Proxy.create, null),
|
||||||
// createProxy(Proxy.createFunction, function(){}),
|
// createProxy(Proxy.createFunction, function(){}),
|
||||||
];
|
];
|
||||||
var properties = ["a", "1", 1, "length", "setPrototype", "name", "caller"];
|
var properties = ["a", "1", 1, "length", "setPrototype",
|
||||||
|
"name", "caller", "prototype"];
|
||||||
|
|
||||||
// Cases that yield non-standard results.
|
// Cases that yield non-standard results.
|
||||||
function blacklisted(obj, prop) {
|
function blacklisted(obj, prop) {
|
||||||
|
Loading…
Reference in New Issue
Block a user