mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-21 05:50:55 +08:00
Throw checked-dynamic primitives as primitives so catch typeof tests see them (#1510)
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/6480-catch-typeof-untyped-throws.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -6421,6 +6421,28 @@ void scr_dyn_throw(ScrDyn *d) {
|
||||
scr_dyn_release(d);
|
||||
return;
|
||||
}
|
||||
/* A checked-dynamic primitive throws as the primitive itself, as a
|
||||
* statically typed `throw 5` does: catch bindings test and extract the
|
||||
* same snapshot kinds (`typeof e === "number"`), and a primitive has no
|
||||
* identity to keep. */
|
||||
if (d->kind == SCR_DYN_NUM) {
|
||||
double value = d->v.num;
|
||||
scr_dyn_release(d);
|
||||
scr_throw_f64(value);
|
||||
return;
|
||||
}
|
||||
if (d->kind == SCR_DYN_BOOL) {
|
||||
bool value = d->v.b;
|
||||
scr_dyn_release(d);
|
||||
scr_throw_bool(value);
|
||||
return;
|
||||
}
|
||||
if (d->kind == SCR_DYN_STR) {
|
||||
ScrStr *value = scr_str_retain(d->v.str);
|
||||
scr_dyn_release(d);
|
||||
scr_throw_str(value);
|
||||
return;
|
||||
}
|
||||
scr_throw_ref_classified(d, scr_dyn_retain_v, scr_dyn_release_v,
|
||||
scr_dyn_trace_v, scr_dyn_is_object(d));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Values thrown from `unknown` storage read back through typeof tests on
|
||||
// the catch binding, like the same values thrown with static types.
|
||||
const thrown: unknown[] = [5, 0, -1.5, "text", "", true, false, null, undefined, { kind: "box" }];
|
||||
function describe(value: unknown): string {
|
||||
try {
|
||||
throw value;
|
||||
} catch (e) {
|
||||
const same = e === value;
|
||||
if (typeof e === "number") return `${same} number ${e + 1}`;
|
||||
if (typeof e === "string") return `${same} string ${e.length}`;
|
||||
if (typeof e === "boolean") return `${same} boolean ${!e}`;
|
||||
if (typeof e === "object") return `${same} object ${e === null ? "null" : "value"}`;
|
||||
return `${same} ${typeof e}`;
|
||||
}
|
||||
}
|
||||
for (const value of thrown) console.log(describe(value));
|
||||
function rethrow(value: unknown): void {
|
||||
try {
|
||||
throw value;
|
||||
} catch (e) {
|
||||
if (typeof e !== "string") throw e;
|
||||
console.log("kept string", e);
|
||||
}
|
||||
}
|
||||
for (const value of ["s", 7, false]) {
|
||||
try {
|
||||
rethrow(value);
|
||||
} catch (e) {
|
||||
console.log("rethrown", typeof e, String(e));
|
||||
}
|
||||
}
|
||||
let count = 0;
|
||||
for (const value of thrown) {
|
||||
try {
|
||||
throw value;
|
||||
} catch (e) {
|
||||
if (typeof e === "number" && e > 0) count += e;
|
||||
}
|
||||
}
|
||||
console.log(count);
|
||||
Reference in New Issue
Block a user