diff --git a/src/org/mozilla/javascript/NativeMap.java b/src/org/mozilla/javascript/NativeMap.java index 0af9a5b0d5..495ff7380d 100644 --- a/src/org/mozilla/javascript/NativeMap.java +++ b/src/org/mozilla/javascript/NativeMap.java @@ -187,30 +187,17 @@ static void loadFromIterable(Context cx, Scriptable scope, ScriptableObject map, // Find the "add" function of our own prototype, since it might have // been replaced. Since we're not fully constructed yet, create a dummy instance // so that we can get our own prototype. - ScriptableObject dummy = ensureScriptableObject(cx.newObject(scope, map.getClassName())); - final Callable set = - ScriptRuntime.getPropFunctionAndThis(dummy.getPrototype(), "set", cx, scope); + Scriptable proto = ScriptableObject.getClassPrototype(scope, map.getClassName()); + final Callable set = ScriptRuntime.getPropFunctionAndThis(proto, "set", cx, scope); ScriptRuntime.lastStoredScriptable(cx); - // Finally, run through all the iterated values and add them! - try (IteratorLikeIterable it = new IteratorLikeIterable(cx, scope, ito)) { - for (Object val : it) { - Scriptable sVal = ScriptableObject.ensureScriptable(val); - if (sVal instanceof Symbol) { - throw ScriptRuntime.typeErrorById( - "msg.arg.not.object", ScriptRuntime.typeof(sVal)); - } - Object finalKey = sVal.get(0, sVal); - if (finalKey == NOT_FOUND) { - finalKey = Undefined.instance; - } - Object finalVal = sVal.get(1, sVal); - if (finalVal == NOT_FOUND) { - finalVal = Undefined.instance; - } - set.call(cx, scope, map, new Object[] {finalKey, finalVal}); - } - } + ScriptRuntime.loadFromIterable( + cx, + scope, + arg1, + (key, value) -> { + set.call(cx, scope, map, new Object[] {key, value}); + }); } private static NativeMap realThis(Scriptable thisObj, IdFunctionObject f) { diff --git a/src/org/mozilla/javascript/NativeObject.java b/src/org/mozilla/javascript/NativeObject.java index e4a62f29ec..a7aec36821 100644 --- a/src/org/mozilla/javascript/NativeObject.java +++ b/src/org/mozilla/javascript/NativeObject.java @@ -9,9 +9,11 @@ import java.util.AbstractCollection; import java.util.AbstractSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Set; import org.mozilla.javascript.ScriptRuntime.StringIdOrIndex; @@ -47,6 +49,9 @@ protected void fillConstructorProperties(IdFunctionObject ctor) { if (Context.getCurrentContext().version >= Context.VERSION_ES6) { addIdFunctionProperty( ctor, OBJECT_TAG, ConstructorId_setPrototypeOf, "setPrototypeOf", 2); + addIdFunctionProperty(ctor, OBJECT_TAG, ConstructorId_entries, "entries", 1); + addIdFunctionProperty(ctor, OBJECT_TAG, ConstructorId_fromEntries, "fromEntries", 1); + addIdFunctionProperty(ctor, OBJECT_TAG, ConstructorId_values, "values", 1); } addIdFunctionProperty(ctor, OBJECT_TAG, ConstructorId_keys, "keys", 1); addIdFunctionProperty( @@ -224,11 +229,7 @@ public Object execIdCall( if (arg instanceof Symbol) { result = ((SymbolScriptable) thisObj).has((Symbol) arg, thisObj); - if (result && thisObj instanceof ScriptableObject) { - ScriptableObject so = (ScriptableObject) thisObj; - int attrs = so.getAttributes((Symbol) arg); - result = ((attrs & ScriptableObject.DONTENUM) == 0); - } + result = result && isEnumerable((Symbol) arg, thisObj); } else { StringIdOrIndex s = ScriptRuntime.toStringIdOrIndex(cx, arg); // When checking if a property is enumerable, a missing property should @@ -237,18 +238,10 @@ public Object execIdCall( try { if (s.stringId == null) { result = thisObj.has(s.index, thisObj); - if (result && thisObj instanceof ScriptableObject) { - ScriptableObject so = (ScriptableObject) thisObj; - int attrs = so.getAttributes(s.index); - result = ((attrs & ScriptableObject.DONTENUM) == 0); - } + result = result && isEnumerable(s.index, thisObj); } else { result = thisObj.has(s.stringId, thisObj); - if (result && thisObj instanceof ScriptableObject) { - ScriptableObject so = (ScriptableObject) thisObj; - int attrs = so.getAttributes(s.stringId); - result = ((attrs & ScriptableObject.DONTENUM) == 0); - } + result = result && isEnumerable(s.stringId, thisObj); } } catch (EvaluatorException ee) { if (ee.getMessage() @@ -403,6 +396,80 @@ public Object execIdCall( } return cx.newArray(scope, ids); } + + case ConstructorId_entries: + { + Object arg = args.length < 1 ? Undefined.instance : args[0]; + Scriptable obj = getCompatibleObject(cx, scope, arg); + Object[] ids = obj.getIds(); + int j = 0; + for (int i = 0; i < ids.length; i++) { + if (ids[i] instanceof Integer) { + int intId = (Integer) ids[i]; + if (obj.has(intId, obj) && isEnumerable(intId, obj)) { + String stringId = ScriptRuntime.toString(ids[i]); + Object[] entry = new Object[] {stringId, obj.get(intId, obj)}; + ids[j++] = cx.newArray(scope, entry); + } + } else { + String stringId = ScriptRuntime.toString(ids[i]); + if (obj.has(stringId, obj) && isEnumerable(stringId, obj)) { + Object[] entry = new Object[] {stringId, obj.get(stringId, obj)}; + ids[j++] = cx.newArray(scope, entry); + } + } + } + if (j != ids.length) { + ids = Arrays.copyOf(ids, j); + } + return cx.newArray(scope, ids); + } + case ConstructorId_fromEntries: + { + Object arg = args.length < 1 ? Undefined.instance : args[0]; + arg = getCompatibleObject(cx, scope, arg); + Scriptable obj = cx.newObject(scope); + ScriptRuntime.loadFromIterable( + cx, + scope, + arg, + (key, value) -> { + if (key instanceof Integer) { + obj.put((Integer) key, obj, value); + } else if (key instanceof Symbol + && obj instanceof SymbolScriptable) { + ((SymbolScriptable) obj).put((Symbol) key, obj, value); + } else { + obj.put(ScriptRuntime.toString(key), obj, value); + } + }); + return obj; + } + case ConstructorId_values: + { + Object arg = args.length < 1 ? Undefined.instance : args[0]; + Scriptable obj = getCompatibleObject(cx, scope, arg); + Object[] ids = obj.getIds(); + int j = 0; + for (int i = 0; i < ids.length; i++) { + if (ids[i] instanceof Integer) { + int intId = (Integer) ids[i]; + if (obj.has(intId, obj) && isEnumerable(intId, obj)) { + ids[j++] = obj.get(intId, obj); + } + } else { + String stringId = ScriptRuntime.toString(ids[i]); + // getter may remove keys + if (obj.has(stringId, obj) && isEnumerable(stringId, obj)) { + ids[j++] = obj.get(stringId, obj); + } + } + } + if (j != ids.length) { + ids = Arrays.copyOf(ids, j); + } + return cx.newArray(scope, ids); + } case ConstructorId_getOwnPropertyNames: { Object arg = args.length < 1 ? Undefined.instance : args[0]; @@ -640,6 +707,36 @@ && isFalse(desc.get("writable"))) { } } + private boolean isEnumerable(int index, Object obj) { + if (obj instanceof ScriptableObject) { + ScriptableObject so = (ScriptableObject) obj; + int attrs = so.getAttributes(index); + return (attrs & ScriptableObject.DONTENUM) == 0; + } else { + return true; + } + } + + private boolean isEnumerable(String key, Object obj) { + if (obj instanceof ScriptableObject) { + ScriptableObject so = (ScriptableObject) obj; + int attrs = so.getAttributes(key); + return (attrs & ScriptableObject.DONTENUM) == 0; + } else { + return true; + } + } + + private boolean isEnumerable(Symbol sym, Object obj) { + if (obj instanceof ScriptableObject) { + ScriptableObject so = (ScriptableObject) obj; + int attrs = so.getAttributes(sym); + return (attrs & ScriptableObject.DONTENUM) == 0; + } else { + return true; + } + } + private static Scriptable getCompatibleObject(Context cx, Scriptable scope, Object arg) { if (cx.getLanguageVersion() >= Context.VERSION_ES6) { Scriptable s = ScriptRuntime.toObject(cx, scope, arg); @@ -931,7 +1028,12 @@ protected int findPrototypeId(String s) { ConstructorId_getOwnPropertySymbols = -14, ConstructorId_assign = -15, ConstructorId_is = -16, + + // ES6 ConstructorId_setPrototypeOf = -17, + ConstructorId_entries = -18, + ConstructorId_fromEntries = -19, + ConstructorId_values = -20, Id_constructor = 1, Id_toString = 2, Id_toLocaleString = 3, diff --git a/src/org/mozilla/javascript/ScriptRuntime.java b/src/org/mozilla/javascript/ScriptRuntime.java index 7e6a462301..31b37ea792 100644 --- a/src/org/mozilla/javascript/ScriptRuntime.java +++ b/src/org/mozilla/javascript/ScriptRuntime.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.Locale; import java.util.ResourceBundle; +import java.util.function.BiConsumer; import org.mozilla.javascript.ast.FunctionNode; import org.mozilla.javascript.v8dtoa.DoubleConversion; import org.mozilla.javascript.v8dtoa.FastDtoa; @@ -2417,6 +2418,50 @@ private static void enumChangeObject(IdEnumeration x) { x.index = 0; } + /** + * This is used to handle all the special cases that are required when invoking + * Object.fromEntries or constructing a NativeMap or NativeWeakMap from an iterable. + * + * @param cx the current context + * @param scope the current scope + * @param arg1 the iterable object. + * @param setter the setter to set the value + * @return true, if arg1 was iterable. + */ + public static boolean loadFromIterable( + Context cx, Scriptable scope, Object arg1, BiConsumer setter) { + if ((arg1 == null) || Undefined.instance.equals(arg1)) { + return false; + } + + // Call the "[Symbol.iterator]" property as a function. + final Object ito = ScriptRuntime.callIterator(arg1, cx, scope); + if (Undefined.instance.equals(ito)) { + // Per spec, ignore if the iterator is undefined + return false; + } + + // Finally, run through all the iterated values and add them! + try (IteratorLikeIterable it = new IteratorLikeIterable(cx, scope, ito)) { + for (Object val : it) { + Scriptable sVal = ScriptableObject.ensureScriptable(val); + if (sVal instanceof Symbol) { + throw ScriptRuntime.typeErrorById( + "msg.arg.not.object", ScriptRuntime.typeof(sVal)); + } + Object finalKey = sVal.get(0, sVal); + if (finalKey == Scriptable.NOT_FOUND) { + finalKey = Undefined.instance; + } + Object finalVal = sVal.get(1, sVal); + if (finalVal == Scriptable.NOT_FOUND) { + finalVal = Undefined.instance; + } + setter.accept(finalKey, finalVal); + } + } + return true; + } /** * Prepare for calling name(...): return function corresponding to name and make current top * scope available as ScriptRuntime.lastStoredScriptable() for consumption as thisObj. The @@ -4293,22 +4338,30 @@ public static Scriptable newObjectLiteral( // -1 for property getter, 1 for property setter, 0 for a regular value property int getterSetter = getterSetters == null ? 0 : getterSetters[i]; Object value = propertyValues[i]; + if (getterSetter == 0) { - if (id instanceof String) { - if (isSpecialProperty((String) id)) { - Ref ref = specialRef(object, (String) id, cx, scope); + if (id instanceof Symbol) { + Symbol sym = (Symbol) id; + SymbolScriptable so = (SymbolScriptable) object; + so.put(sym, object, value); + } else if (id instanceof Integer) { + int index = ((Integer) id).intValue(); + object.put(index, object, value); + } else { + String stringId = ScriptRuntime.toString(id); + if (isSpecialProperty(stringId)) { + Ref ref = specialRef(object, stringId, cx, scope); ref.set(cx, scope, value); } else { - object.put((String) id, object, value); + object.put(stringId, object, value); } - } else { - int index = ((Integer) id).intValue(); - object.put(index, object, value); } } else { ScriptableObject so = (ScriptableObject) object; Callable getterOrSetter = (Callable) value; boolean isSetter = getterSetter == 1; + // XXX: Do we have to handle Symbol here. + // This will be required, when conputedprops are supported. String key = id instanceof String ? (String) id : null; int index = key == null ? ((Integer) id).intValue() : 0; so.setGetterOrSetter(key, index, getterOrSetter, isSetter); diff --git a/testsrc/org/mozilla/javascript/tests/es6/NativeObjectTest.java b/testsrc/org/mozilla/javascript/tests/es6/NativeObjectTest.java index 1a3bb66419..19cbe88995 100644 --- a/testsrc/org/mozilla/javascript/tests/es6/NativeObjectTest.java +++ b/testsrc/org/mozilla/javascript/tests/es6/NativeObjectTest.java @@ -3,21 +3,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* - * Tests for the Object.getOwnPropertyDescriptor(obj, prop) method + * Tests for the Object.getOwnPropertyDescriptor(obj, prop), Object.keys, Object.values and Object.entries method */ package org.mozilla.javascript.tests.es6; import static org.junit.Assert.assertEquals; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mozilla.javascript.Context; import org.mozilla.javascript.ScriptableObject; -/** - * Test for NativeObject. - */ +/** Test for NativeObject. */ public class NativeObjectTest { private Context cx; @@ -37,113 +38,261 @@ public void tearDown() { @Test public void testAssignPropertyGetter() { - Object result = cx.evaluateString( - scope, "var obj = Object.defineProperty({}, 'propA', {\n" - + " enumerable: true,\n" - + " get: function () {\n" - + " Object.defineProperty(this, 'propB', {\n" - + " value: 3,\n" - + " enumerable: false\n" - + " });\n" - + " }\n" - + " });\n" - + "Object.assign(obj, {propB: 2});\n" - + "Object.assign({propB: 1}, obj);\n" - + "'obj.propB = ' + obj.propB + ', enumerable = ' + Object.getOwnPropertyDescriptor(obj, 'propB').enumerable", - "test", 1, null - ); + Object result = + cx.evaluateString( + scope, + "var obj = Object.defineProperty({}, 'propA', {\n" + + " enumerable: true,\n" + + " get: function () {\n" + + " Object.defineProperty(this, 'propB', {\n" + + " value: 3,\n" + + " enumerable: false\n" + + " });\n" + + " }\n" + + " });\n" + + "Object.assign(obj, {propB: 2});\n" + + "Object.assign({propB: 1}, obj);\n" + + "'obj.propB = ' + obj.propB + ', enumerable = ' + Object.getOwnPropertyDescriptor(obj, 'propB').enumerable", + "test", + 1, + null); assertEquals("obj.propB = 3, enumerable = false", result); } @Test public void testAssignOneParameter() { - Object result = cx.evaluateString( - scope, "var obj = {};" - + "res = Object.assign(obj);" - + "res === obj;", - "test", 1, null - ); + Object result = + cx.evaluateString( + scope, + "var obj = {};" + "res = Object.assign(obj);" + "res === obj;", + "test", + 1, + null); assertEquals(true, result); } - @Test public void testAssignMissingParameters() { - Object result = cx.evaluateString( - scope, "try { " - + " Object.assign();" - + "} catch (e) { e.message }", - "test", 1, null - ); + Object result = + cx.evaluateString( + scope, + "try { " + " Object.assign();" + "} catch (e) { e.message }", + "test", + 1, + null); assertEquals("Cannot convert undefined to an object.", result); } @Test public void testAssignNumericPropertyGetter() { - Object result = cx.evaluateString( - scope, "var obj = Object.defineProperty({}, 1, {\n" - + " enumerable: true,\n" - + " get: function () {\n" - + " Object.defineProperty(this, 2, {\n" - + " value: 3,\n" - + " enumerable: false\n" - + " });\n" - + " }\n" - + " });\n" - + "Object.assign(obj, {2: 2});\n" - + "Object.assign({2: 1}, obj);\n" - + "'obj[2] = ' + obj[2] + ', enumerable = ' + Object.getOwnPropertyDescriptor(obj, 2).enumerable", - "test", 1, null - ); + Object result = + cx.evaluateString( + scope, + "var obj = Object.defineProperty({}, 1, {\n" + + " enumerable: true,\n" + + " get: function () {\n" + + " Object.defineProperty(this, 2, {\n" + + " value: 3,\n" + + " enumerable: false\n" + + " });\n" + + " }\n" + + " });\n" + + "Object.assign(obj, {2: 2});\n" + + "Object.assign({2: 1}, obj);\n" + + "'obj[2] = ' + obj[2] + ', enumerable = ' + Object.getOwnPropertyDescriptor(obj, 2).enumerable", + "test", + 1, + null); assertEquals("obj[2] = 3, enumerable = false", result); } @Test public void testSetPrototypeOfNull() { - Object result = cx.evaluateString( - scope, "try { " - + " Object.setPrototypeOf(null, new Object());" - + "} catch (e) { e.message }", - "test", 1, null - ); + Object result = + cx.evaluateString( + scope, + "try { " + + " Object.setPrototypeOf(null, new Object());" + + "} catch (e) { e.message }", + "test", + 1, + null); assertEquals("Object.prototype.setPrototypeOf method called on null or undefined", result); } @Test public void testSetPrototypeOfUndefined() { - Object result = cx.evaluateString( - scope, "try { " - + " Object.setPrototypeOf(undefined, new Object());" - + "} catch (e) { e.message }", - "test", 1, null - ); + Object result = + cx.evaluateString( + scope, + "try { " + + " Object.setPrototypeOf(undefined, new Object());" + + "} catch (e) { e.message }", + "test", + 1, + null); assertEquals("Object.prototype.setPrototypeOf method called on null or undefined", result); } @Test public void testSetPrototypeOfMissingParameters() { - Object result = cx.evaluateString( - scope, "try { " - + " Object.setPrototypeOf();" - + "} catch (e) { e.message }", - "test", 1, null - ); - - assertEquals("Object.setPrototypeOf: At least 2 arguments required, but only 0 passed", result); - - result = cx.evaluateString( - scope, "try { " - + " Object.setPrototypeOf({});" - + "} catch (e) { e.message }", - "test", 1, null - ); - - assertEquals("Object.setPrototypeOf: At least 2 arguments required, but only 1 passed", result); + Object result = + cx.evaluateString( + scope, + "try { " + " Object.setPrototypeOf();" + "} catch (e) { e.message }", + "test", + 1, + null); + + assertEquals( + "Object.setPrototypeOf: At least 2 arguments required, but only 0 passed", result); + + result = + cx.evaluateString( + scope, + "try { " + " Object.setPrototypeOf({});" + "} catch (e) { e.message }", + "test", + 1, + null); + + assertEquals( + "Object.setPrototypeOf: At least 2 arguments required, but only 1 passed", result); + } + + @Test + public void testKeysMissingParameter() { + Object result = + cx.evaluateString( + scope, + "try { " + " Object.keys();" + "} catch (e) { e.message }", + "test", + 1, + null); + + assertEquals("Cannot convert undefined to an object.", result); + } + + @Test + public void testKeysOnObjectParameter() { + evaluateAndAssert( + "Object.keys({'foo':'bar', 2: 'y', 1: 'x'})", Arrays.asList("1", "2", "foo")); + } + + @Test + public void testKeysOnArray() { + evaluateAndAssert("Object.keys(['x','y','z'])", Arrays.asList("0", "1", "2")); + } + + @Test + public void testKeysOnArrayWithProp() { + evaluateAndAssert( + "var arr = ['x','y','z'];\n" + "arr['foo'] = 'bar'; Object.keys(arr)", + Arrays.asList("0", "1", "2", "foo")); + } + + @Test + public void testValuesMissingParameter() { + Object result = + cx.evaluateString( + scope, + "try { " + " Object.values();" + "} catch (e) { e.message }", + "test", + 1, + null); + + assertEquals("Cannot convert undefined to an object.", result); + } + + @Test + public void testValuesOnObjectParameter() { + evaluateAndAssert( + "Object.values({'foo':'bar', 2: 'y', 1: 'x'})", Arrays.asList("x", "y", "bar")); + } + + @Test + public void testValuesOnArray() { + evaluateAndAssert("Object.values(['x','y','z'])", Arrays.asList("x", "y", "z")); + } + + @Test + public void testValuesOnArrayWithProp() { + evaluateAndAssert( + "var arr = [3,4,5];\n" + "arr['foo'] = 'bar'; Object.values(arr)", + Arrays.asList(3, 4, 5, "bar")); + } + + @Test + public void testEntriesMissingParameter() { + Object result = + cx.evaluateString( + scope, + "try { " + " Object.entries();" + "} catch (e) { e.message }", + "test", + 1, + null); + + assertEquals("Cannot convert undefined to an object.", result); + } + + @Test + public void testEntriesOnObjectParameter() { + evaluateAndAssert( + "Object.entries({'foo':'bar', 2: 'y', 1: 'x'})", + Arrays.asList( + Arrays.asList("1", "x"), + Arrays.asList("2", "y"), + Arrays.asList("foo", "bar"))); + } + + @Test + public void testEntriesOnArray() { + evaluateAndAssert( + "Object.entries(['x','y','z'])", + Arrays.asList( + Arrays.asList("0", "x"), Arrays.asList("1", "y"), Arrays.asList("2", "z"))); + } + + @Test + public void testEntriesOnArrayWithProp() { + evaluateAndAssert( + "var arr = [3,4,5];\n" + "arr['foo'] = 'bar'; Object.entries(arr)", + Arrays.asList( + Arrays.asList("0", 3), + Arrays.asList("1", 4), + Arrays.asList("2", 5), + Arrays.asList("foo", "bar"))); + } + + @Test + public void testFromEntriesMissingParameter() { + Object result = + cx.evaluateString( + scope, + "try { " + " Object.fromEntries();" + "} catch (e) { e.message }", + "test", + 1, + null); + + assertEquals("Cannot convert undefined to an object.", result); + } + + @Test + public void testFromEntriesOnArray() { + Map map = new HashMap<>(); + map.put("0", "x"); + map.put("1", "y"); + map.put("2", "z"); + evaluateAndAssert("Object.fromEntries(Object.entries(['x','y','z']))", map); + } + + private void evaluateAndAssert(String script, Object expected) { + Object result = cx.evaluateString(scope, script, "test", 1, null); + assertEquals(expected, result); } } diff --git a/testsrc/test262.properties b/testsrc/test262.properties index cea2ffd5a6..6be30d1f49 100644 --- a/testsrc/test262.properties +++ b/testsrc/test262.properties @@ -728,7 +728,6 @@ built-ins/Object ! defineProperty/15.2.3.6-4-293-3.js ! defineProperty/15.2.3.6-4-293-4.js ! defineProperty/15.2.3.6-4-336.js - ! fromEntries/empty-iterable.js ! fromEntries/evaluation-order.js ! fromEntries/iterator-closed-for-null-entry.js ! fromEntries/iterator-closed-for-string-entry.js @@ -739,35 +738,8 @@ built-ins/Object ! fromEntries/iterator-not-closed-for-throwing-done-accessor.js ! fromEntries/iterator-not-closed-for-throwing-next.js ! fromEntries/iterator-not-closed-for-uncallable-next.js - ! fromEntries/key-order.js - ! fromEntries/length.js - ! fromEntries/name.js - ! fromEntries/prototype.js - ! fromEntries/requires-argument.js - ! fromEntries/simple-properties.js - ! fromEntries/string-entry-object-succeeds.js - ! fromEntries/string-entry-primitive-throws.js - ! fromEntries/string-entry-string-object-succeeds.js - ! fromEntries/supports-symbols.js ! fromEntries/to-property-key.js - ! fromEntries/uses-define-semantics.js ! fromEntries/uses-keys-not-iterator.js - ! entries/exception-during-enumeration.js - ! entries/function-length.js - ! entries/function-name.js - ! entries/function-property-descriptor.js - ! entries/getter-adding-key.js - ! entries/getter-making-future-key-nonenumerable.js - ! entries/getter-removing-future-key.js - ! entries/inherited-properties-omitted.js - ! entries/observable-operations.js - ! entries/primitive-booleans.js - ! entries/primitive-numbers.js - ! entries/primitive-strings.js - ! entries/primitive-symbols.js - ! entries/symbols-omitted.js - ! entries/tamper-with-global-object.js - ! entries/tamper-with-object-keys.js ! getOwnPropertyDescriptor/15.2.3.3-4-187.js ! getOwnPropertyDescriptor/15.2.3.3-4-212.js ! getOwnPropertyDescriptor/15.2.3.3-4-213.js @@ -822,22 +794,6 @@ built-ins/Object ! seal/symbol-object-contains-symbol-properties-non-strict.js ! seal/symbol-object-contains-symbol-properties-strict.js ! setPrototypeOf/set-error.js - ! values/exception-during-enumeration.js - ! values/function-length.js - ! values/function-name.js - ! values/function-property-descriptor.js - ! values/getter-adding-key.js - ! values/getter-making-future-key-nonenumerable.js - ! values/getter-removing-future-key.js - ! values/inherited-properties-omitted.js - ! values/observable-operations.js - ! values/primitive-booleans.js - ! values/primitive-numbers.js - ! values/primitive-strings.js - ! values/primitive-symbols.js - ! values/symbols-omitted.js - ! values/tamper-with-global-object.js - ! values/tamper-with-object-keys.js built-ins/parseFloat ! name.js