From bcbd110b17b3c9bcb0e28e28fd33388f1c954a27 Mon Sep 17 00:00:00 2001 From: polwex Date: Mon, 6 Oct 2025 20:14:44 +0700 Subject: progress in logging nock --- ocaml/lib/boot.ml | 92 ++++++- ocaml/lib/nock.ml | 316 +++++++++++++++-------- vere/pkg/noun/nock.c | 29 +++ vere/pkg/noun/vortex.c | 23 ++ vere/pkg/vere/solid_boot_test.c | 542 ++++++++++++++++++++++++---------------- zod/.urb/log/0i0/data.mdb | Bin 12832768 -> 12832768 bytes zod/.urb/log/0i0/lock.mdb | Bin 8192 -> 8192 bytes zod/.vere.lock | 2 +- 8 files changed, 672 insertions(+), 332 deletions(-) diff --git a/ocaml/lib/boot.ml b/ocaml/lib/boot.ml index 9e3f17c..61bb202 100644 --- a/ocaml/lib/boot.ml +++ b/ocaml/lib/boot.ml @@ -174,9 +174,29 @@ let life eve = Printf.printf "[Boot] About to execute: *[eve [2 [0 3] [0 2]]]\n%!"; Printf.printf "[Boot] This expands to: *[*[eve [0 3]] *[eve [0 2]]]\n%!"; + (* Log eve structure before nock - matching C vortex.c:43-59 *) + Printf.printf "[Boot] eve is %s\n%!" (if Noun.is_cell eve then "cell" else "atom"); + (match eve with + | Noun.Cell (eve_h, eve_t) -> + Printf.printf "[Boot] eve head is %s\n%!" (if Noun.is_cell eve_h then "cell" else "atom"); + Printf.printf "[Boot] eve tail is %s\n%!" (if Noun.is_cell eve_t then "cell" else "atom"); + (match eve_h with + | Noun.Cell (eve_hh, eve_ht) -> + Printf.printf "[Boot] eve head.head is %s\n%!" + (if Noun.is_atom eve_hh then + let z = match eve_hh with Noun.Atom z -> z | _ -> Z.zero in + "atom(" ^ Z.to_string z ^ ")" + else "cell"); + Printf.printf "[Boot] eve head.tail is %s\n%!" + (if Noun.is_cell eve_ht then "cell" else "atom") + | _ -> ()) + | _ -> ()); + (* First, manually compute the two parts to see where it fails *) let gat = try + Printf.printf "[Boot] calling Nock.nock_on(eve, [2 [0 3] [0 2]])...\n%!"; + (* Step 1: Compute *[eve [0 3]] = slot 3 of eve *) Printf.printf "[Boot] Step 1: Computing *[eve [0 3]] (slot 3 of subject)...\n%!"; let slot3_result = Nock.nock_on eve (Noun.cell (Noun.atom 0) (Noun.atom 3)) in @@ -189,9 +209,24 @@ let life eve = Printf.printf "[Boot] ✓ Slot 2 computed: %s\n%!" (if Noun.is_cell slot2_result then "cell" else "atom"); + (* Debug: check if slot2 looks like a valid Nock formula *) + Printf.printf "[Boot] Checking slot2 structure (should be a formula):\n%!"; + (match slot2_result with + | Noun.Cell (h, t) -> + Printf.printf "[Boot] slot2 = [%s %s]\n%!" + (if Noun.is_atom h then + let z = match h with Noun.Atom z -> z | _ -> Z.zero in + "atom(" ^ Z.to_string z ^ ")" + else "cell") + (if Noun.is_atom t then "atom" else "cell") + | Noun.Atom z -> + Printf.printf "[Boot] slot2 = atom(%s)\n%!" (Z.to_string z)); + (* Step 3: Compute *[slot3_result slot2_result] *) Printf.printf "[Boot] Step 3: Computing *[slot3 slot2] (nock slot-2 formula on slot-3 subject)...\n%!"; - Nock.nock_on slot3_result slot2_result + let result = Nock.nock_on slot3_result slot2_result in + Printf.printf "[Boot] ✓ Nock.nock_on returned successfully\n%!"; + result with e -> Printf.printf "[Boot] ✗ Nock failed during lifecycle: %s\n%!" (Printexc.to_string e); @@ -443,9 +478,6 @@ let build_event_list bot mod_ use_ = | _ -> acc in - (* Start with flipped bot events (NO timestamp) *) - let eve = flip (Noun.Atom Z.zero) bot in - (* Weld mod and use lists *) let rec weld l1 l2 = match l1 with @@ -456,7 +488,16 @@ let build_event_list bot mod_ use_ = let lit = weld mod_ use_ in - (* Add timestamped events *) + (* Start with flipped bot events (NO timestamp) *) + let eve = flip (Noun.Atom Z.zero) bot in + + (* Add timestamped mod/use events by consing to FRONT + * This matches C Vere: eve = u3nc(u3nc(now, i), eve) + * After all events are added, eve looks like: + * [[time use_last] ... [time mod1] bot3 bot2 bot1 ~] + * Then we flip to get: + * [bot1 bot2 bot3 [time mod1] ... [time use_last]] + *) let rec add_timestamped acc now_ref noun = match noun with | Noun.Atom z when Z.equal z Z.zero -> acc @@ -468,10 +509,8 @@ let build_event_list bot mod_ use_ = in now_ref := new_now; - (* Create [timestamp event] pair *) + (* Create [timestamp event] pair and cons to FRONT *) let stamped = Noun.Cell (new_now, event) in - - (* Cons onto accumulator *) let new_acc = Noun.Cell (stamped, acc) in add_timestamped new_acc now_ref rest @@ -481,10 +520,29 @@ let build_event_list bot mod_ use_ = let now_ref = ref now in let eve_with_stamped = add_timestamped eve now_ref lit in - (* Flip final list *) + (* Flip final list to get: [bot1 bot2 bot3 [time mod1] ...] *) let ova = flip (Noun.Atom Z.zero) eve_with_stamped in Printf.printf "[Boot] ✓ Event list built: %d events\n%!" (count_list ova); + + (* Debug: Check first few events *) + Printf.printf "[Boot] First event structure:\n%!"; + (match ova with + | Noun.Cell (first, _) -> + Printf.printf "[Boot] first = %s\n%!" + (if Noun.is_cell first then "cell" else "atom"); + (match first with + | Noun.Cell (h, t) -> + Printf.printf "[Boot] head = %s\n%!" + (if Noun.is_atom h then + let z = match h with Noun.Atom z -> z | _ -> Z.zero in + "atom(" ^ Z.to_string z ^ ")" + else "cell"); + Printf.printf "[Boot] tail = %s\n%!" + (if Noun.is_cell t then "cell" else "atom") + | _ -> ()) + | _ -> ()); + ova (* Boot lite - bootstrap ivory pill @@ -608,6 +666,22 @@ let boot_solid ~fs state ivory_path solid_path = (* Step 3.5: Synthesize events (C Vere mars.c:1763-1789) *) Printf.printf "[3.5] Synthesizing events (like C Vere)...\n%!"; + (* Debug: Check what's in first BOT event *) + Printf.printf " [Debug] Checking first BOT event structure:\n%!"; + (match bot with + | Noun.Cell (first_bot, _) -> + Printf.printf " first_bot is %s\n%!" + (if Noun.is_cell first_bot then "cell" else "atom"); + (match first_bot with + | Noun.Cell (h, _) -> + Printf.printf " first_bot head is %s\n%!" + (if Noun.is_atom h then + let z = match h with Noun.Atom z -> z | _ -> Z.zero in + "atom(" ^ Z.to_string z ^ ")" + else "cell") + | _ -> ()) + | _ -> ()); + (* Generate 4 synthetic MOD events *) let synth_mod = synthesize_mod_events () in Printf.printf " ✓ Generated 4 synthetic MOD events\n%!"; diff --git a/ocaml/lib/nock.ml b/ocaml/lib/nock.ml index 34065b8..670b12b 100644 --- a/ocaml/lib/nock.ml +++ b/ocaml/lib/nock.ml @@ -19,6 +19,10 @@ open Noun - 11: scry (errors in reference implementation) *) +(* Trace depth counter - only log first 20 levels *) +let trace_depth = ref 0 +let max_trace_depth = 20 + (** Main nock evaluation function: nock(subject, formula) In Nock notation: *[subject formula] @@ -26,120 +30,210 @@ open Noun This is a direct port of _n_nock_on from nock.c:157-396 *) let rec nock_on bus fol = - match fol with - | Cell (hib, gal) when is_cell hib -> - (* [a b] -> compute both sides and cons *) - let poz = nock_on bus hib in - let riv = nock_on bus gal in - cell poz riv - - | Cell (Atom op, gal) -> - (match Z.to_int op with - | 0 -> - (* /[axis subject] - slot/fragment lookup *) - if not (is_atom gal) then raise Exit - else slot (match gal with Atom n -> n | _ -> raise Exit) bus - - | 1 -> - (* =[constant subject] - return constant *) - gal - - | 2 -> - (* *[subject formula new_subject] - evaluate with new subject *) - if not (is_cell gal) then raise Exit; - let b_gal = head gal in - let c_gal = tail gal in - let seb = nock_on bus b_gal in - let nex = nock_on bus c_gal in - nock_on seb nex - - | 3 -> - (* ?[subject formula] - is-cell test *) - let gof = nock_on bus gal in - if is_cell gof then atom 0 else atom 1 - - | 4 -> - (* +[subject formula] - increment *) - let gof = nock_on bus gal in - inc gof - - | 5 -> - (* =[subject formula] - equality test *) - let wim = nock_on bus gal in - if not (is_cell wim) then raise Exit; - let a = head wim in - let b = tail wim in - if equal a b then atom 0 else atom 1 - - | 6 -> - (* if-then-else *) - if not (is_cell gal) then raise Exit; - let b_gal = head gal in - let cd_gal = tail gal in - if not (is_cell cd_gal) then raise Exit; - let c_gal = head cd_gal in - let d_gal = tail cd_gal in - - let tys = nock_on bus b_gal in - let nex = match tys with - | Atom n when Z.equal n Z.zero -> c_gal - | Atom n when Z.equal n Z.one -> d_gal - | _ -> raise Exit - in - nock_on bus nex - - | 7 -> - (* composition: *[*[subject b] c] *) - if not (is_cell gal) then raise Exit; - let b_gal = head gal in - let c_gal = tail gal in - let bod = nock_on bus b_gal in - nock_on bod c_gal - - | 8 -> - (* push: *[[*[subject b] subject] c] *) - if not (is_cell gal) then raise Exit; - let b_gal = head gal in - let c_gal = tail gal in - let heb = nock_on bus b_gal in - let bod = cell heb bus in - nock_on bod c_gal - - | 9 -> - (* call: *[*[subject c] axis] *) - if not (is_cell gal) then raise Exit; - let b_gal = head gal in - let c_gal = tail gal in - if not (is_atom b_gal) then raise Exit; - - let seb = nock_on bus c_gal in - let nex = slot (match b_gal with Atom n -> n | _ -> raise Exit) seb in - nock_on seb nex - - | 10 -> - (* hint - in reference implementation, hints are mostly ignored *) - let nex = - if is_cell gal then - (* [[hint-tag hint-value] formula] *) - tail gal - else - (* [hint-tag formula] where hint-value is implicit *) - gal - in - nock_on bus nex - - | 11 -> - (* scry - not implemented in reference nock, raises error *) - raise Exit + let should_trace = !trace_depth < max_trace_depth in + if should_trace then incr trace_depth; + try + let result = match fol with + | Cell (hib, gal) when is_cell hib -> + (* [a b] -> compute both sides and cons *) + if should_trace then Printf.eprintf "[Nock:%d] Cell-cell formula\n%!" !trace_depth; + let poz = nock_on bus hib in + let riv = nock_on bus gal in + cell poz riv - | _ -> - (* Invalid opcode *) + | Cell (Atom op, gal) -> + (* Check if opcode fits in int *) + if Z.compare op (Z.of_int max_int) > 0 then ( + if should_trace then Printf.eprintf "[Nock:%d] Opcode too large: %s\n%!" !trace_depth (Z.to_string op); raise Exit - ) + ); + let opcode = Z.to_int op in + if should_trace then Printf.eprintf "[Nock:%d] Opcode %d\n%!" !trace_depth opcode; + (match opcode with + | 0 -> + (* /[axis subject] - slot/fragment lookup *) + if not (is_atom gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op0: gal not atom\n%!" !trace_depth; + raise Exit + ) + else slot (match gal with Atom n -> n | _ -> raise Exit) bus + + | 1 -> + (* =[constant subject] - return constant *) + gal + + | 2 -> + (* *[subject formula new_subject] - evaluate with new subject *) + if not (is_cell gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op2: gal not cell\n%!" !trace_depth; + raise Exit + ); + let b_gal = head gal in + let c_gal = tail gal in + let seb = nock_on bus b_gal in + let nex = nock_on bus c_gal in + nock_on seb nex + + | 3 -> + (* ?[subject formula] - is-cell test *) + let gof = nock_on bus gal in + if is_cell gof then atom 0 else atom 1 + + | 4 -> + (* +[subject formula] - increment *) + let gof = nock_on bus gal in + inc gof + + | 5 -> + (* =[subject formula] - equality test *) + let wim = nock_on bus gal in + if not (is_cell wim) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op5: wim not cell\n%!" !trace_depth; + raise Exit + ); + let a = head wim in + let b = tail wim in + if equal a b then atom 0 else atom 1 + + | 6 -> + (* if-then-else *) + if not (is_cell gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op6: gal not cell\n%!" !trace_depth; + raise Exit + ); + let b_gal = head gal in + let cd_gal = tail gal in + if not (is_cell cd_gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op6: cd_gal not cell\n%!" !trace_depth; + raise Exit + ); + let c_gal = head cd_gal in + let d_gal = tail cd_gal in + + let tys = nock_on bus b_gal in + let nex = match tys with + | Atom n when Z.equal n Z.zero -> c_gal + | Atom n when Z.equal n Z.one -> d_gal + | _ -> + if should_trace then Printf.eprintf "[Nock:%d] Op6: tys not 0 or 1\n%!" !trace_depth; + raise Exit + in + nock_on bus nex + + | 7 -> + (* composition: *[*[subject b] c] *) + if not (is_cell gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op7: gal not cell\n%!" !trace_depth; + raise Exit + ); + let b_gal = head gal in + let c_gal = tail gal in + let bod = nock_on bus b_gal in + nock_on bod c_gal + + | 8 -> + (* push: *[[*[subject b] subject] c] *) + if not (is_cell gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op8: gal not cell\n%!" !trace_depth; + raise Exit + ); + let b_gal = head gal in + let c_gal = tail gal in + if should_trace then Printf.eprintf "[Nock:%d] Op8: computing b_gal...\n%!" !trace_depth; + let heb = nock_on bus b_gal in + if should_trace then Printf.eprintf "[Nock:%d] Op8: creating new subject [heb bus]...\n%!" !trace_depth; + let bod = cell heb bus in + if should_trace then Printf.eprintf "[Nock:%d] Op8: computing c_gal on new subject...\n%!" !trace_depth; + nock_on bod c_gal + + | 9 -> + (* call: *[*[subject c] axis] *) + if not (is_cell gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op9: gal not cell\n%!" !trace_depth; + raise Exit + ); + let b_gal = head gal in + let c_gal = tail gal in + if not (is_atom b_gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op9: b_gal not atom\n%!" !trace_depth; + raise Exit + ); + + let seb = nock_on bus c_gal in + let nex = slot (match b_gal with Atom n -> n | _ -> raise Exit) seb in + nock_on seb nex + + | 10 -> + (* hint - in reference implementation, hints are mostly ignored *) + if should_trace then Printf.eprintf "[Nock:%d] Op10: hint (gal is %s)\n%!" !trace_depth + (if is_cell gal then "cell" else "atom"); + let nex = + if is_cell gal then begin + (* [[hint-tag hint-value] formula] *) + let hint_part = head gal in + let formula = tail gal in + if should_trace then Printf.eprintf "[Nock:%d] Op10: hint_part is %s, formula is %s\n%!" !trace_depth + (if is_cell hint_part then "cell" else "atom") + (if is_cell formula then "cell" else "atom"); + formula + end else begin + (* [hint-tag formula] where hint-value is implicit *) + if should_trace then Printf.eprintf "[Nock:%d] Op10: implicit hint\n%!" !trace_depth; + gal + end + in + nock_on bus nex + + | 11 -> + (* scry - static scry *) + if should_trace then Printf.eprintf "[Nock:%d] Op11: scry (gal is %s)\n%!" !trace_depth + (if is_cell gal then "cell" else "atom"); + if not (is_cell gal) then ( + if should_trace then Printf.eprintf "[Nock:%d] Op11: gal not cell\n%!" !trace_depth; + raise Exit + ); + let ref_formula = head gal in + let gof_formula = tail gal in + + if should_trace then Printf.eprintf "[Nock:%d] Op11: ref_formula is %s, gof_formula is %s\n%!" !trace_depth + (if is_cell ref_formula then "cell" else "atom") + (if is_cell gof_formula then "cell" else "atom"); + + (* Check if ref_formula looks valid *) + (match ref_formula with + | Cell (Atom op, _) when Z.to_int op > 11 -> + if should_trace then Printf.eprintf "[Nock:%d] Op11: WARNING ref_formula has invalid opcode %d\n%!" !trace_depth (Z.to_int op) + | _ -> ()); + + (* Evaluate both formulas *) + if should_trace then Printf.eprintf "[Nock:%d] Op11: evaluating ref...\n%!" !trace_depth; + let _ref = nock_on bus ref_formula in + if should_trace then Printf.eprintf "[Nock:%d] Op11: evaluating gof...\n%!" !trace_depth; + let _gof = nock_on bus gof_formula in + + (* For now, scry always fails (returns block) + * In real Urbit, this would call into the scry handler + * C Vere calls u3m_soft_esc which can fail + * We'll return a crash for now *) + if should_trace then Printf.eprintf "[Nock:%d] Op11: scry not supported, crashing\n%!" !trace_depth; + raise Exit + + | n -> + (* Invalid opcode *) + if should_trace then Printf.eprintf "[Nock:%d] Invalid opcode: %d\n%!" !trace_depth n; + raise Exit + ) - | _ -> - (* Invalid formula structure *) - raise Exit + | _ -> + (* Invalid formula structure *) + if should_trace then Printf.eprintf "[Nock:%d] Invalid formula (not [atom cell] or [cell cell])\n%!" !trace_depth; + raise Exit + in + if should_trace then decr trace_depth; + result + with e -> + if should_trace then decr trace_depth; + raise e (** Convenience function: nock(subject, formula) *) let nock subject formula = diff --git a/vere/pkg/noun/nock.c b/vere/pkg/noun/nock.c index 8218efa..8de6d7e 100644 --- a/vere/pkg/noun/nock.c +++ b/vere/pkg/noun/nock.c @@ -8,6 +8,7 @@ #include "jets.h" #include "jets/k.h" #include "jets/q.h" +#include "log.h" #include "manage.h" #include "options.h" #include "retrieve.h" @@ -167,6 +168,17 @@ _n_nock_on(u3_noun bus, u3_noun fol) u3R->pro.nox_d += 1; #endif + // Trace first 30 opcodes + static c3_w opcode_count = 0; + if ( opcode_count < 30 ) { + if ( c3y == u3du(hib) ) { + u3l_log("[C-Nock:%u] cell-cell formula", opcode_count); + } else { + u3l_log("[C-Nock:%u] opcode %u", opcode_count, hib); + } + opcode_count++; + } + if ( c3y == u3du(hib) ) { u3_noun poz, riv; @@ -2907,6 +2919,17 @@ u3n_burn(u3p(u3n_prog) pog_p, u3_noun bus) static u3_noun _n_burn_on(u3_noun bus, u3_noun fol) { + static c3_w burn_count = 0; + if ( burn_count < 30 ) { + u3_noun hib = u3h(fol); + if ( c3y == u3du(hib) ) { + u3l_log("[C-Burn:%u] cell-cell formula", burn_count); + } else { + u3l_log("[C-Burn:%u] opcode %u", burn_count, hib); + } + burn_count++; + } + u3n_prog* pog_u = _n_find(u3_nul, fol); u3z(fol); @@ -2920,6 +2943,12 @@ u3n_nock_on(u3_noun bus, u3_noun fol) { u3_noun pro; + static c3_w call_count = 0; + if ( call_count < 10 ) { + u3l_log(">>> u3n_nock_on call #%u <<<", call_count); + call_count++; + } + u3t_on(noc_o); #if 0 pro = _n_nock_on(bus, fol); diff --git a/vere/pkg/noun/vortex.c b/vere/pkg/noun/vortex.c index 63b4fc2..e4b55d9 100644 --- a/vere/pkg/noun/vortex.c +++ b/vere/pkg/noun/vortex.c @@ -38,7 +38,30 @@ u3v_life(u3_noun eve) u3l_log("u3v_life: processing %llu events", (unsigned long long)len_d); u3_noun lyf = u3nt(2, u3nc(0, 3), u3nc(0, 2)); + + // Log eve structure before nock + u3l_log("u3v_life: eve is %s", (c3y == u3a_is_atom(eve)) ? "atom" : "cell"); + if ( c3y == u3a_is_cell(eve) ) { + u3_noun eve_h = u3h(eve); + u3_noun eve_t = u3t(eve); + u3l_log("u3v_life: eve head is %s", (c3y == u3a_is_atom(eve_h)) ? "atom" : "cell"); + u3l_log("u3v_life: eve tail is %s", (c3y == u3a_is_atom(eve_t)) ? "atom" : "cell"); + + if ( c3y == u3a_is_cell(eve_h) ) { + u3_noun eve_hh = u3h(eve_h); + u3_noun eve_ht = u3t(eve_h); + u3l_log("u3v_life: eve head.head is %s", (c3y == u3a_is_atom(eve_hh)) ? "atom" : "cell"); + if ( c3y == u3a_is_atom(eve_hh) ) { + u3l_log("u3v_life: eve head.head = %u", u3r_word(0, eve_hh)); + } + u3l_log("u3v_life: eve head.tail is %s", (c3y == u3a_is_atom(eve_ht)) ? "atom" : "cell"); + } + } + + u3l_log("u3v_life: calling u3n_nock_on(eve, [2 [0 3] [0 2]])..."); u3_noun gat = u3n_nock_on(eve, lyf); + u3l_log("u3v_life: u3n_nock_on returned successfully"); + u3_noun cor = u3k(u3x_at(7, gat)); u3z(gat); diff --git a/vere/pkg/vere/solid_boot_test.c b/vere/pkg/vere/solid_boot_test.c index e6bd23a..00078ee 100644 --- a/vere/pkg/vere/solid_boot_test.c +++ b/vere/pkg/vere/solid_boot_test.c @@ -1,243 +1,363 @@ +// /// @file +// /// Test solid pill boot flow - exactly as mars.c does it + +// #include "vere.h" + +// static void +// _setup(void) +// { +// u3m_boot_lite(1 << 28); // 256MB loom +// } + +// /* Helper wrapper for u3v_boot to use with u3m_soft */ +// static u3_noun +// _boot_wrapper(u3_noun ova) +// { +// if ( c3n == u3v_boot(ova) ) { +// return u3nc(c3__exit, u3_nul); +// } +// return u3nc(u3_blip, u3_nul); +// } + +// /* _test_solid_boot(): boot from solid.pill following exact mars.c flow +// */ +// static c3_i +// _test_solid_boot(void) +// { +// fprintf(stderr, "\n"); +// fprintf(stderr, "═══════════════════════════════════════════════════\n"); +// fprintf(stderr, " Solid Pill Boot Test (Exact C Vere Flow)\n"); +// fprintf(stderr, "═══════════════════════════════════════════════════\n\n"); + +// /* Step 1: Load solid.pill (like king.c:611) */ +// fprintf(stderr, "[1] Loading solid.pill (u3m_file like king.c)...\n"); +// // u3_noun pil_p = u3m_file("solid.pill"); +// u3_noun pil_p = u3m_file("/home/y/code/urbit/vere/ocaml/solid.pill"); +// u3_noun arv = u3_nul; +// c3_o arv_atom = u3a_is_atom(arv); +// c3_o atom2 = u3a_is_atom(42); +// c3_o atom3 = u3a_is_atom(u3nc(1, 5)); +// u3l_log("arv_atom %u", arv_atom); +// u3l_log("atoms ? %u - %u", atom2, atom3); +// u3l_log("c3y %u", c3y); +// u3l_log("c3n %u", c3n); +// u3_noun pil2 = u3nc(pil_p, arv); + +// fprintf(stderr, " ✓ Loaded pill as atom\n\n"); + +// /* Step 2: Cue the pill atom (like _mars_sift_pill:1597) */ +// fprintf(stderr, "[2] Cuing pill atom (like _mars_sift_pill)...\n"); +// u3_noun pro = u3m_soft(0, u3ke_cue, u3k(pil_p)); +// u3_noun mot, tag, dat; + +// if ( (c3n == u3r_trel(pro, &mot, &tag, &dat)) +// || (u3_blip != mot) ) +// { +// fprintf(stderr, " ✗ Failed to cue pill\n"); +// u3z(pro); +// u3z(pil_p); +// return 0; +// } + +// /* Check for %pill tag */ +// if ( c3__pill != tag ) { +// fprintf(stderr, " ✗ Not a pill (expected %%pill tag)\n"); +// u3z(pro); +// u3z(pil_p); +// return 0; +// } + +// fprintf(stderr, " ✓ Cued successfully, got %%pill\n\n"); + +// /* Step 3: Parse pill structure [%solid [bot mod use]] */ +// fprintf(stderr, "[3] Parsing pill structure...\n"); + +// u3_noun sol_tag, events; +// if ( c3n == u3r_cell(dat, &sol_tag, &events) ) { +// fprintf(stderr, " ✗ Invalid pill data structure\n"); +// u3z(pro); +// u3z(pil_p); +// return 0; +// } + +// /* Extract bot, mod, use */ +// u3_noun bot, mod, use; +// if ( c3n == u3r_trel(events, &bot, &mod, &use) ) { +// fprintf(stderr, " ✗ Cannot extract bot/mod/use\n"); +// u3z(pro); +// u3z(pil_p); +// return 0; +// } + +// u3k(bot); u3k(mod); u3k(use); +// u3z(pro); +// u3z(pil_p); + +// c3_d bot_c = u3qb_lent(bot); +// c3_d mod_c = u3qb_lent(mod); +// c3_d use_c = u3qb_lent(use); + +// fprintf(stderr, " Bot events: %llu\n", (unsigned long long)bot_c); +// fprintf(stderr, " Mod events: %llu\n", (unsigned long long)mod_c); +// fprintf(stderr, " Use events: %llu\n", (unsigned long long)use_c); +// fprintf(stderr, " Total: %llu events\n\n", +// (unsigned long long)(bot_c + mod_c + use_c)); + +// /* Step 3.5: Dump full pill structure */ +// fprintf(stderr, "[3.5] Dumping full pill structure to /tmp/pill_dump.txt...\n"); +// { +// FILE* f = fopen("/tmp/pill_dump.txt", "w"); +// if ( f ) { +// fprintf(f, "========================================\n"); +// fprintf(f, "BOT events: %llu\n", (unsigned long long)bot_c); +// fprintf(f, "========================================\n"); +// u3_noun t = bot; +// c3_d i = 0; +// while ( u3_nul != t ) { +// u3_noun item = u3h(t); +// fprintf(f, "\nBot[%llu]: %s (mug: 0x%x)\n", +// (unsigned long long)i, +// u3a_is_atom(item) ? "ATOM" : "CELL", +// u3r_mug(item)); +// if ( u3a_is_atom(item) ) { +// fprintf(f, " Size: %u bits\n", u3r_met(0, item)); +// } +// t = u3t(t); +// i++; +// } + +// fprintf(f, "\n========================================\n"); +// fprintf(f, "MOD events: %llu\n", (unsigned long long)mod_c); +// fprintf(f, "========================================\n"); +// t = mod; +// i = 0; +// while ( u3_nul != t ) { +// u3_noun item = u3h(t); +// fprintf(f, "\nMod[%llu]: %s (mug: 0x%x)\n", +// (unsigned long long)i, +// u3a_is_atom(item) ? "ATOM" : "CELL", +// u3r_mug(item)); +// t = u3t(t); +// i++; +// } + +// fprintf(f, "\n========================================\n"); +// fprintf(f, "USE events: %llu\n", (unsigned long long)use_c); +// fprintf(f, "========================================\n"); +// t = use; +// i = 0; +// while ( u3_nul != t ) { +// u3_noun item = u3h(t); +// fprintf(f, "\nUse[%llu]: %s (mug: 0x%x)\n", +// (unsigned long long)i, +// u3a_is_atom(item) ? "ATOM" : "CELL", +// u3r_mug(item)); +// t = u3t(t); +// i++; +// } + +// fclose(f); +// fprintf(stderr, " ✓ Wrote basic structure to /tmp/pill_dump.txt\n\n"); +// } else { +// fprintf(stderr, " ✗ Failed to open /tmp/pill_dump.txt\n\n"); +// } +// } + +// /* STOP HERE - don't actually boot, just wanted the structure dump */ +// fprintf(stderr, "✓ PILL STRUCTURE DUMPED - exiting without boot\n"); +// u3z(bot); u3z(mod); u3z(use); +// return 1; + +// /* Step 4: Build event list (like _mars_boot_make lines 1814-1836) */ +// fprintf(stderr, "[4] Building event list (C Vere style)...\n"); +// fprintf(stderr, " Bot events: NOT timestamped\n"); +// fprintf(stderr, " Mod/use events: timestamped\n\n"); + +// struct timeval tim_u; +// gettimeofday(&tim_u, 0); +// u3_noun now = u3_time_in_tv(&tim_u); +// u3_noun bit = u3qc_bex(48); // 1/2^16 seconds +// u3_noun eve = u3kb_flop(u3k(bot)); // Bot events WITHOUT timestamp + +// { +// u3_noun lit = u3kb_weld(u3k(mod), u3k(use)); +// u3_noun i, t = lit; + +// while ( u3_nul != t ) { +// u3x_cell(t, &i, &t); +// now = u3ka_add(now, u3k(bit)); +// eve = u3nc(u3nc(u3k(now), u3k(i)), eve); // WITH timestamp +// } + +// u3z(lit); +// } + +// u3_noun ova = u3kb_flop(eve); +// u3z(now); u3z(bit); +// u3z(bot); u3z(mod); u3z(use); + +// c3_d eve_count = u3qb_lent(ova); +// fprintf(stderr, " ✓ Event list built: %llu events\n\n", (unsigned long long)eve_count); + +// /* Step 5: Call u3v_boot (like _mars_do_boot line 1160) */ +// fprintf(stderr, "[5] Calling u3v_boot with event list...\n"); +// fprintf(stderr, " (This is what actually happens in C Vere!)\n\n"); + +// u3_noun boot_pro = u3m_soft(0, _boot_wrapper, ova); + +// if ( u3_blip != u3h(boot_pro) ) { +// fprintf(stderr, " ✗ BOOT FAILED!\n"); +// fprintf(stderr, " Error: "); +// u3m_p("", u3h(boot_pro)); +// fprintf(stderr, "\n"); +// u3z(boot_pro); +// return 0; +// } + +// fprintf(stderr, " ✓ BOOT SUCCEEDED!\n"); +// fprintf(stderr, " Kernel mug: %x\n", u3r_mug(u3A->roc)); +// fprintf(stderr, "\n"); + +// fprintf(stderr, "═══════════════════════════════════════════════════\n"); +// fprintf(stderr, " ✓ SOLID PILL BOOT TEST PASSED!\n"); +// fprintf(stderr, "═══════════════════════════════════════════════════\n\n"); + +// u3z(boot_pro); + +// return 1; +// } + +// int +// main(int argc, char* argv[]) +// { +// _setup(); + +// if ( !_test_solid_boot() ) { +// fprintf(stderr, "test solid boot: FAILED\r\n"); +// return 1; +// } + +// u3m_grab(u3_none); +// fprintf(stderr, "test solid boot: OK\r\n"); +// return 0; +// } +// + /// @file -/// Test solid pill boot flow - exactly as mars.c does it +#include "ivory.h" +#include "noun.h" +#include "ur/ur.h" #include "vere.h" +/* _setup(): prepare for tests. +*/ static void _setup(void) { - u3m_boot_lite(1 << 28); // 256MB loom -} - -/* Helper wrapper for u3v_boot to use with u3m_soft */ -static u3_noun -_boot_wrapper(u3_noun ova) -{ - if ( c3n == u3v_boot(ova) ) { - return u3nc(c3__exit, u3_nul); + c3_d len_d = u3_Ivory_pill_len; + c3_y* byt_y = u3_Ivory_pill; + u3_cue_xeno* sil_u; + u3_weak pil; + + u3C.wag_w |= u3o_hashless; + u3m_boot_lite(1 << 26); + // this follows king.c + sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28); + if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) { + printf("*** fail _setup 1\n"); + exit(1); } - return u3nc(u3_blip, u3_nul); -} -/* _test_solid_boot(): boot from solid.pill following exact mars.c flow -*/ -static c3_i -_test_solid_boot(void) -{ - fprintf(stderr, "\n"); - fprintf(stderr, "═══════════════════════════════════════════════════\n"); - fprintf(stderr, " Solid Pill Boot Test (Exact C Vere Flow)\n"); - fprintf(stderr, "═══════════════════════════════════════════════════\n\n"); - - /* Step 1: Load solid.pill (like king.c:611) */ - fprintf(stderr, "[1] Loading solid.pill (u3m_file like king.c)...\n"); - // u3_noun pil_p = u3m_file("solid.pill"); - u3_noun pil_p = u3m_file("/home/y/code/urbit/vere/ocaml/solid.pill"); - u3_noun arv = u3_nul; - c3_o arv_atom = u3a_is_atom(arv); - c3_o atom2 = u3a_is_atom(42); - c3_o atom3 = u3a_is_atom(u3nc(1, 5)); - u3l_log("arv_atom %u", arv_atom); - u3l_log("atoms ? %u - %u", atom2, atom3); - u3l_log("c3y %u", c3y); - u3l_log("c3n %u", c3n); - u3_noun pil2 = u3nc(pil_p, arv); - - fprintf(stderr, " ✓ Loaded pill as atom\n\n"); - - /* Step 2: Cue the pill atom (like _mars_sift_pill:1597) */ - fprintf(stderr, "[2] Cuing pill atom (like _mars_sift_pill)...\n"); - u3_noun pro = u3m_soft(0, u3ke_cue, u3k(pil_p)); - u3_noun mot, tag, dat; - - if ( (c3n == u3r_trel(pro, &mot, &tag, &dat)) - || (u3_blip != mot) ) + u3l_log("embed_pil_is_atom %u", u3a_is_atom(pil)); + u3_noun local_pil = u3m_file("/home/y/code/urbit/vere/ocaml/solid.pill"); + u3_noun cued_pil = u3ke_cue(local_pil); + + u3l_log("local_pil_is_atom %u", u3a_is_atom(local_pil)); + u3l_log("cued_pil_is_atom %u", u3a_is_atom(cued_pil)); + + c3_d len_pp; { - fprintf(stderr, " ✗ Failed to cue pill\n"); - u3z(pro); - u3z(pil_p); - return 0; + u3_noun len = u3qb_lent(pil); + u3_assert( c3y == u3r_safe_chub(len, &len_pp) ); + u3z(len); } - - /* Check for %pill tag */ - if ( c3__pill != tag ) { - fprintf(stderr, " ✗ Not a pill (expected %%pill tag)\n"); - u3z(pro); - u3z(pil_p); - return 0; + u3l_log("embedded pill length %llu", (unsigned long long)len_pp); + c3_d len_pp2; + { + u3_noun len = u3qb_lent(cued_pil); + u3_assert( c3y == u3r_safe_chub(len, &len_pp2) ); + u3z(len); } + u3l_log("file_pill_length %llu", (unsigned long long)len_pp2); - fprintf(stderr, " ✓ Cued successfully, got %%pill\n\n"); + // 1. Direct equality check + c3_o match = u3r_sing(pil, cued_pil); + u3l_log("pills equal: %u", match); - /* Step 3: Parse pill structure [%solid [bot mod use]] */ - fprintf(stderr, "[3] Parsing pill structure...\n"); + // 2. Compare mugs (32-bit hashes) + u3l_log("embedded mug: %x", u3r_mug(pil)); + u3l_log("file mug: %x", u3r_mug(cued_pil)); - u3_noun sol_tag, events; - if ( c3n == u3r_cell(dat, &sol_tag, &events) ) { - fprintf(stderr, " ✗ Invalid pill data structure\n"); - u3z(pro); - u3z(pil_p); - return 0; + // 3. If they're cells, compare heads + if ( c3y == u3a_is_cell(pil) && c3y == u3a_is_cell(cued_pil) ) { + u3l_log("head mug embedded: %x", u3r_mug(u3h(pil))); + u3l_log("head mug file: %x", u3r_mug(u3h(cued_pil))); } - /* Extract bot, mod, use */ - u3_noun bot, mod, use; - if ( c3n == u3r_trel(events, &bot, &mod, &use) ) { - fprintf(stderr, " ✗ Cannot extract bot/mod/use\n"); - u3z(pro); - u3z(pil_p); - return 0; + // 4. Jam both and compare sizes + u3_noun jam1 = u3qe_jam(pil); + u3_noun jam2 = u3qe_jam(cued_pil); + u3l_log("jammed embedded: %u met", u3r_met(3, jam1)); + u3l_log("jammed file: %u met", u3r_met(3, jam2)); + u3l_log("jams equal: %u", u3r_sing(jam1, jam2)); + u3z(jam1); u3z(jam2); + + + // + u3s_cue_xeno_done(sil_u); + if ( c3n == u3v_boot_lite(pil) ) { + printf("*** fail _setup 2\n"); + exit(1); } +} - u3k(bot); u3k(mod); u3k(use); - u3z(pro); - u3z(pil_p); - - c3_d bot_c = u3qb_lent(bot); - c3_d mod_c = u3qb_lent(mod); - c3_d use_c = u3qb_lent(use); - - fprintf(stderr, " Bot events: %llu\n", (unsigned long long)bot_c); - fprintf(stderr, " Mod events: %llu\n", (unsigned long long)mod_c); - fprintf(stderr, " Use events: %llu\n", (unsigned long long)use_c); - fprintf(stderr, " Total: %llu events\n\n", - (unsigned long long)(bot_c + mod_c + use_c)); - - /* Step 3.5: Dump full pill structure */ - fprintf(stderr, "[3.5] Dumping full pill structure to /tmp/pill_dump.txt...\n"); - { - FILE* f = fopen("/tmp/pill_dump.txt", "w"); - if ( f ) { - fprintf(f, "========================================\n"); - fprintf(f, "BOT events: %llu\n", (unsigned long long)bot_c); - fprintf(f, "========================================\n"); - u3_noun t = bot; - c3_d i = 0; - while ( u3_nul != t ) { - u3_noun item = u3h(t); - fprintf(f, "\nBot[%llu]: %s (mug: 0x%x)\n", - (unsigned long long)i, - u3a_is_atom(item) ? "ATOM" : "CELL", - u3r_mug(item)); - if ( u3a_is_atom(item) ) { - fprintf(f, " Size: %u bits\n", u3r_met(0, item)); - } - t = u3t(t); - i++; - } - - fprintf(f, "\n========================================\n"); - fprintf(f, "MOD events: %llu\n", (unsigned long long)mod_c); - fprintf(f, "========================================\n"); - t = mod; - i = 0; - while ( u3_nul != t ) { - u3_noun item = u3h(t); - fprintf(f, "\nMod[%llu]: %s (mug: 0x%x)\n", - (unsigned long long)i, - u3a_is_atom(item) ? "ATOM" : "CELL", - u3r_mug(item)); - t = u3t(t); - i++; - } - - fprintf(f, "\n========================================\n"); - fprintf(f, "USE events: %llu\n", (unsigned long long)use_c); - fprintf(f, "========================================\n"); - t = use; - i = 0; - while ( u3_nul != t ) { - u3_noun item = u3h(t); - fprintf(f, "\nUse[%llu]: %s (mug: 0x%x)\n", - (unsigned long long)i, - u3a_is_atom(item) ? "ATOM" : "CELL", - u3r_mug(item)); - t = u3t(t); - i++; - } - - fclose(f); - fprintf(stderr, " ✓ Wrote basic structure to /tmp/pill_dump.txt\n\n"); - } else { - fprintf(stderr, " ✗ Failed to open /tmp/pill_dump.txt\n\n"); - } +/* _test_lily(): test small noun parsing. +*/ +static void +_test_lily() +{ + c3_l lit_l; + c3_w big_w[] = {0, 0, 1}; + u3_noun big = u3i_words(3, big_w); + u3_noun cod = u3dc("scot", c3__uv, big); + + if ( c3y == u3v_lily(c3__uv, cod, &lit_l) ) { + printf("*** fail _test_lily-1\n"); + exit(1); } - - /* STOP HERE - don't actually boot, just wanted the structure dump */ - fprintf(stderr, "✓ PILL STRUCTURE DUMPED - exiting without boot\n"); - u3z(bot); u3z(mod); u3z(use); - return 1; - - /* Step 4: Build event list (like _mars_boot_make lines 1814-1836) */ - fprintf(stderr, "[4] Building event list (C Vere style)...\n"); - fprintf(stderr, " Bot events: NOT timestamped\n"); - fprintf(stderr, " Mod/use events: timestamped\n\n"); - - struct timeval tim_u; - gettimeofday(&tim_u, 0); - u3_noun now = u3_time_in_tv(&tim_u); - u3_noun bit = u3qc_bex(48); // 1/2^16 seconds - u3_noun eve = u3kb_flop(u3k(bot)); // Bot events WITHOUT timestamp - - { - u3_noun lit = u3kb_weld(u3k(mod), u3k(use)); - u3_noun i, t = lit; - - while ( u3_nul != t ) { - u3x_cell(t, &i, &t); - now = u3ka_add(now, u3k(bit)); - eve = u3nc(u3nc(u3k(now), u3k(i)), eve); // WITH timestamp - } - - u3z(lit); + cod = u3dc("scot", c3__ud, 0x7fffffff); + if ( (c3n == u3v_lily(c3__ud, cod, &lit_l)) || + (0x7fffffff != lit_l) ) { + printf("*** fail _test_lily-2a\n"); + exit(1); } - - u3_noun ova = u3kb_flop(eve); - u3z(now); u3z(bit); - u3z(bot); u3z(mod); u3z(use); - - c3_d eve_count = u3qb_lent(ova); - fprintf(stderr, " ✓ Event list built: %llu events\n\n", (unsigned long long)eve_count); - - /* Step 5: Call u3v_boot (like _mars_do_boot line 1160) */ - fprintf(stderr, "[5] Calling u3v_boot with event list...\n"); - fprintf(stderr, " (This is what actually happens in C Vere!)\n\n"); - - u3_noun boot_pro = u3m_soft(0, _boot_wrapper, ova); - - if ( u3_blip != u3h(boot_pro) ) { - fprintf(stderr, " ✗ BOOT FAILED!\n"); - fprintf(stderr, " Error: "); - u3m_p("", u3h(boot_pro)); - fprintf(stderr, "\n"); - u3z(boot_pro); - return 0; + cod = u3dc("scot", c3__ux, u3i_word(0x80000000)); + if ( c3y == u3v_lily(c3__ux, cod, &lit_l) ) { + printf("*** fail _test_lily-2b\n"); + exit(1); } - - fprintf(stderr, " ✓ BOOT SUCCEEDED!\n"); - fprintf(stderr, " Kernel mug: %x\n", u3r_mug(u3A->roc)); - fprintf(stderr, "\n"); - - fprintf(stderr, "═══════════════════════════════════════════════════\n"); - fprintf(stderr, " ✓ SOLID PILL BOOT TEST PASSED!\n"); - fprintf(stderr, "═══════════════════════════════════════════════════\n\n"); - - u3z(boot_pro); - - return 1; } +/* main(): run all test cases. +*/ int main(int argc, char* argv[]) { _setup(); - if ( !_test_solid_boot() ) { - fprintf(stderr, "test solid boot: FAILED\r\n"); - return 1; - } + _test_lily(); - u3m_grab(u3_none); - fprintf(stderr, "test solid boot: OK\r\n"); + fprintf(stderr, "test boot: ok\n"); return 0; } diff --git a/zod/.urb/log/0i0/data.mdb b/zod/.urb/log/0i0/data.mdb index 4f86596..78ab8ed 100644 Binary files a/zod/.urb/log/0i0/data.mdb and b/zod/.urb/log/0i0/data.mdb differ diff --git a/zod/.urb/log/0i0/lock.mdb b/zod/.urb/log/0i0/lock.mdb index bc75f1c..11ec112 100644 Binary files a/zod/.urb/log/0i0/lock.mdb and b/zod/.urb/log/0i0/lock.mdb differ diff --git a/zod/.vere.lock b/zod/.vere.lock index 04d560a..ad9619f 100644 --- a/zod/.vere.lock +++ b/zod/.vere.lock @@ -1 +1 @@ -661315 +762914 -- cgit v1.2.3