diff --git a/packages/compiler/src/frontend/lowering/expressions/object-literals.ts b/packages/compiler/src/frontend/lowering/expressions/object-literals.ts index a2f399e34..93bf43e95 100644 --- a/packages/compiler/src/frontend/lowering/expressions/object-literals.ts +++ b/packages/compiler/src/frontend/lowering/expressions/object-literals.ts @@ -36,7 +36,6 @@ import { tryLowerExpression } from "./try-lower-expression.js"; import { fenceSymbolFieldCopy } from "../symbol-fields.js"; import { planUnionRetag } from "../union-retag.js"; import { jsHoldsDynObject, runtimeOptionalStorageOperand } from "../lower-exprs.js"; -import { builtinGlobalValue } from "./property-access.js"; /** `{ a: 1, b: "x" }` → recordLit. The record type comes from the * contextual type when tsc has one (annotated declarations, arguments, @@ -395,11 +394,9 @@ export function lowerDynObjectLiteral( const lowerValue = (): IrExpr => ts.isMethodDeclaration(prop) ? lowerer.lowerLambda(prop, true) - : ts.isShorthandPropertyAssignment(prop) && shorthandBuiltinValue(lowerer, prop) - ? shorthandBuiltinValue(lowerer, prop)! - : !boxValue && ts.isObjectLiteralExpression(valueExpr) - ? lowerer.lowerExprExpecting(valueExpr, DYN) - : lowerer.lowerExpr(valueExpr as ts.Expression); + : !boxValue && ts.isObjectLiteralExpression(valueExpr) + ? lowerer.lowerExprExpecting(valueExpr, DYN) + : lowerer.lowerExpr(valueExpr as ts.Expression); raw = fenceClosureProbe(lowerer, valueExpr, undefined, lowerValue) ?? lowerValue(); } catch (err) { // A PURE member read a JS file cannot lower (a namespace object @@ -3157,20 +3154,6 @@ function lowerDeclaredSpreadMerge( /** The value of a shorthand property (`{ x }`): the binding `x` refers to. * The property name's own symbol is the PROPERTY, so resolution goes * through getShorthandAssignmentValueSymbol. */ -/** `{ TypeError }`: a stdlib global in shorthand position reads as the value - * its name reads as elsewhere (the interned constructor or function value), - * or null when the global has no such value. The shorthand's name carries - * the property's symbol, so the identifier path cannot resolve it. */ -function shorthandBuiltinValue( - lowerer: Lowerer, - prop: ts.ShorthandPropertyAssignment, -): IrExpr | null { - const symbol = lowerer.checker.getShorthandAssignmentValueSymbol(prop); - if (!symbol || !lowerer.isStdlibSymbol(symbol)) return null; - const js = isJsSourceFile(ts.getSourceFileOfNode(prop)); - return builtinGlobalValue(ts.symbolName(symbol), locOf(prop.name), js); -} - export function lowerShorthandValue( lowerer: Lowerer, prop: ts.ShorthandPropertyAssignment, @@ -3187,8 +3170,6 @@ export function lowerShorthandValue( const callable = lowerer.lowerBuiltinCallableValue(builtin, loc); if (callable) return callable; } - const builtinValue = shorthandBuiltinValue(lowerer, prop); - if (builtinValue) return builtinValue; if (symbol) { if (lowerer.ctx.selfSymbol === symbol) { return { kind: "selfRef", type: lowerer.ctx.selfType!, loc }; diff --git a/packages/compiler/src/frontend/lowering/expressions/property-access.ts b/packages/compiler/src/frontend/lowering/expressions/property-access.ts index d66110950..06186c4dc 100644 --- a/packages/compiler/src/frontend/lowering/expressions/property-access.ts +++ b/packages/compiler/src/frontend/lowering/expressions/property-access.ts @@ -4024,26 +4024,10 @@ function lowerStreamObjectProperty( return lowerStreamProperty(lowerer, expr, info); } -/** The error constructors among GLOBAL_CONSTRUCTOR_VALUES. Their statics - * (`Error.stackTraceLimit`, `Error.captureStackTrace`) keep their own - * lowerings, so fenceBuiltinConstructorStaticRead leaves them alone. */ -const ERROR_CONSTRUCTOR_VALUES: ReadonlySet = new Set([ - "Error", - "TypeError", - "RangeError", - "SyntaxError", - "ReferenceError", - "EvalError", - "URIError", - "AggregateError", -]); - /** The builtin constructors JavaScript sources read as real function * values rather than identity tokens: the runtime interns one function per * constructor, and dynamic values answer `.constructor` with the same one, - * so `o.constructor === Object` and `err.constructor === TypeError` are - * exact identity tests, and `err.constructor.name` is the constructor's - * name. */ + * so `o.constructor === Object` is an exact identity test. */ const GLOBAL_CONSTRUCTOR_VALUES: ReadonlySet = new Set([ "Object", "Function", @@ -4054,7 +4038,6 @@ const GLOBAL_CONSTRUCTOR_VALUES: ReadonlySet = new Set([ "Promise", "WeakMap", "WeakSet", - ...ERROR_CONSTRUCTOR_VALUES, ]); /** The builtin global functions JavaScript sources read as interned @@ -4197,7 +4180,6 @@ function fenceBuiltinConstructorStaticRead( symbol !== undefined && ts.symbolName(symbol).endsWith("Constructor") && GLOBAL_CONSTRUCTOR_VALUES.has(ts.symbolName(symbol).slice(0, -"Constructor".length)) && - !ERROR_CONSTRUCTOR_VALUES.has(ts.symbolName(symbol).slice(0, -"Constructor".length)) && lowerer.isStdlibSymbol(symbol) ) lowerer.stdlibMemberFence(access); diff --git a/packages/compiler/src/frontend/lowering/lower-stmts.ts b/packages/compiler/src/frontend/lowering/lower-stmts.ts index 7dc0b87cc..84c54307a 100644 --- a/packages/compiler/src/frontend/lowering/lower-stmts.ts +++ b/packages/compiler/src/frontend/lowering/lower-stmts.ts @@ -3889,9 +3889,6 @@ function stdlibGlobalTokenDestructure( if (decl.initializer === undefined || !isJsSourceFile(ts.getSourceFileOfNode(decl))) return null; const globalName = stdlibGlobalNameOf(lowerer, decl.initializer); if (globalName === null) return null; - // `workerData` is a value (the data the worker was started with), not an - // API surface: its members destructure as any untyped value's do. - if (globalName === "workerData") return null; if (!ts.isObjectBindingPattern(decl.name)) { lowerer.unsupported( "SC1031", diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6870-error-constructor-values.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6870-error-constructor-values.js.json deleted file mode 100644 index a2f0e02ea..000000000 --- a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6870-error-constructor-values.js.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "order": [ - "/tests/corpus/6870-error-constructor-values.js" - ], - "diags": [] -} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6871-worker-data-destructuring.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6871-worker-data-destructuring.cjs.json deleted file mode 100644 index b610a5878..000000000 --- a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6871-worker-data-destructuring.cjs.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "order": [ - "/tests/corpus/6871-worker-data-destructuring.cjs" - ], - "diags": [] -} diff --git a/packages/runtime/src/scr_dyn.h b/packages/runtime/src/scr_dyn.h index 1d8a7f1d4..cafc8d07e 100644 --- a/packages/runtime/src/scr_dyn.h +++ b/packages/runtime/src/scr_dyn.h @@ -725,9 +725,6 @@ ScrDyn *scr_dyn_array_constructor(void); /* The interned builtin constructor `name` (Object, Date, RegExp, Map, Set, * Promise, WeakMap, WeakSet) as a dynamic function value: +1. */ ScrDyn *scr_dyn_global_constructor(const ScrStr *name); -/* The interned function value of an error constructor ("TypeError"), or - * NULL for other names. */ -ScrDyn *scr_dyn_error_constructor(const char *name); /* A builtin global function (setTimeout, setImmediate, process.nextTick, ...) * as an interned dynamic function value: +1. */ ScrDyn *scr_dyn_builtin_function(const ScrStr *name); diff --git a/packages/runtime/src/scr_dyn_invoke.c b/packages/runtime/src/scr_dyn_invoke.c index 7b375018b..2a010f213 100644 --- a/packages/runtime/src/scr_dyn_invoke.c +++ b/packages/runtime/src/scr_dyn_invoke.c @@ -1913,8 +1913,6 @@ static ScrDyn *dyn_function_constructor(void) { ScrDyn *scr_dyn_global_constructor(const ScrStr *name) { if (strcmp(name->data, dyn_s20) == 0) return dyn_function_constructor(); - ScrDyn *error = scr_dyn_error_constructor(name->data); - if (error) return error; ScrDyn *ctor = dyn_global_ctor(name->data); if (!ctor) scr_trap(dyn_s3); return ctor; diff --git a/packages/runtime/src/scr_json.c b/packages/runtime/src/scr_json.c index 57846b041..194ade887 100644 --- a/packages/runtime/src/scr_json.c +++ b/packages/runtime/src/scr_json.c @@ -1801,55 +1801,6 @@ static void scr_builtin_object_prototype_cleanup(void) { scr_dyn_release(prototype); } -/* The error constructors as values (an error's `constructor`, and the - * globals in JavaScript): one interned function per constructor and thread, - * indexed like scr_error_vts, with the constructor's name and length. - * Calling one through the value is not supported yet, as for the other - * interned constructors (scr_dyn_global_constructor). */ -static const char *const scr_error_ctor_names[] = { - "Error", "TypeError", "RangeError", "SyntaxError", NULL, - "ReferenceError", "EvalError", "URIError", "AggregateError", -}; -#define SCR_ERROR_CTORS (sizeof scr_error_ctor_names / sizeof scr_error_ctor_names[0]) -static SCR_TL ScrDyn *scr_error_ctor_values[SCR_ERROR_CTORS]; -static SCR_TL bool scr_error_ctors_registered; - -static void scr_error_ctors_cleanup(void) { - for (size_t i = 0; i < SCR_ERROR_CTORS; i++) { - scr_dyn_release(scr_error_ctor_values[i]); - scr_error_ctor_values[i] = NULL; - } -} - -static ScrDyn *scr_error_ctor_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) { - (void)args; - (void)argc; - char message[128]; - int length = snprintf(message, sizeof message, - "calling the %s constructor through a stored value is not supported yet", - (const char *)closure->fn); - scr_throw_error_msg_code(SCR_ERR_ERROR, message, (size_t)length, "SC2020"); - return NULL; -} - -ScrDyn *scr_dyn_error_constructor(const char *name) { - for (size_t i = 0; i < SCR_ERROR_CTORS; i++) { - if (!scr_error_ctor_names[i] || strcmp(scr_error_ctor_names[i], name) != 0) continue; - if (!scr_error_ctors_registered) { - scr_error_ctors_registered = true; - scr_atexit(scr_error_ctors_cleanup); - } - if (!scr_error_ctor_values[i]) { - uint32_t length = strcmp(name, "AggregateError") == 0 ? 2 : 1; - scr_error_ctor_values[i] = - scr_dyn_new_func(scr_closure_new((void *)scr_error_ctor_names[i], 0), scr_error_ctor_call, length, - "native:constructor", scr_error_ctor_names[i]); - } - return scr_dyn_retain(scr_error_ctor_values[i]); - } - return NULL; -} - ScrDyn *scr_dyn_object_prototype(void) { if (!scr_builtin_object_prototype) { scr_builtin_object_prototype = scr_dyn_alloc(SCR_DYN_OBJ); @@ -7756,17 +7707,6 @@ ScrStr *scr_dyn_to_string(const ScrDyn *d, const ScrStr *enc) { return out; } case SCR_DYN_FUNC: { - /* The interned builtin constructors print with their names, as in Node - * (function Map() { [native code] }); other functions without a source - * text print the anonymous native form. */ - if (d->v.fn.sig && strcmp(d->v.fn.sig, "native:constructor") == 0 && d->v.fn.name) { - ScrJsonBuf b; - scr_jb_init(&b); - scr_jb_puts(&b, "function "); - scr_jb_puts(&b, d->v.fn.name); - scr_jb_puts(&b, "() { [native code] }"); - return scr_jb_finish(&b); - } static const char f[] = "function () { [native code] }"; return scr_str_new(f, sizeof f - 1); } @@ -11720,18 +11660,21 @@ static ScrDyn *scr_dyn_obj_read_receiver(const ScrDyn *d, const char *key, size_ ScrDyn *own = scr_dyn_obj_get(d, key, key_len); if (own) return scr_dyn_retain(own); if (key_len == 11 && memcmp(key, "constructor", 11) == 0) { - /* An error's constructor: the interned function value its global - * reads as (scr_dyn_error_constructor). */ - static const char *const names[] = { - "Error", "TypeError", "RangeError", "SyntaxError", NULL, - "ReferenceError", "EvalError", "URIError", "AggregateError", + static const char *const tokens[] = { + "[builtin Error]", "[builtin TypeError]", + "[builtin RangeError]", "[builtin SyntaxError]", + NULL, "[builtin ReferenceError]", "[builtin EvalError]", "[builtin URIError]", + "[builtin AggregateError]", }; size_t hit = scr_errdyn_find(d, false); const ScrVt *vt = hit == SIZE_MAX ? NULL : scr_errdyn_cache[hit].err->vt; - for (size_t kind = 0; vt && kind < sizeof names / sizeof names[0]; kind++) { - if (!names[kind]) continue; + for (size_t kind = 0; vt && kind < sizeof tokens / sizeof tokens[0]; kind++) { + if (!tokens[kind]) continue; if (vt != &scr_error_vts[kind]) continue; - return scr_dyn_error_constructor(names[kind]); + ScrStr *token = scr_str_new(tokens[kind], strlen(tokens[kind])); + ScrDyn *result = scr_dyn_new_str(token); + scr_str_release(token); + return result; } } return scr_dyn_retain(scr_dyn_undefined()); diff --git a/tests/corpus/6870-error-constructor-values.js b/tests/corpus/6870-error-constructor-values.js deleted file mode 100644 index 81f5086d2..000000000 --- a/tests/corpus/6870-error-constructor-values.js +++ /dev/null @@ -1,55 +0,0 @@ -// The error constructors as values in JavaScript: an error's `constructor` -// is the same function the global names, whose name, length, typeof and -// String() are Node's, for errors the program throws, errors the runtime -// throws, and errors read back from catch bindings and containers. -function describe(label, error) { - const ctor = error.constructor; - console.log(label, error.name, error.constructor.name, typeof ctor, ctor.length, String(ctor)); -} - -describe('Error', new Error('e')); -describe('TypeError', new TypeError('t')); -describe('RangeError', new RangeError('r')); -describe('SyntaxError', new SyntaxError('s')); -describe('ReferenceError', new ReferenceError('f')); -describe('EvalError', new EvalError('v')); -describe('URIError', new URIError('u')); -describe('AggregateError', new AggregateError([], 'a')); - -const thrown = [ - () => JSON.parse('{'), - () => { - const holder = JSON.parse('{"value":null}'); - return holder.value.missing; - }, - () => new Array(-1), - () => decodeURIComponent('%'), - () => { - throw new TypeError('own'); - }, -]; -const constructors = { SyntaxError, TypeError, RangeError, URIError }; -const caught = []; -for (const run of thrown) { - try { - run(); - } catch (error) { - caught.push(error); - console.log('caught', error.constructor.name, error.constructor === constructors[error.name]); - } -} - -const byName = new Map(); -for (const error of caught) byName.set(error.constructor.name, (byName.get(error.constructor.name) ?? 0) + 1); -console.log('kinds', JSON.stringify([...byName])); - -console.log('identity', new TypeError('x').constructor === TypeError, new RangeError('x').constructor === TypeError); -console.log('globals', Error.name, TypeError.length, AggregateError.length, typeof RangeError, String(SyntaxError)); - -const renamed = new TypeError('x'); -renamed.name = 'Custom'; -console.log('renamed', renamed.name, renamed.constructor.name); - -class ParseFailure extends SyntaxError {} -const failure = new ParseFailure('p'); -console.log('subclass', failure.name, failure.constructor.name, failure instanceof SyntaxError); diff --git a/tests/corpus/6871-worker-data-destructuring.cjs b/tests/corpus/6871-worker-data-destructuring.cjs deleted file mode 100644 index 63ae789bd..000000000 --- a/tests/corpus/6871-worker-data-destructuring.cjs +++ /dev/null @@ -1,30 +0,0 @@ -// Destructuring the members of a worker's workerData in JavaScript: plain, -// renamed, defaulted, nested and rest bindings read the data the worker was -// started with, as reading `workerData.` does. -'use strict'; -const { Worker, isMainThread, parentPort, workerData } = require('node:worker_threads'); - -if (isMainThread) { - const sab = new SharedArrayBuffer(8); - const data = { name: 'job-7', size: 3, options: { verbose: true, tags: ['a', 'b'] }, counters: new Int32Array(sab), extra: 1, more: 'x' }; - const worker = new Worker(__filename, { workerData: data }); - worker.on('message', (lines) => { - for (const line of lines) console.log(line); - console.log('main sees', new Int32Array(sab)[0]); - }); -} else { - const lines = []; - const { name, size } = workerData; - lines.push(`plain ${name} ${size}`); - const { name: jobName, missing = 'fallback', size: count = 10 } = workerData; - lines.push(`renamed ${jobName} ${missing} ${count}`); - const { - options: { verbose, tags: [firstTag, ...otherTags] }, - } = workerData; - lines.push(`nested ${verbose} ${firstTag} ${JSON.stringify(otherTags)}`); - const { name: ignored, size: alsoIgnored, options, counters, ...rest } = workerData; - lines.push(`rest ${JSON.stringify(rest)} ${typeof options} ${ignored === name && alsoIgnored === size}`); - counters[0] = 41; - counters[0] += 1; - parentPort.postMessage(lines); -} diff --git a/tests/harness/corpus-costs/6870-error-constructor-values.js.json b/tests/harness/corpus-costs/6870-error-constructor-values.js.json deleted file mode 100644 index c608ce33a..000000000 --- a/tests/harness/corpus-costs/6870-error-constructor-values.js.json +++ /dev/null @@ -1 +0,0 @@ -{ "plain": 1200, "san": 3400 } diff --git a/tests/harness/corpus-costs/6871-worker-data-destructuring.cjs.json b/tests/harness/corpus-costs/6871-worker-data-destructuring.cjs.json deleted file mode 100644 index d6c0cb9ee..000000000 --- a/tests/harness/corpus-costs/6871-worker-data-destructuring.cjs.json +++ /dev/null @@ -1 +0,0 @@ -{ "plain": 1300, "san": 3490 }