diff --git a/rhino/src/main/java/org/mozilla/javascript/AbstractEcmaObjectOperations.java b/rhino/src/main/java/org/mozilla/javascript/AbstractEcmaObjectOperations.java index 26633b6428..acde62d55b 100644 --- a/rhino/src/main/java/org/mozilla/javascript/AbstractEcmaObjectOperations.java +++ b/rhino/src/main/java/org/mozilla/javascript/AbstractEcmaObjectOperations.java @@ -46,7 +46,7 @@ enum KEY_COERCION { static boolean hasOwnProperty(Context cx, Object o, Object property) { Scriptable obj = ScriptableObject.ensureScriptable(o); boolean result; - if (property instanceof Symbol) { + if (ScriptRuntime.isSymbol(property)) { result = ScriptableObject.ensureSymbolScriptable(o).has((Symbol) property, obj); } else { ScriptRuntime.StringIdOrIndex s = ScriptRuntime.toStringIdOrIndex(property); diff --git a/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java b/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java index d617123811..62679a10e7 100644 --- a/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java +++ b/rhino/src/main/java/org/mozilla/javascript/IdScriptableObject.java @@ -182,7 +182,7 @@ final void set(int id, Scriptable start, Object value) { } else { int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT; Object name = valueArray[nameSlot]; - if (name instanceof Symbol) { + if (ScriptRuntime.isSymbol(name)) { if (start instanceof SymbolScriptable) { ((SymbolScriptable) start).put((Symbol) name, start, value); } @@ -241,7 +241,7 @@ final Object[] getNames(boolean getAll, boolean getSymbols, Object[] extraEntrie names = new Object[maxId]; } names[count++] = name; - } else if (getSymbols && (name instanceof Symbol)) { + } else if (getSymbols && ScriptRuntime.isSymbol(name)) { if (names == null) { names = new Object[maxId]; } diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeArray.java b/rhino/src/main/java/org/mozilla/javascript/NativeArray.java index d0276715d7..37447b9a37 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeArray.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeArray.java @@ -1949,7 +1949,7 @@ private static Boolean js_includes( Object compareTo = args.length > 0 ? args[0] : Undefined.instance; Scriptable o = ScriptRuntime.toObject(cx, scope, thisObj); - long len = ScriptRuntime.toLength(new Object[] {getProperty(thisObj, "length")}, 0); + long len = getLengthProperty(cx, o); if (len == 0) return Boolean.FALSE; long k; diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeDate.java b/rhino/src/main/java/org/mozilla/javascript/NativeDate.java index dc7601510c..b231de28b2 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeDate.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeDate.java @@ -15,6 +15,7 @@ import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Optional; /** * This class implements the Date native object. See ECMA 15.9. @@ -254,6 +255,10 @@ protected void initPrototypeId(int id) { arity = 1; s = "toJSON"; break; + case SymbolId_toPrimitive: + initPrototypeMethod( + DATE_TAG, id, SymbolKey.TO_PRIMITIVE, "[Symbol.toPrimitive]", 1); + return; default: throw new IllegalArgumentException(String.valueOf(id)); } @@ -293,7 +298,8 @@ public Object execIdCall( final String toISOString = "toISOString"; Scriptable o = ScriptRuntime.toObject(cx, scope, thisObj); - Object tv = ScriptRuntime.toPrimitive(o, ScriptRuntime.NumberClass); + Object tv = + ScriptRuntime.toPrimitive(o, Optional.of(ScriptRuntime.NumberClass)); if (tv instanceof Number) { double d = ((Number) tv).doubleValue(); if (Double.isNaN(d) || Double.isInfinite(d)) { @@ -322,6 +328,30 @@ public Object execIdCall( } return result; } + case SymbolId_toPrimitive: + { + Scriptable o = ScriptRuntime.toObject(cx, scope, thisObj); + final Object arg0 = args.length > 0 ? args[0] : Undefined.instance; + final Optional hint = + Optional.ofNullable( + arg0 instanceof CharSequence ? arg0.toString() : null); + final Class tryFirst = + hint.map( + h -> { + if (h.equals("string") || h.equals("default")) { + return ScriptRuntime.StringClass; + } else if (h.equals("number")) { + return ScriptRuntime.NumberClass; + } + return null; + }) + .orElseThrow( + () -> + ScriptRuntime.typeErrorById( + "msg.invalid.toprimitive.hint", + ScriptRuntime.toString(arg0))); + return ScriptableObject.getDefaultValue(o, tryFirst); + } } // The rest of Date.prototype methods require thisObj to be Date @@ -1373,21 +1403,19 @@ private static Object jsConstructor(Context cx, Object[] args) { // if called with just one arg - if (args.length == 1) { - Object arg0 = args[0]; - if (arg0 instanceof NativeDate) { - obj.date = ((NativeDate) arg0).date; + final Object value = args[0]; + if (value instanceof NativeDate) { + obj.date = ((NativeDate) value).date; return obj; } - if (arg0 instanceof Scriptable) { - arg0 = ((Scriptable) arg0).getDefaultValue(null); - } - double date; - if (arg0 instanceof CharSequence) { + final Object v = ScriptRuntime.toPrimitive(value); + final double date; + if (v instanceof CharSequence) { // it's a string; parse it. - date = date_parseString(cx, arg0.toString()); + date = date_parseString(cx, v.toString()); } else { // if it's not a string, use it as a millisecond date - date = ScriptRuntime.toNumber(arg0); + date = ScriptRuntime.toNumber(v); } obj.date = TimeClip(date); return obj; @@ -1899,6 +1927,14 @@ protected int findPrototypeId(String s) { return id; } + @Override + protected int findPrototypeId(Symbol key) { + if (SymbolKey.TO_PRIMITIVE.equals(key)) { + return SymbolId_toPrimitive; + } + return 0; + } + private static final int ConstructorId_now = -3, ConstructorId_parse = -2, ConstructorId_UTC = -1, @@ -1949,7 +1985,8 @@ protected int findPrototypeId(String s) { Id_setYear = 45, Id_toISOString = 46, Id_toJSON = 47, - MAX_PROTOTYPE_ID = Id_toJSON; + SymbolId_toPrimitive = 48, + MAX_PROTOTYPE_ID = SymbolId_toPrimitive; private static final int Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6 diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeObject.java b/rhino/src/main/java/org/mozilla/javascript/NativeObject.java index ce316bbe22..721d1c0568 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeObject.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeObject.java @@ -361,7 +361,7 @@ public Object execIdCall( Integer.toString(args.length)); } Scriptable proto = (args[1] == null) ? null : ensureScriptable(args[1]); - if (proto instanceof Symbol) { + if (ScriptRuntime.isSymbol(proto)) { throw ScriptRuntime.typeErrorById( "msg.arg.not.object", ScriptRuntime.typeof(proto)); } @@ -440,7 +440,7 @@ public Object execIdCall( (key, value) -> { if (key instanceof Integer) { obj.put((Integer) key, obj, value); - } else if (key instanceof Symbol + } else if (ScriptRuntime.isSymbol(key) && obj instanceof SymbolScriptable) { ((SymbolScriptable) obj).put((Symbol) key, obj, value); } else { diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeSymbol.java b/rhino/src/main/java/org/mozilla/javascript/NativeSymbol.java index 8add15dae2..c19479707b 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeSymbol.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeSymbol.java @@ -32,18 +32,20 @@ public static void init(Context cx, Scriptable scope, boolean sealed) { cx.putThreadLocal(CONSTRUCTOR_SLOT, Boolean.TRUE); try { - createStandardSymbol(cx, scope, ctor, "iterator", SymbolKey.ITERATOR); - createStandardSymbol(cx, scope, ctor, "species", SymbolKey.SPECIES); - createStandardSymbol(cx, scope, ctor, "toStringTag", SymbolKey.TO_STRING_TAG); + createStandardSymbol(cx, scope, ctor, "asyncIterator", SymbolKey.ASYNC_ITERATOR); createStandardSymbol(cx, scope, ctor, "hasInstance", SymbolKey.HAS_INSTANCE); createStandardSymbol( cx, scope, ctor, "isConcatSpreadable", SymbolKey.IS_CONCAT_SPREADABLE); createStandardSymbol(cx, scope, ctor, "isRegExp", SymbolKey.IS_REGEXP); - createStandardSymbol(cx, scope, ctor, "toPrimitive", SymbolKey.TO_PRIMITIVE); + createStandardSymbol(cx, scope, ctor, "iterator", SymbolKey.ITERATOR); createStandardSymbol(cx, scope, ctor, "match", SymbolKey.MATCH); + createStandardSymbol(cx, scope, ctor, "matchAll", SymbolKey.MATCH_ALL); createStandardSymbol(cx, scope, ctor, "replace", SymbolKey.REPLACE); createStandardSymbol(cx, scope, ctor, "search", SymbolKey.SEARCH); + createStandardSymbol(cx, scope, ctor, "species", SymbolKey.SPECIES); createStandardSymbol(cx, scope, ctor, "split", SymbolKey.SPLIT); + createStandardSymbol(cx, scope, ctor, "toPrimitive", SymbolKey.TO_PRIMITIVE); + createStandardSymbol(cx, scope, ctor, "toStringTag", SymbolKey.TO_STRING_TAG); createStandardSymbol(cx, scope, ctor, "unscopables", SymbolKey.UNSCOPABLES); } finally { @@ -164,7 +166,7 @@ protected void initPrototypeId(int id) { break; case SymbolId_toPrimitive: initPrototypeMethod( - CLASS_NAME, id, SymbolKey.TO_PRIMITIVE, "Symbol.toPrimitive", 1); + CLASS_NAME, id, SymbolKey.TO_PRIMITIVE, "[Symbol.toPrimitive]", 1); break; default: super.initPrototypeId(id); diff --git a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java index 337f7e0bba..9215f8d915 100644 --- a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java +++ b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java @@ -436,15 +436,10 @@ public static double toNumber(Object val) { if (val instanceof String) return toNumber((String) val); if (val instanceof CharSequence) return toNumber(val.toString()); if (val instanceof Boolean) return ((Boolean) val).booleanValue() ? 1 : +0.0; - if (val instanceof Symbol) throw typeErrorById("msg.not.a.number"); - if (val instanceof Scriptable) { - val = ((Scriptable) val).getDefaultValue(NumberClass); - if ((val instanceof Scriptable) && !isSymbol(val)) - throw errorWithClassName("msg.primitive.expected", val); - continue; - } - warnAboutNonJSObject(val); - return NaN; + if (isSymbol(val)) throw typeErrorById("msg.not.a.number"); + // Assert: val is an Object + val = toPrimitive(val, Optional.of(NumberClass)); + // Assert: val is a primitive } } @@ -713,56 +708,45 @@ public static double toNumber(String s) { /** Convert the value to a BigInt. */ public static BigInteger toBigInt(Object val) { - for (; ; ) { - if (val instanceof BigInteger) { - return (BigInteger) val; - } - if (val instanceof BigDecimal) { - return ((BigDecimal) val).toBigInteger(); - } - if (val instanceof Number) { - if (val instanceof Long) { - return BigInteger.valueOf(((Long) val)); - } else { - double d = ((Number) val).doubleValue(); - if (Double.isNaN(d) || Double.isInfinite(d)) { - throw rangeErrorById( - "msg.cant.convert.to.bigint.isnt.integer", toString(val)); - } - BigDecimal bd = new BigDecimal(d, MathContext.UNLIMITED); - try { - return bd.toBigIntegerExact(); - } catch (ArithmeticException e) { - throw rangeErrorById( - "msg.cant.convert.to.bigint.isnt.integer", toString(val)); - } + val = toPrimitive(val, Optional.of(NumberClass)); + if (val instanceof BigInteger) { + return (BigInteger) val; + } + if (val instanceof BigDecimal) { + return ((BigDecimal) val).toBigInteger(); + } + if (val instanceof Number) { + if (val instanceof Long) { + return BigInteger.valueOf(((Long) val)); + } else { + double d = ((Number) val).doubleValue(); + if (Double.isNaN(d) || Double.isInfinite(d)) { + throw rangeErrorById("msg.cant.convert.to.bigint.isnt.integer", toString(val)); } - } - if (val == null || Undefined.isUndefined(val)) { - throw typeErrorById("msg.cant.convert.to.bigint", toString(val)); - } - if (val instanceof String) { - return toBigInt((String) val); - } - if (val instanceof CharSequence) { - return toBigInt(val.toString()); - } - if (val instanceof Boolean) { - return ((Boolean) val).booleanValue() ? BigInteger.ONE : BigInteger.ZERO; - } - if (val instanceof Symbol) { - throw typeErrorById("msg.cant.convert.to.bigint", toString(val)); - } - if (val instanceof Scriptable) { - val = ((Scriptable) val).getDefaultValue(BigIntegerClass); - if ((val instanceof Scriptable) && !isSymbol(val)) { - throw errorWithClassName("msg.primitive.expected", val); + BigDecimal bd = new BigDecimal(d, MathContext.UNLIMITED); + try { + return bd.toBigIntegerExact(); + } catch (ArithmeticException e) { + throw rangeErrorById("msg.cant.convert.to.bigint.isnt.integer", toString(val)); } - continue; } - warnAboutNonJSObject(val); - return BigInteger.ZERO; } + if (val == null || Undefined.isUndefined(val)) { + throw typeErrorById("msg.cant.convert.to.bigint", toString(val)); + } + if (val instanceof String) { + return toBigInt((String) val); + } + if (val instanceof CharSequence) { + return toBigInt(val.toString()); + } + if (val instanceof Boolean) { + return ((Boolean) val).booleanValue() ? BigInteger.ONE : BigInteger.ZERO; + } + if (isSymbol(val)) { + throw typeErrorById("msg.cant.convert.to.bigint", toString(val)); + } + throw errorWithClassName("msg.primitive.expected", val); } /** ToBigInt applied to the String type */ @@ -841,6 +825,7 @@ public static BigInteger toBigInt(String s) { *

See ECMA 7.1.3 (v11.0). */ public static Number toNumeric(Object val) { + val = toPrimitive(val, Optional.of(NumberClass)); if (val instanceof Number) { return (Number) val; } @@ -1027,24 +1012,22 @@ public static String toString(Object val) { return val.toString(); } if (val instanceof BigInteger) { - return val.toString(); + return ((BigInteger) val).toString(10); } if (val instanceof Number) { // XXX should we just teach NativeNumber.stringValue() // about Numbers? return numberToString(((Number) val).doubleValue(), 10); } - if (val instanceof Symbol) { - throw typeErrorById("msg.not.a.string"); + if (val instanceof Boolean) { + return val.toString(); } - if (val instanceof Scriptable) { - val = ((Scriptable) val).getDefaultValue(StringClass); - if ((val instanceof Scriptable) && !isSymbol(val)) { - throw errorWithClassName("msg.primitive.expected", val); - } - continue; + if (isSymbol(val)) { + throw typeErrorById("msg.not.a.string"); } - return val.toString(); + // Assert: val is an Object + val = toPrimitive(val, Optional.of(StringClass)); + // Assert: val is a primitive } } @@ -2983,55 +2966,58 @@ public static boolean isObject(Object value) { // implement the '~' operator inline in the caller // as "~toInt32(val)" - public static Object add(Object val1, Object val2, Context cx) { - if (val1 instanceof BigInteger && val2 instanceof BigInteger) { - return ((BigInteger) val1).add((BigInteger) val2); - } - if ((val1 instanceof Number && val2 instanceof BigInteger) - || (val1 instanceof BigInteger && val2 instanceof Number)) { - throw ScriptRuntime.typeErrorById("msg.cant.convert.to.number", "BigInt"); + public static Object add(Object lval, Object rval, Context cx) { + // if lval and rval are primitive numerics of the same type, give them priority + if (lval instanceof Integer && rval instanceof Integer) { + return add((Integer) lval, (Integer) rval); } - if (val1 instanceof Integer && val2 instanceof Integer) { - return add((Integer) val1, (Integer) val2); + if (lval instanceof BigInteger && rval instanceof BigInteger) { + return ((BigInteger) lval).add((BigInteger) rval); } - if (val1 instanceof Number && val2 instanceof Number) { - return wrapNumber(((Number) val1).doubleValue() + ((Number) val2).doubleValue()); + if (lval instanceof Number + && !(lval instanceof BigInteger) + && rval instanceof Number + && !(rval instanceof BigInteger)) { + return wrapNumber(((Number) lval).doubleValue() + ((Number) rval).doubleValue()); } - if (val1 instanceof CharSequence && val2 instanceof CharSequence) { - // If we let this happen later, then the "getDefaultValue" logic - // undoes many optimizations - return new ConsString((CharSequence) val1, (CharSequence) val2); + + // spec starts here for abstract operation ApplyStringOrNumericBinaryOperator + // where opText is "+". + final Object lprim = toPrimitive(lval); + final Object rprim = toPrimitive(rval); + if (lprim instanceof CharSequence || rprim instanceof CharSequence) { + final CharSequence lstr = + (lprim instanceof CharSequence) ? (CharSequence) lprim : toString(lprim); + final CharSequence rstr = + (rprim instanceof CharSequence) ? (CharSequence) rprim : toString(rprim); + return new ConsString(lstr, rstr); } - if (val1 instanceof XMLObject) { - Object test = ((XMLObject) val1).addValues(cx, true, val2); + + // e4x extension start + if (lval instanceof XMLObject) { + Object test = ((XMLObject) lval).addValues(cx, true, rval); if (test != Scriptable.NOT_FOUND) { return test; } } - if (val2 instanceof XMLObject) { - Object test = ((XMLObject) val2).addValues(cx, false, val1); + if (rval instanceof XMLObject) { + Object test = ((XMLObject) rval).addValues(cx, false, lval); if (test != Scriptable.NOT_FOUND) { return test; } } - if ((val1 instanceof Symbol) || (val2 instanceof Symbol)) { - throw typeErrorById("msg.not.a.number"); - } - if (val1 instanceof Scriptable) val1 = ((Scriptable) val1).getDefaultValue(null); - if (val2 instanceof Scriptable) val2 = ((Scriptable) val2).getDefaultValue(null); - if (!(val1 instanceof CharSequence) && !(val2 instanceof CharSequence)) { - Number num1 = val1 instanceof Number ? (Number) val1 : toNumeric(val1); - Number num2 = val2 instanceof Number ? (Number) val2 : toNumeric(val2); + // e4x extension end - if (num1 instanceof BigInteger && num2 instanceof BigInteger) { - return ((BigInteger) num1).add((BigInteger) num2); - } - if (num1 instanceof BigInteger || num2 instanceof BigInteger) { - throw ScriptRuntime.typeErrorById("msg.cant.convert.to.number", "BigInt"); - } - return num1.doubleValue() + num2.doubleValue(); + // Skipping (lval = lprim, rval = rprim) and using xprim values directly. + final Number lnum = toNumeric(lprim); + final Number rnum = toNumeric(rprim); + if (lnum instanceof BigInteger && rnum instanceof BigInteger) { + return ((BigInteger) lnum).add((BigInteger) rnum); + } + if (lnum instanceof BigInteger || rnum instanceof BigInteger) { + throw ScriptRuntime.typeErrorById("msg.cant.convert.to.number", "BigInt"); } - return new ConsString(toCharSequence(val1), toCharSequence(val2)); + return lnum.doubleValue() + rnum.doubleValue(); } /** @@ -3474,16 +3460,70 @@ public static Number negate(Number val) { return -val.doubleValue(); } - public static Object toPrimitive(Object val) { - return toPrimitive(val, null); + public static Object toPrimitive(Object input) { + return toPrimitive(input, Optional.empty()); } - public static Object toPrimitive(Object val, Class typeHint) { - if (!(val instanceof Scriptable)) { - return val; + /** @deprecated Use {@link #toPrimitive(Object, Optional)} instead */ + @Deprecated + public static Object toPrimitive(Object input, Class preferredType) { + return toPrimitive(input, Optional.ofNullable(preferredType)); + } + + /* + * 1. If input is an Object, then + * a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive). + * b. If exoticToPrim is not undefined, then + * i. If preferredType is not present, then + * 1. Let hint be "default". + * ii. Else if preferredType is string, then + * 1. Let hint be "string". + * iii. Else, + * 1. Assert: preferredType is number. + * 2. Let hint be "number". + * iv. Let result be ? Call(exoticToPrim, input, « hint »). + * v. If result is not an Object, return result. + * vi. Throw a TypeError exception. + * c. If preferredType is not present, let preferredType be number. + * d. Return ? OrdinaryToPrimitive(input, preferredType). + * 2. Return input. + / + /** + * @param input + * @param preferredType + * @return + * @see + */ + public static Object toPrimitive(Object input, Optional> preferredType) { + if (!isObject(input)) { + return input; } - Scriptable s = (Scriptable) val; - Object result = s.getDefaultValue(typeHint); + final Scriptable s = (Scriptable) input; + final Context cx = Context.getCurrentContext(); + if (cx.getLanguageVersion() >= Context.VERSION_ES6) { + final Object exoticToPrim = ScriptableObject.getProperty(s, SymbolKey.TO_PRIMITIVE); + if (exoticToPrim instanceof Function) { + final Function func = (Function) exoticToPrim; + final Scriptable scope = func.getParentScope(); + final String hint = + preferredType + .map(type -> type == StringClass ? "string" : "number") + .orElse("default"); + final Object[] args = new Object[] {hint}; + final Object result = func.call(cx, scope, s, args); + if (isObject(result)) { + throw typeErrorById("msg.cant.convert.to.primitive"); + } + return result; + } + if (!Undefined.isUndefined(exoticToPrim) + && exoticToPrim != null + && exoticToPrim != Scriptable.NOT_FOUND) { + throw notFunctionError(exoticToPrim); + } + } + final Class defaultValueHint = preferredType.orElse(NumberClass); + final Object result = s.getDefaultValue(defaultValueHint); if ((result instanceof Scriptable) && !isSymbol(result)) throw typeErrorById("msg.bad.default.value"); return result; @@ -3526,6 +3566,8 @@ public static boolean eq(Object x, Object y) { } } return eqNumber(b ? 1.0 : 0.0, y); + } else if (isSymbol(x) && isObject(y)) { + return eq(x, toPrimitive(y)); } else if (x instanceof Scriptable) { if (x instanceof Delegator) { x = ((Delegator) x).getDelegee(); @@ -3540,6 +3582,10 @@ public static boolean eq(Object x, Object y) { return true; } + if (isSymbol(y) && isObject(x)) { + return eq(toPrimitive(x), y); + } + if (y instanceof Scriptable) { if (x instanceof ScriptableObject) { Object test = ((ScriptableObject) x).equivalentValues(y); @@ -3878,18 +3924,32 @@ public static boolean compare(Object val1, Object val2, int op) { if (val1 instanceof Number && val2 instanceof Number) { return compare((Number) val1, (Number) val2, op); } else { - if ((val1 instanceof Symbol) || (val2 instanceof Symbol)) { + if (isSymbol(val1) || isSymbol(val2)) { throw typeErrorById("msg.compare.symbol"); } - if (val1 instanceof Scriptable) { - val1 = ((Scriptable) val1).getDefaultValue(NumberClass); - } - if (val2 instanceof Scriptable) { - val2 = ((Scriptable) val2).getDefaultValue(NumberClass); - } + val1 = toPrimitive(val1, Optional.of(NumberClass)); + val2 = toPrimitive(val2, Optional.of(NumberClass)); if (val1 instanceof CharSequence && val2 instanceof CharSequence) { return compareTo(val1.toString(), val2.toString(), op); } + if (val1 instanceof BigInteger && val2 instanceof CharSequence) { + final BigInteger ny; + try { + ny = toBigInt(val2.toString()); + } catch (EcmaError e) { + return false; + } + return compareTo((BigInteger) val1, ny, op); + } + if (val1 instanceof CharSequence && val2 instanceof BigInteger) { + final BigInteger nx; + try { + nx = toBigInt(val1.toString()); + } catch (EcmaError e) { + return false; + } + return compareTo(nx, (BigInteger) val2, op); + } return compare(toNumeric(val1), toNumeric(val2), op); } } @@ -4593,7 +4653,7 @@ public static Scriptable newObjectLiteral( Object value = propertyValues[i]; if (getterSetter == 0) { - if (id instanceof Symbol) { + if (isSymbol(id)) { Symbol sym = (Symbol) id; SymbolScriptable so = (SymbolScriptable) object; so.put(sym, object, value); diff --git a/rhino/src/main/java/org/mozilla/javascript/Symbol.java b/rhino/src/main/java/org/mozilla/javascript/Symbol.java index 181708401b..8370c58d39 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Symbol.java +++ b/rhino/src/main/java/org/mozilla/javascript/Symbol.java @@ -7,7 +7,7 @@ package org.mozilla.javascript; /** - * A Symbol is a JavaScript objecy that obeys the special properties of the Symbol prototype. This + * A Symbol is a JavaScript object that obeys the special properties of the Symbol prototype. This * interface lets us possibly support multiple implementations of Symbol. * * @since 1.7.8 diff --git a/rhino/src/main/java/org/mozilla/javascript/SymbolKey.java b/rhino/src/main/java/org/mozilla/javascript/SymbolKey.java index 4649777cf2..5547bc10d2 100644 --- a/rhino/src/main/java/org/mozilla/javascript/SymbolKey.java +++ b/rhino/src/main/java/org/mozilla/javascript/SymbolKey.java @@ -12,17 +12,19 @@ public class SymbolKey implements Symbol, Serializable { // These are common SymbolKeys that are equivalent to well-known symbols // defined in ECMAScript. - public static final SymbolKey ITERATOR = new SymbolKey("Symbol.iterator"); - public static final SymbolKey TO_STRING_TAG = new SymbolKey("Symbol.toStringTag"); - public static final SymbolKey SPECIES = new SymbolKey("Symbol.species"); + public static final SymbolKey ASYNC_ITERATOR = new SymbolKey("Symbol.asyncIterator"); public static final SymbolKey HAS_INSTANCE = new SymbolKey("Symbol.hasInstance"); public static final SymbolKey IS_CONCAT_SPREADABLE = new SymbolKey("Symbol.isConcatSpreadable"); public static final SymbolKey IS_REGEXP = new SymbolKey("Symbol.isRegExp"); - public static final SymbolKey TO_PRIMITIVE = new SymbolKey("Symbol.toPrimitive"); + public static final SymbolKey ITERATOR = new SymbolKey("Symbol.iterator"); public static final SymbolKey MATCH = new SymbolKey("Symbol.match"); + public static final SymbolKey MATCH_ALL = new SymbolKey("Symbol.matchAll"); public static final SymbolKey REPLACE = new SymbolKey("Symbol.replace"); public static final SymbolKey SEARCH = new SymbolKey("Symbol.search"); + public static final SymbolKey SPECIES = new SymbolKey("Symbol.species"); public static final SymbolKey SPLIT = new SymbolKey("Symbol.split"); + public static final SymbolKey TO_PRIMITIVE = new SymbolKey("Symbol.toPrimitive"); + public static final SymbolKey TO_STRING_TAG = new SymbolKey("Symbol.toStringTag"); public static final SymbolKey UNSCOPABLES = new SymbolKey("Symbol.unscopables"); private String name; diff --git a/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties b/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties index 642491e89c..003588f044 100644 --- a/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties +++ b/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties @@ -257,6 +257,10 @@ msg.invalid.date =\ msg.toisostring.must.return.primitive =\ toISOString must return a primitive value, but instead returned "{0}" +# NativeSymbol +msg.invalid.toprimitive.hint =\ + [Symbol.toPrimitive]: expected "string", "number", or "default", but got {0} + # NativeJSON msg.json.cant.serialize =\ Do not know how to serialize a {0} @@ -668,6 +672,9 @@ msg.bigint.negative.exponent = \ msg.bigint.out.of.range.arithmetic = \ BigInt is too large. +msg.cant.convert.to.primitive = \ + Cannot convert object to primitive value. + # ScriptableObject msg.default.value =\ Cannot find default value for object. diff --git a/tests/src/test/java/org/mozilla/javascript/tests/Test262SuiteTest.java b/tests/src/test/java/org/mozilla/javascript/tests/Test262SuiteTest.java index aade747ea9..98eccb17b7 100644 --- a/tests/src/test/java/org/mozilla/javascript/tests/Test262SuiteTest.java +++ b/tests/src/test/java/org/mozilla/javascript/tests/Test262SuiteTest.java @@ -112,7 +112,6 @@ public class Test262SuiteTest { "regexp-unicode-property-escapes", "super", "String.prototype.matchAll", - "Symbol.matchAll", "tail-call-optimization", "u180e")); diff --git a/tests/testsrc/test262.properties b/tests/testsrc/test262.properties index 734e5b37e0..0e0263a971 100644 --- a/tests/testsrc/test262.properties +++ b/tests/testsrc/test262.properties @@ -26,7 +26,7 @@ harness 22/115 (19.13%) isConstructor.js {unsupported: [Reflect.construct]} nativeFunctionMatcher.js -built-ins/Array 362/3055 (11.85%) +built-ins/Array 361/3055 (11.82%) fromAsync 94/94 (100.0%) from/calling-from-valid-1-noStrict.js non-strict Spec pretty clearly says this should be undefined from/elements-deleted-after.js Checking to see if length changed, but spec says it should not @@ -134,7 +134,6 @@ built-ins/Array 362/3055 (11.85%) prototype/find/resizable-buffer.js prototype/find/resizable-buffer-grow-mid-iteration.js prototype/find/resizable-buffer-shrink-mid-iteration.js - prototype/flatMap/array-like-objects-poisoned-length.js prototype/flatMap/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/flatMap/proxy-access-count.js prototype/flatMap/target-array-non-extensible.js @@ -361,26 +360,19 @@ built-ins/ArrayIteratorPrototype 1/27 (3.7%) ~built-ins/Atomics -built-ins/BigInt 21/75 (28.0%) +built-ins/BigInt 14/75 (18.67%) asIntN/bigint-tobigint-errors.js - asIntN/bigint-tobigint-toprimitive.js - asIntN/bigint-tobigint-wrapped-values.js asIntN/bits-toindex-errors.js - asIntN/bits-toindex-toprimitive.js asIntN/bits-toindex-wrapped-values.js asIntN/not-a-constructor.js {unsupported: [Reflect.construct]} asUintN/bigint-tobigint-errors.js - asUintN/bigint-tobigint-toprimitive.js - asUintN/bigint-tobigint-wrapped-values.js asUintN/bits-toindex-errors.js - asUintN/bits-toindex-toprimitive.js asUintN/bits-toindex-wrapped-values.js asUintN/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/toLocaleString/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/toString/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/toString/prototype-call.js Check IsInteger in ES2020, not IsSafeInteger, https://github.com/tc39/test262/commit/bf1b79d65a760a5f03df1198557da2d010f8f397#diff-3ecd6a0c50da5c8f8eff723afb6182a889b7315d99545b055559e22d302cc453 prototype/valueOf/not-a-constructor.js {unsupported: [Reflect.construct]} - constructor-coercion.js is-a-constructor.js {unsupported: [Reflect.construct]} wrapper-object-ordinary-toprimitive.js @@ -645,7 +637,7 @@ built-ins/DataView 254/550 (46.18%) toindex-bytelength-sab.js {unsupported: [SharedArrayBuffer]} toindex-byteoffset-sab.js {unsupported: [SharedArrayBuffer]} -built-ins/Date 90/770 (11.69%) +built-ins/Date 68/770 (8.83%) now/not-a-constructor.js {unsupported: [Reflect.construct]} parse/not-a-constructor.js {unsupported: [Reflect.construct]} parse/year-zero.js @@ -683,18 +675,7 @@ built-ins/Date 90/770 (11.69%) prototype/setUTCMinutes/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/setUTCMonth/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/setUTCSeconds/not-a-constructor.js {unsupported: [Reflect.construct]} - prototype/Symbol.toPrimitive/hint-default-first-invalid.js - prototype/Symbol.toPrimitive/hint-default-first-non-callable.js - prototype/Symbol.toPrimitive/hint-default-first-valid.js - prototype/Symbol.toPrimitive/hint-invalid.js - prototype/Symbol.toPrimitive/hint-number-first-invalid.js - prototype/Symbol.toPrimitive/hint-number-first-non-callable.js - prototype/Symbol.toPrimitive/hint-number-first-valid.js - prototype/Symbol.toPrimitive/hint-string-first-invalid.js - prototype/Symbol.toPrimitive/hint-string-first-non-callable.js - prototype/Symbol.toPrimitive/hint-string-first-valid.js - prototype/Symbol.toPrimitive/length.js - prototype/Symbol.toPrimitive/name.js + prototype/Symbol.toPrimitive/called-as-function.js prototype/Symbol.toPrimitive/prop-desc.js prototype/Symbol.toPrimitive/this-val-non-obj.js prototype/toDateString/not-a-constructor.js {unsupported: [Reflect.construct]} @@ -724,17 +705,6 @@ built-ins/Date 90/770 (11.69%) proto-from-ctor-realm-two.js {unsupported: [Reflect]} proto-from-ctor-realm-zero.js {unsupported: [Reflect]} subclassing.js {unsupported: [Reflect]} - value-get-symbol-to-prim-err.js - value-symbol-to-prim-err.js - value-symbol-to-prim-invocation.js - value-symbol-to-prim-return-obj.js - value-symbol-to-prim-return-prim.js - value-to-primitive-call.js - value-to-primitive-call-err.js - value-to-primitive-get-meth-err.js - value-to-primitive-result-faulty.js - value-to-primitive-result-non-string-prim.js - value-to-primitive-result-string.js year-zero.js built-ins/Error 6/41 (14.63%) @@ -1098,7 +1068,7 @@ built-ins/Number 24/335 (7.16%) S9.3.1_A3_T1_U180E.js {unsupported: [u180e]} S9.3.1_A3_T2_U180E.js {unsupported: [u180e]} -built-ins/Object 218/3403 (6.41%) +built-ins/Object 217/3403 (6.38%) assign/assignment-to-readonly-property-of-target-must-throw-a-typeerror-exception.js assign/not-a-constructor.js {unsupported: [Reflect.construct]} assign/source-own-prop-desc-missing.js {unsupported: [Proxy]} @@ -1163,7 +1133,6 @@ built-ins/Object 218/3403 (6.41%) freeze/proxy-with-defineProperty-handler.js {unsupported: [Proxy, Reflect]} freeze/throws-when-false.js fromEntries/not-a-constructor.js {unsupported: [Reflect.construct]} - fromEntries/to-property-key.js fromEntries/uses-keys-not-iterator.js getOwnPropertyDescriptors/not-a-constructor.js {unsupported: [Reflect.construct]} getOwnPropertyDescriptors/observable-operations.js {unsupported: [Proxy]} @@ -1739,7 +1708,7 @@ built-ins/Promise 429/631 (67.99%) ~built-ins/Reflect -built-ins/RegExp 1169/1853 (63.09%) +built-ins/RegExp 1166/1853 (62.92%) CharacterClassEscapes 24/24 (100.0%) dotall 4/4 (100.0%) escape 20/20 (100.0%) @@ -1818,7 +1787,29 @@ built-ins/RegExp 1169/1853 (63.09%) prototype/sticky/name.js prototype/sticky/prop-desc.js prototype/sticky/this-val-regexp-prototype.js - prototype/Symbol.matchAll 26/26 (100.0%) + prototype/Symbol.matchAll/isregexp-called-once.js + prototype/Symbol.matchAll/isregexp-this-throws.js + prototype/Symbol.matchAll/length.js + prototype/Symbol.matchAll/name.js + prototype/Symbol.matchAll/not-a-constructor.js {unsupported: [Reflect.construct]} + prototype/Symbol.matchAll/prop-desc.js + prototype/Symbol.matchAll/regexpcreate-this-throws.js + prototype/Symbol.matchAll/species-constructor.js + prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js + prototype/Symbol.matchAll/species-constructor-get-species-throws.js + prototype/Symbol.matchAll/species-constructor-is-undefined.js + prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js + prototype/Symbol.matchAll/species-constructor-species-throws.js + prototype/Symbol.matchAll/species-regexp-get-global-throws.js + prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js + prototype/Symbol.matchAll/string-tostring.js + prototype/Symbol.matchAll/string-tostring-throws.js + prototype/Symbol.matchAll/this-get-flags.js + prototype/Symbol.matchAll/this-get-flags-throws.js + prototype/Symbol.matchAll/this-lastindex-cached.js + prototype/Symbol.matchAll/this-tolength-lastindex-throws.js + prototype/Symbol.matchAll/this-tostring-flags.js + prototype/Symbol.matchAll/this-tostring-flags-throws.js prototype/Symbol.match/builtin-infer-unicode.js prototype/Symbol.match/builtin-success-g-set-lastindex.js prototype/Symbol.match/builtin-success-g-set-lastindex-err.js @@ -2188,7 +2179,7 @@ built-ins/SetIteratorPrototype 0/11 (0.0%) ~built-ins/SharedArrayBuffer -built-ins/String 140/1182 (11.84%) +built-ins/String 128/1182 (10.83%) fromCharCode/not-a-constructor.js {unsupported: [Reflect.construct]} fromCodePoint/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/charAt/not-a-constructor.js {unsupported: [Reflect.construct]} @@ -2200,13 +2191,8 @@ built-ins/String 140/1182 (11.84%) prototype/includes/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/includes/return-abrupt-from-searchstring-regexp-test.js prototype/indexOf/not-a-constructor.js {unsupported: [Reflect.construct]} - prototype/indexOf/position-tointeger-bigint.js prototype/indexOf/position-tointeger-errors.js - prototype/indexOf/position-tointeger-toprimitive.js prototype/indexOf/position-tointeger-wrapped-values.js - prototype/indexOf/searchstring-tostring-bigint.js - prototype/indexOf/searchstring-tostring-errors.js - prototype/indexOf/searchstring-tostring-toprimitive.js prototype/indexOf/searchstring-tostring-wrapped-values.js prototype/isWellFormed 8/8 (100.0%) prototype/lastIndexOf/not-a-constructor.js {unsupported: [Reflect.construct]} @@ -2228,7 +2214,6 @@ built-ins/String 140/1182 (11.84%) prototype/replaceAll/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/replaceAll/replaceValue-call-each-match-position.js prototype/replaceAll/replaceValue-call-matching-empty.js - prototype/replaceAll/replaceValue-value-tostring.js prototype/replaceAll/searchValue-flags-no-g-throws.js prototype/replaceAll/searchValue-flags-null-undefined-throws.js prototype/replaceAll/searchValue-flags-toString-abrupt.js @@ -2241,7 +2226,6 @@ built-ins/String 140/1182 (11.84%) prototype/replaceAll/searchValue-replacer-RegExp-call.js {unsupported: [class]} prototype/replaceAll/searchValue-replacer-RegExp-call-fn.js {unsupported: [class]} prototype/replaceAll/searchValue-tostring-regexp.js - prototype/replaceAll/this-tostring.js prototype/replace/cstm-replace-get-err.js prototype/replace/cstm-replace-invocation.js prototype/replace/not-a-constructor.js {unsupported: [Reflect.construct]} @@ -2254,7 +2238,6 @@ built-ins/String 140/1182 (11.84%) prototype/slice/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/split/cstm-split-get-err.js prototype/split/cstm-split-invocation.js - prototype/split/limit-touint32-error.js prototype/split/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/split/separator-regexp.js prototype/split/separator-tostring-error.js @@ -2277,16 +2260,12 @@ built-ins/String 140/1182 (11.84%) prototype/toWellFormed 8/8 (100.0%) prototype/trimEnd/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/trimEnd/this-value-object-toprimitive-call-err.js - prototype/trimEnd/this-value-object-toprimitive-meth-err.js prototype/trimEnd/this-value-object-toprimitive-meth-priority.js - prototype/trimEnd/this-value-object-toprimitive-returns-object-err.js prototype/trimEnd/this-value-object-tostring-meth-priority.js prototype/trimEnd/this-value-object-valueof-meth-priority.js prototype/trimStart/not-a-constructor.js {unsupported: [Reflect.construct]} prototype/trimStart/this-value-object-toprimitive-call-err.js - prototype/trimStart/this-value-object-toprimitive-meth-err.js prototype/trimStart/this-value-object-toprimitive-meth-priority.js - prototype/trimStart/this-value-object-toprimitive-returns-object-err.js prototype/trimStart/this-value-object-tostring-meth-priority.js prototype/trimStart/this-value-object-valueof-meth-priority.js prototype/trim/not-a-constructor.js {unsupported: [Reflect.construct]} @@ -2299,8 +2278,8 @@ built-ins/String 140/1182 (11.84%) built-ins/StringIteratorPrototype 0/7 (0.0%) -built-ins/Symbol 34/92 (36.96%) - asyncIterator/prop-desc.js +built-ins/Symbol 32/92 (34.78%) + asyncIterator/cross-realm.js for/cross-realm.js for/description.js for/not-a-constructor.js {unsupported: [Reflect.construct]} @@ -2310,7 +2289,7 @@ built-ins/Symbol 34/92 (36.96%) keyFor/arg-non-symbol.js keyFor/cross-realm.js keyFor/not-a-constructor.js {unsupported: [Reflect.construct]} - matchAll 2/2 (100.0%) + matchAll/cross-realm.js match/cross-realm.js prototype/description/description-symboldescriptivestring.js prototype/description/descriptor.js @@ -2318,7 +2297,6 @@ built-ins/Symbol 34/92 (36.96%) prototype/description/this-val-non-symbol.js prototype/description/this-val-symbol.js prototype/description/wrapper.js - prototype/Symbol.toPrimitive/name.js prototype/Symbol.toPrimitive/prop-desc.js prototype/Symbol.toPrimitive/redefined-symbol-wrapper-ordinary-toprimitive.js prototype/Symbol.toPrimitive/removed-symbol-wrapper-ordinary-toprimitive.js @@ -2925,7 +2903,7 @@ built-ins/TypedArray 1053/1386 (75.97%) name.js prototype.js -built-ins/TypedArrayConstructors 582/721 (80.72%) +built-ins/TypedArrayConstructors 580/721 (80.44%) BigInt64Array/prototype 4/4 (100.0%) BigInt64Array 8/8 (100.0%) BigUint64Array/prototype 4/4 (100.0%) @@ -2996,8 +2974,6 @@ built-ins/TypedArrayConstructors 582/721 (80.72%) ctors/object-arg/proto-from-ctor-realm.js {unsupported: [Reflect]} ctors/object-arg/returns.js ctors/object-arg/throws-from-property.js - ctors/object-arg/throws-setting-obj-to-primitive.js - ctors/object-arg/throws-setting-obj-to-primitive-typeerror.js ctors/object-arg/throws-setting-property.js ctors/object-arg/throws-setting-symbol-property.js ctors/object-arg/use-custom-proto-if-object.js {unsupported: [Reflect]} @@ -3245,25 +3221,13 @@ built-ins/eval 3/10 (30.0%) built-ins/global 0/29 (0.0%) -built-ins/isFinite 8/17 (47.06%) +built-ins/isFinite 2/17 (11.76%) length.js not-a-constructor.js {unsupported: [Reflect.construct]} - toprimitive-call-abrupt.js - toprimitive-get-abrupt.js - toprimitive-not-callable-throws.js - toprimitive-result-is-object-throws.js - toprimitive-result-is-symbol-throws.js - toprimitive-valid-result.js - -built-ins/isNaN 8/17 (47.06%) + +built-ins/isNaN 2/17 (11.76%) length.js not-a-constructor.js {unsupported: [Reflect.construct]} - toprimitive-call-abrupt.js - toprimitive-get-abrupt.js - toprimitive-not-callable-throws.js - toprimitive-result-is-object-throws.js - toprimitive-result-is-symbol-throws.js - toprimitive-valid-result.js built-ins/parseFloat 3/59 (5.08%) not-a-constructor.js {unsupported: [Reflect.construct]} @@ -3859,15 +3823,8 @@ language/eval-code 257/347 (74.06%) ~language/export -language/expressions/addition 9/48 (18.75%) +language/expressions/addition 2/48 (4.17%) bigint-errors.js - bigint-toprimitive.js - bigint-wrapped-values.js - coerce-symbol-to-prim-err.js - coerce-symbol-to-prim-invocation.js - coerce-symbol-to-prim-return-obj.js - coerce-symbol-to-prim-return-prim.js - get-symbol-to-prim-err.js order-of-evaluation.js language/expressions/array 41/52 (78.85%) @@ -4385,25 +4342,15 @@ language/expressions/async-arrow-function 44/60 (73.33%) ~language/expressions/await -language/expressions/bitwise-and 4/30 (13.33%) - bigint-non-primitive.js - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/bitwise-and 1/30 (3.33%) order-of-evaluation.js -language/expressions/bitwise-not 1/16 (6.25%) - bigint-non-primitive.js +language/expressions/bitwise-not 0/16 (0.0%) -language/expressions/bitwise-or 4/30 (13.33%) - bigint-non-primitive.js - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/bitwise-or 1/30 (3.33%) order-of-evaluation.js -language/expressions/bitwise-xor 4/30 (13.33%) - bigint-non-primitive.js - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/bitwise-xor 1/30 (3.33%) order-of-evaluation.js language/expressions/call 60/92 (65.22%) @@ -4628,26 +4575,16 @@ language/expressions/delete 5/67 (7.46%) super-property-method.js {unsupported: [class]} super-property-null-base.js {unsupported: [class]} -language/expressions/division 3/45 (6.67%) - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/division 1/45 (2.22%) order-of-evaluation.js language/expressions/does-not-equals 0/38 (0.0%) ~language/expressions/dynamic-import -language/expressions/equals 6/47 (12.77%) - coerce-symbol-to-prim-err.js - coerce-symbol-to-prim-invocation.js - coerce-symbol-to-prim-return-obj.js - coerce-symbol-to-prim-return-prim.js - get-symbol-to-prim-err.js - to-prim-hint.js +language/expressions/equals 0/47 (0.0%) -language/expressions/exponentiation 3/44 (6.82%) - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/exponentiation 1/44 (2.27%) order-of-evaluation.js language/expressions/function 214/264 (81.06%) @@ -5096,12 +5033,9 @@ language/expressions/generators 232/290 (80.0%) yield-star-after-newline.js yield-star-before-newline.js -language/expressions/greater-than 2/49 (4.08%) - bigint-and-incomparable-string.js - bigint-and-string.js +language/expressions/greater-than 0/49 (0.0%) -language/expressions/greater-than-or-equal 1/43 (2.33%) - bigint-and-incomparable-string.js +language/expressions/greater-than-or-equal 0/43 (0.0%) language/expressions/grouping 0/9 (0.0%) @@ -5138,18 +5072,12 @@ language/expressions/instanceof 7/43 (16.28%) symbol-hasinstance-not-callable.js symbol-hasinstance-to-boolean.js -language/expressions/left-shift 4/45 (8.89%) - bigint-non-primitive.js - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/left-shift 1/45 (2.22%) order-of-evaluation.js -language/expressions/less-than 1/45 (2.22%) - bigint-and-incomparable-string.js +language/expressions/less-than 0/45 (0.0%) -language/expressions/less-than-or-equal 2/47 (4.26%) - bigint-and-incomparable-string.js - bigint-and-string.js +language/expressions/less-than-or-equal 0/47 (0.0%) language/expressions/logical-and 1/18 (5.56%) tco-right.js {unsupported: [tail-call-optimization]} @@ -5216,14 +5144,10 @@ language/expressions/logical-not 0/19 (0.0%) language/expressions/logical-or 1/18 (5.56%) tco-right.js {unsupported: [tail-call-optimization]} -language/expressions/modulus 3/40 (7.5%) - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/modulus 1/40 (2.5%) order-of-evaluation.js -language/expressions/multiplication 3/40 (7.5%) - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/multiplication 1/40 (2.5%) order-of-evaluation.js language/expressions/new 41/59 (69.49%) @@ -6189,19 +6113,14 @@ language/expressions/property-accessors 0/21 (0.0%) language/expressions/relational 0/1 (0.0%) -language/expressions/right-shift 4/37 (10.81%) - bigint-non-primitive.js - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/right-shift 1/37 (2.7%) order-of-evaluation.js language/expressions/strict-does-not-equals 0/30 (0.0%) language/expressions/strict-equals 0/30 (0.0%) -language/expressions/subtraction 3/38 (7.89%) - bigint-toprimitive.js - bigint-wrapped-values.js +language/expressions/subtraction 1/38 (2.63%) order-of-evaluation.js ~language/expressions/super @@ -6221,13 +6140,11 @@ language/expressions/typeof 2/16 (12.5%) built-in-ordinary-objects-no-call.js proxy.js {unsupported: [Proxy]} -language/expressions/unary-minus 1/14 (7.14%) - bigint-non-primitive.js +language/expressions/unary-minus 0/14 (0.0%) language/expressions/unary-plus 0/17 (0.0%) -language/expressions/unsigned-right-shift 3/45 (6.67%) - bigint-non-primitive.js +language/expressions/unsigned-right-shift 2/45 (4.44%) bigint-toprimitive.js order-of-evaluation.js