Commit f74a08d8 authored by ricow@chromium.org's avatar ricow@chromium.org

Added Object.defineProperty + needed internal functionality:

  DefineOwnProperty (changed to allow for redefinition of existing property)
  SameValue
  Extra info on propertydescriptor
  GetProperty
  HasProperty

Currently the DefineOrRedefineAccessorProperty deletes the existing
property on the object if it is a dataproperty (FIELD or NORMAL) and
adds a new one. This can potentially be optimized.


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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3786 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 04c4d908
......@@ -162,6 +162,8 @@ function FormatMessage(message) {
value_and_accessor: "Invalid property. A property cannot both have accessors and be writable or have a value: %0",
proto_object_or_null: "Object prototype may only be an Object or null",
property_desc_object: "Property description must be an object: %0",
redefine_disallowed: "Cannot redefine property: %0",
define_disallowed: "Cannot define property, object is not extensible: %0",
// RangeError
invalid_array_length: "Invalid array length",
stack_overflow: "Maximum call stack size exceeded",
......
......@@ -596,8 +596,9 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
if (result.type() == CALLBACKS) {
Object* structure = result.GetCallbackObject();
if (structure->IsProxy()) {
// Property that is internally implemented as a callback.
if (structure->IsProxy() || structure->IsAccessorInfo()) {
// Property that is internally implemented as a callback or
// an API defined callback.
Object* value = obj->GetPropertyWithCallback(
obj, structure, name, result.holder());
elms->set(0, Heap::false_value());
......@@ -609,7 +610,6 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
elms->set(1, FixedArray::cast(structure)->get(0));
elms->set(2, FixedArray::cast(structure)->get(1));
} else {
// TODO(ricow): Handle API callbacks.
return Heap::undefined_value();
}
} else {
......@@ -619,7 +619,7 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
}
elms->set(3, Heap::ToBoolean(!result.IsDontEnum()));
elms->set(4, Heap::ToBoolean(!result.IsReadOnly()));
elms->set(4, Heap::ToBoolean(!result.IsDontDelete()));
return *desc;
}
......@@ -2888,6 +2888,66 @@ static Object* Runtime_KeyedGetProperty(Arguments args) {
}
static Object* Runtime_DefineOrRedefineAccessorProperty(Arguments args) {
ASSERT(args.length() == 5);
HandleScope scope;
Handle<JSObject> obj = args.at<JSObject>(0);
CONVERT_CHECKED(String, name, args[1]);
CONVERT_CHECKED(Smi, flag_setter, args[2]);
CONVERT_CHECKED(JSFunction, fun, args[3]);
CONVERT_CHECKED(Smi, flag_attr, args[4]);
int unchecked = flag_attr->value();
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
LookupResult result;
obj->LocalLookupRealNamedProperty(name, &result);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
// If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
// delete it to avoid running into trouble in DefineAccessor, which
// handles this incorrectly if the property is readonly (does nothing)
if (result.type() == FIELD || result.type() == NORMAL
|| result.type() == CONSTANT_FUNCTION)
obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
}
static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) {
ASSERT(args.length() == 4);
HandleScope scope;
Handle<Object> obj = args.at<Object>(0);
Handle<Object> name = args.at<Object>(1);
Handle<Object> obj_value = args.at<Object>(2);
Handle<JSObject> js_object = Handle<JSObject>::cast(obj);
Handle<String> key_string = Handle<String>::cast(name);
CONVERT_CHECKED(Smi, flag, args[3]);
int unchecked = flag->value();
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
LookupResult result;
js_object->LocalLookupRealNamedProperty(*key_string, &result);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
// Take special care when attributes are different and there is already
// a property. For simplicity we normalize the property which enables us
// to not worry about changing the instance_descriptor and creating a new
// map. The current version of SetObjectProperty does not handle attributes
// correctly in the case where a property is a field and is reset with
// new attributes.
if (result.IsProperty() && attr != result.GetAttributes()) {
PropertyDetails details = PropertyDetails(attr, NORMAL);
// New attributes - normalize to avoid writing to instance descriptor
js_object->NormalizeProperties(KEEP_INOBJECT_PROPERTIES, 0);
return js_object->SetNormalizedProperty(*key_string, *obj_value, details);
}
return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
}
Object* Runtime::SetObjectProperty(Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
......
......@@ -215,6 +215,8 @@ namespace internal {
F(ResolvePossiblyDirectEval, 3, 2) \
\
F(SetProperty, -1 /* 3 or 4 */, 1) \
F(DefineOrRedefineDataProperty, 4, 1) \
F(DefineOrRedefineAccessorProperty, 5, 1) \
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
\
/* Arrays */ \
......
......@@ -506,6 +506,16 @@ function ToPrimitive(x, hint) {
}
// ECMA-262, section 9.2, page 30
function ToBoolean(x) {
if (IS_BOOLEAN(x)) return x;
if (IS_STRING(x)) return x.length != 0;
if (x == null) return false;
if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x));
return true;
}
// ECMA-262, section 9.3, page 31.
function ToNumber(x) {
if (IS_NUMBER(x)) return x;
......@@ -526,16 +536,6 @@ function ToString(x) {
}
// ... where did this come from?
function ToBoolean(x) {
if (IS_BOOLEAN(x)) return x;
if (IS_STRING(x)) return x.length != 0;
if (x == null) return false;
if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x));
return true;
}
// ECMA-262, section 9.9, page 36.
function ToObject(x) {
if (IS_STRING(x)) return new $String(x);
......@@ -569,6 +569,25 @@ function ToInt32(x) {
}
// ES5, section 9.12
function SameValue(x, y) {
if (typeof x != typeof y) return false;
if (IS_NULL_OR_UNDEFINED(x)) return true;
if (IS_NUMBER(x)) {
if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
// x is +0 and y is -0 or vice versa
if (x === 0 && y === 0 && !%_IsSmi(x) && !%_IsSmi(y) &&
((1 / x < 0 && 1 / y > 0) || (1 / x > 0 && 1 / y < 0))) {
return false;
}
return x == y;
}
if (IS_STRING(x)) return %StringEquals(x, y);
if (IS_BOOLEAN(x))return %NumberEquals(%ToNumber(x),%ToNumber(y));
return %_ObjectEquals(x, y);
}
/* ---------------------------------
- - - U t i l i t i e s - - -
......
......@@ -307,7 +307,7 @@ function IsInconsistentDescriptor(desc) {
// ES5 8.10.4
function FromPropertyDescriptor(desc) {
if(IS_UNDEFINED(desc)) return desc;
if (IS_UNDEFINED(desc)) return desc;
var obj = new $Object();
if (IsDataDescriptor(desc)) {
obj.value = desc.getValue();
......@@ -333,7 +333,6 @@ function ToPropertyDescriptor(obj) {
desc.setEnumerable(ToBoolean(obj.enumerable));
}
if ("configurable" in obj) {
desc.setConfigurable(ToBoolean(obj.configurable));
}
......@@ -377,7 +376,9 @@ function PropertyDescriptor() {
this.writable_ = false;
this.hasWritable_ = false;
this.enumerable_ = false;
this.hasEnumerable_ = false;
this.configurable_ = false;
this.hasConfigurable_ = false;
this.get_ = void 0;
this.hasGetter_ = false;
this.set_ = void 0;
......@@ -396,8 +397,14 @@ PropertyDescriptor.prototype.getValue = function() {
}
PropertyDescriptor.prototype.hasValue = function() {
return this.hasValue_;
}
PropertyDescriptor.prototype.setEnumerable = function(enumerable) {
this.enumerable_ = enumerable;
this.hasEnumerable_ = true;
}
......@@ -406,6 +413,11 @@ PropertyDescriptor.prototype.isEnumerable = function () {
}
PropertyDescriptor.prototype.hasEnumerable = function() {
return this.hasEnumerable_;
}
PropertyDescriptor.prototype.setWritable = function(writable) {
this.writable_ = writable;
this.hasWritable_ = true;
......@@ -419,6 +431,12 @@ PropertyDescriptor.prototype.isWritable = function() {
PropertyDescriptor.prototype.setConfigurable = function(configurable) {
this.configurable_ = configurable;
this.hasConfigurable_ = true;
}
PropertyDescriptor.prototype.hasConfigurable = function() {
return this.hasConfigurable_;
}
......@@ -438,6 +456,11 @@ PropertyDescriptor.prototype.getGet = function() {
}
PropertyDescriptor.prototype.hasGetter = function() {
return this.hasGetter_;
}
PropertyDescriptor.prototype.setSet = function(set) {
this.set_ = set;
this.hasSetter_ = true;
......@@ -449,6 +472,12 @@ PropertyDescriptor.prototype.getSet = function() {
}
PropertyDescriptor.prototype.hasSetter = function() {
return this.hasSetter_;
}
// ES5 section 8.12.1.
function GetOwnProperty(obj, p) {
var desc = new PropertyDescriptor();
......@@ -458,8 +487,7 @@ function GetOwnProperty(obj, p) {
// obj is an accessor [true, Get, Set, Enumerable, Configurable]
var props = %GetOwnProperty(ToObject(obj), ToString(p));
if (IS_UNDEFINED(props))
return void 0;
if (IS_UNDEFINED(props)) return void 0;
// This is an accessor
if (props[0]) {
......@@ -476,16 +504,89 @@ function GetOwnProperty(obj, p) {
}
// ES5 8.12.9. This version cannot cope with the property p already
// being present on obj.
// ES5 section 8.12.2.
function GetProperty(obj, p) {
var prop = GetOwnProperty(obj);
if (!IS_UNDEFINED(prop)) return prop;
var proto = obj.__proto__;
if (IS_NULL(proto)) return void 0;
return GetProperty(proto, p);
}
// ES5 section 8.12.6
function HasProperty(obj, p) {
var desc = GetProperty(obj, p);
return IS_UNDEFINED(desc) ? false : true;
}
// ES5 8.12.9.
function DefineOwnProperty(obj, p, desc, should_throw) {
var flag = desc.isEnumerable() ? 0 : DONT_ENUM;
if (IsDataDescriptor(desc)) {
flag |= desc.isWritable() ? 0 : (DONT_DELETE | READ_ONLY);
%SetProperty(obj, p, desc.getValue(), flag);
var current = GetOwnProperty(obj, p);
var extensible = %IsExtensible(ToObject(obj));
// Error handling according to spec.
// Step 3
if (IS_UNDEFINED(current) && !extensible)
throw MakeTypeError("define_disallowed", ["defineProperty"]);
if (!IS_UNDEFINED(current) && !current.isConfigurable()) {
// Step 7
if (desc.isConfigurable() || desc.isEnumerable() != current.isEnumerable())
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
// Step 9
if (IsDataDescriptor(current) != IsDataDescriptor(desc))
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
// Step 10
if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
if (!current.isWritable() && desc.isWritable())
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
if (!current.isWritable() && desc.hasValue() &&
!SameValue(desc.getValue(), current.getValue())) {
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
}
}
// Step 11
if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())){
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
}
if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet()))
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
}
}
// Send flags - enumerable and configurable are common - writable is
// only send to the data descriptor.
// Take special care if enumerable and configurable is not defined on
// desc (we need to preserve the existing values from current).
var flag = NONE;
if (desc.hasEnumerable()) {
flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
} else if (!IS_UNDEFINED(current)) {
flag |= current.isEnumerable() ? 0 : DONT_ENUM;
} else {
if (IS_FUNCTION(desc.getGet())) %DefineAccessor(obj, p, GETTER, desc.getGet(), flag);
if (IS_FUNCTION(desc.getSet())) %DefineAccessor(obj, p, SETTER, desc.getSet(), flag);
flag |= DONT_ENUM;
}
if (desc.hasConfigurable()) {
flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
} else if (!IS_UNDEFINED(current)) {
flag |= current.isConfigurable() ? 0 : DONT_DELETE;
} else
flag |= DONT_DELETE;
if (IsDataDescriptor(desc) || IsGenericDescriptor(desc)) {
flag |= desc.isWritable() ? 0 : READ_ONLY;
%DefineOrRedefineDataProperty(obj, p, desc.getValue(), flag);
} else {
if (desc.hasGetter() && IS_FUNCTION(desc.getGet())) {
%DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
}
if (desc.hasSetter() && IS_FUNCTION(desc.getSet())) {
%DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
}
}
return true;
}
......@@ -558,10 +659,21 @@ function ObjectCreate(proto, properties) {
}
// ES5 section 15.2.3.7. This version cannot cope with the properies already
// being present on obj. Therefore it is not exposed as
// Object.defineProperties yet.
// ES5 section 15.2.3.6.
function ObjectDefineProperty(obj, p, attributes) {
if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj))
throw MakeTypeError("obj_ctor_property_non_object", ["defineProperty"]);
var name = ToString(p);
var desc = ToPropertyDescriptor(attributes);
DefineOwnProperty(obj, name, desc, true);
return obj;
}
// ES5 section 15.2.3.7.
function ObjectDefineProperties(obj, properties) {
if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj))
throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]);
var props = ToObject(properties);
var key_values = [];
for (var key in props) {
......@@ -611,6 +723,8 @@ function SetupObject() {
InstallFunctions($Object, DONT_ENUM, $Array(
"keys", ObjectKeys,
"create", ObjectCreate,
"defineProperty", ObjectDefineProperty,
"defineProperties", ObjectDefineProperties,
"getPrototypeOf", ObjectGetPrototypeOf,
"getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
"getOwnPropertyNames", ObjectGetOwnPropertyNames
......
......@@ -2297,6 +2297,103 @@ THREADED_TEST(SimplePropertyRead) {
}
}
THREADED_TEST(DefinePropertyOnAPIAccessor) {
v8::HandleScope scope;
Local<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
// Uses getOwnPropertyDescriptor to check the configurable status
Local<Script> script_desc
= Script::Compile(v8_str("var prop =Object.getOwnPropertyDescriptor( "
"obj, 'x');"
"prop.configurable;"));
Local<Value> result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), true);
// Redefine get - but still configurable
Local<Script> script_define
= Script::Compile(v8_str("var desc = { get: function(){return 42; },"
" configurable: true };"
"Object.defineProperty(obj, 'x', desc);"
"obj.x"));
result = script_define->Run();
CHECK_EQ(result, v8_num(42));
// Check that the accessor is still configurable
result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), true);
// Redefine to a non-configurable
script_define
= Script::Compile(v8_str("var desc = { get: function(){return 43; },"
" configurable: false };"
"Object.defineProperty(obj, 'x', desc);"
"obj.x"));
result = script_define->Run();
CHECK_EQ(result, v8_num(43));
result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), false);
// Make sure that it is not possible to redefine again
v8::TryCatch try_catch;
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::AsciiValue exception_value(try_catch.Exception());
CHECK_EQ(*exception_value,
"TypeError: Cannot redefine property: defineProperty");
}
THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
v8::HandleScope scope;
Local<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
Local<Script> script_desc = Script::Compile(v8_str("var prop ="
"Object.getOwnPropertyDescriptor( "
"obj, 'x');"
"prop.configurable;"));
Local<Value> result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), true);
Local<Script> script_define =
Script::Compile(v8_str("var desc = {get: function(){return 42; },"
" configurable: true };"
"Object.defineProperty(obj, 'x', desc);"
"obj.x"));
result = script_define->Run();
CHECK_EQ(result, v8_num(42));
result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), true);
script_define =
Script::Compile(v8_str("var desc = {get: function(){return 43; },"
" configurable: false };"
"Object.defineProperty(obj, 'x', desc);"
"obj.x"));
result = script_define->Run();
CHECK_EQ(result, v8_num(43));
result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), false);
v8::TryCatch try_catch;
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::AsciiValue exception_value(try_catch.Exception());
CHECK_EQ(*exception_value,
"TypeError: Cannot redefine property: defineProperty");
}
v8::Persistent<Value> xValue;
......
......@@ -39,8 +39,6 @@ chapter14: UNIMPLEMENTED
chapter15/15.1: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.1: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.5: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.6: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.7: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.8: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.9: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.10: UNIMPLEMENTED
......@@ -48,24 +46,6 @@ chapter15/15.2/15.2.3/15.2.3.11: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.12: UNIMPLEMENTED
chapter15/15.2/15.2.3/15.2.3.13: UNIMPLEMENTED
# Object.getPrototypeOf
chapter15/15.2/15.2.3/15.2.3.2: PASS
# Object.getOwnPropertyDescriptor
chapter15/15.2/15.2.3/15.2.3.3: PASS
# NOT IMPLEMENTED: defineProperty
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-3: FAIL_OK
# NOT IMPLEMENTED: getOwnPropertyNames
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-16: FAIL_OK
# NOT IMPLEMENTED: defineProperty
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-18: FAIL_OK
# NOT IMPLEMENTED: defineProperties
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-19: FAIL_OK
# NOT IMPLEMENTED: seal
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-20: FAIL_OK
......@@ -87,37 +67,24 @@ chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-25: FAIL_OK
# NOT IMPLEMENTED: bind
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-38: FAIL_OK
# Built-ins have wrong descriptor (should all be false)
# NaN is writable
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-178: FAIL_OK
# Infinity is writable
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-179: FAIL_OK
# undefined is writable
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-180: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-182: FAIL_OK
# Our Function object has a "arguments" property which is used as a non
# property in in the test
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK
# Our Function object has a "caller" property which is used as a non
# property in in the test
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-184: FAIL_OK
# Built-ins have wrong descriptor (should all be false)
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-185: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-186: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-187: FAIL_OK
# Our function object has a name property which is used as a non
# property in the test
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-188: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-189: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-190: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-191: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-192: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-193: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-194: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-195: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-201: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-210: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-211: FAIL_OK
# NOT IMPLEMENTED: RegExp.prototype.source
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-212: FAIL_OK
......@@ -131,18 +98,6 @@ chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-214: FAIL_OK
# NOT IMPLEMENTED: RegExp.prototype.multiline
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215: FAIL_OK
# Errors have wrong descriptor (should all be false)
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-216: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-217: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-218: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-219: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-220: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-221: FAIL_OK
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-222: FAIL_OK
# Object.getOwnPropertyNames
chapter15/15.2/15.2.3/15.2.3.4: PASS
# All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because
# the tests assumes that objects can not have more properties
# than those described in the spec - but according to spec they can
......@@ -252,12 +207,9 @@ chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-b-1: FAIL_OK
# Object.keys
chapter15/15.2/15.2.3/15.2.3.14: PASS
# We fail this because Object.keys returns numbers for element indices
# rather than strings.
chapter15/15.2/15.2.3/15.2.3.14/15.2.3.14-3-3: FAIL_OK
#chapter15/15.2/15.2.3/15.2.3.14/15.2.3.14-3-3: FAIL_OK
chapter15/15.3: UNIMPLEMENTED
......@@ -267,9 +219,6 @@ chapter15/15.4/15.4.4/15.4.4.20: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.21: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.22: UNIMPLEMENTED
# Array.prototype.every
chapter15/15.4/15.4.4/15.4.4.16: PASS
# Wrong test - because this is not given as argument to arr.every
# this._15_4_4_16_5_1 evaluates to undefined
chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-5-1: FAIL_OK
......@@ -285,10 +234,6 @@ chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-7-7: FAIL_OK
# if (val>1) in test should be if (val>2)
chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-8-10: FAIL_OK
# Array.prototype.some
chapter15/15.4/15.4.4/15.4.4.17: PASS
# Wrong assumption - according to spec some returns a Boolean, not a number
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-4-9: FAIL_OK
......@@ -304,20 +249,12 @@ chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-7-7: FAIL_OK
# Same as 15.4.4.16-10-8
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-8-10: FAIL_OK
# Array.prototype.forEach
chapter15/15.4/15.4.4/15.4.4.18: PASS
# Same as 15.4.4.16-5-1
chapter15/15.4/15.4.4/15.4.4.18/15.4.4.18-5-1: FAIL_OK
# Same as 15.4.4.16-7-7
chapter15/15.4/15.4.4/15.4.4.18/15.4.4.18-7-6: FAIL_OK
# Array.prototype.map
chapter15/15.4/15.4.4/15.4.4.19: PASS
# Same as 15.4.4.16-5-1
chapter15/15.4/15.4.4/15.4.4.19/15.4.4.19-5-1: FAIL_OK
......
This diff is collapsed.
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