Fix large TypeScript Msg union compilation

- Derive comptime scan quotas from Msg shape and identifier bytes across generated shims, persistence, channels, and environment routing.
- Keep tag-skew diagnostics precise and teach future generated-code quota failures without blaming contracts.
- Add 160-arm compile/link and full TypeScript pipeline regression coverage.

Co-authored-by: Mohak Bajaj <77928693+MohakBajaj@users.noreply.github.com>
This commit is contained in:
Chris Tate
2026-08-16 21:30:17 -05:00
parent 8d0da34e62
commit f726d6c06c
9 changed files with 626 additions and 6 deletions
+3
View File
@@ -3515,6 +3515,9 @@ fn tsCoreE2eArtifact(
// against (the same module the generated shims stage).
conformance_mod.addImport("corewire_rt", module(b, target, optimize, "tools/corewire/shim_rt.zig"));
conformance_mod.addImport("shim_markup_core", sidecarShimModule(b, target, optimize, corewire_exe, b.path("tests/sidecar/markup_fixture.contract.json")));
// Compile-cost guard: this generated mirror carries 160 realistically
// named Msg arms and must need no quota setting in app or test code.
conformance_mod.addImport("shim_wide_core", sidecarShimModule(b, target, optimize, corewire_exe, b.path("tests/sidecar/wide_msg_fixture.contract.json")));
// The integer-class fixture: a hand-written sidecar attesting mixed
// i64/u64 slot classes, so the suite drives boundary and full-range
// integer values through a generated mirror's decode paths.
+2
View File
@@ -477,6 +477,7 @@ fn manifestPersistDebounce(comptime config: anytype) u32 {
}
fn validatePersistRoutes(comptime routes: anytype) void {
@setEvalBranchQuota(Adapter.persist_route_scan_quota);
if (!persistRouteMatches(routes.ok, void)) {
@compileError("app.zon .persist.restore.ok must name a void Msg arm in src/core.ts");
}
@@ -489,6 +490,7 @@ fn validatePersistRoutes(comptime routes: anytype) void {
}
fn persistRouteMatches(comptime name: []const u8, comptime Payload: type) bool {
@setEvalBranchQuota(Adapter.msg_scan_quota);
const info = @typeInfo(core.Msg);
if (info != .@"union") return false;
inline for (info.@"union".fields) |field| {
+32
View File
@@ -80,6 +80,27 @@ const ts_core_host = @import("ts_core_host.zig");
const ts_ui_app_log = std.log.scoped(.zero_ts_ui_app);
/// Quota for a comptime scan of an app-authored type. TS `Msg` unions may
/// legally carry 256 arms; include total identifier bytes because
/// `std.mem.eql`'s comptime scalar path scales with the compared names.
fn typeScanQuota(comptime T: type) u32 {
const fields = switch (@typeInfo(T)) {
.@"struct" => |info| info.fields,
.@"union" => |info| info.fields,
.@"enum" => |info| info.fields,
else => return 2_000,
};
var name_bytes: u64 = 0;
for (fields) |field| name_bytes += field.name.len;
const quota: u64 = 100_000 + @as(u64, fields.len) * 1_024 + name_bytes * 256;
return @intCast(@min(quota, std.math.maxInt(u32)));
}
fn scaledTypeScanQuota(comptime T: type, comptime scans: usize) u32 {
const quota = @as(u64, typeScanQuota(T)) * @max(scans, 1);
return @intCast(@min(quota, std.math.maxInt(u32)));
}
pub fn TsUiApp(comptime core: type) type {
return struct {
/// The effect bridge — shared with any direct `TsCoreHost(core)`
@@ -92,6 +113,9 @@ pub fn TsUiApp(comptime core: type) type {
pub const Options = App.Options;
pub const Effects = App.Effects;
pub const Ui = App.Ui;
/// Shared with generated launchers that perform their own Msg scans.
pub const msg_scan_quota = typeScanQuota(Msg);
pub const persist_route_scan_quota = scaledTypeScanQuota(Msg, 3);
/// Internal keyed-channel namespace for persistence write failures
/// ("TSPR"). It never shares an app-authored TS bridge index.
@@ -223,12 +247,14 @@ pub fn TsUiApp(comptime core: type) type {
/// a typo or payload mismatch fails during `native build`, before a
/// first boot can reach the dynamic dispatch path below.
pub fn validatePersistRoutes(comptime routes: PersistRoutes) void {
@setEvalBranchQuota(persist_route_scan_quota);
validatePersistRoute(routes.ok, void, "ok");
validatePersistRoute(routes.none, void, "none");
validatePersistRoute(routes.err, []const u8, "err");
}
fn validatePersistRoute(comptime route: []const u8, comptime Payload: type, comptime role: []const u8) void {
@setEvalBranchQuota(msg_scan_quota);
inline for (@typeInfo(Msg).@"union".fields) |arm| {
if (comptime std.mem.eql(u8, arm.name, route)) {
if (arm.type != Payload) {
@@ -1029,6 +1055,7 @@ pub fn TsUiApp(comptime core: type) type {
}
fn persistOutcomeMsg(event: runtime_effects.EffectChannelEvent) Msg {
@setEvalBranchQuota(msg_scan_quota);
const reason: []const u8 = switch (event.kind) {
.data => event.bytes,
.rejected => "rejected",
@@ -1044,6 +1071,7 @@ pub fn TsUiApp(comptime core: type) type {
}
fn dispatchPersistVoid(fx: *Effects, route: []const u8) void {
@setEvalBranchQuota(msg_scan_quota);
inline for (@typeInfo(Msg).@"union".fields) |arm| {
if (comptime arm.type == void) {
if (std.mem.eql(u8, arm.name, route)) {
@@ -1056,6 +1084,7 @@ pub fn TsUiApp(comptime core: type) type {
}
fn dispatchPersistError(fx: *Effects, route: []const u8, reason: []const u8) void {
@setEvalBranchQuota(msg_scan_quota);
inline for (@typeInfo(Msg).@"union".fields) |arm| {
if (comptime arm.type == []const u8) {
if (std.mem.eql(u8, arm.name, route)) {
@@ -1098,6 +1127,7 @@ pub fn TsUiApp(comptime core: type) type {
/// One env delivery: resolve the arm by name and dispatch the
/// value through a full core cycle.
fn dispatchOneEnvValue(fx: *Effects, msg: []const u8, value: []const u8) void {
@setEvalBranchQuota(msg_scan_quota);
inline for (@typeInfo(Msg).@"union".fields) |arm| {
if (comptime arm.type == []const u8) {
if (std.mem.eql(u8, arm.name, msg)) {
@@ -1117,6 +1147,7 @@ pub fn TsUiApp(comptime core: type) type {
/// hand-assembled cores: every `envMsgs` entry must name a Msg
/// arm carrying exactly one bytes payload.
fn validateEnvMsgs() void {
@setEvalBranchQuota(scaledTypeScanQuota(Msg, core.envMsgs.len));
for (core.envMsgs) |entry| {
var found = false;
for (@typeInfo(Msg).@"union".fields) |arm| {
@@ -1333,6 +1364,7 @@ pub fn TsUiApp(comptime core: type) type {
/// error the frontend's NS1033 re-derives for hand-written
/// cores.
fn channelArmIndex(comptime tag: []const u8, comptime channel: []const u8) usize {
@setEvalBranchQuota(msg_scan_quota);
for (@typeInfo(Msg).@"union".fields, 0..) |arm, index| {
if (std.mem.eql(u8, arm.name, tag)) return index;
}
+1
View File
@@ -254,6 +254,7 @@ fn runZig(io: std.Io, verb: Verb, argv: []const []const u8) !void {
// SDK builds with Zig 0.16, where std APIs moved, and those failures
// read "no member named 'cwd'/'init'/'io'" on std types.
std.debug.print("if the errors above name missing std members, the code may use pre-0.16 Zig idioms - run `native skills get zig` or see https://native-sdk.dev/zig\n", .{});
std.debug.print("if generated core wiring exceeds Zig's eval branch quota, do not regenerate the TypeScript contract or add an app-side quota - update or report the SDK-generated scan\n", .{});
return error.ZigBuildFailed;
}
+36 -2
View File
@@ -1,6 +1,6 @@
//! Sidecar-shim conformance: for every core in the ts-core corpus,
//! corewire generates the mirror from that core's contract sidecar —
//! the frontend-emitted document for the compiled fixtures, plus two
//! the frontend-emitted document for the compiled fixtures, plus three
//! hand-written ground truths for the schema itself — and this suite
//! validates the generated surface:
//!
@@ -11,7 +11,9 @@
//! surface and declaration-order wire tags.
//! 2. The integer fixture's mirror decodes every slot per its attested
//! class over hand-computed wire vectors.
//! 3. Every generated shim (dispatch stubs, snapshot decoder, channel
//! 3. A committed 160-arm sidecar proves generated Msg mirrors compile
//! without an app- or test-side eval-branch quota.
//! 4. Every generated shim (dispatch stubs, snapshot decoder, channel
//! forwarders, helper methods) fully analyzes and links against the
//! stub core's exported symbol set — the executable surface is
//! compile- and link-proven for the whole corpus without driving
@@ -30,6 +32,7 @@ const stub_core = @import("stub_core.zig");
const corewire_rt = @import("corewire_rt");
const shim_markup = @import("shim_markup_core");
const shim_wide = @import("shim_wide_core");
const shim_integer = @import("shim_integer_core");
const shim_host = @import("shim_host_core");
const shim_kanban = @import("shim_kanban_core");
@@ -38,6 +41,36 @@ const shim_monitor = @import("shim_monitor_core");
const shim_ai_chat = @import("shim_ai_chat_core");
const testing = std.testing;
const WideAdapter = native_sdk.TsUiApp(shim_wide);
// --------------------------------------------------------- wide Msg guard
//
// Compile-cost guard: a legal 160-arm TypeScript-core contract must compile
// through corewire without this test (or any app) raising
// `@setEvalBranchQuota`. The arm names are deliberately production-shaped,
// because comptime string comparison cost scales with their total bytes.
test "wide Msg mirror compiles and canonical union scans reach the final arm" {
comptime WideAdapter.validatePersistRoutes(.{
.ok = "quota_probe_message_arm_157_with_realistic_name",
.none = "quota_probe_message_arm_158_with_realistic_name",
.err = "quota_probe_message_arm_159_with_realistic_name",
});
try testing.expectEqual(@as(usize, 160), shim_wide.msg_tags.len);
try testing.expectEqualStrings(
"quota_probe_message_arm_159_with_realistic_name",
shim_wide.msg_tags[159],
);
var arena_state = std.heap.ArenaAllocator.init(testing.allocator);
defer arena_state.deinit();
const arena = arena_state.allocator();
const value: shim_wide.Msg = .{ .quota_probe_message_arm_159_with_realistic_name = "wide" };
const encoded = corewire_rt.encodeAlloc(shim_wide.Msg, value, arena);
try testing.expectEqualSlices(u8, &.{ 159, 4, 0, 0, 0, 'w', 'i', 'd', 'e' }, encoded);
const decoded = corewire_rt.decodeExact(shim_wide.Msg, encoded, arena);
try testing.expectEqualStrings("wide", decoded.quota_probe_message_arm_159_with_realistic_name);
}
// ------------------------------------------------------ markup fixture
// The bootstrap mirror: hand-written sidecar (independent ground truth
@@ -307,6 +340,7 @@ fn refAllDeclsRecursive(comptime T: type) void {
test "every generated shim fully analyzes and links against the ABI" {
refAllDeclsRecursive(shim_markup);
refAllDeclsRecursive(shim_wide);
refAllDeclsRecursive(shim_integer);
refAllDeclsRecursive(shim_host);
refAllDeclsRecursive(shim_kanban);
@@ -0,0 +1,216 @@
{
"format": 1,
"wire_version": 7,
"abi_version": 2,
"compiler_version": "0.0.1",
"entry": "tests/sidecar/wide_msg_fixture.ts",
"source_hash": "00000000c0ffee03",
"build_id": "00000000b01d0003",
"model_fingerprint": "00000000a11ce003",
"types": {
"structs": [
{"name": "Model", "fields": [
{"name": "count", "type": {"kind": "i64"}}
]}
],
"enums": [],
"unions": []
},
"model": "Model",
"model_helpers": [],
"model_unbound": [],
"msg": {
"name": "Msg",
"arms": [
{"name": "quota_probe_message_arm_000_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_001_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_002_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_003_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_004_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_005_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_006_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_007_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_008_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_009_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_010_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_011_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_012_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_013_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_014_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_015_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_016_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_017_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_018_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_019_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_020_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_021_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_022_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_023_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_024_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_025_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_026_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_027_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_028_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_029_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_030_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_031_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_032_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_033_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_034_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_035_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_036_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_037_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_038_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_039_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_040_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_041_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_042_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_043_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_044_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_045_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_046_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_047_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_048_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_049_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_050_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_051_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_052_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_053_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_054_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_055_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_056_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_057_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_058_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_059_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_060_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_061_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_062_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_063_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_064_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_065_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_066_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_067_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_068_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_069_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_070_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_071_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_072_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_073_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_074_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_075_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_076_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_077_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_078_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_079_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_080_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_081_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_082_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_083_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_084_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_085_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_086_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_087_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_088_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_089_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_090_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_091_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_092_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_093_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_094_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_095_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_096_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_097_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_098_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_099_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_100_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_101_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_102_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_103_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_104_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_105_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_106_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_107_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_108_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_109_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_110_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_111_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_112_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_113_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_114_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_115_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_116_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_117_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_118_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_119_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_120_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_121_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_122_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_123_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_124_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_125_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_126_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_127_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_128_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_129_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_130_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_131_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_132_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_133_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_134_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_135_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_136_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_137_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_138_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_139_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_140_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_141_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_142_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_143_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_144_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_145_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_146_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_147_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_148_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_149_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_150_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_151_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_152_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_153_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_154_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_155_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_156_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_157_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_158_with_realistic_name", "payload": {"kind": "void"}},
{"name": "quota_probe_message_arm_159_with_realistic_name", "payload": {"kind": "bytes"}}
],
"unbound": []
},
"init_returns_cmd": false,
"update_returns_cmd": true,
"has_subscriptions": false,
"has_migrate": false,
"channels": {
"command_msg": false,
"frame_msg": false,
"key_msg": false,
"pinch_msg": false,
"drop_msg": false,
"appearance_msg": null,
"chrome_msg": null,
"env_msgs": []
},
"abi": {
"prefix": "nsc_core_",
"exports": ["abi_version", "build_id", "set_panic_sink", "init", "collect",
"frame_reset", "boot_cmd", "dispatch_void", "dispatch_bytes", "dispatch_number",
"dispatch_number_bytes", "dispatch_bool", "dispatch_enum", "dispatch_record",
"dispatch_text_input", "dispatch_scroll_state", "subscriptions", "model_snapshot",
"persist_snapshot", "restore_model", "migrate_model", "helper_call"],
"snapshot_format": 1
},
"integer_slots": [
{"slot": "Model.count", "class": "i64"}
],
"deterministic": true,
"async_free": true
}
+298 -1
View File
@@ -83,7 +83,156 @@ export type Msg =
| { readonly kind: "zoomed"; readonly factor: number; readonly windowId: number; readonly fromBoard: boolean }
| { readonly kind: "appearance_changed"; readonly colorScheme: ColorScheme; readonly reduceMotion: boolean; readonly highContrast: boolean }
| { readonly kind: "chrome_changed"; readonly insets: ChromeInsets; readonly buttons: ChromeButtons; readonly tabsProjected: boolean }
| { readonly kind: "banner_set"; readonly value: Uint8Array };
| { readonly kind: "banner_set"; readonly value: Uint8Array }
// Compile-cost guard for the default TypeScript path. Together with the
// 15 functional arms above these make a 160-arm Msg, crossing the former
// Zig comptime-quota cliff while the real checker -> contract -> corewire ->
// TsUiApp channel pipeline compiles with no app-side quota.
| { readonly kind: "quota_probe_000_with_realistic_message_name" }
| { readonly kind: "quota_probe_001_with_realistic_message_name" }
| { readonly kind: "quota_probe_002_with_realistic_message_name" }
| { readonly kind: "quota_probe_003_with_realistic_message_name" }
| { readonly kind: "quota_probe_004_with_realistic_message_name" }
| { readonly kind: "quota_probe_005_with_realistic_message_name" }
| { readonly kind: "quota_probe_006_with_realistic_message_name" }
| { readonly kind: "quota_probe_007_with_realistic_message_name" }
| { readonly kind: "quota_probe_008_with_realistic_message_name" }
| { readonly kind: "quota_probe_009_with_realistic_message_name" }
| { readonly kind: "quota_probe_010_with_realistic_message_name" }
| { readonly kind: "quota_probe_011_with_realistic_message_name" }
| { readonly kind: "quota_probe_012_with_realistic_message_name" }
| { readonly kind: "quota_probe_013_with_realistic_message_name" }
| { readonly kind: "quota_probe_014_with_realistic_message_name" }
| { readonly kind: "quota_probe_015_with_realistic_message_name" }
| { readonly kind: "quota_probe_016_with_realistic_message_name" }
| { readonly kind: "quota_probe_017_with_realistic_message_name" }
| { readonly kind: "quota_probe_018_with_realistic_message_name" }
| { readonly kind: "quota_probe_019_with_realistic_message_name" }
| { readonly kind: "quota_probe_020_with_realistic_message_name" }
| { readonly kind: "quota_probe_021_with_realistic_message_name" }
| { readonly kind: "quota_probe_022_with_realistic_message_name" }
| { readonly kind: "quota_probe_023_with_realistic_message_name" }
| { readonly kind: "quota_probe_024_with_realistic_message_name" }
| { readonly kind: "quota_probe_025_with_realistic_message_name" }
| { readonly kind: "quota_probe_026_with_realistic_message_name" }
| { readonly kind: "quota_probe_027_with_realistic_message_name" }
| { readonly kind: "quota_probe_028_with_realistic_message_name" }
| { readonly kind: "quota_probe_029_with_realistic_message_name" }
| { readonly kind: "quota_probe_030_with_realistic_message_name" }
| { readonly kind: "quota_probe_031_with_realistic_message_name" }
| { readonly kind: "quota_probe_032_with_realistic_message_name" }
| { readonly kind: "quota_probe_033_with_realistic_message_name" }
| { readonly kind: "quota_probe_034_with_realistic_message_name" }
| { readonly kind: "quota_probe_035_with_realistic_message_name" }
| { readonly kind: "quota_probe_036_with_realistic_message_name" }
| { readonly kind: "quota_probe_037_with_realistic_message_name" }
| { readonly kind: "quota_probe_038_with_realistic_message_name" }
| { readonly kind: "quota_probe_039_with_realistic_message_name" }
| { readonly kind: "quota_probe_040_with_realistic_message_name" }
| { readonly kind: "quota_probe_041_with_realistic_message_name" }
| { readonly kind: "quota_probe_042_with_realistic_message_name" }
| { readonly kind: "quota_probe_043_with_realistic_message_name" }
| { readonly kind: "quota_probe_044_with_realistic_message_name" }
| { readonly kind: "quota_probe_045_with_realistic_message_name" }
| { readonly kind: "quota_probe_046_with_realistic_message_name" }
| { readonly kind: "quota_probe_047_with_realistic_message_name" }
| { readonly kind: "quota_probe_048_with_realistic_message_name" }
| { readonly kind: "quota_probe_049_with_realistic_message_name" }
| { readonly kind: "quota_probe_050_with_realistic_message_name" }
| { readonly kind: "quota_probe_051_with_realistic_message_name" }
| { readonly kind: "quota_probe_052_with_realistic_message_name" }
| { readonly kind: "quota_probe_053_with_realistic_message_name" }
| { readonly kind: "quota_probe_054_with_realistic_message_name" }
| { readonly kind: "quota_probe_055_with_realistic_message_name" }
| { readonly kind: "quota_probe_056_with_realistic_message_name" }
| { readonly kind: "quota_probe_057_with_realistic_message_name" }
| { readonly kind: "quota_probe_058_with_realistic_message_name" }
| { readonly kind: "quota_probe_059_with_realistic_message_name" }
| { readonly kind: "quota_probe_060_with_realistic_message_name" }
| { readonly kind: "quota_probe_061_with_realistic_message_name" }
| { readonly kind: "quota_probe_062_with_realistic_message_name" }
| { readonly kind: "quota_probe_063_with_realistic_message_name" }
| { readonly kind: "quota_probe_064_with_realistic_message_name" }
| { readonly kind: "quota_probe_065_with_realistic_message_name" }
| { readonly kind: "quota_probe_066_with_realistic_message_name" }
| { readonly kind: "quota_probe_067_with_realistic_message_name" }
| { readonly kind: "quota_probe_068_with_realistic_message_name" }
| { readonly kind: "quota_probe_069_with_realistic_message_name" }
| { readonly kind: "quota_probe_070_with_realistic_message_name" }
| { readonly kind: "quota_probe_071_with_realistic_message_name" }
| { readonly kind: "quota_probe_072_with_realistic_message_name" }
| { readonly kind: "quota_probe_073_with_realistic_message_name" }
| { readonly kind: "quota_probe_074_with_realistic_message_name" }
| { readonly kind: "quota_probe_075_with_realistic_message_name" }
| { readonly kind: "quota_probe_076_with_realistic_message_name" }
| { readonly kind: "quota_probe_077_with_realistic_message_name" }
| { readonly kind: "quota_probe_078_with_realistic_message_name" }
| { readonly kind: "quota_probe_079_with_realistic_message_name" }
| { readonly kind: "quota_probe_080_with_realistic_message_name" }
| { readonly kind: "quota_probe_081_with_realistic_message_name" }
| { readonly kind: "quota_probe_082_with_realistic_message_name" }
| { readonly kind: "quota_probe_083_with_realistic_message_name" }
| { readonly kind: "quota_probe_084_with_realistic_message_name" }
| { readonly kind: "quota_probe_085_with_realistic_message_name" }
| { readonly kind: "quota_probe_086_with_realistic_message_name" }
| { readonly kind: "quota_probe_087_with_realistic_message_name" }
| { readonly kind: "quota_probe_088_with_realistic_message_name" }
| { readonly kind: "quota_probe_089_with_realistic_message_name" }
| { readonly kind: "quota_probe_090_with_realistic_message_name" }
| { readonly kind: "quota_probe_091_with_realistic_message_name" }
| { readonly kind: "quota_probe_092_with_realistic_message_name" }
| { readonly kind: "quota_probe_093_with_realistic_message_name" }
| { readonly kind: "quota_probe_094_with_realistic_message_name" }
| { readonly kind: "quota_probe_095_with_realistic_message_name" }
| { readonly kind: "quota_probe_096_with_realistic_message_name" }
| { readonly kind: "quota_probe_097_with_realistic_message_name" }
| { readonly kind: "quota_probe_098_with_realistic_message_name" }
| { readonly kind: "quota_probe_099_with_realistic_message_name" }
| { readonly kind: "quota_probe_100_with_realistic_message_name" }
| { readonly kind: "quota_probe_101_with_realistic_message_name" }
| { readonly kind: "quota_probe_102_with_realistic_message_name" }
| { readonly kind: "quota_probe_103_with_realistic_message_name" }
| { readonly kind: "quota_probe_104_with_realistic_message_name" }
| { readonly kind: "quota_probe_105_with_realistic_message_name" }
| { readonly kind: "quota_probe_106_with_realistic_message_name" }
| { readonly kind: "quota_probe_107_with_realistic_message_name" }
| { readonly kind: "quota_probe_108_with_realistic_message_name" }
| { readonly kind: "quota_probe_109_with_realistic_message_name" }
| { readonly kind: "quota_probe_110_with_realistic_message_name" }
| { readonly kind: "quota_probe_111_with_realistic_message_name" }
| { readonly kind: "quota_probe_112_with_realistic_message_name" }
| { readonly kind: "quota_probe_113_with_realistic_message_name" }
| { readonly kind: "quota_probe_114_with_realistic_message_name" }
| { readonly kind: "quota_probe_115_with_realistic_message_name" }
| { readonly kind: "quota_probe_116_with_realistic_message_name" }
| { readonly kind: "quota_probe_117_with_realistic_message_name" }
| { readonly kind: "quota_probe_118_with_realistic_message_name" }
| { readonly kind: "quota_probe_119_with_realistic_message_name" }
| { readonly kind: "quota_probe_120_with_realistic_message_name" }
| { readonly kind: "quota_probe_121_with_realistic_message_name" }
| { readonly kind: "quota_probe_122_with_realistic_message_name" }
| { readonly kind: "quota_probe_123_with_realistic_message_name" }
| { readonly kind: "quota_probe_124_with_realistic_message_name" }
| { readonly kind: "quota_probe_125_with_realistic_message_name" }
| { readonly kind: "quota_probe_126_with_realistic_message_name" }
| { readonly kind: "quota_probe_127_with_realistic_message_name" }
| { readonly kind: "quota_probe_128_with_realistic_message_name" }
| { readonly kind: "quota_probe_129_with_realistic_message_name" }
| { readonly kind: "quota_probe_130_with_realistic_message_name" }
| { readonly kind: "quota_probe_131_with_realistic_message_name" }
| { readonly kind: "quota_probe_132_with_realistic_message_name" }
| { readonly kind: "quota_probe_133_with_realistic_message_name" }
| { readonly kind: "quota_probe_134_with_realistic_message_name" }
| { readonly kind: "quota_probe_135_with_realistic_message_name" }
| { readonly kind: "quota_probe_136_with_realistic_message_name" }
| { readonly kind: "quota_probe_137_with_realistic_message_name" }
| { readonly kind: "quota_probe_138_with_realistic_message_name" }
| { readonly kind: "quota_probe_139_with_realistic_message_name" }
| { readonly kind: "quota_probe_140_with_realistic_message_name" }
| { readonly kind: "quota_probe_141_with_realistic_message_name" }
| { readonly kind: "quota_probe_142_with_realistic_message_name" }
| { readonly kind: "quota_probe_143_with_realistic_message_name" }
| { readonly kind: "quota_probe_144_with_realistic_message_name" };
/// Presented frames dispatch ONLY on a width change (the idle law: a
/// frame that changes nothing dispatches nothing, so the channel starves
@@ -239,5 +388,153 @@ export function update(model: Model, msg: Msg): [Model, Cmd<Msg>] {
return [{ ...model, chromeTop: msg.insets.top }, Cmd.none];
case "banner_set":
return [{ ...model, banner: msg.value }, Cmd.none];
// The wide-union arms are compile-only probes; they intentionally share
// one inert reducer branch so the switch remains exhaustive.
case "quota_probe_000_with_realistic_message_name":
case "quota_probe_001_with_realistic_message_name":
case "quota_probe_002_with_realistic_message_name":
case "quota_probe_003_with_realistic_message_name":
case "quota_probe_004_with_realistic_message_name":
case "quota_probe_005_with_realistic_message_name":
case "quota_probe_006_with_realistic_message_name":
case "quota_probe_007_with_realistic_message_name":
case "quota_probe_008_with_realistic_message_name":
case "quota_probe_009_with_realistic_message_name":
case "quota_probe_010_with_realistic_message_name":
case "quota_probe_011_with_realistic_message_name":
case "quota_probe_012_with_realistic_message_name":
case "quota_probe_013_with_realistic_message_name":
case "quota_probe_014_with_realistic_message_name":
case "quota_probe_015_with_realistic_message_name":
case "quota_probe_016_with_realistic_message_name":
case "quota_probe_017_with_realistic_message_name":
case "quota_probe_018_with_realistic_message_name":
case "quota_probe_019_with_realistic_message_name":
case "quota_probe_020_with_realistic_message_name":
case "quota_probe_021_with_realistic_message_name":
case "quota_probe_022_with_realistic_message_name":
case "quota_probe_023_with_realistic_message_name":
case "quota_probe_024_with_realistic_message_name":
case "quota_probe_025_with_realistic_message_name":
case "quota_probe_026_with_realistic_message_name":
case "quota_probe_027_with_realistic_message_name":
case "quota_probe_028_with_realistic_message_name":
case "quota_probe_029_with_realistic_message_name":
case "quota_probe_030_with_realistic_message_name":
case "quota_probe_031_with_realistic_message_name":
case "quota_probe_032_with_realistic_message_name":
case "quota_probe_033_with_realistic_message_name":
case "quota_probe_034_with_realistic_message_name":
case "quota_probe_035_with_realistic_message_name":
case "quota_probe_036_with_realistic_message_name":
case "quota_probe_037_with_realistic_message_name":
case "quota_probe_038_with_realistic_message_name":
case "quota_probe_039_with_realistic_message_name":
case "quota_probe_040_with_realistic_message_name":
case "quota_probe_041_with_realistic_message_name":
case "quota_probe_042_with_realistic_message_name":
case "quota_probe_043_with_realistic_message_name":
case "quota_probe_044_with_realistic_message_name":
case "quota_probe_045_with_realistic_message_name":
case "quota_probe_046_with_realistic_message_name":
case "quota_probe_047_with_realistic_message_name":
case "quota_probe_048_with_realistic_message_name":
case "quota_probe_049_with_realistic_message_name":
case "quota_probe_050_with_realistic_message_name":
case "quota_probe_051_with_realistic_message_name":
case "quota_probe_052_with_realistic_message_name":
case "quota_probe_053_with_realistic_message_name":
case "quota_probe_054_with_realistic_message_name":
case "quota_probe_055_with_realistic_message_name":
case "quota_probe_056_with_realistic_message_name":
case "quota_probe_057_with_realistic_message_name":
case "quota_probe_058_with_realistic_message_name":
case "quota_probe_059_with_realistic_message_name":
case "quota_probe_060_with_realistic_message_name":
case "quota_probe_061_with_realistic_message_name":
case "quota_probe_062_with_realistic_message_name":
case "quota_probe_063_with_realistic_message_name":
case "quota_probe_064_with_realistic_message_name":
case "quota_probe_065_with_realistic_message_name":
case "quota_probe_066_with_realistic_message_name":
case "quota_probe_067_with_realistic_message_name":
case "quota_probe_068_with_realistic_message_name":
case "quota_probe_069_with_realistic_message_name":
case "quota_probe_070_with_realistic_message_name":
case "quota_probe_071_with_realistic_message_name":
case "quota_probe_072_with_realistic_message_name":
case "quota_probe_073_with_realistic_message_name":
case "quota_probe_074_with_realistic_message_name":
case "quota_probe_075_with_realistic_message_name":
case "quota_probe_076_with_realistic_message_name":
case "quota_probe_077_with_realistic_message_name":
case "quota_probe_078_with_realistic_message_name":
case "quota_probe_079_with_realistic_message_name":
case "quota_probe_080_with_realistic_message_name":
case "quota_probe_081_with_realistic_message_name":
case "quota_probe_082_with_realistic_message_name":
case "quota_probe_083_with_realistic_message_name":
case "quota_probe_084_with_realistic_message_name":
case "quota_probe_085_with_realistic_message_name":
case "quota_probe_086_with_realistic_message_name":
case "quota_probe_087_with_realistic_message_name":
case "quota_probe_088_with_realistic_message_name":
case "quota_probe_089_with_realistic_message_name":
case "quota_probe_090_with_realistic_message_name":
case "quota_probe_091_with_realistic_message_name":
case "quota_probe_092_with_realistic_message_name":
case "quota_probe_093_with_realistic_message_name":
case "quota_probe_094_with_realistic_message_name":
case "quota_probe_095_with_realistic_message_name":
case "quota_probe_096_with_realistic_message_name":
case "quota_probe_097_with_realistic_message_name":
case "quota_probe_098_with_realistic_message_name":
case "quota_probe_099_with_realistic_message_name":
case "quota_probe_100_with_realistic_message_name":
case "quota_probe_101_with_realistic_message_name":
case "quota_probe_102_with_realistic_message_name":
case "quota_probe_103_with_realistic_message_name":
case "quota_probe_104_with_realistic_message_name":
case "quota_probe_105_with_realistic_message_name":
case "quota_probe_106_with_realistic_message_name":
case "quota_probe_107_with_realistic_message_name":
case "quota_probe_108_with_realistic_message_name":
case "quota_probe_109_with_realistic_message_name":
case "quota_probe_110_with_realistic_message_name":
case "quota_probe_111_with_realistic_message_name":
case "quota_probe_112_with_realistic_message_name":
case "quota_probe_113_with_realistic_message_name":
case "quota_probe_114_with_realistic_message_name":
case "quota_probe_115_with_realistic_message_name":
case "quota_probe_116_with_realistic_message_name":
case "quota_probe_117_with_realistic_message_name":
case "quota_probe_118_with_realistic_message_name":
case "quota_probe_119_with_realistic_message_name":
case "quota_probe_120_with_realistic_message_name":
case "quota_probe_121_with_realistic_message_name":
case "quota_probe_122_with_realistic_message_name":
case "quota_probe_123_with_realistic_message_name":
case "quota_probe_124_with_realistic_message_name":
case "quota_probe_125_with_realistic_message_name":
case "quota_probe_126_with_realistic_message_name":
case "quota_probe_127_with_realistic_message_name":
case "quota_probe_128_with_realistic_message_name":
case "quota_probe_129_with_realistic_message_name":
case "quota_probe_130_with_realistic_message_name":
case "quota_probe_131_with_realistic_message_name":
case "quota_probe_132_with_realistic_message_name":
case "quota_probe_133_with_realistic_message_name":
case "quota_probe_134_with_realistic_message_name":
case "quota_probe_135_with_realistic_message_name":
case "quota_probe_136_with_realistic_message_name":
case "quota_probe_137_with_realistic_message_name":
case "quota_probe_138_with_realistic_message_name":
case "quota_probe_139_with_realistic_message_name":
case "quota_probe_140_with_realistic_message_name":
case "quota_probe_141_with_realistic_message_name":
case "quota_probe_142_with_realistic_message_name":
case "quota_probe_143_with_realistic_message_name":
case "quota_probe_144_with_realistic_message_name":
return [model, Cmd.none];
}
}
+18 -3
View File
@@ -42,6 +42,19 @@ const Sidecar = sidecar_mod.Sidecar;
const TypeRef = sidecar_mod.TypeRef;
const Payload = sidecar_mod.Payload;
/// Comptime string scans pay for every arm and every byte in its name.
/// Keep the generated consistency fence independent of Zig's default
/// 1000-backwards-branch quota: the sidecar admits 256 arms, and long legal
/// TypeScript identifiers must remain legal here too. The fixed floor covers
/// the surrounding reflection; the linear terms leave generous headroom over
/// `std.mem.eql`'s scalar comptime path.
fn msgTagConsistencyQuota(arms: []const sidecar_mod.MsgArm) u32 {
var name_bytes: u64 = 0;
for (arms) |arm| name_bytes += arm.name.len;
const quota: u64 = 100_000 + @as(u64, arms.len) * 1_024 + name_bytes * 256;
return @intCast(@min(quota, std.math.maxInt(u32)));
}
/// The eleven text-input event tags the markup engines recognize
/// structurally; a union payload carrying exactly these dispatches
/// through the ABI's text_input entry.
@@ -883,6 +896,7 @@ const Emitter = struct {
}
fn tagTable(self: *Emitter) Error!void {
const consistency_quota = msgTagConsistencyQuota(self.sidecar.msg.arms);
try self.raw(
\\
\\/// Declaration-order wire tags: the arm's index in this table IS
@@ -898,16 +912,17 @@ const Emitter = struct {
try self.print(
\\
\\comptime {{
\\ @setEvalBranchQuota({d});
\\ // The union and the tag table are emitted from one arm list;
\\ // hold them equal anyway so a hand edit cannot skew dispatch.
\\ const fields = @typeInfo({f}).@"union".fields;
\\ if (fields.len != msg_tags.len) @compileError("core_shim: msg_tags and the message union disagree — regenerate from the sidecar");
\\ if (fields.len != msg_tags.len) @compileError("core_shim: Msg arm count does not match msg_tags");
\\ for (fields, msg_tags) |field, tag_name| {{
\\ if (!std.mem.eql(u8, field.name, tag_name)) @compileError("core_shim: msg_tags and the message union disagree — regenerate from the sidecar");
\\ if (!std.mem.eql(u8, field.name, tag_name)) @compileError("core_shim: Msg arm names do not match msg_tags");
\\ }}
\\}}
\\
, .{ident(self.sidecar.msg.name)});
, .{ consistency_quota, ident(self.sidecar.msg.name) });
}
// --------------------------------------------------- entry points
+20
View File
@@ -92,6 +92,24 @@ var model_arenas = [2]std.heap.ArenaAllocator{
};
var model_arena_index: u1 = 0;
/// Quota for one comptime reflection pass over a record/union/enum. Canonical
/// encoding specializes over sidecar-shaped types, whose legal 256-arm unions
/// and long authored names can outrun Zig's default quota while resolving an
/// arm index. Scale with both entries and identifier bytes so app code never
/// has to raise a quota for generated shim work.
fn typeScanQuota(comptime T: type) u32 {
const fields = switch (@typeInfo(T)) {
.@"struct" => |info| info.fields,
.@"union" => |info| info.fields,
.@"enum" => |info| info.fields,
else => return 2_000,
};
var name_bytes: u64 = 0;
for (fields) |field| name_bytes += field.name.len;
const quota: u64 = 100_000 + @as(u64, fields.len) * 1_024 + name_bytes * 256;
return @intCast(@min(quota, std.math.maxInt(u32)));
}
/// Decode a committed-model snapshot into a fresh mirror root. The
/// PREVIOUS decode's root stays valid until the decode after this one;
/// anything older is gone (the host holds exactly one committed root at
@@ -116,6 +134,7 @@ pub fn encodeAlloc(comptime T: type, value: T, allocator: std.mem.Allocator) []c
}
fn encodeInto(comptime T: type, value: T, allocator: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8)) error{OutOfMemory}!void {
@setEvalBranchQuota(comptime typeScanQuota(T));
switch (@typeInfo(T)) {
.bool => try out.append(allocator, @intFromBool(value)),
.int => {
@@ -220,6 +239,7 @@ pub const Reader = struct {
/// records and slices into `allocator` (the shim frame arena in the
/// dispatch path).
pub fn decode(comptime T: type, reader: *Reader, allocator: std.mem.Allocator) T {
@setEvalBranchQuota(comptime typeScanQuota(T));
switch (@typeInfo(T)) {
.bool => {
const raw = reader.take(1)[0];