Fix special handling of DefineOwnProperty on arrays.

According to the ES5 spec the implementation of DefineOwnProperty() has
to special case handling of arrays. This implementation correctly
handles definitions of array index properties and redefinitions of the
length property.

R=svenpanne@chromium.org
BUG=v8:1756
TEST=test262

Review URL: http://codereview.chromium.org/8776045

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10149 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 49a4dd98
...@@ -660,6 +660,21 @@ function GetOwnProperty(obj, v) { ...@@ -660,6 +660,21 @@ function GetOwnProperty(obj, v) {
} }
// ES5 section 8.12.7.
function Delete(obj, p, should_throw) {
var desc = GetOwnProperty(obj, p);
if (IS_UNDEFINED(desc)) return true;
if (desc.isConfigurable()) {
%DeleteProperty(obj, p, 0);
return true;
} else if (should_throw) {
throw MakeTypeError("define_disallowed", [p]);
} else {
return;
}
}
// Harmony proxies. // Harmony proxies.
function DefineProxyProperty(obj, p, attributes, should_throw) { function DefineProxyProperty(obj, p, attributes, should_throw) {
var handler = %GetHandler(obj); var handler = %GetHandler(obj);
...@@ -677,12 +692,7 @@ function DefineProxyProperty(obj, p, attributes, should_throw) { ...@@ -677,12 +692,7 @@ function DefineProxyProperty(obj, p, attributes, should_throw) {
// ES5 8.12.9. // ES5 8.12.9.
function DefineOwnProperty(obj, p, desc, should_throw) { function DefineObjectProperty(obj, p, desc, should_throw) {
if (%IsJSProxy(obj)) {
var attributes = FromGenericPropertyDescriptor(desc);
return DefineProxyProperty(obj, p, attributes, should_throw);
}
var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p)); var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
// A false value here means that access checks failed. // A false value here means that access checks failed.
if (current_or_access === false) return void 0; if (current_or_access === false) return void 0;
...@@ -846,6 +856,86 @@ function DefineOwnProperty(obj, p, desc, should_throw) { ...@@ -846,6 +856,86 @@ function DefineOwnProperty(obj, p, desc, should_throw) {
} }
// ES5 section 15.4.5.1.
function DefineArrayProperty(obj, p, desc, should_throw) {
// Note that the length of an array is not actually stored as part of the
// property, hence we use generated code throughout this function instead of
// DefineObjectProperty() to modify its value.
// Step 3 - Special handling for length property.
if (p == "length") {
var length = obj.length;
if (!desc.hasValue()) {
return DefineObjectProperty(obj, "length", desc, should_throw);
}
var new_length = ToUint32(desc.getValue());
if (new_length != ToNumber(desc.getValue())) {
throw new $RangeError('defineProperty() array length out of range');
}
var length_desc = GetOwnProperty(obj, "length");
// Make sure the below call to DefineObjectProperty() doesn't overwrite
// any magic "length" property by removing the value.
desc.value_ = void 0;
desc.hasValue_ = false;
if ((new_length != length && !length_desc.isWritable()) ||
!DefineObjectProperty(obj, "length", desc, should_throw)) {
if (should_throw) {
throw MakeTypeError("redefine_disallowed", [p]);
} else {
return false;
}
}
obj.length = new_length;
while (new_length < length--) {
if (!Delete(obj, length, false)) {
obj.length = length + 1;
if (should_throw) {
throw MakeTypeError("redefine_disallowed", [p]);
} else {
return false;
}
}
}
return true;
}
// Step 4 - Special handling for array index.
var index = ToUint32(p);
if (index == ToNumber(p) && index != 4294967295) {
var length = obj.length;
var length_desc = GetOwnProperty(obj, "length");
if ((index >= length && !length_desc.isWritable()) ||
!DefineObjectProperty(obj, p, desc, true)) {
if (should_throw) {
throw MakeTypeError("define_disallowed", [p]);
} else {
return false;
}
}
if (index >= length) {
obj.length = index + 1;
}
return true;
}
// Step 5 - Fallback to default implementation.
return DefineObjectProperty(obj, p, desc, should_throw);
}
// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
function DefineOwnProperty(obj, p, desc, should_throw) {
if (%IsJSProxy(obj)) {
var attributes = FromGenericPropertyDescriptor(desc);
return DefineProxyProperty(obj, p, attributes, should_throw);
} else if (IS_ARRAY(obj)) {
return DefineArrayProperty(obj, p, desc, should_throw);
} else {
return DefineObjectProperty(obj, p, desc, should_throw);
}
}
// ES5 section 15.2.3.2. // ES5 section 15.2.3.2.
function ObjectGetPrototypeOf(obj) { function ObjectGetPrototypeOf(obj) {
if (!IS_SPEC_OBJECT(obj)) { if (!IS_SPEC_OBJECT(obj)) {
......
...@@ -43,190 +43,13 @@ S10.4.2.1_A1: FAIL ...@@ -43,190 +43,13 @@ S10.4.2.1_A1: FAIL
S15.3.3.1_A4: FAIL S15.3.3.1_A4: FAIL
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1756 # V8 Bug: http://code.google.com/p/v8/issues/detail?id=1756
15.2.3.6-4-116: FAIL
15.2.3.6-4-117: FAIL
15.2.3.6-4-125: FAIL
15.2.3.6-4-126: FAIL
15.2.3.6-4-127: FAIL
15.2.3.6-4-128: FAIL
15.2.3.6-4-129: FAIL
15.2.3.6-4-130: FAIL
15.2.3.6-4-131: FAIL
15.2.3.6-4-132: FAIL
15.2.3.6-4-133: FAIL
15.2.3.6-4-134: FAIL
15.2.3.6-4-135: FAIL
15.2.3.6-4-136: FAIL
15.2.3.6-4-137: FAIL
15.2.3.6-4-138: FAIL
15.2.3.6-4-139: FAIL
15.2.3.6-4-140: FAIL
15.2.3.6-4-141: FAIL
15.2.3.6-4-142: FAIL
15.2.3.6-4-143: FAIL
15.2.3.6-4-144: FAIL
15.2.3.6-4-145: FAIL
15.2.3.6-4-146: FAIL
15.2.3.6-4-147: FAIL
15.2.3.6-4-148: FAIL
15.2.3.6-4-149: FAIL
15.2.3.6-4-150: FAIL
15.2.3.6-4-151: FAIL
15.2.3.6-4-152: FAIL
15.2.3.6-4-153: FAIL
15.2.3.6-4-154: FAIL
15.2.3.6-4-155: FAIL
15.2.3.6-4-156: FAIL
15.2.3.6-4-157: FAIL
15.2.3.6-4-159: FAIL
15.2.3.6-4-161: FAIL
15.2.3.6-4-165: FAIL
15.2.3.6-4-166: FAIL
15.2.3.6-4-167: FAIL 15.2.3.6-4-167: FAIL
15.2.3.6-4-168: FAIL 15.2.3.6-4-168: FAIL
15.2.3.6-4-169: FAIL
15.2.3.6-4-170: FAIL
15.2.3.6-4-171: FAIL
15.2.3.6-4-172: FAIL
15.2.3.6-4-173: FAIL
15.2.3.6-4-174: FAIL
15.2.3.6-4-175: FAIL
15.2.3.6-4-176: FAIL
15.2.3.6-4-177: FAIL
15.2.3.6-4-178: FAIL
15.2.3.6-4-179-1: FAIL
15.2.3.6-4-181: FAIL 15.2.3.6-4-181: FAIL
15.2.3.6-4-183: FAIL
15.2.3.6-4-188: FAIL
15.2.3.6-4-189: FAIL
15.2.3.6-4-275: FAIL
15.2.3.6-4-276: FAIL
15.2.3.6-4-292-1: FAIL
15.2.3.6-4-293-2: FAIL
15.2.3.6-4-293-3: FAIL
15.2.3.6-4-294-1: FAIL
15.2.3.6-4-295-1: FAIL
15.2.3.6-4-296-1: FAIL
15.2.3.6-4-333-11: FAIL
15.2.3.6-4-360-1: FAIL
15.2.3.6-4-360-6: FAIL
15.2.3.6-4-360-7: FAIL
15.2.3.6-4-405: FAIL
15.2.3.6-4-410: FAIL
15.2.3.6-4-415: FAIL
15.2.3.6-4-420: FAIL
15.2.3.7-6-a-112: FAIL
15.2.3.7-6-a-113: FAIL
15.2.3.7-6-a-122: FAIL
15.2.3.7-6-a-123: FAIL
15.2.3.7-6-a-124: FAIL
15.2.3.7-6-a-125: FAIL
15.2.3.7-6-a-126: FAIL
15.2.3.7-6-a-127: FAIL
15.2.3.7-6-a-128: FAIL
15.2.3.7-6-a-133: FAIL
15.2.3.7-6-a-138: FAIL
15.2.3.7-6-a-139: FAIL
15.2.3.7-6-a-140: FAIL
15.2.3.7-6-a-142: FAIL
15.2.3.7-6-a-143: FAIL
15.2.3.7-6-a-144: FAIL
15.2.3.7-6-a-145: FAIL
15.2.3.7-6-a-147: FAIL
15.2.3.7-6-a-150: FAIL
15.2.3.7-6-a-151: FAIL
15.2.3.7-6-a-155: FAIL
15.2.3.7-6-a-157: FAIL
15.2.3.7-6-a-161: FAIL
15.2.3.7-6-a-162: FAIL
15.2.3.7-6-a-163: FAIL 15.2.3.7-6-a-163: FAIL
15.2.3.7-6-a-164: FAIL 15.2.3.7-6-a-164: FAIL
15.2.3.7-6-a-165: FAIL 15.2.3.7-6-a-176: FAIL || PASS
15.2.3.7-6-a-166: FAIL
15.2.3.7-6-a-167: FAIL
15.2.3.7-6-a-168: FAIL
15.2.3.7-6-a-169: FAIL
15.2.3.7-6-a-170: FAIL
15.2.3.7-6-a-171: FAIL
15.2.3.7-6-a-172: FAIL
15.2.3.7-6-a-173: FAIL
15.2.3.7-6-a-174: FAIL
15.2.3.7-6-a-175: FAIL
15.2.3.7-6-a-176: FAIL
15.2.3.7-6-a-177: FAIL 15.2.3.7-6-a-177: FAIL
15.2.3.7-6-a-121: FAIL
15.2.3.7-6-a-130: FAIL
15.2.3.7-6-a-129: FAIL
15.2.3.7-6-a-131: FAIL
15.2.3.7-6-a-132: FAIL
15.2.3.7-6-a-136: FAIL
15.2.3.7-6-a-135: FAIL
15.2.3.7-6-a-134: FAIL
15.2.3.7-6-a-137: FAIL
15.2.3.7-6-a-141: FAIL
15.2.3.7-6-a-146: FAIL
15.2.3.7-6-a-148: FAIL
15.2.3.7-6-a-149: FAIL
15.2.3.7-6-a-152: FAIL
15.2.3.7-6-a-153: FAIL
15.2.3.7-6-a-179: FAIL
15.2.3.7-6-a-184: FAIL
15.2.3.7-6-a-185: FAIL
15.2.3.7-6-a-264: FAIL
15.2.3.7-6-a-265: FAIL
15.4.4.14-9-b-i-11: FAIL
15.4.4.14-9-b-i-13: FAIL
15.4.4.14-9-b-i-17: FAIL
15.4.4.14-9-b-i-19: FAIL
15.4.4.14-9-b-i-28: FAIL
15.4.4.14-9-b-i-30: FAIL
15.4.4.15-8-a-14: FAIL
15.4.4.15-8-b-i-11: FAIL
15.4.4.15-8-b-i-13: FAIL
15.4.4.15-8-b-i-17: FAIL
15.4.4.15-8-b-i-28: FAIL
15.4.4.15-8-b-i-30: FAIL
15.4.4.16-7-c-i-10: FAIL
15.4.4.16-7-c-i-12: FAIL
15.4.4.16-7-c-i-14: FAIL
15.4.4.16-7-c-i-18: FAIL
15.4.4.16-7-c-i-20: FAIL
15.4.4.16-7-c-i-28: FAIL
15.4.4.17-7-c-i-10: FAIL
15.4.4.17-7-c-i-12: FAIL
15.4.4.17-7-c-i-14: FAIL
15.4.4.17-7-c-i-18: FAIL
15.4.4.17-7-c-i-20: FAIL
15.4.4.17-7-c-i-28: FAIL
15.4.4.18-7-c-i-10: FAIL
15.4.4.18-7-c-i-12: FAIL
15.4.4.18-7-c-i-14: FAIL
15.4.4.18-7-c-i-18: FAIL
15.4.4.18-7-c-i-20: FAIL
15.4.4.18-7-c-i-28: FAIL
15.4.4.19-8-c-i-10: FAIL
15.4.4.19-8-c-i-14: FAIL
15.4.4.19-8-c-i-12: FAIL
15.4.4.19-8-c-i-18: FAIL
15.4.4.19-8-c-i-19: FAIL
15.4.4.19-8-c-i-28: FAIL
15.4.4.20-9-c-i-10: FAIL
15.4.4.20-9-c-i-12: FAIL
15.4.4.20-9-c-i-14: FAIL
15.4.4.20-9-c-i-18: FAIL
15.4.4.20-9-c-i-20: FAIL
15.4.4.20-9-c-i-28: FAIL
15.4.4.22-8-b-2: FAIL
15.4.4.22-8-b-iii-1-12: FAIL
15.4.4.22-8-b-iii-1-18: FAIL
15.4.4.22-8-b-iii-1-20: FAIL
15.4.4.22-8-b-iii-1-33: FAIL
15.4.4.22-8-b-iii-1-30: FAIL
15.4.4.22-9-b-13: FAIL
15.4.4.22-9-b-24: FAIL
15.4.4.22-9-b-26: FAIL
15.4.4.22-9-b-9: FAIL
15.4.4.22-9-c-i-30: FAIL
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1772 # V8 Bug: http://code.google.com/p/v8/issues/detail?id=1772
15.2.3.6-4-292-1: FAIL 15.2.3.6-4-292-1: FAIL
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment