align vm runtime
This commit is contained in:
parent
fa651af3c3
commit
c7382763cd
@ -498,7 +498,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
return Ok(());
|
||||
}
|
||||
Syscall::SystemRunCart => {
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
@ -513,15 +513,14 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
|
||||
// --- GFX Syscalls ---
|
||||
|
||||
// gfx.clear(color_index) -> null
|
||||
// gfx.clear(color_index) -> void (ret_slots = 0)
|
||||
Syscall::GfxClear => {
|
||||
let color_val = expect_int(args, 0)?;
|
||||
let color = self.get_color(color_val);
|
||||
hw.gfx_mut().clear(color);
|
||||
ret.push_null();
|
||||
Ok(())
|
||||
}
|
||||
// gfx.draw_rect(x, y, w, h, color_index) -> null
|
||||
// gfx.draw_rect(x, y, w, h, color_index) -> void (ret_slots = 0)
|
||||
Syscall::GfxFillRect => {
|
||||
let x = expect_int(args, 0)? as i32;
|
||||
let y = expect_int(args, 1)? as i32;
|
||||
@ -530,10 +529,9 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let color_val = expect_int(args, 4)?;
|
||||
let color = self.get_color(color_val);
|
||||
hw.gfx_mut().fill_rect(x, y, w, h, color);
|
||||
ret.push_null();
|
||||
Ok(())
|
||||
}
|
||||
// gfx.draw_line(x1, y1, x2, y2, color_index) -> null
|
||||
// gfx.draw_line(x1, y1, x2, y2, color_index) -> void (ret_slots = 0)
|
||||
Syscall::GfxDrawLine => {
|
||||
let x1 = expect_int(args, 0)? as i32;
|
||||
let y1 = expect_int(args, 1)? as i32;
|
||||
@ -542,10 +540,9 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let color_val = expect_int(args, 4)?;
|
||||
let color = self.get_color(color_val);
|
||||
hw.gfx_mut().draw_line(x1, y1, x2, y2, color);
|
||||
ret.push_null();
|
||||
Ok(())
|
||||
}
|
||||
// gfx.draw_circle(x, y, r, color_index) -> null
|
||||
// gfx.draw_circle(x, y, r, color_index) -> void (ret_slots = 0)
|
||||
Syscall::GfxDrawCircle => {
|
||||
let x = expect_int(args, 0)? as i32;
|
||||
let y = expect_int(args, 1)? as i32;
|
||||
@ -553,10 +550,9 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let color_val = expect_int(args, 3)?;
|
||||
let color = self.get_color(color_val);
|
||||
hw.gfx_mut().draw_circle(x, y, r, color);
|
||||
ret.push_null();
|
||||
Ok(())
|
||||
}
|
||||
// gfx.draw_disc(x, y, r, border_color_idx, fill_color_idx) -> null
|
||||
// gfx.draw_disc(x, y, r, border_color_idx, fill_color_idx) -> void (ret_slots = 0)
|
||||
Syscall::GfxDrawDisc => {
|
||||
let x = expect_int(args, 0)? as i32;
|
||||
let y = expect_int(args, 1)? as i32;
|
||||
@ -566,10 +562,9 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let fill_color = self.get_color(fill_color_val);
|
||||
let border_color = self.get_color(border_color_val);
|
||||
hw.gfx_mut().draw_disc(x, y, r, border_color, fill_color);
|
||||
ret.push_null();
|
||||
Ok(())
|
||||
}
|
||||
// gfx.draw_square(x, y, w, h, border_color_idx, fill_color_idx) -> null
|
||||
// gfx.draw_square(x, y, w, h, border_color_idx, fill_color_idx) -> void (ret_slots = 0)
|
||||
Syscall::GfxDrawSquare => {
|
||||
let x = expect_int(args, 0)? as i32;
|
||||
let y = expect_int(args, 1)? as i32;
|
||||
@ -580,7 +575,6 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let fill_color = self.get_color(fill_color_val);
|
||||
let border_color = self.get_color(border_color_val);
|
||||
hw.gfx_mut().draw_square(x, y, w, h, border_color, fill_color);
|
||||
ret.push_null();
|
||||
Ok(())
|
||||
}
|
||||
// gfx.set_sprite(asset_name, id, x, y, tile_id, palette_id, active, flip_x, flip_y, priority)
|
||||
@ -617,7 +611,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
priority,
|
||||
};
|
||||
}
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
Syscall::GfxDrawText => {
|
||||
@ -633,7 +627,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let color_val = expect_int(args, 3)?;
|
||||
let color = self.get_color(color_val);
|
||||
hw.gfx_mut().draw_text(x, y, &msg, color);
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
// gfx.clear565(color_u16) -> void
|
||||
@ -873,7 +867,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
0,
|
||||
prometeu_hal::LoopMode::Off,
|
||||
);
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -909,7 +903,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
hw.assets().find_slot_by_name(&asset_name, BankType::SOUNDS).unwrap_or(0);
|
||||
|
||||
hw.audio_mut().play(bank_id, sample_id, voice_id, volume, pan, pitch, 0, loop_mode);
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -971,7 +965,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
Syscall::FsClose => {
|
||||
let handle = expect_int(args, 0)? as u32;
|
||||
self.open_files.remove(&handle);
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
// FS_LIST_DIR(path)
|
||||
@ -1087,13 +1081,13 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
Syscall::AssetCommit => {
|
||||
let handle = expect_int(args, 0)? as u32;
|
||||
hw.assets().commit(handle);
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
Syscall::AssetCancel => {
|
||||
let handle = expect_int(args, 0)? as u32;
|
||||
hw.assets().cancel(handle);
|
||||
ret.push_null();
|
||||
// ret_slots = 0 (void). Must return exactly 0 values per SyscallMeta.
|
||||
Ok(())
|
||||
}
|
||||
Syscall::BankInfo => {
|
||||
|
||||
@ -1732,11 +1732,17 @@ mod tests {
|
||||
let mut ctx = HostContext::new(None);
|
||||
|
||||
vm.prepare_call("0");
|
||||
vm.run_budget(100, &mut native, &mut ctx).unwrap();
|
||||
|
||||
assert_eq!(vm.pop().unwrap(), Value::Bounded(255));
|
||||
assert_eq!(vm.pop().unwrap(), Value::Int64(42));
|
||||
assert_eq!(vm.pop().unwrap(), Value::Boolean(true));
|
||||
// Ensure we have SYSTEM capability so we pass capability gate
|
||||
vm.set_capabilities(prometeu_hal::syscalls::caps::SYSTEM);
|
||||
let report = vm.run_budget(100, &mut native, &mut ctx).unwrap();
|
||||
// Under PR5, VM enforces return-slot count based on SyscallMeta during syscall
|
||||
// execution. A mismatch yields a Panic with a descriptive message.
|
||||
match report.reason {
|
||||
LogicalFrameEndingReason::Panic(msg) => {
|
||||
assert!(msg.contains("results mismatch"));
|
||||
}
|
||||
_ => panic!("Expected Panic with results mismatch, got {:?}", report.reason),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1810,6 +1816,8 @@ mod tests {
|
||||
let mut ctx = HostContext::new(None);
|
||||
|
||||
vm.prepare_call("0");
|
||||
// Ensure we have GFX capability so we reach type checking inside native handler
|
||||
vm.set_capabilities(prometeu_hal::syscalls::caps::GFX);
|
||||
let report = vm.run_budget(100, &mut native, &mut ctx).unwrap();
|
||||
|
||||
match report.reason {
|
||||
@ -1832,6 +1840,8 @@ mod tests {
|
||||
let mut ctx = HostContext::new(None);
|
||||
|
||||
vm.prepare_call("0");
|
||||
// Grant GFX capability so arg underflow is checked (capability gate is first)
|
||||
vm.set_capabilities(prometeu_hal::syscalls::caps::GFX);
|
||||
let report = vm.run_budget(100, &mut native, &mut ctx).unwrap();
|
||||
|
||||
match report.reason {
|
||||
@ -1857,6 +1867,8 @@ mod tests {
|
||||
let mut ctx = HostContext::new(None);
|
||||
|
||||
vm.prepare_call("0");
|
||||
// Grant GFX capability so arg underflow is checked (capability gate is first)
|
||||
vm.set_capabilities(prometeu_hal::syscalls::caps::GFX);
|
||||
let report = vm.run_budget(100, &mut native, &mut ctx).unwrap();
|
||||
|
||||
match report.reason {
|
||||
@ -1949,6 +1961,8 @@ mod tests {
|
||||
}
|
||||
|
||||
let mut vm = new_test_vm(rom.clone(), vec![]);
|
||||
// Grant GFX capability so results mismatch path is exercised
|
||||
vm.set_capabilities(prometeu_hal::syscalls::caps::GFX);
|
||||
let mut native = BadNative;
|
||||
let mut ctx = HostContext::new(None);
|
||||
|
||||
|
||||
@ -44,6 +44,8 @@ fn vm_syscall_multi_return_stack_contents() {
|
||||
let mut native = TestNative;
|
||||
let mut ctx = HostContext::new(None);
|
||||
vm.prepare_call("0");
|
||||
// Grant INPUT capability to pass capability gate for PadGetUp
|
||||
vm.set_capabilities(prometeu_hal::syscalls::caps::INPUT);
|
||||
let _ = vm.run_budget(100, &mut native, &mut ctx).expect("VM run failed");
|
||||
|
||||
// Verify stack order: last pushed is on top
|
||||
|
||||
34
files/VM RESET.md
Normal file
34
files/VM RESET.md
Normal file
@ -0,0 +1,34 @@
|
||||
6 — Closures (first-class user functions)
|
||||
|
||||
6.1. Definir objeto Closure no heap: fn_id + env (captures) + metadata mínima.
|
||||
6.2. Definir como capturas são materializadas (layout do env e como o bytecode cria closures).
|
||||
6.3. Implementar instruções/semântica para criar closure e para CALL_CLOSURE.
|
||||
6.4. Atualizar GC traversal: closure → env → heap refs internos.
|
||||
6.5. Atualizar verifier: tipo “closure value”, validação de call sites, ret_slots.
|
||||
6.6. Testes: closure simples, closure capturando, closure retornando outra closure.
|
||||
|
||||
7 — Coroutines (único modelo de concorrência, cooperativo)
|
||||
|
||||
7.1. Definir objeto Coroutine no heap: stack/frames próprios, status, wake time, mailbox/queue se existir.
|
||||
7.2. Definir scheduler determinístico: fila pronta, fila dormindo, política estável.
|
||||
7.3. Implementar SPAWN: criar coroutine + capturar entry + agendar.
|
||||
7.4. Implementar YIELD: ceder controle de forma cooperativa (somente em locais válidos).
|
||||
7.5. Implementar SLEEP: mover para fila dormindo até tick/time.
|
||||
7.6. Integrar execução/switch apenas em safepoints (FRAME_SYNC).
|
||||
7.7. Integrar GC roots: stacks suspensas e frames de todas as coroutines.
|
||||
7.8. Verifier: invariantes (ex.: proibir yield em contextos ilegais, validar spawn args/ret).
|
||||
7.9. Testes: determinismo (mesma ordem), sleep/wake, stress com GC + muitas coroutines.
|
||||
|
||||
8 — Tooling & test harness (para manter “JVM-grade”)
|
||||
|
||||
8.1. Disasm atualizado e confiável (roundtrip + snapshots).
|
||||
8.2. Harness de execução determinística para testes (seed fixo, time controlado).
|
||||
8.3. Suite de testes por camadas: bytecode (encode/decode), verifier, VM, GC, scheduler.
|
||||
8.4. “No legacy artifacts” check: busca por símbolos/nomes (retain/release/hip/gate/scope), módulos mortos removidos.
|
||||
|
||||
9 — Hardening final e documentação do novo baseline
|
||||
|
||||
9.1. Consolidar documentação de arquitetura (curta, objetiva, em inglês).
|
||||
9.2. Garantir que o “surface area” público está minimalista (APIs internas escondidas).
|
||||
9.3. Remover qualquer feature flag temporária que tenha sobrado.
|
||||
9.4. Rodar limpeza final: dead code, warnings, docs desatualizadas, exemplos antigos.
|
||||
Loading…
x
Reference in New Issue
Block a user