Skip to content

Commit 468cb6d

Browse files
committed
abi checker
1 parent 6f5e16b commit 468cb6d

13 files changed

Lines changed: 711 additions & 47 deletions

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ test-validation: test-zem-inherit-env
256256
test-validation: test-zem-caps
257257
test-validation: test-zem-sniff-ret-trunc
258258
test-validation: test-zem-sniff-hop-bad-args
259+
test-validation: test-zem-sniff-zi-read-bad-args
260+
test-validation: test-zem-sniff-zi-telemetry-bad-args
261+
test-validation: test-zem-sniff-zi-argv-copy-bad-args
262+
test-validation: test-zem-sniff-zi-alloc-bad-args
263+
test-validation: test-zem-sniff-zi-str-concat-bad-args
259264
test-validation: test-zem-diag-ret-trunc-ld32s64
260265
test-validation: test-zem-coverage-smoke
261266
test-validation: test-zem-coverage-blackholes
@@ -348,6 +353,21 @@ test-zem-sniff-ret-trunc: zas zem
348353
test-zem-sniff-hop-bad-args: zas zem
349354
sh test/zem_sniff_hop_bad_args.sh
350355

356+
test-zem-sniff-zi-read-bad-args: zas zem
357+
sh test/zem_sniff_zi_read_bad_args.sh
358+
359+
test-zem-sniff-zi-telemetry-bad-args: zas zem
360+
sh test/zem_sniff_zi_telemetry_bad_args.sh
361+
362+
test-zem-sniff-zi-argv-copy-bad-args: zas zem
363+
sh test/zem_sniff_zi_argv_copy_bad_args.sh
364+
365+
test-zem-sniff-zi-alloc-bad-args: zas zem
366+
sh test/zem_sniff_zi_alloc_bad_args.sh
367+
368+
test-zem-sniff-zi-str-concat-bad-args: zas zem
369+
sh test/zem_sniff_zi_str_concat_bad_args.sh
370+
351371
test-zem-diag-ret-trunc-ld32s64: zas zem
352372
sh test/zem_diag_ret_trunc_ld32s64.sh
353373

docs/tools/zem.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ This is intended to make “trap, identify, explain” workflows fast when debug
318318
- `--sniff` enables heuristic warnings for high-signal bug signatures (currently: return-slot pointer truncation patterns).
319319
- `--sniff-fatal` like `--sniff`, but turns a warning into a failing trap.
320320

321+
In addition, `--sniff` warns when common ABI v2 (`zi_*`) call arguments look invalid at the boundary (e.g. a sign-extended i32 used where the ABI expects a u32 pointer/length, or obvious out-of-bounds spans). This is meant to surface “will crash later” issues early, with provenance.
322+
321323
The warning includes the detected pattern PCs, the suspect register’s current value, and its provenance.
322324

323325
### Shake mode (deterministic perturbations)

src/zem/exec/zem_exec_call_alloc.c

Lines changed: 167 additions & 44 deletions
Large diffs are not rendered by default.

src/zem/exec/zem_exec_call_env_time_proc.c

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/* SPDX-FileCopyrightText: 2026 Frogfish */
22
/* SPDX-License-Identifier: GPL-3.0-or-later */
33

4+
#include <inttypes.h>
45
#include <limits.h>
56
#include <stdint.h>
7+
#include <stdio.h>
68
#include <string.h>
79

810
#include "zem_exec_internal.h"
@@ -66,6 +68,16 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
6668
uint32_t key_len_u = 0;
6769
if (!zabi_u32_from_u64(regs->HL, &key_ptr) ||
6870
!zabi_u32_from_u64(regs->DE, &key_len_u)) {
71+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
72+
"key_ptr/key_len not representable as u32")) {
73+
return 1;
74+
}
75+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
76+
fprintf(stderr, " HL(key_ptr)=0x%016" PRIx64 " DE(key_len)=0x%016" PRIx64 "\n",
77+
regs->HL, regs->DE);
78+
zem_diag_print_regprov(stderr, regprov, "HL");
79+
zem_diag_print_regprov(stderr, regprov, "DE");
80+
}
6981
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
7082
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
7183
r->m);
@@ -74,6 +86,16 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
7486
}
7587
int32_t key_len = (int32_t)key_len_u;
7688
if (key_len < 0 || !mem_check_span(mem, key_ptr, (uint32_t)key_len)) {
89+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
90+
"key span out of bounds")) {
91+
return 1;
92+
}
93+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
94+
fprintf(stderr, " key_ptr=%" PRIu32 " key_len=%" PRId32 " mem_len=%zu\n",
95+
key_ptr, key_len, mem ? mem->len : 0);
96+
zem_diag_print_regprov(stderr, regprov, "HL");
97+
zem_diag_print_regprov(stderr, regprov, "DE");
98+
}
7799
regs->HL = (uint64_t)(uint32_t)ZI_E_BOUNDS;
78100
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
79101
r->m);
@@ -108,6 +130,20 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
108130
!zabi_u32_from_u64(regs->DE, &key_len_u) ||
109131
!zabi_u32_from_u64(regs->BC, &out_ptr) ||
110132
!zabi_u32_from_u64(regs->IX, &out_cap_u)) {
133+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
134+
"key/out args not representable as u32")) {
135+
return 1;
136+
}
137+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
138+
fprintf(stderr,
139+
" HL(key_ptr)=0x%016" PRIx64 " DE(key_len)=0x%016" PRIx64
140+
" BC(out_ptr)=0x%016" PRIx64 " IX(out_cap)=0x%016" PRIx64 "\n",
141+
regs->HL, regs->DE, regs->BC, regs->IX);
142+
zem_diag_print_regprov(stderr, regprov, "HL");
143+
zem_diag_print_regprov(stderr, regprov, "DE");
144+
zem_diag_print_regprov(stderr, regprov, "BC");
145+
zem_diag_print_regprov(stderr, regprov, "IX");
146+
}
111147
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
112148
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
113149
r->m);
@@ -118,6 +154,20 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
118154
int32_t out_cap = (int32_t)out_cap_u;
119155
if (key_len < 0 || out_cap < 0 ||
120156
!mem_check_span(mem, key_ptr, (uint32_t)key_len)) {
157+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
158+
"key span out of bounds (or negative lens)")) {
159+
return 1;
160+
}
161+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
162+
fprintf(stderr,
163+
" key_ptr=%" PRIu32 " key_len=%" PRId32 " out_ptr=%" PRIu32
164+
" out_cap=%" PRId32 " mem_len=%zu\n",
165+
key_ptr, key_len, out_ptr, out_cap, mem ? mem->len : 0);
166+
zem_diag_print_regprov(stderr, regprov, "HL");
167+
zem_diag_print_regprov(stderr, regprov, "DE");
168+
zem_diag_print_regprov(stderr, regprov, "BC");
169+
zem_diag_print_regprov(stderr, regprov, "IX");
170+
}
121171
regs->HL = (uint64_t)(uint32_t)ZI_E_BOUNDS;
122172
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
123173
r->m);
@@ -182,6 +232,14 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
182232
if (trace_enabled && trace_pending && trace_meta) trace_meta->call_is_prim = 1;
183233
uint32_t index = 0;
184234
if (!zabi_u32_from_u64(regs->HL, &index)) {
235+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
236+
"index not representable as u32")) {
237+
return 1;
238+
}
239+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
240+
fprintf(stderr, " HL(index)=0x%016" PRIx64 "\n", regs->HL);
241+
zem_diag_print_regprov(stderr, regprov, "HL");
242+
}
185243
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
186244
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
187245
r->m);
@@ -212,6 +270,19 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
212270
if (!zabi_u32_from_u64(regs->HL, &index) ||
213271
!zabi_u32_from_u64(regs->DE, &out_ptr) ||
214272
!zabi_u32_from_u64(regs->BC, &out_cap_u)) {
273+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
274+
"index/out_ptr/out_cap not representable as u32")) {
275+
return 1;
276+
}
277+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
278+
fprintf(stderr,
279+
" HL(index)=0x%016" PRIx64 " DE(out_ptr)=0x%016" PRIx64
280+
" BC(out_cap)=0x%016" PRIx64 "\n",
281+
regs->HL, regs->DE, regs->BC);
282+
zem_diag_print_regprov(stderr, regprov, "HL");
283+
zem_diag_print_regprov(stderr, regprov, "DE");
284+
zem_diag_print_regprov(stderr, regprov, "BC");
285+
}
215286
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
216287
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
217288
r->m);
@@ -220,6 +291,14 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
220291
}
221292
int32_t out_cap = (int32_t)out_cap_u;
222293
if (out_cap < 0) {
294+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
295+
"out_cap negative")) {
296+
return 1;
297+
}
298+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
299+
fprintf(stderr, " out_cap=%" PRId32 "\n", out_cap);
300+
zem_diag_print_regprov(stderr, regprov, "BC");
301+
}
223302
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
224303
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
225304
r->m);
@@ -242,6 +321,16 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
242321
return 1;
243322
}
244323
if (!mem_check_span(mem, out_ptr, (uint32_t)n)) {
324+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
325+
"out_ptr span out of bounds")) {
326+
return 1;
327+
}
328+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
329+
fprintf(stderr,
330+
" out_ptr=%" PRIu32 " n=%zu mem_len=%zu\n",
331+
out_ptr, n, mem ? mem->len : 0);
332+
zem_diag_print_regprov(stderr, regprov, "DE");
333+
}
245334
regs->HL = (uint64_t)(uint32_t)ZI_E_BOUNDS;
246335
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
247336
r->m);
@@ -308,7 +397,23 @@ int zem_exec_call_env_time_proc(zem_exec_ctx_t *ctx, const record_t *r,
308397

309398
if (strcmp(callee, "zi_time_sleep_ms") == 0) {
310399
if (trace_enabled && trace_pending && trace_meta) trace_meta->call_is_prim = 1;
311-
zi_time_ms += (uint32_t)regs->HL;
400+
uint32_t delta_ms = 0;
401+
if (!zabi_u32_from_u64(regs->HL, &delta_ms)) {
402+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
403+
"delta_ms not representable as u32")) {
404+
return 1;
405+
}
406+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
407+
fprintf(stderr, " HL(delta_ms)=0x%016" PRIx64 "\n", regs->HL);
408+
zem_diag_print_regprov(stderr, regprov, "HL");
409+
}
410+
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
411+
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
412+
r->m);
413+
*ctx->pc = pc + 1;
414+
return 1;
415+
}
416+
zi_time_ms += delta_ms;
312417
regs->HL = (uint64_t)(uint32_t)ZI_OK;
313418
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
314419
r->m);

src/zem/exec/zem_exec_call_io.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ int zem_exec_call_io(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
124124
if (!zabi_u32_from_u64(regs->HL, &handle_u) ||
125125
!zabi_u32_from_u64(regs->DE, &ptr) ||
126126
!zabi_u32_from_u64(regs->BC, &len)) {
127+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, "zi_write",
128+
cur_label,
129+
"handle/ptr/len not representable as u32")) {
130+
return 1;
131+
}
132+
if (dbg_cfg && dbg_cfg->sniff) {
133+
fprintf(stderr,
134+
" HL(handle)=0x%016" PRIx64 " DE(ptr)=0x%016" PRIx64
135+
" BC(len)=0x%016" PRIx64 "\n",
136+
regs->HL, regs->DE, regs->BC);
137+
zem_diag_print_regprov(stderr, regprov, "HL");
138+
zem_diag_print_regprov(stderr, regprov, "DE");
139+
zem_diag_print_regprov(stderr, regprov, "BC");
140+
}
127141
regs->HL = (uint64_t)(uint32_t)(strcmp(callee, "zi_write") == 0 ? ZI_E_INVALID
128142
: 0xffffffffu);
129143
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
@@ -133,6 +147,16 @@ int zem_exec_call_io(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
133147
}
134148
int32_t handle = (int32_t)handle_u;
135149
if (!mem_check_span(mem, ptr, len)) {
150+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, "zi_write", cur_label,
151+
"ptr/len out of bounds")) {
152+
return 1;
153+
}
154+
if (dbg_cfg && dbg_cfg->sniff) {
155+
fprintf(stderr, " ptr=%" PRIu32 " len=%" PRIu32 " mem_len=%zu\n", ptr, len,
156+
mem ? mem->len : 0);
157+
zem_diag_print_regprov(stderr, regprov, "DE");
158+
zem_diag_print_regprov(stderr, regprov, "BC");
159+
}
136160
regs->HL = (uint64_t)(uint32_t)(strcmp(callee, "zi_write") == 0 ? ZI_E_BOUNDS
137161
: 0xffffffffu);
138162
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
@@ -156,6 +180,20 @@ int zem_exec_call_io(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
156180
if (!zabi_u32_from_u64(regs->HL, &handle_u) ||
157181
!zabi_u32_from_u64(regs->DE, &ptr) ||
158182
!zabi_u32_from_u64(regs->BC, &cap)) {
183+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, "zi_read",
184+
cur_label,
185+
"handle/ptr/cap not representable as u32")) {
186+
return 1;
187+
}
188+
if (dbg_cfg && dbg_cfg->sniff) {
189+
fprintf(stderr,
190+
" HL(handle)=0x%016" PRIx64 " DE(ptr)=0x%016" PRIx64
191+
" BC(cap)=0x%016" PRIx64 "\n",
192+
regs->HL, regs->DE, regs->BC);
193+
zem_diag_print_regprov(stderr, regprov, "HL");
194+
zem_diag_print_regprov(stderr, regprov, "DE");
195+
zem_diag_print_regprov(stderr, regprov, "BC");
196+
}
159197
regs->HL = (uint64_t)(uint32_t)(strcmp(callee, "zi_read") == 0 ? ZI_E_INVALID
160198
: 0xffffffffu);
161199
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
@@ -165,6 +203,16 @@ int zem_exec_call_io(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
165203
}
166204
int32_t handle = (int32_t)handle_u;
167205
if (!mem_check_span(mem, ptr, cap)) {
206+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, "zi_read", cur_label,
207+
"ptr/cap out of bounds")) {
208+
return 1;
209+
}
210+
if (dbg_cfg && dbg_cfg->sniff) {
211+
fprintf(stderr, " ptr=%" PRIu32 " cap=%" PRIu32 " mem_len=%zu\n", ptr, cap,
212+
mem ? mem->len : 0);
213+
zem_diag_print_regprov(stderr, regprov, "DE");
214+
zem_diag_print_regprov(stderr, regprov, "BC");
215+
}
168216
regs->HL = (uint64_t)(uint32_t)(strcmp(callee, "zi_read") == 0 ? ZI_E_BOUNDS
169217
: 0xffffffffu);
170218
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,

src/zem/exec/zem_exec_call_misc.c

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
/* SPDX-License-Identifier: GPL-3.0-or-later */
33

44
#include <stdint.h>
5+
#include <inttypes.h>
6+
#include <stdio.h>
57
#include <string.h>
68

79
#include "zem_exec_internal.h"
@@ -37,6 +39,20 @@ int zem_exec_call_misc(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
3739
!zabi_u32_from_u64(regs->DE, &topic_len) ||
3840
!zabi_u32_from_u64(regs->BC, &msg_ptr) ||
3941
!zabi_u32_from_u64(regs->IX, &msg_len)) {
42+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
43+
"topic/msg args not representable as u32")) {
44+
return 1;
45+
}
46+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
47+
fprintf(stderr,
48+
" HL(topic_ptr)=0x%016" PRIx64 " DE(topic_len)=0x%016" PRIx64
49+
" BC(msg_ptr)=0x%016" PRIx64 " IX(msg_len)=0x%016" PRIx64 "\n",
50+
regs->HL, regs->DE, regs->BC, regs->IX);
51+
zem_diag_print_regprov(stderr, regprov, "HL");
52+
zem_diag_print_regprov(stderr, regprov, "DE");
53+
zem_diag_print_regprov(stderr, regprov, "BC");
54+
zem_diag_print_regprov(stderr, regprov, "IX");
55+
}
4056
regs->HL = (uint64_t)(uint32_t)ZI_E_INVALID;
4157
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
4258
r->m);
@@ -45,6 +61,20 @@ int zem_exec_call_misc(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
4561
}
4662
if (!mem_check_span(mem, topic_ptr, topic_len) ||
4763
!mem_check_span(mem, msg_ptr, msg_len)) {
64+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
65+
"topic/msg span out of bounds")) {
66+
return 1;
67+
}
68+
if (ctx->dbg_cfg && ctx->dbg_cfg->sniff) {
69+
fprintf(stderr,
70+
" topic_ptr=%" PRIu32 " topic_len=%" PRIu32 " msg_ptr=%" PRIu32
71+
" msg_len=%" PRIu32 " mem_len=%zu\n",
72+
topic_ptr, topic_len, msg_ptr, msg_len, mem ? mem->len : 0);
73+
zem_diag_print_regprov(stderr, regprov, "HL");
74+
zem_diag_print_regprov(stderr, regprov, "DE");
75+
zem_diag_print_regprov(stderr, regprov, "BC");
76+
zem_diag_print_regprov(stderr, regprov, "IX");
77+
}
4878
regs->HL = (uint64_t)(uint32_t)ZI_E_BOUNDS;
4979
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
5080
r->m);
@@ -165,9 +195,21 @@ int zem_exec_call_misc(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
165195
if (r->nops >= 2) {
166196
(void)op_to_u64(syms, regs, &r->ops[1], &key_obj64);
167197
}
198+
uint32_t key_obj = 0;
199+
if (!zabi_u32_from_u64(key_obj64, &key_obj)) {
200+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
201+
"key_obj not representable as u32")) {
202+
return 1;
203+
}
204+
regs->HL = 0;
205+
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
206+
r->m);
207+
*ctx->pc = pc + 1;
208+
return 1;
209+
}
168210
uint32_t key_ptr = 0, key_len = 0;
169211
uint64_t key = 0;
170-
if (bytes_view(mem, (uint32_t)key_obj64, &key_ptr, &key_len) &&
212+
if (bytes_view(mem, key_obj, &key_ptr, &key_len) &&
171213
mem_check_span(mem, key_ptr, key_len)) {
172214
key = hash64_fnv1a(mem->bytes + key_ptr, (size_t)key_len);
173215
}
@@ -196,9 +238,21 @@ int zem_exec_call_misc(zem_exec_ctx_t *ctx, const record_t *r, zem_op_t op) {
196238
(void)op_to_u64(syms, regs, &r->ops[1], &key_obj64);
197239
(void)op_to_u64(syms, regs, &r->ops[2], &value);
198240
}
241+
uint32_t key_obj = 0;
242+
if (!zabi_u32_from_u64(key_obj64, &key_obj)) {
243+
if (zem_sniff_abi_fail_or_warn(ctx, r, pc, callee, cur_label,
244+
"key_obj not representable as u32")) {
245+
return 1;
246+
}
247+
regs->HL = 0;
248+
zem_regprov_note(regprov, ZEM_REG_HL, (uint32_t)pc, cur_label, r->line,
249+
r->m);
250+
*ctx->pc = pc + 1;
251+
return 1;
252+
}
199253
uint32_t key_ptr = 0, key_len = 0;
200254
uint64_t key = 0;
201-
if (bytes_view(mem, (uint32_t)key_obj64, &key_ptr, &key_len) &&
255+
if (bytes_view(mem, key_obj, &key_ptr, &key_len) &&
202256
mem_check_span(mem, key_ptr, key_len)) {
203257
key = hash64_fnv1a(mem->bytes + key_ptr, (size_t)key_len);
204258
}

0 commit comments

Comments
 (0)