From 962c14a49c0899e91067c2bbabc1164de5614f3e Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Thu, 24 Sep 2026 23:46:15 -0500 Subject: [PATCH] fix(codemode): honor thisArg, program toString in computed keys, and ToPrimitive in String and Number arguments (#51264) --- packages/codemode/interpreter-support.md | 46 ++- packages/codemode/src/interpreter/callback.ts | 13 +- .../codemode/src/interpreter/interpreter.ts | 40 ++- packages/codemode/src/stdlib/array.ts | 13 +- packages/codemode/src/stdlib/collections.ts | 4 +- packages/codemode/src/stdlib/headers.ts | 2 +- packages/codemode/src/stdlib/number.ts | 47 ++- packages/codemode/src/stdlib/string.ts | 315 +++++++++++------- packages/codemode/src/stdlib/url.ts | 2 +- packages/codemode/test/parity.test.ts | 199 +++++++++++ packages/codemode/test/test262/skipped.txt | 172 ---------- 11 files changed, 496 insertions(+), 357 deletions(-) diff --git a/packages/codemode/interpreter-support.md b/packages/codemode/interpreter-support.md index 33e298eea74..7b3e5b23c58 100644 --- a/packages/codemode/interpreter-support.md +++ b/packages/codemode/interpreter-support.md @@ -131,7 +131,7 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262 - [x] Built-in method references as callbacks, such as `values.map(Math.abs)`, `records.map(JSON.stringify)`, `items.forEach(console.log)`, and `Promise.resolve(-1).then(Math.abs)`. Extra callback arguments a built-in does not consume are ignored, like JS, and consumed arguments coerce, like JS (`"3.7".replace(/\d\.\d/, - Math.floor)` is `"3"`). A detached method loses its receiver, as in JS: `values.filter("abc".includes)` is a `TypeError` +Math.floor)` is `"3"`). A detached method loses its receiver, as in JS: `values.filter("abc".includes)` is a `TypeError` because `includes` is called without a string `this`. - [x] Constructors work as callbacks with JS call semantics: `Error` types construct (`messages.map(Error)`), and new-requiring constructors (`Map`, `Set`, `URL`, `URLSearchParams`, `Headers`, `Promise`) throw a `TypeError`, @@ -155,8 +155,9 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262 array, an array-like object (its `length` clamped and capped like `Array.from`), or `null`/`undefined`. A bound function is named `bound f`, has its remaining `length`, and is not constructible. - [x] `JSON.parse` revivers and `JSON.stringify` function replacers see the holder object as `this`. -- [ ] The optional `thisArg` of iteration methods (`map`, `forEach`, `Map.prototype.forEach`, `Array.from`, …) is - accepted but not yet passed as `this`; callbacks run with `this` undefined. +- [x] The optional `thisArg` of the Array, Uint8Array, and `Array.from` callback methods and of Map, Set, + URLSearchParams, and Headers `forEach` is the callback's `this`: `[1, 2].forEach(function () { this.n++ }, c)` + increments `c.n` twice. Arrows ignore it, as in JS; `reduce`/`reduceRight` take an initial value instead. - [ ] User-defined constructor calls. - [ ] Classes and private fields. - [x] Functions are objects: they hold own properties (`fn.count = 1`), enumerate them, and expose read-only `name` @@ -241,11 +242,19 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262 throws: `{ valueOf() { return 7 } } * 2` is `14`, `` `${{ toString() { return "x" } }}` `` is `"x"`, and `[1, 2]` with `arr.toString = () => "x"` makes `arr + ""` `"x"`. Dates keep their `Symbol.toPrimitive` behavior (`date + 1` concatenates, `date - date` subtracts). -- [ ] ToPrimitive elsewhere: `Error.prototype.toString` on an object `message` and numeric built-in arguments outside - `Math` and `Date` (`at`, `indexOf` start, `toFixed` digits) still use the built-in form (`NaN`, - `"[object Object]"`) and ignore own methods. -- [x] Property keys follow ToPropertyKey: `x[null]`, `x[true]`, and objects (via their built-in string form) become - string keys. +- [x] String and Number method arguments convert through ToPrimitive in spec order, receiver first: search strings, + separators, fills, and replacements with the string hint, indexes, counts, digits, and radixes with the number + hint (`"abc".indexOf({ toString() { return "b" } })` is `1`, `(255).toString({ valueOf() { return 16 } })` is + `"ff"`, `String.prototype.trim.call({ toString() { return " a " } })` is `"a"`). Only consumed positions + convert; a RegExp pattern is used as is, and `includes`/`startsWith`/`endsWith` reject one before converting. +- [ ] ToPrimitive elsewhere: `Error.prototype.toString` on an object `message` and numeric arguments of the Array and + Uint8Array methods (`at`, `indexOf` start, `slice`) still use the built-in form (`NaN`, `"[object Object]"`) and + ignore own methods. +- [x] Property keys follow ToPropertyKey: `x[null]` and `x[true]` become string keys, and a data object key + converts through its own `toString`/`valueOf` (string hint) exactly once per access, in reads, writes, + compound assignment, `++`, `delete`, `in`, object literals, and destructuring: + `o[{ toString() { return "id" } }] += 1` updates `o.id`. A nullish base throws before the key converts, as + in JS. Opaque values (functions, promises, tool references) keep their built-in string form. ## Promises and tools @@ -306,8 +315,9 @@ reject }` object. - [x] `Object()` and `new Object()` return `{}` for nullish arguments and pass objects through unchanged; primitive wrapper objects (`Object(1)`) are rejected explicitly. - [x] Computed property names and object spread. Any value works as a key (ToPropertyKey): strings, numbers, and the - two confined symbols as themselves, everything else as its string form (`o[null]` is `o["null"]`, `o[{}]` is - `o["[object Object]"]`), in reads, writes, literals, `in`, and destructuring. + two confined symbols as themselves, data objects through their own `toString` (`o[[1, 2]]` is `o["1,2"]`), and + everything else as its string form (`o[null]` is `o["null"]`), in reads, writes, literals, `in`, and + destructuring. - [x] `Object.keys`, `Object.values`, `Object.entries`, `Object.hasOwn`, `Object.assign`, and `Object.fromEntries`, with synchronous iterator support for `fromEntries`. Sources follow ToObject: strings enumerate by index, other primitives and wrappers contribute nothing, and `null`/`undefined` throw. `Object.assign` accepts array @@ -368,7 +378,6 @@ reject }` object. shares one prototype, where JavaScript gives each collection its own; `Object.getPrototypeOf` shows the difference. - [x] `length`, numeric indexing, index assignment, spread, and `for...of`. -- [x] The `thisArg` argument of `Array.from` is accepted and ignored, like JS arrows. - [x] `Array.prototype.toSpliced`. - [x] Canonical array/string index parsing: keys such as `"01"` are ordinary properties rather than aliases of index `1`. @@ -381,9 +390,9 @@ reject }` object. `flat(1.9)`, `with(1.5, v)`, `Math.max("3", "2")`, `parseInt("11", "2")`, `(1.5).toFixed("2")`, `String.fromCharCode("65")`, and the Uint8Array equivalents. `join(sep)` and `JSON.parse(text)` apply ToString (`join(null)` is `"1null2"`, `JSON.parse(123)` is `123`). `Array.from({ length: "2" })` applies ToLength; a - promise source still throws with an `await` hint rather than JS's silent `[]`. `join`, `Math.*`, and - `parseInt` consult a program object's own `valueOf`/`toString`; the array and number methods do not yet (see - ToPrimitive above). + promise source still throws with an `await` hint rather than JS's silent `[]`. `join`, `Math.*`, `parseInt`, + and the String and Number methods consult a program object's own `valueOf`/`toString`; the array methods do not + yet (see ToPrimitive above). ## Strings @@ -400,14 +409,15 @@ reject }` object. - [x] Static `String.fromCharCode` and `String.fromCodePoint`. - [x] Native argument coercion for supported String methods; for example, `includes(1)` and `slice("1")` coerce like native JS, `split(undefined)` returns the whole string, and `includes`/`startsWith`/`endsWith` reject regular - expressions with a native-style `TypeError`. Opaque runtime references still reject as data errors, and - `repeat` still requires a finite non-negative count. + expressions with a native-style `TypeError`. Data objects convert through their own `toString`/`valueOf` (see + ToPrimitive above). Opaque runtime references still reject as data errors, and `repeat` still requires a finite + non-negative count. - [x] Native no-argument parity for `match()`, `matchAll()`, and `search()`; all behave as an empty pattern. - [x] `String.raw`, on a template object or any `{ raw }` object; raw strings and substitutions coerce through their own `toString`. - [x] `match`, `matchAll`, `search`, and `split` read any non-RegExp argument as a pattern string, as `new RegExp(arg)` - would: `"a1b".match(1)` matches `/1/`, `search(null)` looks for `"null"`, and `undefined` is the empty pattern. - Objects use their built-in string form until ToPrimitive lands. + would: `"a1b".match(1)` matches `/1/`, `search(null)` looks for `"null"`, `undefined` is the empty pattern, and + an object supplies its own `toString`. ## Numbers and Math diff --git a/packages/codemode/src/interpreter/callback.ts b/packages/codemode/src/interpreter/callback.ts index 8147c9c2deb..43d0b660ebf 100644 --- a/packages/codemode/src/interpreter/callback.ts +++ b/packages/codemode/src/interpreter/callback.ts @@ -67,21 +67,24 @@ export const toPrimitiveNumber = (ctx: Interpreter, value: Value) => Effect.map(toPrimitive(ctx, value, "number"), coerceToNumber) /** - * Runs a synchronous native body on its arguments after ToPrimitive, in order, with one hint for all positions or - * one per position. Primitive arguments skip the Effect entirely. + * Runs a native body on its arguments after ToPrimitive, in order, with one hint for all positions or one per + * position. Primitive arguments skip the Effect entirely. */ export const withPrimitives = ( ctx: Interpreter, hints: Hint | ReadonlyArray, values: Array, - body: (primitives: Array) => Value, + body: (primitives: Array) => Value | Effect.Effect, ): Value | Effect.Effect => { if (!values.some((value) => value instanceof Obj)) return body(values) - return Effect.map( + return Effect.flatMap( Effect.forEach(values, (value, index) => toPrimitive(ctx, value, typeof hints === "string" ? hints : hints[index]!), ), - body, + (primitives) => { + const result = body(primitives) + return Effect.isEffect(result) ? result : Effect.succeed(result) + }, ) } diff --git a/packages/codemode/src/interpreter/interpreter.ts b/packages/codemode/src/interpreter/interpreter.ts index bec9efa4eb3..b60ab8404a9 100644 --- a/packages/codemode/src/interpreter/interpreter.ts +++ b/packages/codemode/src/interpreter/interpreter.ts @@ -123,6 +123,10 @@ const primitiveOperators = new Set([ ">>>", ]) +/** ToPropertyKey on a primitive (or an opaque value, which keeps its built-in string form). */ +const propertyKey = (value: Value): PropertyKey => + typeof value === "string" || typeof value === "number" || typeof value === "symbol" ? value : coerceToString(value) + // What a loop does with its body's result: exit with a StatementResult, or undefined to keep iterating. // Unlabelled break ends this loop; a label the loop does not carry propagates outward. const loopExit = (result: StatementResult, labels: ReadonlySet | undefined): StatementResult | undefined => { @@ -1277,7 +1281,7 @@ class Frame { } const keyNode = property.key if (property.computed) { - return Effect.map(this.evaluateExpression(keyNode), (value) => this.toPropertyKey(value)) + return Effect.flatMap(this.evaluateExpression(keyNode), (value) => this.toPropertyKey(value, keyNode)) } if (keyNode.type === "Identifier") return Effect.succeed(keyNode.name) if (keyNode.type === "Literal") return Effect.succeed(String(keyNode.value)) @@ -1400,6 +1404,10 @@ class Frame { // IsLooselyEqual converts only an object facing a non-nullish primitive; two objects (including tool // references, which are not Obj) compare by identity. const equality = operator === "==" || operator === "!=" + // `in` checks the right operand before ToPropertyKey on the left, so a bad right side wins over a bad key. + if (operator === "in" && lhs instanceof Obj && !isOpaque(lhs) && rhs instanceof Obj) { + return Effect.map(this.toPropertyKey(lhs, node), (key) => has(rhs, key)) + } const other = lhs instanceof Obj ? rhs : lhs const converts = primitiveOperators.has(operator) || @@ -1419,9 +1427,7 @@ class Frame { if (operator === "!==") return lhs !== rhs if (operator === "==") return this.looselyEqual(lhs, rhs, node) if (operator === "!=") return !this.looselyEqual(lhs, rhs, node) - if (operator === "in" && rhs instanceof Obj && !isOpaque(lhs)) { - return has(rhs, lhs !== null && typeof lhs === "object" ? coerceToString(lhs) : (lhs as PropertyKey)) - } + if (operator === "in" && rhs instanceof Obj && !isOpaque(lhs)) return has(rhs, propertyKey(lhs)) if (isOpaque(lhs) || isOpaque(rhs)) { throw invalidData("Binary operators require data values.", node) } @@ -2046,11 +2052,11 @@ class Frame { let key: PropertyKey if (property.computed) { - key = self.toPropertyKey(yield* self.evaluateExpression(keyNode)) + key = yield* self.toPropertyKey(yield* self.evaluateExpression(keyNode), keyNode) } else if (keyNode.type === "Identifier") { key = keyNode.name } else if (keyNode.type === "Literal") { - key = self.toPropertyKey(literal(keyNode)) + key = propertyKey(literal(keyNode)) } else { throw typeError("Unsupported object property key shape.", keyNode) } @@ -2178,11 +2184,16 @@ class Frame { if (objectValue === OptionalShortCircuit) return OptionalShortCircuit if ((objectValue === null || objectValue === undefined) && node.optional) return OptionalShortCircuit - const key = node.computed - ? self.toPropertyKey(yield* self.evaluateExpression(propertyNode)) - : propertyNode.type === "Identifier" + const keyValue = + !node.computed && propertyNode.type === "Identifier" ? propertyNode.name - : self.toPropertyKey(yield* self.evaluateExpression(propertyNode)) + : yield* self.evaluateExpression(propertyNode) + // GetValue applies ToObject to the base before ToPropertyKey, so a nullish base throws before the key's own + // toString runs. + if (objectValue === null || objectValue === undefined) { + throw typeError(`Cannot read properties of ${objectValue} (reading '${coerceToString(keyValue)}').`, objectNode) + } + const key = yield* self.toPropertyKey(keyValue, propertyNode) return self.resolveProperty(objectValue, key, objectNode, propertyNode) }) } @@ -2314,9 +2325,10 @@ class Frame { throw typeError(`Cannot assign to read only property '${String(key)}'.`, node) } - // ToPropertyKey: anything else becomes its string form, so `counts[row.category]` works when the field is null. - private toPropertyKey(value: Value): PropertyKey { - if (typeof value === "string" || typeof value === "number" || typeof value === "symbol") return value - return coerceToString(value) + // ToPropertyKey: a data object converts through its own `toString`/`valueOf` first; anything else becomes its + // string form synchronously, so `counts[row.category]` works when the field is null. + private toPropertyKey(value: Value, node: AstNode): Effect.Effect { + if (!(value instanceof Obj)) return Effect.succeed(propertyKey(value)) + return Effect.map(this.toPrimitive(value, "string", node), propertyKey) } } diff --git a/packages/codemode/src/stdlib/array.ts b/packages/codemode/src/stdlib/array.ts index a613de2f779..6f483a50820 100644 --- a/packages/codemode/src/stdlib/array.ts +++ b/packages/codemode/src/stdlib/array.ts @@ -49,7 +49,7 @@ const arrayFrom = (ctx: Interpreter, args: Array): Effect.Effect = [] for (let index = 0; index < arrayLike.length; index += 1) { const item = get(arrayLike.source, index) - values.push(apply === undefined ? item : yield* apply([item, index])) + values.push(apply === undefined ? item : yield* apply([item, index], args[2])) } return new Arr(proto, values) } @@ -59,7 +59,9 @@ const arrayFrom = (ctx: Interpreter, args: Array): Effect.Effect(ctx: Interpreter) => { const values: Array = [] for (let index = 0; index < length; index += 1) { if (!(index in target.items)) continue - const mapped = yield* apply([target.items[index], index, target]) + const mapped = yield* apply([target.items[index], index, target], args[1]) if (mapped instanceof Arr) values.push(...mapped.items) else values.push(mapped) } @@ -411,7 +413,10 @@ export const callbackMethods = ( length, (thisValue, args) => { const target = self(thisValue, name) - return body(elements(target), target, applyCollectionCallback(ctx, args[0], `${label}.${name}`), args) + const call = applyCollectionCallback(ctx, args[0], `${label}.${name}`) + // reduce and reduceRight take an initial value where the others take a thisArg. + const thisArg = name.startsWith("reduce") ? undefined : args[1] + return body(elements(target), target, (callbackArgs) => call(callbackArgs, thisArg), args) }, ] return [ diff --git a/packages/codemode/src/stdlib/collections.ts b/packages/codemode/src/stdlib/collections.ts index fa78199d8e0..5defb53d72b 100644 --- a/packages/codemode/src/stdlib/collections.ts +++ b/packages/codemode/src/stdlib/collections.ts @@ -188,7 +188,7 @@ export const mapGlobal = (ctx: Interpreter) => { const target = self(thisValue, "forEach") const apply = applyCollectionCallback(ctx, args[0], "Map.forEach") return Effect.gen(function* () { - for (const [key, item] of target.map.entries()) yield* apply([item, key, target]) + for (const [key, item] of target.map.entries()) yield* apply([item, key, target], args[1]) return undefined }) }, @@ -386,7 +386,7 @@ export const setGlobal = (ctx: Interpreter) => { const target = self(thisValue, "forEach") const apply = applyCollectionCallback(ctx, args[0], "Set.forEach") return Effect.gen(function* () { - for (const item of target.set.values()) yield* apply([item, item, target]) + for (const item of target.set.values()) yield* apply([item, item, target], args[1]) return undefined }) }, diff --git a/packages/codemode/src/stdlib/headers.ts b/packages/codemode/src/stdlib/headers.ts index 96ed8f5216c..e2ac6e72264 100644 --- a/packages/codemode/src/stdlib/headers.ts +++ b/packages/codemode/src/stdlib/headers.ts @@ -117,7 +117,7 @@ export const headersGlobal = (ctx: Interpreter) => { const target = self(thisValue, "forEach") const apply = applyCollectionCallback(ctx, args[0], "Headers.forEach") return Effect.gen(function* () { - for (const [key, value] of Array.from(target.headers.entries())) yield* apply([value, key, target]) + for (const [key, value] of Array.from(target.headers.entries())) yield* apply([value, key, target], args[1]) return undefined }) }, diff --git a/packages/codemode/src/stdlib/number.ts b/packages/codemode/src/stdlib/number.ts index 35dda1ac4e4..d7f9358d4d2 100644 --- a/packages/codemode/src/stdlib/number.ts +++ b/packages/codemode/src/stdlib/number.ts @@ -1,7 +1,8 @@ -import { constructor, constants, methods } from "../interpreter/native.js" +import { constructor, constants, type Method, methods } from "../interpreter/native.js" import { coerceToNumber, type Value } from "../interpreter/objects.js" import { rangeError, typeError } from "../interpreter/model.js" import type { Interpreter } from "../interpreter/interpreter.js" +import { withPrimitives } from "../interpreter/callback.js" import { coerce, coercion } from "./value.js" export const numberGlobal = (ctx: Interpreter) => { @@ -34,32 +35,28 @@ export const numberGlobal = (ctx: Interpreter) => { if (typeof thisValue === "number") return thisValue throw typeError(`Number.prototype.${name} requires that 'this' be a Number.`) } - const optNum = (arg: Value): number | undefined => (arg === undefined ? undefined : coerceToNumber(arg)) + // The receiver is checked first, then the one argument converts through ToPrimitive with the number hint. + const formatting = (name: string, op: (value: number, digits: number | undefined) => string): Method => [ + name, + 1, + (thisValue, args) => { + const value = self(thisValue, name) + return withPrimitives(ctx, "number", [args[0]], ([digits]) => + op(value, digits === undefined ? undefined : coerceToNumber(digits)), + ) + }, + ] methods(builtins, builtins.Number, [ - ["toFixed", 1, (thisValue, args) => self(thisValue, "toFixed").toFixed(optNum(args[0]))], + formatting("toFixed", (value, digits) => value.toFixed(digits)), ["toLocaleString", 0, (thisValue) => self(thisValue, "toLocaleString").toLocaleString("en-US")], - ["toExponential", 1, (thisValue, args) => self(thisValue, "toExponential").toExponential(optNum(args[0]))], - [ - "toPrecision", - 1, - (thisValue, args) => { - const value = self(thisValue, "toPrecision") - const digits = optNum(args[0]) - return digits === undefined ? value.toString() : value.toPrecision(digits) - }, - ], - [ - "toString", - 1, - (thisValue, args) => { - const value = self(thisValue, "toString") - const radix = optNum(args[0]) - if (radix !== undefined && (radix < 2 || radix > 36)) { - throw rangeError("Number.toString radix must be between 2 and 36.") - } - return value.toString(radix) - }, - ], + formatting("toExponential", (value, digits) => value.toExponential(digits)), + formatting("toPrecision", (value, digits) => (digits === undefined ? value.toString() : value.toPrecision(digits))), + formatting("toString", (value, radix) => { + if (radix !== undefined && (radix < 2 || radix > 36)) { + throw rangeError("Number.toString radix must be between 2 and 36.") + } + return value.toString(radix) + }), ["valueOf", 0, (thisValue) => self(thisValue, "valueOf")], ]) return number diff --git a/packages/codemode/src/stdlib/string.ts b/packages/codemode/src/stdlib/string.ts index 6c9d4547af0..d9cc9044973 100644 --- a/packages/codemode/src/stdlib/string.ts +++ b/packages/codemode/src/stdlib/string.ts @@ -17,7 +17,13 @@ import { type Value, } from "../interpreter/objects.js" import { containsOpaqueReference, typeofValue } from "../interpreter/references.js" -import { applyCollectionCallback, isSupportedCallback, toPrimitiveString } from "../interpreter/callback.js" +import { + applyCollectionCallback, + type Hint, + isSupportedCallback, + toPrimitiveString, + withPrimitives, +} from "../interpreter/callback.js" import type { Interpreter } from "../interpreter/interpreter.js" import { matchToValue, toHostRegex } from "./regexp.js" import { coercion } from "./value.js" @@ -142,34 +148,72 @@ export const stringGlobal = (ctx: Interpreter) => { args[index] === undefined ? undefined : num(name, args, index) const optStr = (name: string, args: Array, index: number): string | undefined => args[index] === undefined ? undefined : str(name, args, index) - const rejectRegex = (name: string, args: Array): void => { - if (args[0] instanceof RegExpObj) { - throw typeError( - `String.${name} cannot take a regular expression; use regex.test(string) or String.search instead.`, - ) - } - } + // ToPrimitive in spec order: the receiver, then the arguments the method consumes, one hint per position; the + // rest pass through as they are. const simple = ( name: string, length: number, op: (value: string, args: Array) => ReturnType, - ): Method => [name, length, (thisValue, args) => op(self(thisValue, name), args)] - const replace = (name: "replace" | "replaceAll") => - simple(name, 2, (value, args) => { - if (isSupportedCallback(args[1])) return replaceWithCallback(ctx, value, name, args) - if (typeofValue(args[1]) === "function") { + hints: ReadonlyArray = [], + ): Method => [ + name, + length, + (thisValue, args) => { + if (thisValue === null || thisValue === undefined) { + throw typeError(`String.prototype.${name} called on null or undefined.`) + } + return withPrimitives( + ctx, + ["string", ...hints], + [thisValue, ...args.slice(0, hints.length)], + ([value, ...primitives]) => op(coerceToString(value), [...primitives, ...args.slice(hints.length)]), + ) + }, + ] + // includes, startsWith, and endsWith reject a RegExp before converting their search string and position. + const searching = (name: string, op: (value: string, search: string, position: number | undefined) => boolean) => + simple(name, 1, (value, args) => { + if (args[0] instanceof RegExpObj) { throw typeError( - `String.${name} cannot use this callable as a replacer; wrap it in an arrow function, e.g. (match) => tools.ns.tool(match).`, + `String.${name} cannot take a regular expression; use regex.test(string) or String.search instead.`, ) } - if (args[0] instanceof RegExpObj) { - const pattern = args[0].regex - const replacement = str(name, args, 1) - if (name === "replaceAll") replaceAllNeedsGlobal(pattern) - return name === "replace" ? value.replace(pattern, replacement) : value.replaceAll(pattern, replacement) - } - if (name === "replace") return value.replace(str(name, args, 0), str(name, args, 1)) - return value.replaceAll(str(name, args, 0), str(name, args, 1)) + return withPrimitives(ctx, ["string", "number"], args.slice(0, 2), (primitives) => + op(value, str(name, primitives, 0), optNum(name, primitives, 1)), + ) + }) + // match, matchAll, and search read a RegExp as is and convert anything else to its pattern text. + const withPattern = (args: Array, op: (pattern: Value) => Value) => + args[0] instanceof RegExpObj ? op(args[0]) : withPrimitives(ctx, "string", [args[0]], ([text]) => op(text)) + const replace = (name: "replace" | "replaceAll") => + simple(name, 2, (value, args) => { + const pattern = args[0] + const replacer = args[1] + // A RegExp pattern is used as is; a plain one converts to its search string, then a non-callable replacement. + return withPrimitives( + ctx, + "string", + [pattern instanceof RegExpObj ? undefined : pattern, isSupportedCallback(replacer) ? undefined : replacer], + ([search, replacement]) => { + if (isSupportedCallback(replacer)) { + return replaceWithCallback(ctx, value, name, [pattern instanceof RegExpObj ? pattern : search, replacer]) + } + if (typeofValue(replacer) === "function") { + throw typeError( + `String.${name} cannot use this callable as a replacer; wrap it in an arrow function, e.g. (match) => tools.ns.tool(match).`, + ) + } + const primitives = [search, replacement] + if (pattern instanceof RegExpObj) { + const regex = pattern.regex + const text = str(name, primitives, 1) + if (name === "replaceAll") replaceAllNeedsGlobal(regex) + return name === "replace" ? value.replace(regex, text) : value.replaceAll(regex, text) + } + if (name === "replace") return value.replace(str(name, primitives, 0), str(name, primitives, 1)) + return value.replaceAll(str(name, primitives, 0), str(name, primitives, 1)) + }, + ) }) methods(builtins, builtins.String, [ @@ -185,107 +229,148 @@ export const stringGlobal = (ctx: Interpreter) => { simple("trimEnd", 0, (value) => value.trimEnd()), simple("trimRight", 0, (value) => value.trimEnd()), // Locale/options are deliberately unsupported; comparison uses the host default locale. - simple("localeCompare", 1, (value, args) => value.localeCompare(str("localeCompare", args, 0))), - simple("normalize", 0, (value, args) => { - const form = optStr("normalize", args, 0) - try { - return value.normalize(form) - } catch { - throw rangeError( - `String.normalize expects the form "NFC", "NFD", "NFKC", or "NFKD" (got ${JSON.stringify(form)}).`, - ) - } - }), + simple("localeCompare", 1, (value, args) => value.localeCompare(str("localeCompare", args, 0)), ["string"]), + simple( + "normalize", + 0, + (value, args) => { + const form = optStr("normalize", args, 0) + try { + return value.normalize(form) + } catch { + throw rangeError( + `String.normalize expects the form "NFC", "NFD", "NFKC", or "NFKD" (got ${JSON.stringify(form)}).`, + ) + } + }, + ["string"], + ), simple("split", 2, (value, args) => { - const wrap = (parts: Array) => new Arr(builtins.Array, parts) - // Native: an undefined separator returns the whole string, not a split on "undefined", - // unless the limit truncates to zero. - const requestedLimit = optNum("split", args, 1) - if (args[0] === undefined) { - return wrap(requestedLimit !== undefined && requestedLimit >>> 0 === 0 ? [] : [value]) - } - const parts = - args[0] instanceof RegExpObj - ? value.split(args[0].regex, requestedLimit) - : value.split(str("split", args, 0), requestedLimit === undefined ? undefined : requestedLimit >>> 0) - checkArrayLength(parts.length) - return wrap(parts) + const separator = args[0] + // A RegExp separator is used as is; the limit converts before a plain separator does, as in the spec. + return withPrimitives( + ctx, + ["number", "string"], + [args[1], separator instanceof RegExpObj ? undefined : separator], + ([limit, pattern]) => { + const wrap = (parts: Array) => new Arr(builtins.Array, parts) + // Native: an undefined separator returns the whole string, not a split on "undefined", + // unless the limit truncates to zero. + const requestedLimit = args[1] === undefined ? undefined : num("split", [pattern, limit], 1) + if (separator === undefined) { + return wrap(requestedLimit !== undefined && requestedLimit >>> 0 === 0 ? [] : [value]) + } + const parts = + separator instanceof RegExpObj + ? value.split(separator.regex, requestedLimit) + : value.split(str("split", [pattern], 0), requestedLimit === undefined ? undefined : requestedLimit >>> 0) + checkArrayLength(parts.length) + return wrap(parts) + }, + ) }), - simple("slice", 2, (value, args) => value.slice(optNum("slice", args, 0), optNum("slice", args, 1))), - simple("includes", 1, (value, args) => { - rejectRegex("includes", args) - return value.includes(str("includes", args, 0), optNum("includes", args, 1)) - }), - simple("startsWith", 1, (value, args) => { - rejectRegex("startsWith", args) - return value.startsWith(str("startsWith", args, 0), optNum("startsWith", args, 1)) - }), - simple("endsWith", 1, (value, args) => { - rejectRegex("endsWith", args) - return value.endsWith(str("endsWith", args, 0), optNum("endsWith", args, 1)) - }), - simple("indexOf", 1, (value, args) => value.indexOf(str("indexOf", args, 0), optNum("indexOf", args, 1))), - simple("lastIndexOf", 1, (value, args) => - value.lastIndexOf(str("lastIndexOf", args, 0), optNum("lastIndexOf", args, 1)), + simple("slice", 2, (value, args) => value.slice(optNum("slice", args, 0), optNum("slice", args, 1)), [ + "number", + "number", + ]), + searching("includes", (value, search, position) => value.includes(search, position)), + searching("startsWith", (value, search, position) => value.startsWith(search, position)), + searching("endsWith", (value, search, position) => value.endsWith(search, position)), + simple("indexOf", 1, (value, args) => value.indexOf(str("indexOf", args, 0), optNum("indexOf", args, 1)), [ + "string", + "number", + ]), + simple( + "lastIndexOf", + 1, + (value, args) => value.lastIndexOf(str("lastIndexOf", args, 0), optNum("lastIndexOf", args, 1)), + ["string", "number"], ), replace("replace"), replace("replaceAll"), - simple("match", 1, (value, args) => { - const pattern = toHostRegex(args[0], "match") - const matched = value.match(pattern) - if (matched === null) return null - // Preserve the own `index` and `groups` properties on non-global matches. - if (pattern.global) return new Arr(builtins.Array, [...matched]) - return matchToValue(builtins, matched) - }), - simple("matchAll", 1, (value, args) => { - const pattern = toHostRegex(args[0], "matchAll", "g") - if (!pattern.global) { - throw typeError( - `String.matchAll requires a regular expression with the global (g) flag: write /${pattern.source}/${pattern.flags}g, or use String.match for a single match.`, - ) - } - const matches: Array = [] - for (const match of value.matchAll(pattern)) { - checkArrayLength(matches.length + 1) - matches.push(matchToValue(builtins, match)) - } - return new Arr(builtins.Array, matches) - }), - simple("search", 1, (value, args) => value.search(toHostRegex(args[0], "search"))), - simple("repeat", 1, (value, args) => { - const count = num("repeat", args, 0) - if (!Number.isFinite(count) || count < 0) { - throw rangeError("String.repeat expects a finite non-negative count.") - } - checkStringLength(value.length * count) - return value.repeat(count) - }), - simple("padStart", 1, (value, args) => { - const length = num("padStart", args, 0) - checkStringLength(length) - return value.padStart(length, optStr("padStart", args, 1)) - }), - simple("padEnd", 1, (value, args) => { - const length = num("padEnd", args, 0) - checkStringLength(length) - return value.padEnd(length, optStr("padEnd", args, 1)) - }), - simple("charAt", 1, (value, args) => value.charAt(optNum("charAt", args, 0) ?? 0)), - simple("at", 1, (value, args) => value.at(optNum("at", args, 0) ?? 0)), - simple("substring", 2, (value, args) => - value.substring(optNum("substring", args, 0) ?? 0, optNum("substring", args, 1)), + simple("match", 1, (value, args) => + withPattern(args, (arg) => { + const regex = toHostRegex(arg, "match") + const matched = value.match(regex) + if (matched === null) return null + // Preserve the own `index` and `groups` properties on non-global matches. + if (regex.global) return new Arr(builtins.Array, [...matched]) + return matchToValue(builtins, matched) + }), ), - simple("substr", 2, (value, args) => value.substr(optNum("substr", args, 0) ?? 0, optNum("substr", args, 1))), + simple("matchAll", 1, (value, args) => + withPattern(args, (arg) => { + const regex = toHostRegex(arg, "matchAll", "g") + if (!regex.global) { + throw typeError( + `String.matchAll requires a regular expression with the global (g) flag: write /${regex.source}/${regex.flags}g, or use String.match for a single match.`, + ) + } + const matches: Array = [] + for (const match of value.matchAll(regex)) { + checkArrayLength(matches.length + 1) + matches.push(matchToValue(builtins, match)) + } + return new Arr(builtins.Array, matches) + }), + ), + simple("search", 1, (value, args) => withPattern(args, (arg) => value.search(toHostRegex(arg, "search")))), + simple( + "repeat", + 1, + (value, args) => { + const count = num("repeat", args, 0) + if (!Number.isFinite(count) || count < 0) { + throw rangeError("String.repeat expects a finite non-negative count.") + } + checkStringLength(value.length * count) + return value.repeat(count) + }, + ["number"], + ), + simple( + "padStart", + 1, + (value, args) => { + const length = num("padStart", args, 0) + checkStringLength(length) + return value.padStart(length, optStr("padStart", args, 1)) + }, + ["number", "string"], + ), + simple( + "padEnd", + 1, + (value, args) => { + const length = num("padEnd", args, 0) + checkStringLength(length) + return value.padEnd(length, optStr("padEnd", args, 1)) + }, + ["number", "string"], + ), + simple("charAt", 1, (value, args) => value.charAt(optNum("charAt", args, 0) ?? 0), ["number"]), + simple("at", 1, (value, args) => value.at(optNum("at", args, 0) ?? 0), ["number"]), + simple( + "substring", + 2, + (value, args) => value.substring(optNum("substring", args, 0) ?? 0, optNum("substring", args, 1)), + ["number", "number"], + ), + simple("substr", 2, (value, args) => value.substr(optNum("substr", args, 0) ?? 0, optNum("substr", args, 1)), [ + "number", + "number", + ]), simple("isWellFormed", 0, (value) => value.isWellFormed()), simple("toWellFormed", 0, (value) => value.toWellFormed()), - simple("charCodeAt", 1, (value, args) => value.charCodeAt(optNum("charCodeAt", args, 0) ?? 0)), - simple("codePointAt", 1, (value, args) => value.codePointAt(optNum("codePointAt", args, 0) ?? 0)), - simple("concat", 1, (value, args) => { - const joined = value.concat(...args.map((_, index) => str("concat", args, index))) - checkStringLength(joined.length) - return joined - }), + simple("charCodeAt", 1, (value, args) => value.charCodeAt(optNum("charCodeAt", args, 0) ?? 0), ["number"]), + simple("codePointAt", 1, (value, args) => value.codePointAt(optNum("codePointAt", args, 0) ?? 0), ["number"]), + simple("concat", 1, (value, args) => + withPrimitives(ctx, "string", args, (parts) => { + const joined = value.concat(...parts.map((_, index) => str("concat", parts, index))) + checkStringLength(joined.length) + return joined + }), + ), ]) define( builtins.String, diff --git a/packages/codemode/src/stdlib/url.ts b/packages/codemode/src/stdlib/url.ts index e6ea6c472af..666f692045c 100644 --- a/packages/codemode/src/stdlib/url.ts +++ b/packages/codemode/src/stdlib/url.ts @@ -281,7 +281,7 @@ export const urlSearchParamsGlobal = (ctx: Interpreter) => { const target = self(thisValue, "forEach") const apply = applyCollectionCallback(ctx, args[0], "URLSearchParams.forEach") return Effect.gen(function* () { - for (const [key, value] of Array.from(target.params.entries())) yield* apply([value, key, target]) + for (const [key, value] of Array.from(target.params.entries())) yield* apply([value, key, target], args[1]) return undefined }) }, diff --git a/packages/codemode/test/parity.test.ts b/packages/codemode/test/parity.test.ts index d05b5ce2ee8..050e9b57d0b 100644 --- a/packages/codemode/test/parity.test.ts +++ b/packages/codemode/test/parity.test.ts @@ -1737,3 +1737,202 @@ describe("Date components convert through ToPrimitive", () => { ).toEqual([true, 0, true]) }) }) + +describe("iteration callbacks receive thisArg", () => { + test("Array, Array.from, Map, Set, URLSearchParams, Headers, and Uint8Array pass it as this", async () => { + expect( + await value(` + const c = { n: 0 } + const count = function () { this.n++ } + ;[1, 2].forEach(count, c) + ;[1].map(count, c) + ;[1].filter(count, c) + ;[1].find(count, c) + ;[1].findIndex(count, c) + ;[1].findLast(count, c) + ;[1].findLastIndex(count, c) + ;[1].some(count, c) + ;[1].every(count, c) + ;[1].flatMap(count, c) + Array.from([1], count, c) + Array.from({ length: 1 }, count, c) + new Map([[1, 1]]).forEach(count, c) + new Set([1]).forEach(count, c) + new URLSearchParams("a=1").forEach(count, c) + new Headers({ a: "1" }).forEach(count, c) + new Uint8Array([1]).forEach(count, c) + return c.n + `), + ).toBe(18) + expect(await value(`return [1, 2].map(function (x) { return x + this.v }, { v: 10 })`)).toEqual([11, 12]) + }) + + test("arrows keep their lexical this, reduce takes an initial value instead, and opaque values are only bound", async () => { + expect(await value(`return [1].map(() => typeof this, { v: 1 })`)).toEqual(["undefined"]) + expect( + await value(`return [1, 2].reduce(function (a, b) { return a + b + (this === undefined ? 0 : 100) }, 0)`), + ).toBe(3) + expect( + await value(` + let seen + ;[1].forEach(function () { seen = this }, tools.nowhere) + return typeof seen + `), + ).toBe("function") + }) +}) + +describe("computed property keys convert through the object's own toString", () => { + test("reads, writes, compound assignment, in, delete, literals, and destructuring share one conversion", async () => { + expect( + await value(` + const key = { toString() { return "id" } } + const o = {} + o[key] = 1 + o[key] += 1 + const literal = { [key]: "lit" } + const had = key in o + delete literal[key] + return [o.id, had, (({ [key]: v }) => v)(o), literal, o[[1, 2]] === undefined] + `), + ).toEqual([2, true, 2, {}, true]) + expect( + await value(` + const seen = [] + const base = { x: 1 } + base[{ toString() { seen.push(1); return "" } }] ^= 0 + base[{ toString() { seen.push(2); return "x" } }]++ + return [seen, base[""], base.x] + `), + ).toEqual([[1, 2], 0, 2]) + }) + + test("valueOf is the fallback, a symbol result stays a symbol, and conversion failures surface", async () => { + expect( + await value(` + const o = { 7: "seven" } + const sym = { toString() { return Symbol.iterator } } + o[sym] = 1 + return [o[{ valueOf() { return 7 }, toString: undefined }], typeof o[Symbol.iterator], Object.keys(o)] + `), + ).toEqual(["seven", "number", ["7"]]) + expect((await error(`({})[{ toString() { throw new RangeError("bad key") } }]`)).message).toContain("bad key") + expect((await error(`({})[{ toString() { return {} }, valueOf() { return {} } }]`)).message).toContain( + "Cannot convert object to primitive value", + ) + expect((await error(`const key = { toString() { return "a" } }; key in 5`)).message).toContain( + "requires a data object on the right-hand side", + ) + }) + + test("a nullish base throws before the key converts, as ToObject precedes ToPropertyKey", async () => { + const failure = await error(`const base = null; base[{ toString() { throw new RangeError("key evaluated") } }]`) + expect(failure.message).toContain("Cannot read properties of null") + }) + + test("opaque values keep their built-in key form and a tool reference toString is never called", async () => { + expect( + await value(` + const o = { "[object Function]": 1, "[object Promise]": 2 } + return [o[() => 1], o[Promise.resolve("k")]] + `), + ).toEqual([1, 2]) + expect((await error(`({})[{ toString: tools.nowhere }] = 1`)).message).toContain( + "Cannot convert object to primitive value", + ) + }) +}) + +describe("String and Number method arguments convert through ToPrimitive", () => { + test("string positions use the string hint and numeric positions the number hint", async () => { + expect( + await value(` + const s = { toString() { return "b" } } + const n = { valueOf() { return 1 } } + return [ + "abc".indexOf(s), "abc".lastIndexOf(s), "abc".includes(s), "abc".startsWith(s, n), "abc".endsWith(s, 2), + "abc".charAt(n), "abc".at({ valueOf() { return -1 } }), "abc".slice(n), "abc".substring(n, 2), + "abc".charCodeAt(n), "a".padStart({ valueOf() { return 3 } }, s), "x".padEnd(3, s), "ab".repeat({ valueOf() { return 2 } }), + "a".concat(s, { valueOf() { return 1 }, toString() { return "T" } }), "b".localeCompare(s), + (1.005).toFixed({ valueOf() { return 2 } }), (255).toString({ valueOf() { return 16 } }), + (1234.5678).toPrecision({ valueOf() { return 6 } }), (12345).toExponential({ valueOf() { return 2 } }), + ] + `), + ).toEqual([ + 1, + 1, + true, + true, + true, + "b", + "c", + "bc", + "b", + 98, + "bba", + "xbb", + "abab", + "abT", + 0, + "1.00", + "ff", + "1234.57", + "1.23e+4", + ]) + }) + + test("split, replace, match, and search convert a plain pattern but keep a RegExp as is", async () => { + expect( + await value(` + const s = { toString() { return "b" } } + return [ + "abc".split(s), "abc".split(/b/, { valueOf() { return 1 } }), "abc".split(undefined, { valueOf() { return undefined } }), + "abc".replace(s, "X"), "abc".replace(/b/, { toString() { return "R" } }), "abc".replaceAll(s, s), + "abc".replace(s, (m) => m.toUpperCase()), "abc".match(s)[0], "abcb".matchAll(s).length, "abc".search(s), + ] + `), + ).toEqual([["a", "c"], ["a"], [], "aXc", "aRc", "abc", "aBc", "b", 2, 1]) + expect((await error(`"abc".includes(/b/)`)).message).toContain("cannot take a regular expression") + }) + + test("the receiver converts first, then each consumed argument, in spec order; extra arguments are untouched", async () => { + expect( + await value(` + const log = [] + const observer = (name, string, number) => ({ + toString() { log.push("toString:" + name); return string }, + valueOf() { log.push("valueOf:" + name); return number }, + }) + const padded = String.prototype.padStart.call(observer("receiver", {}, "abc"), observer("maxLength", 11, {}), observer("fillString", {}, "def")) + const extra = "abc".indexOf("b", 1, { valueOf() { throw new Error("extra argument converted") } }) + return [padded, log, extra, String.prototype.trim.call({ toString() { return " abc " } })] + `), + ).toEqual([ + "defdefdeabc", + [ + "toString:receiver", + "valueOf:receiver", + "valueOf:maxLength", + "toString:maxLength", + "toString:fillString", + "valueOf:fillString", + ], + 1, + "abc", + ]) + }) + + test("conversion failures surface and opaque arguments still reject", async () => { + expect((await error(`"abc".indexOf({ toString() { throw new RangeError("intostr") } })`)).message).toContain( + "intostr", + ) + expect((await error(`(1).toString({ valueOf() { throw new SyntaxError("poison") } })`)).message).toContain("poison") + expect((await error(`(1).toFixed({ toString() { return {} }, valueOf() { return {} } })`)).message).toContain( + "Cannot convert object to primitive value", + ) + expect((await error(`"abc".indexOf(tools.nowhere)`)).message).toContain("expects argument 1 to be a data value") + expect((await error(`"abc".indexOf(Promise.resolve("b"))`)).message).toContain( + "expects argument 1 to be a data value", + ) + }) +}) diff --git a/packages/codemode/test/test262/skipped.txt b/packages/codemode/test/test262/skipped.txt index 5dcbf81b84a..b16ed98c79c 100644 --- a/packages/codemode/test/test262/skipped.txt +++ b/packages/codemode/test/test262/skipped.txt @@ -1,12 +1,9 @@ built-ins/AggregateError/message-undefined-no-prop.js # explicit Expected SameValue(«true», «false») to be true built-ins/Array/S15.4.5.2_A3_T3.js # RangeError: Invalid array length -built-ins/Array/S15.4_A1.1_T9.js # The value of x[0] is expected to be 0 Expected SameValue(«undefined», «0») to be true built-ins/Array/from/Array.from_forwards-length-for-array-likes.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/from/calling-from-valid-2.js # The value of calls[0].thisArg is expected to equal the value of thisArg Expected SameValue(«undefine built-ins/Array/from/elements-deleted-after.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/from/iter-cstm-ctor-err.js # Array.from.call(C, items) throws a Test262Error exception Expected a Test262Error but got a TypeErro built-ins/Array/from/iter-cstm-ctor.js # TypeError: The right-hand side of '…' has no '…' object. -built-ins/Array/from/iter-map-fn-this-arg.js # The value of thisVals[0] is expected to equal the value of thisVal Expected SameValue(«undefined», « built-ins/Array/from/source-array-boundary.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/from/source-object-constructor.js # The value of Array.from.call(Object, []).constructor is expected to equal the value of Object Expect built-ins/Array/isArray/15.4.3.2-2-1.js # TypeError: Con cannot be constructed: user-defined constructors and classes are not supported. Call @@ -73,22 +70,8 @@ built-ins/Array/prototype/every/15.4.4.16-3-6.js # TypeError: Array.prototype.e built-ins/Array/prototype/every/15.4.4.16-3-7.js # TypeError: Array.prototype.every called on incompatible receiver a data object. built-ins/Array/prototype/every/15.4.4.16-3-8.js # TypeError: Array.prototype.every called on incompatible receiver a data object. built-ins/Array/prototype/every/15.4.4.16-3-9.js # TypeError: Array.prototype.every called on incompatible receiver a data object. -built-ins/Array/prototype/every/15.4.4.16-5-10.js # [11].every(callbackfn, objArray) !== true -built-ins/Array/prototype/every/15.4.4.16-5-14.js # [11].every(callbackfn, Math) !== true -built-ins/Array/prototype/every/15.4.4.16-5-15.js # [11].every(callbackfn, objDate) !== true -built-ins/Array/prototype/every/15.4.4.16-5-16.js # [11].every(callbackfn, objRegExp) !== true -built-ins/Array/prototype/every/15.4.4.16-5-17.js # [11].every(callbackfn, JSON) !== true -built-ins/Array/prototype/every/15.4.4.16-5-18.js # [11].every(callbackfn, objError) !== true -built-ins/Array/prototype/every/15.4.4.16-5-19.js # [11].every(callbackfn, arg) !== true -built-ins/Array/prototype/every/15.4.4.16-5-2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/every/15.4.4.16-5-22.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/every/15.4.4.16-5-23.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/every/15.4.4.16-5-24.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/every/15.4.4.16-5-3.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/every/15.4.4.16-5-4.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/every/15.4.4.16-5-5.js # TypeError: foo cannot be constructed: user-defined constructors and classes are not supported. Call -built-ins/Array/prototype/every/15.4.4.16-5-6.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/every/15.4.4.16-5-9.js # [11].every(callbackfn, objFunction) !== true built-ins/Array/prototype/every/15.4.4.16-7-6.js # res Expected SameValue(«true», «false») to be true built-ins/Array/prototype/every/15.4.4.16-7-8.js # TypeError: Array.prototype.every called on incompatible receiver a data object. built-ins/Array/prototype/every/15.4.4.16-7-c-i-1.js # TypeError: Array.prototype.every called on incompatible receiver a data object. @@ -168,22 +151,8 @@ built-ins/Array/prototype/filter/15.4.4.20-3-5.js # TypeError: Array.prototype. built-ins/Array/prototype/filter/15.4.4.20-3-6.js # TypeError: Array.prototype.filter called on incompatible receiver a data object. built-ins/Array/prototype/filter/15.4.4.20-3-7.js # TypeError: Array.prototype.filter called on incompatible receiver a data object. built-ins/Array/prototype/filter/15.4.4.20-3-9.js # TypeError: Array.prototype.filter called on incompatible receiver a data object. -built-ins/Array/prototype/filter/15.4.4.20-5-10.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-14.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-15.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-16.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-17.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-18.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-19.js # newArr[0] Expected SameValue(«undefined», «11») to be true -built-ins/Array/prototype/filter/15.4.4.20-5-2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/filter/15.4.4.20-5-22.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/filter/15.4.4.20-5-23.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/filter/15.4.4.20-5-24.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/filter/15.4.4.20-5-3.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/filter/15.4.4.20-5-4.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/filter/15.4.4.20-5-5.js # TypeError: foo cannot be constructed: user-defined constructors and classes are not supported. Call -built-ins/Array/prototype/filter/15.4.4.20-5-6.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/filter/15.4.4.20-5-9.js # newArr[0] Expected SameValue(«undefined», «11») to be true built-ins/Array/prototype/filter/15.4.4.20-6-2.js # … cannot be constructed: user-defined constructors and classes are not supported. Call it as a funct built-ins/Array/prototype/filter/15.4.4.20-6-3.js # … cannot be constructed: user-defined constructors and classes are not supported. Call it as a funct built-ins/Array/prototype/filter/15.4.4.20-6-4.js # … cannot be constructed: user-defined constructors and classes are not supported. Call it as a funct @@ -224,20 +193,15 @@ built-ins/Array/prototype/filter/15.4.4.20-9-c-iii-5.js # TypeError: Array.prot built-ins/Array/prototype/filter/call-with-boolean.js # TypeError: Array.prototype.filter called on incompatible receiver a boolean. built-ins/Array/prototype/filter/create-ctor-non-object.js # null value Expected a TypeError to be thrown but no exception was thrown at all built-ins/Array/prototype/find/call-with-boolean.js # TypeError: Array.prototype.find called on incompatible receiver a boolean. -built-ins/Array/prototype/find/predicate-call-this-strict.js # Expected SameValue(«undefined», «object») to be true built-ins/Array/prototype/findIndex/call-with-boolean.js # TypeError: Array.prototype.findIndex called on incompatible receiver a boolean. -built-ins/Array/prototype/findIndex/predicate-call-this-strict.js # Expected SameValue(«undefined», «object») to be true built-ins/Array/prototype/findLast/call-with-boolean.js # TypeError: Array.prototype.findLast called on incompatible receiver a boolean. built-ins/Array/prototype/findLast/maximum-index.js # TypeError: Array.prototype.findLast called on incompatible receiver a data object. -built-ins/Array/prototype/findLast/predicate-call-this-strict.js # Expected SameValue(«undefined», «object») to be true built-ins/Array/prototype/findLastIndex/call-with-boolean.js # TypeError: Array.prototype.findLastIndex called on incompatible receiver a boolean. built-ins/Array/prototype/findLastIndex/maximum-index.js # TypeError: Array.prototype.findLastIndex called on incompatible receiver a data object. -built-ins/Array/prototype/findLastIndex/predicate-call-this-strict.js # Expected SameValue(«undefined», «object») to be true built-ins/Array/prototype/flat/array-like-objects.js # TypeError: Array.prototype.flat called on incompatible receiver a data object. built-ins/Array/prototype/flat/call-with-boolean.js # TypeError: Array.prototype.flat called on incompatible receiver a boolean. built-ins/Array/prototype/flat/non-object-ctor-throws.js # null value Expected a TypeError to be thrown but no exception was thrown at all built-ins/Array/prototype/flatMap/call-with-boolean.js # TypeError: Array.prototype.flatMap called on incompatible receiver a boolean. -built-ins/Array/prototype/flatMap/thisArg-argument.js # Actual [undefined] and expected ["TestString"] should have the same contents. The value of actual is built-ins/Array/prototype/forEach/15.4.4.18-1-10.js # TypeError: Array.prototype.forEach called on incompatible receiver a data object. built-ins/Array/prototype/forEach/15.4.4.18-1-11.js # TypeError: Array.prototype.forEach called on incompatible receiver a Date. built-ins/Array/prototype/forEach/15.4.4.18-1-12.js # TypeError: Array.prototype.forEach called on incompatible receiver a RegExp. @@ -276,22 +240,8 @@ built-ins/Array/prototype/forEach/15.4.4.18-3-5.js # TypeError: Array.prototype built-ins/Array/prototype/forEach/15.4.4.18-3-6.js # TypeError: Array.prototype.forEach called on incompatible receiver a data object. built-ins/Array/prototype/forEach/15.4.4.18-3-7.js # TypeError: Array.prototype.forEach called on incompatible receiver a data object. built-ins/Array/prototype/forEach/15.4.4.18-3-9.js # TypeError: Array.prototype.forEach called on incompatible receiver a data object. -built-ins/Array/prototype/forEach/15.4.4.18-5-10.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-14.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-15.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-16.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-17.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-18.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-19.js # result !== true -built-ins/Array/prototype/forEach/15.4.4.18-5-2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/forEach/15.4.4.18-5-22.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/forEach/15.4.4.18-5-23.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/forEach/15.4.4.18-5-24.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/forEach/15.4.4.18-5-3.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/forEach/15.4.4.18-5-4.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/forEach/15.4.4.18-5-5.js # TypeError: foo cannot be constructed: user-defined constructors and classes are not supported. Call -built-ins/Array/prototype/forEach/15.4.4.18-5-6.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/forEach/15.4.4.18-5-9.js # result !== true built-ins/Array/prototype/forEach/15.4.4.18-7-5.js # callCnt Expected SameValue(«4», «5») to be true built-ins/Array/prototype/forEach/15.4.4.18-7-8.js # TypeError: Array.prototype.forEach called on incompatible receiver a data object. built-ins/Array/prototype/forEach/15.4.4.18-7-c-i-1.js # TypeError: Array.prototype.forEach called on incompatible receiver a data object. @@ -513,22 +463,8 @@ built-ins/Array/prototype/map/15.4.4.19-3-6.js # TypeError: Array.prototype.map built-ins/Array/prototype/map/15.4.4.19-3-7.js # TypeError: Array.prototype.map called on incompatible receiver a data object. built-ins/Array/prototype/map/15.4.4.19-3-8.js # Expected a RangeError but got a TypeError built-ins/Array/prototype/map/15.4.4.19-3-9.js # TypeError: Array.prototype.map called on incompatible receiver a data object. -built-ins/Array/prototype/map/15.4.4.19-5-10.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-14.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-15.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-16.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-17.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-18.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-19.js # testResult[0] Expected SameValue(«false», «true») to be true -built-ins/Array/prototype/map/15.4.4.19-5-2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/map/15.4.4.19-5-22.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/map/15.4.4.19-5-23.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/map/15.4.4.19-5-24.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/map/15.4.4.19-5-3.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/map/15.4.4.19-5-4.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/map/15.4.4.19-5-5.js # TypeError: foo cannot be constructed: user-defined constructors and classes are not supported. Call -built-ins/Array/prototype/map/15.4.4.19-5-6.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/map/15.4.4.19-5-9.js # testResult[0] Expected SameValue(«false», «true») to be true built-ins/Array/prototype/map/15.4.4.19-8-6.js # resArr[4] Expected SameValue(«undefined», «1») to be true built-ins/Array/prototype/map/15.4.4.19-8-8.js # TypeError: Array.prototype.map called on incompatible receiver a data object. built-ins/Array/prototype/map/15.4.4.19-8-c-i-1.js # TypeError: Array.prototype.map called on incompatible receiver a data object. @@ -843,22 +779,8 @@ built-ins/Array/prototype/some/15.4.4.17-3-6.js # TypeError: Array.prototype.so built-ins/Array/prototype/some/15.4.4.17-3-7.js # TypeError: Array.prototype.some called on incompatible receiver a data object. built-ins/Array/prototype/some/15.4.4.17-3-8.js # TypeError: Array.prototype.some called on incompatible receiver a data object. built-ins/Array/prototype/some/15.4.4.17-3-9.js # TypeError: Array.prototype.some called on incompatible receiver a data object. -built-ins/Array/prototype/some/15.4.4.17-5-10.js # [11].some(callbackfn, objArray) !== true -built-ins/Array/prototype/some/15.4.4.17-5-14.js # [11].some(callbackfn, Math) !== true -built-ins/Array/prototype/some/15.4.4.17-5-15.js # [11].some(callbackfn, objDate) !== true -built-ins/Array/prototype/some/15.4.4.17-5-16.js # [11].some(callbackfn, objRegExp) !== true -built-ins/Array/prototype/some/15.4.4.17-5-17.js # [11].some(callbackfn, JSON) !== true -built-ins/Array/prototype/some/15.4.4.17-5-18.js # [11].some(callbackfn, objError) !== true -built-ins/Array/prototype/some/15.4.4.17-5-19.js # [11].some(callbackfn, arg) !== true -built-ins/Array/prototype/some/15.4.4.17-5-2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/some/15.4.4.17-5-22.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/some/15.4.4.17-5-23.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/some/15.4.4.17-5-24.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/some/15.4.4.17-5-3.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/some/15.4.4.17-5-4.js # TypeError: Cannot read properties of undefined (reading '…'). built-ins/Array/prototype/some/15.4.4.17-5-5.js # TypeError: foo cannot be constructed: user-defined constructors and classes are not supported. Call -built-ins/Array/prototype/some/15.4.4.17-5-6.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/Array/prototype/some/15.4.4.17-5-9.js # [11].some(callbackfn, objFunction) !== true built-ins/Array/prototype/some/15.4.4.17-7-6.js # res Expected SameValue(«false», «true») to be true built-ins/Array/prototype/some/15.4.4.17-7-8.js # TypeError: Array.prototype.some called on incompatible receiver a data object. built-ins/Array/prototype/some/15.4.4.17-7-c-i-1.js # TypeError: Array.prototype.some called on incompatible receiver a data object. @@ -1032,19 +954,15 @@ built-ins/Map/iterable-calls-set.js # `Map.prototype.set` called twice. Expecte built-ins/Map/iterator-close-after-set-failure.js # TimeoutExceeded: Execution timed out after 5000ms. built-ins/Map/iterator-close-failure-after-set-failure.js # TimeoutExceeded: Execution timed out after 5000ms. built-ins/Map/map-iterable-throws-when-set-is-not-callable.js # Expected a TypeError to be thrown but no exception was thrown at all -built-ins/Map/prototype/forEach/second-parameter-as-callback-context.js # Expected SameValue(«undefined», «object») to be true built-ins/Math/sumPrecise/takes-iterable.js # Expected SameValue(«4», «3») to be true built-ins/Number/prototype/S15.7.3.1_A2_T1.js # Number.prototype.toString() must return "[object Number]" Expected SameValue(«"[object Object]"», «" built-ins/Number/prototype/S15.7.3.1_A2_T2.js # Number.prototype.toString() must return "[object Number]" Expected SameValue(«"[object Object]"», «" built-ins/Number/prototype/S15.7.3.1_A3.js # TypeError: Number.prototype.valueOf requires that '…' be a Number. built-ins/Number/prototype/S15.7.4_A1.js # TypeError: Number.prototype.valueOf requires that '…' be a Number. -built-ins/Number/prototype/toExponential/return-abrupt-tointeger-fractiondigits.js # valueOf Expected a Test262Error to be thrown but no exception was thrown at all built-ins/Number/prototype/toExponential/this-is-0-fractiondigits-is-0.js # TypeError: Number.prototype.toExponential requires that '…' be a Number. built-ins/Number/prototype/toFixed/S15.7.4.5_A1.1_T01.js # TypeError: Number.prototype.toFixed requires that '…' be a Number. -built-ins/Number/prototype/toFixed/toFixed-tonumber-throws-typeerror-toprimitive.js # TypeError is thrown when _fractionDigits_ cannot be converted to a primitive Expected a TypeError to built-ins/Number/prototype/toPrecision/return-abrupt-tointeger-precision.js # valueOf Expected a Test262Error but got a TypeError built-ins/Number/prototype/toPrecision/this-is-0-precision-is-1.js # TypeError: Number.prototype.toPrecision requires that '…' be a Number. -built-ins/Number/prototype/toString/numeric-literal-tostring-radix-poisoned.js # Expected a Test262Error but got a RangeError built-ins/Object/S15.2.1.1_A2_T1.js # TypeError: Object(boolean) wrapper objects are not supported; use the primitive value directly. built-ins/Object/S15.2.1.1_A2_T13.js # TypeError: Object(boolean) wrapper objects are not supported; use the primitive value directly. built-ins/Object/S15.2.1.1_A2_T2.js # TypeError: Object(number) wrapper objects are not supported; use the primitive value directly. @@ -1393,7 +1311,6 @@ built-ins/RegExp/prototype/exec/success-lastindex-access.js # Expected SameValu built-ins/RegExp/prototype/test/S15.10.6.3_A1_T7.js # The value of e is expected to be "intostr" Expected SameValue(«Test262Error: #1.1: /[a-z]/.test({toS built-ins/RegExp/prototype/test/S15.10.6.3_A1_T8.js # The value of e is expected to be "invalof" Expected SameValue(«Test262Error: #1.1: /[a-z]/.test({toS built-ins/Set/prototype/difference/size-is-a-number.js # TypeError: BigInt literals are not supported. -built-ins/Set/prototype/forEach/this-arg-explicit.js # `this` is `thisArg` Expected SameValue(«undefined», «object») to be true built-ins/Set/prototype/intersection/size-is-a-number.js # TypeError: BigInt literals are not supported. built-ins/Set/prototype/isDisjointFrom/set-like-iter-return.js # Expected SameValue(«4», «1») to be true built-ins/Set/prototype/isDisjointFrom/size-is-a-number.js # TypeError: BigInt literals are not supported. @@ -1415,104 +1332,16 @@ built-ins/String/prototype/S15.5.4_A1.js # #1: delete String.prototype.toString built-ins/String/prototype/S15.5.4_A2.js # #1: String.prototype =="". Actual: String.prototype ==[object Object] built-ins/String/prototype/S15.5.4_A3.js # #2: delete String.prototype.toString; String.prototype.toString() == "[object "+"String"+"]". Actual built-ins/String/prototype/Symbol.iterator/this-val-to-str-err.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/at/index-argument-tointeger.js # TypeError: String.at expects argument 1 to be a data value. built-ins/String/prototype/at/index-non-numeric-argument-tointeger.js # TypeError: String.at expects argument 1 to be a data value. -built-ins/String/prototype/charAt/S15.5.4.4_A1_T10.js # TypeError: String.charAt expects argument 1 to be a data value. built-ins/String/prototype/charAt/S15.5.4.4_A2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/String/prototype/charAt/S15.5.4.4_A5.js # #1.1: Exception === '…'. Actual: exception ===[object Error] -built-ins/String/prototype/charAt/pos-coerce-err.js # Expected a TypeError to be thrown but no exception was thrown at all -built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T10.js # TypeError: String.charCodeAt expects argument 1 to be a data value. built-ins/String/prototype/charCodeAt/S15.5.4.5_A2.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/String/prototype/charCodeAt/S15.5.4.5_A4.js # #1.1: Exception === '…'. Actual: exception ===[object Error] -built-ins/String/prototype/charCodeAt/pos-coerce-err.js # Expected a TypeError to be thrown but no exception was thrown at all -built-ins/String/prototype/codePointAt/return-abrupt-from-object-pos-to-integer.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/codePointAt/return-abrupt-from-this.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/concat/S15.5.4.6_A1_T10.js # TypeError: String.concat expects argument 1 to be a data value. -built-ins/String/prototype/concat/S15.5.4.6_A4_T1.js # #1: var x; __instance = {toString:function(){return "one"}}; __instance.concat = String.prototype.co -built-ins/String/prototype/concat/S15.5.4.6_A4_T2.js # #1: e === "intostring". Actual: TypeError: String.concat expects argument 1 to be a data value. built-ins/String/prototype/constructor/S15.5.4.1_A1_T2.js # TypeError: new __constr(...) is not supported; call __constr(...) without new instead. -built-ins/String/prototype/endsWith/return-abrupt-from-position.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/endsWith/return-abrupt-from-searchstring.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/endsWith/return-abrupt-from-this.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/includes/return-abrupt-from-position.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/includes/return-abrupt-from-searchstring.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/includes/return-abrupt-from-this.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/indexOf/S15.5.4.7_A1_T10.js # TypeError: String.indexOf expects argument 1 to be a data value. -built-ins/String/prototype/indexOf/S15.5.4.7_A4_T1.js # #1.1: Exception === "intointeger". Actual: TypeError: String.indexOf expects argument 1 to be a data -built-ins/String/prototype/indexOf/S15.5.4.7_A4_T3.js # TypeError: String.indexOf expects argument 1 to be a data value. -built-ins/String/prototype/isWellFormed/to-string.js # coerces the receiver to a string Expected a Test262Error to be thrown but no exception was thrown at -built-ins/String/prototype/lastIndexOf/S15.5.4.8_A1_T10.js # TypeError: String.lastIndexOf expects argument 1 to be a data value. -built-ins/String/prototype/lastIndexOf/S15.5.4.8_A4_T1.js # #1.1: Exception === "intointeger". Actual: TypeError: String.lastIndexOf expects argument 1 to be a -built-ins/String/prototype/lastIndexOf/S15.5.4.8_A4_T3.js # TypeError: String.lastIndexOf expects argument 1 to be a data value. -built-ins/String/prototype/match/S15.5.4.10_A1_T10.js # TypeError: Cannot read properties of null (reading '…'). -built-ins/String/prototype/match/S15.5.4.10_A1_T11.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/match/S15.5.4.10_A1_T13.js # TypeError: Cannot read properties of null (reading '…'). -built-ins/String/prototype/normalize/return-abrupt-from-form.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/normalize/return-abrupt-from-this.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/normalize/return-normalized-string-from-coerced-form.js # TypeError: String.normalize expects argument 1 to be a data value. -built-ins/String/prototype/padEnd/exception-not-object-coercible.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/padEnd/observable-operations.js # TypeError: String.padEnd expects argument 1 to be a data value. -built-ins/String/prototype/padStart/exception-not-object-coercible.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/padStart/observable-operations.js # TypeError: String.padStart expects argument 1 to be a data value. built-ins/String/prototype/repeat/count-coerced-to-zero-returns-empty-string.js # RangeError: String.repeat expects a finite non-negative count. -built-ins/String/prototype/repeat/return-abrupt-from-count.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/repeat/return-abrupt-from-this.js # Expected a Test262Error but got a RangeError -built-ins/String/prototype/replace/S15.5.4.11_A1_T10.js # TypeError: String.replace expects argument 1 to be a data value. -built-ins/String/prototype/replace/S15.5.4.11_A1_T11.js # #1.1: Exception === "insearchValue". Actual: TypeError: String.replace expects argument 1 to be a da -built-ins/String/prototype/replace/S15.5.4.11_A1_T13.js # #1.1: Exception === "inreplaceValue". Actual: TypeError: String.replace expects argument 1 to be a d -built-ins/String/prototype/replace/replaceValue-evaluation-order-regexp-object.js # Expected SameValue(«0», «1») to be true -built-ins/String/prototype/replace/replaceValue-evaluation-order.js # TypeError: String.replace expects argument 2 to be a data value. -built-ins/String/prototype/replace/tostring-this-throws-toprimitive.js # String.prototype.replace should throw a TypeError in its ToPrimitive step. Expected a TypeError to b -built-ins/String/prototype/search/S15.5.4.12_A1_T10.js # #1: var __obj = {toString:function(){return "AB";}}; var __str = "ssABBABABAB"; __str.search(__obj) -built-ins/String/prototype/search/S15.5.4.12_A1_T11.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/search/S15.5.4.12_A1_T13.js # #1: var __obj = {toString:function(){return {};},valueOf:function(){return 1;}}; "ABB\u0041B\u0031AB -built-ins/String/prototype/slice/S15.5.4.13_A1_T10.js # TypeError: String.slice expects argument 1 to be a data value. -built-ins/String/prototype/slice/S15.5.4.13_A1_T11.js # #1.1: Exception === "instart". Actual: TypeError: String.slice expects argument 1 to be a data value -built-ins/String/prototype/slice/S15.5.4.13_A1_T13.js # #1.1: Exception === "inend". Actual: TypeError: String.slice expects argument 1 to be a data value. -built-ins/String/prototype/slice/S15.5.4.13_A3_T3.js # #1: __instance = function(){}; __instance.slice = String.prototype.slice; __instance.slice(-Infinity built-ins/String/prototype/slice/S15.5.4.13_A3_T4.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/String/prototype/slice/this-value-tostring-throws-toprimitive.js # String.prototype.slice throws in its toprimitive step. Expected a TypeError to be thrown but no exce -built-ins/String/prototype/split/instance-is-function.js # __split[0].substring(0, 8) must return "function" Expected SameValue(«"[object "», «"function"») to built-ins/String/prototype/split/instance-is-math.js # The value of __split[0] is "[object Math]" Expected SameValue(«"[object Object]"», «"[object Math]"» -built-ins/String/prototype/split/separator-override-tostring-limit-override-valueof-throws.js # The value of `e` is "intointeger" Expected SameValue(«TypeError: String.split expects argument 2 to -built-ins/String/prototype/split/separator-override-tostring-limit-override-valueof-tostring.js # TypeError: String.split expects argument 2 to be a data value. -built-ins/String/prototype/split/separator-override-tostring-limit-override-valueof.js # TypeError: String.split expects argument 2 to be a data value. built-ins/String/prototype/split/separator-tostring-error.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/String/prototype/split/separator-undef-limit-custom.js # TypeError: String.split expects argument 2 to be a data value. -built-ins/String/prototype/split/separator-undef-limit-zero.js # TypeError: String.split expects argument 2 to be a data value. built-ins/String/prototype/split/transferred-to-custom.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/String/prototype/split/valueOf-is-called-for-limit-argument.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/startsWith/return-abrupt-from-position.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/startsWith/return-abrupt-from-searchstring.js # Expected a Test262Error but got a TypeError -built-ins/String/prototype/startsWith/return-abrupt-from-this.js # Expected a Test262Error to be thrown but no exception was thrown at all -built-ins/String/prototype/substring/S15.5.4.15_A1_T10.js # TypeError: String.substring expects argument 1 to be a data value. -built-ins/String/prototype/substring/S15.5.4.15_A1_T11.js # #1.1: Exception === "instart". Actual: TypeError: String.substring expects argument 1 to be a data v -built-ins/String/prototype/substring/S15.5.4.15_A1_T13.js # #1.1: Exception === "inend". Actual: TypeError: String.substring expects argument 1 to be a data val built-ins/String/prototype/substring/S15.5.4.15_A3_T10.js # TypeError: Cannot read properties of undefined (reading '…'). -built-ins/String/prototype/substring/S15.5.4.15_A3_T7.js # #1: __instance = function(){}; __instance.substring = String.prototype.substring; __instance.substr -built-ins/String/prototype/substring/this-value-tostring-throws-toprimitive.js # String.prototype.substring throws in its toprimitive step. Expected a TypeError to be thrown but no -built-ins/String/prototype/toLocaleLowerCase/S15.5.4.17_A1_T10.js # #1: var __obj = {toString:function(){return "AB";}}; __obj.toLocaleLowerCase = String.prototype.toLo -built-ins/String/prototype/toLocaleLowerCase/S15.5.4.17_A1_T11.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toLocaleLowerCase/S15.5.4.17_A1_T12.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toLocaleLowerCase/S15.5.4.17_A1_T13.js # #1: var __obj = {toString:function(){return {};},valueOf:function(){return 1;}}; __obj.toLocaleLower -built-ins/String/prototype/toLocaleUpperCase/S15.5.4.19_A1_T10.js # #1: var __obj = {toString:function(){return "Ab";}}; __obj.toLocaleUpperCase = String.prototype.toLo -built-ins/String/prototype/toLocaleUpperCase/S15.5.4.19_A1_T11.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toLocaleUpperCase/S15.5.4.19_A1_T12.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toLocaleUpperCase/S15.5.4.19_A1_T13.js # #1: var __obj = {toString:function(){return {};},valueOf:function(){return 1;}}; __obj.toLocaleUpper -built-ins/String/prototype/toLowerCase/S15.5.4.16_A1_T10.js # #1: var __obj = {toString:function(){return "AB";}}; __obj.toLowerCase = String.prototype.toLowerCas -built-ins/String/prototype/toLowerCase/S15.5.4.16_A1_T11.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toLowerCase/S15.5.4.16_A1_T12.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toLowerCase/S15.5.4.16_A1_T13.js # #1: var __obj = {toString:function(){return {};},valueOf:function(){return 1;}}; __obj.toLowerCase = -built-ins/String/prototype/toLowerCase/this-value-tostring-throws-toprimitive.js # String.prototype.toLowerCase throws in its toprimitive step. Expected a TypeError to be thrown but n -built-ins/String/prototype/toUpperCase/S15.5.4.18_A1_T10.js # #1: var __obj = {toString:function(){return "Ab";}}; __obj.toUpperCase = String.prototype.toUpperCas -built-ins/String/prototype/toUpperCase/S15.5.4.18_A1_T11.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toUpperCase/S15.5.4.18_A1_T12.js # #1.1: Exception === "intostr". Actual: [object Error] -built-ins/String/prototype/toUpperCase/S15.5.4.18_A1_T13.js # #1: var __obj = {toString:function(){return {};},valueOf:function(){return 1;}}; __obj.toUpperCase = -built-ins/String/prototype/toWellFormed/to-string.js # coerces the receiver to a string Expected a Test262Error to be thrown but no exception was thrown at -built-ins/String/prototype/trim/15.5.4.20-2-38.js # String.prototype.trim.call(obj) Expected SameValue(«"[object Object]"», «"abc"») to be true -built-ins/String/prototype/trim/15.5.4.20-2-40.js # String.prototype.trim.call(obj) Expected SameValue(«"[object Object]"», «"abc"») to be true -built-ins/String/prototype/trim/15.5.4.20-2-41.js # String.prototype.trim.call(obj) Expected SameValue(«"[object Object]"», «"abc"») to be true -built-ins/String/prototype/trim/15.5.4.20-2-42.js # Expected a TypeError to be thrown but no exception was thrown at all built-ins/String/prototype/trim/15.5.4.20-2-43.js # TypeError: Con cannot be constructed: user-defined constructors and classes are not supported. Call built-ins/decodeURI/S15.1.3.1_A1.10_T1.js # Execution exceeded the maximum nesting depth. built-ins/decodeURI/S15.1.3.1_A1.11_T1.js # Execution exceeded the maximum nesting depth. @@ -1686,7 +1515,6 @@ language/expressions/new/spread-sngl-iter.js # TypeError: The called value cann language/expressions/new/spread-sngl-literal.js # TypeError: The called value cannot be constructed: user-defined constructors and classes are not sup language/expressions/object/__proto__-duplicate-computed.js # prototype is defined Expected SameValue(«object», «object») to be true language/expressions/object/accessor-name-literal-string-line-continuation.js # TypeError: Only init object properties are supported. -language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js # Expected SameValue(«undefined», «"ok"») to be true language/expressions/object/dstr/async-gen-meth-ary-init-iter-get-err-array-prototype.js # Expected a TypeError to be thrown but no exception was thrown at all language/expressions/object/dstr/async-gen-meth-ary-ptrn-elem-id-iter-val-array-prototype.js # Expected SameValue(«3», «42») to be true language/expressions/object/dstr/async-gen-meth-dflt-ary-init-iter-get-err-array-prototype.js # Expected a TypeError to be thrown but no exception was thrown at all