Stage D batch 2: fix silent error sites in log_words.c, resolve the flagged category-iii special case (FABRIC-3.md §XXXII.6)
log_word_set_level(), log_do_emit(), and log_emit_string() (7 sites total) now log a diagnostic via log_message(LOG_ERROR, ...) before setting vm->error, matching this file's own already-correct log_str_emit() sibling and defer_words.c's gold-standard pattern. log_word_append_raw() (backing (LOG-APPEND-RAW), 3 sites) resolved differently per §XXXII.3's own triage note: its doc comment forbids log_message() here (recursion into the log ring it writes to), but the word can also be invoked by hand at the console -- console_println() carries no such recursion risk and matches Stage B's policy for a manual interactive invocation. Added the console.h include this required. Three-arch clean qemu acceptance passed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5417ffb2bf
commit
1a8c0e4fcf
+56
-10
@@ -18,6 +18,7 @@
|
||||
#include "starkernel/log_region.h"
|
||||
#include "starkernel/log_attrib.h" /* vm_log_attributed_vm() */
|
||||
#include "starkernel/capsule_birth.h" /* capsule_vm_registry_get, VMRegistryEntry */
|
||||
#include "starkernel/console.h" /* console_println() -- (LOG-APPEND-RAW) diagnostics */
|
||||
#include <string.h> /* strlen */
|
||||
#endif
|
||||
|
||||
@@ -45,7 +46,11 @@ static void log_word_debug(VM *vm) { vm_push(vm, (cell_t)LOG_DEBUG); }
|
||||
*/
|
||||
static void log_word_set_level(VM *vm)
|
||||
{
|
||||
if (vm->dsp < 0) { vm->error = 1; return; }
|
||||
if (vm->dsp < 0) {
|
||||
log_message(LOG_ERROR, "LOG-LEVEL!: stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
cell_t n = vm_pop(vm);
|
||||
if (n < (cell_t)LOG_ERROR) n = (cell_t)LOG_ERROR;
|
||||
if (n > (cell_t)LOG_DEBUG) n = (cell_t)LOG_DEBUG;
|
||||
@@ -75,9 +80,17 @@ static void log_word_get_level(VM *vm)
|
||||
|
||||
static void log_do_emit(VM *vm, LogLevel level)
|
||||
{
|
||||
if (vm->rsp < 0) { vm->error = 1; return; }
|
||||
if (vm->rsp < 0) {
|
||||
log_message(LOG_ERROR, "(do-log-*): return-stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
uint8_t *data = (uint8_t *)(uintptr_t)vm->return_stack[vm->rsp];
|
||||
if (!data) { vm->error = 1; return; }
|
||||
if (!data) {
|
||||
log_message(LOG_ERROR, "(do-log-*): NULL inline-string pointer");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
uint8_t n = data[0];
|
||||
/* advance IP before emitting so re-entrant calls see correct state */
|
||||
size_t skip = 1 + (size_t)n;
|
||||
@@ -106,12 +119,20 @@ static void log_emit_string(VM *vm, LogLevel level,
|
||||
size_t pos = vm->input_pos;
|
||||
size_t end = vm->input_length;
|
||||
|
||||
if (!src || pos > end) { vm->error = 1; return; }
|
||||
if (!src || pos > end) {
|
||||
log_message(LOG_ERROR, "LOG-*\": no input buffer");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
if (pos < end && src[pos] == ' ') pos++;
|
||||
|
||||
size_t start = pos;
|
||||
while (pos < end && src[pos] != '"') pos++;
|
||||
if (pos >= end) { vm->error = 1; return; }
|
||||
if (pos >= end) {
|
||||
log_message(LOG_ERROR, "LOG-*\": unterminated string literal");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t n = pos - start;
|
||||
if (n > 255) n = 255;
|
||||
@@ -124,13 +145,21 @@ static void log_emit_string(VM *vm, LogLevel level,
|
||||
|
||||
/* Compilation: emit runtime word then inline [len][chars][pad] */
|
||||
DictEntry *rt = vm_find_word(vm, rt_name, (size_t)rt_nlen);
|
||||
if (!rt) { vm->error = 1; return; }
|
||||
if (!rt) {
|
||||
log_message(LOG_ERROR, "LOG-*\": runtime word '%.*s' not found", rt_nlen, rt_name);
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
vm_compile_word(vm, rt);
|
||||
|
||||
size_t skip = 1 + n;
|
||||
size_t padded = (skip + (sizeof(cell_t) - 1)) & ~(sizeof(cell_t) - 1);
|
||||
uint8_t *raw = (uint8_t *)vm_allot(vm, padded);
|
||||
if (!raw) { vm->error = 1; return; }
|
||||
if (!raw) {
|
||||
log_message(LOG_ERROR, "LOG-*\": vm_allot failed");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
raw[0] = (uint8_t)n;
|
||||
for (size_t i = 0; i < n; i++) raw[1 + i] = (uint8_t)src[start + i];
|
||||
for (size_t i = 1 + n; i < padded; i++) raw[i] = 0;
|
||||
@@ -214,14 +243,31 @@ static void log_word_debug_str(VM *vm) { log_str_emit(vm, LOG_DEBUG); }
|
||||
#ifdef __STARKERNEL__
|
||||
static void log_word_append_raw(VM *vm)
|
||||
{
|
||||
if (vm->dsp < 3) { vm->error = 1; return; }
|
||||
/* Diagnostics here go via console_println(), not log_message() -- this
|
||||
* function's own doc comment above forbids log_message() (recursion
|
||||
* into the log ring it writes to); console_println() carries no such
|
||||
* risk and covers the "by hand at the console for a smoke test" case
|
||||
* that same comment names (FABRIC-3.md §XXXII.6). */
|
||||
if (vm->dsp < 3) {
|
||||
console_println("(LOG-APPEND-RAW): stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
cell_t msg_u = vm_pop(vm);
|
||||
cell_t msg_addr = vm_pop(vm);
|
||||
cell_t timestamp = vm_pop(vm);
|
||||
cell_t level = vm_pop(vm);
|
||||
|
||||
if (msg_u < 0) { vm->error = 1; return; }
|
||||
if (msg_addr < 0 || (msg_addr + msg_u) > (cell_t)VM_MEMORY_SIZE) { vm->error = 1; return; }
|
||||
if (msg_u < 0) {
|
||||
console_println("(LOG-APPEND-RAW): negative message length");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
if (msg_addr < 0 || (msg_addr + msg_u) > (cell_t)VM_MEMORY_SIZE) {
|
||||
console_println("(LOG-APPEND-RAW): message address out of range");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const char *msg = (const char *)&vm->memory[msg_addr];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user