mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
- Compile the production validator and exercise native IR construction and validation on C and LLVM. - Preserve Error causes, wider callbacks, and discriminated JSON layouts in static programs. - Version the IR and runtime ABI and cover the new compiler paths with differential and sanitizer tests.
63 lines
2.3 KiB
TypeScript
63 lines
2.3 KiB
TypeScript
export {};
|
|
|
|
// Data-bearing class options cross the typed-reference boundary lazily.
|
|
class Options {
|
|
cause: string;
|
|
constructor(cause: string) { this.cause = cause; }
|
|
}
|
|
class DerivedOptions extends Options {}
|
|
function wrap(options: ErrorOptions): Error {
|
|
return new Error("wrapped", options);
|
|
}
|
|
const options = new DerivedOptions("first");
|
|
const forwarded: ErrorOptions = options;
|
|
options.cause = "second";
|
|
const error = wrap(forwarded);
|
|
options.cause = "third";
|
|
console.log("class options", error.message, error.cause, "cause" in error);
|
|
|
|
// An ordinary data record and the named interface agree about presence.
|
|
const record = { cause: "record" };
|
|
console.log("record options", new TypeError("typed", record).cause);
|
|
const empty: ErrorOptions = {};
|
|
const present: ErrorOptions = { cause: undefined };
|
|
console.log("presence", "cause" in wrap(empty), "cause" in wrap(present));
|
|
|
|
// Passing options through a closure must preserve identity of its cause.
|
|
const root: Error = new Error("root", { cause: "deep" });
|
|
function wrapper(cause: unknown): () => Error {
|
|
const saved: ErrorOptions = { cause };
|
|
return () => new Error("outer", saved);
|
|
}
|
|
const make = wrapper(root);
|
|
const outer = make();
|
|
const nested = outer.cause;
|
|
if (nested instanceof Error) {
|
|
console.log("nested", nested === root, nested.message, nested.cause);
|
|
}
|
|
|
|
// Argument evaluation happens before message conversion; conversion may
|
|
// throw before super returns and before subclass field initialization.
|
|
let order = "";
|
|
function getOptions(): ErrorOptions { order += "options;"; return { cause: 3 }; }
|
|
const message: any = {
|
|
toString(): string { order += "toString;"; return "converted"; },
|
|
};
|
|
console.log("message", new Error(message, getOptions()).message, order);
|
|
let initialized = 0;
|
|
function field(): string { initialized++; return "field"; }
|
|
class Failing extends Error {
|
|
detail = field();
|
|
constructor(message: any) { super(message, { cause: "owned" }); }
|
|
}
|
|
const throwing: any = { toString(): string { throw new RangeError("coercion"); } };
|
|
for (let i = 0; i < 20; i++) {
|
|
try { new Failing(throwing); }
|
|
catch (caught) {
|
|
if (i === 0 && caught instanceof Error) console.log("throw", caught.name, caught.message);
|
|
}
|
|
}
|
|
try { new Error(throwing); }
|
|
catch (caught) { if (caught instanceof Error) console.log("builtin throw", caught.message); }
|
|
console.log("initializers", initialized);
|