mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-17 05:09:24 +08:00
- The library trap funnel (scr_library.c) now assembles every detected trap into the ratified 0x01 text 0x1F code 0x1F symbol [0x1F remediation] form: the baseline human line rides unchanged as field 0, and 0x01-led messages (facade-authored throws, the compile-time SC4012 contract trap) still pass verbatim. - Trap kinds classify over the runtime's own message conventions into a new SC4013-SC4019 runtime code family (escaped exception, range, type, syntax, OOM, internal invariant, residual), documented beside SC4012 in the diagnostics registry; no arithmetic kind exists because no runtime site can fire one. - Every generated entry prologue (init, reset, collect, each export, both emissions) records its external symbol in a SCR_LIB-only static slot the funnel reads, so the structured message names the trapping entry as the host linked it; profile teachings/remediations for the family land as a program-TU overlay table both backends emit identically. - K5/K7/init-trap fixtures now pin the structured layout with the spec's parse rule (default text, code, entry symbol, fields=3 on a no-teachings profile), and new K12 tests pin the SC4014 teaching/remediation overlay plus the undeclared-code default; the verbatim and text-leads-printable pins stay. - The default executable lane is byte-identical (signature-stripped cmp over a stash/rebuild pair); all library suites and the diagnostics suite are green on both emissions.
53 lines
1.6 KiB
C
53 lines
1.6 KiB
C
/* A trap during init routes to the sink exactly once; the host survives
|
|
* through its own longjmp frame below the entry. Init counts as an entry:
|
|
* the structured message's symbol field names the init symbol itself. */
|
|
#include <setjmp.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
extern void ki_init(void);
|
|
extern void ki_set_panic_sink(void (*fn)(void *, const uint8_t *, size_t, uint64_t), void *ctx);
|
|
|
|
static jmp_buf trap_jmp;
|
|
static int sink_calls = 0;
|
|
|
|
/* The spec's parse rule (see traps/probe.c). */
|
|
static void show(const uint8_t *msg, size_t len) {
|
|
if (len == 0 || msg[0] != 0x01) {
|
|
printf("baseline printable=%d text=%.*s", len > 0 && msg[0] >= 0x20, (int)len, (const char *)msg);
|
|
return;
|
|
}
|
|
static const char *names[4] = {"text", "code", "symbol", "remediation"};
|
|
const uint8_t *p = msg + 1, *end = msg + len;
|
|
int fields = 0;
|
|
for (;;) {
|
|
const uint8_t *sep = memchr(p, 0x1f, (size_t)(end - p));
|
|
const uint8_t *stop = sep != NULL ? sep : end;
|
|
if (fields < 4) printf("%s=[%.*s]\n", names[fields], (int)(stop - p), (const char *)p);
|
|
fields++;
|
|
if (sep == NULL) break;
|
|
p = sep + 1;
|
|
}
|
|
printf("fields=%d text_printable=%d\n", fields, len > 1 && msg[1] >= 0x20);
|
|
}
|
|
|
|
static void sink(void *ctx, const uint8_t *msg, size_t len, uint64_t addr) {
|
|
(void)ctx; (void)addr;
|
|
sink_calls++;
|
|
printf("sink[%d]:\n", sink_calls);
|
|
show(msg, len);
|
|
longjmp(trap_jmp, 1);
|
|
}
|
|
|
|
int main(void) {
|
|
ki_set_panic_sink(sink, NULL);
|
|
if (setjmp(trap_jmp) == 0) {
|
|
ki_init();
|
|
printf("UNREACHABLE\n");
|
|
} else {
|
|
printf("survived init trap, sink_calls=%d\n", sink_calls);
|
|
}
|
|
return 0;
|
|
}
|