dev/perf-host-debug-overlay-isolation #14

Merged
bquarkz merged 11 commits from dev/perf-host-debug-overlay-isolation into master 2026-04-10 22:20:40 +00:00
10 changed files with 227 additions and 445 deletions
Showing only changes of commit f5580ae0ce - Show all commits

View File

@ -96,6 +96,62 @@ pub struct SyscallRegistryEntry {
pub meta: SyscallMeta,
}
impl SyscallRegistryEntry {
/// Starts the builder with mandatory fields and sensible default values.
pub const fn builder(syscall: Syscall, module: &'static str, name: &'static str) -> Self {
Self {
syscall,
meta: SyscallMeta {
id: syscall as u32,
module,
name,
version: 1, // Default for new syscalls
arg_slots: 0,
ret_slots: 0,
caps: 0,
determinism: Determinism::Deterministic,
may_allocate: false,
cost_hint: 1,
},
}
}
pub const fn version(mut self, n: u16) -> Self {
self.meta.version = n;
self
}
pub const fn args(mut self, n: u8) -> Self {
self.meta.arg_slots = n;
self
}
pub const fn rets(mut self, n: u16) -> Self {
self.meta.ret_slots = n;
self
}
pub const fn caps(mut self, caps: CapFlags) -> Self {
self.meta.caps = caps;
self
}
pub const fn non_deterministic(mut self) -> Self {
self.meta.determinism = Determinism::NonDeterministic;
self
}
pub const fn may_allocate(mut self) -> Self {
self.meta.may_allocate = true;
self
}
pub const fn cost(mut self, cost: u32) -> Self {
self.meta.cost_hint = cost;
self
}
}
pub fn meta_for(syscall: Syscall) -> &'static SyscallMeta {
registry::meta_for(syscall)
}

View File

@ -1,53 +1,27 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::AssetLoad,
"asset",
"load",
1,
2,
2,
caps::ASSET,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::AssetStatus,
"asset",
"status",
1,
1,
1,
caps::ASSET,
Determinism::NonDeterministic,
false,
1,
),
entry(
Syscall::AssetCommit,
"asset",
"commit",
1,
1,
1,
caps::ASSET,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::AssetCancel,
"asset",
"cancel",
1,
1,
1,
caps::ASSET,
Determinism::NonDeterministic,
false,
20,
),
SyscallRegistryEntry::builder(Syscall::AssetLoad, "asset", "load")
.args(2)
.rets(2)
.caps(caps::ASSET)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::AssetStatus, "asset", "status")
.args(1)
.rets(1)
.caps(caps::ASSET)
.non_deterministic(),
SyscallRegistryEntry::builder(Syscall::AssetCommit, "asset", "commit")
.args(1)
.rets(1)
.caps(caps::ASSET)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::AssetCancel, "asset", "cancel")
.args(1)
.rets(1)
.caps(caps::ASSET)
.non_deterministic()
.cost(20),
];

View File

@ -1,29 +1,14 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::AudioPlaySample,
"audio",
"play_sample",
1,
5,
1,
caps::AUDIO,
Determinism::Deterministic,
false,
5,
),
entry(
Syscall::AudioPlay,
"audio",
"play",
1,
7,
1,
caps::AUDIO,
Determinism::Deterministic,
false,
5,
),
SyscallRegistryEntry::builder(Syscall::AudioPlaySample, "audio", "play_sample")
.args(5)
.rets(1)
.caps(caps::AUDIO)
.cost(5),
SyscallRegistryEntry::builder(Syscall::AudioPlay, "audio", "play")
.args(7)
.rets(1)
.caps(caps::AUDIO)
.cost(5),
];

View File

@ -1,29 +1,12 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::BankInfo,
"bank",
"info",
1,
1,
1,
caps::BANK,
Determinism::Deterministic,
false,
1,
),
entry(
Syscall::BankSlotInfo,
"bank",
"slot_info",
1,
2,
1,
caps::BANK,
Determinism::Deterministic,
false,
1,
),
SyscallRegistryEntry::builder(Syscall::BankInfo, "bank", "info")
.args(1)
.rets(1)
.caps(caps::BANK),
SyscallRegistryEntry::builder(Syscall::BankSlotInfo, "bank", "slot_info")
.args(2)
.rets(1)
.caps(caps::BANK),
];

View File

@ -1,150 +1,68 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::FsOpen,
"fs",
"open",
1,
1,
1,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::FsRead,
"fs",
"read",
1,
1,
1,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::FsWrite,
"fs",
"write",
1,
2,
1,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(Syscall::FsClose, "fs", "close", 1, 1, 0, caps::FS, Determinism::Deterministic, false, 5),
entry(
Syscall::FsListDir,
"fs",
"list_dir",
1,
1,
1,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::FsExists,
"fs",
"exists",
1,
1,
1,
caps::FS,
Determinism::Deterministic,
false,
1,
),
entry(
Syscall::FsDelete,
"fs",
"delete",
1,
1,
0,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::MemSlotCount,
"mem",
"slot_count",
1,
0,
2,
caps::FS,
Determinism::Deterministic,
false,
1,
),
entry(
Syscall::MemSlotStat,
"mem",
"slot_stat",
1,
1,
5,
caps::FS,
Determinism::NonDeterministic,
false,
5,
),
entry(
Syscall::MemSlotRead,
"mem",
"slot_read",
1,
3,
3,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::MemSlotWrite,
"mem",
"slot_write",
1,
3,
2,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::MemSlotCommit,
"mem",
"slot_commit",
1,
1,
1,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
entry(
Syscall::MemSlotClear,
"mem",
"slot_clear",
1,
1,
1,
caps::FS,
Determinism::NonDeterministic,
false,
20,
),
SyscallRegistryEntry::builder(Syscall::FsOpen, "fs", "open")
.args(1)
.rets(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::FsRead, "fs", "read")
.args(1)
.rets(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::FsWrite, "fs", "write")
.args(2)
.rets(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::FsClose, "fs", "close").args(1).caps(caps::FS).cost(5),
SyscallRegistryEntry::builder(Syscall::FsListDir, "fs", "list_dir")
.args(1)
.rets(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::FsExists, "fs", "exists").args(1).rets(1).caps(caps::FS),
SyscallRegistryEntry::builder(Syscall::FsDelete, "fs", "delete")
.args(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::MemSlotCount, "mem", "slot_count")
.rets(2)
.caps(caps::FS),
SyscallRegistryEntry::builder(Syscall::MemSlotStat, "mem", "slot_stat")
.args(1)
.rets(5)
.caps(caps::FS)
.non_deterministic()
.cost(5),
SyscallRegistryEntry::builder(Syscall::MemSlotRead, "mem", "slot_read")
.args(3)
.rets(3)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::MemSlotWrite, "mem", "slot_write")
.args(3)
.rets(2)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::MemSlotCommit, "mem", "slot_commit")
.args(1)
.rets(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
SyscallRegistryEntry::builder(Syscall::MemSlotClear, "mem", "slot_clear")
.args(1)
.rets(1)
.caps(caps::FS)
.non_deterministic()
.cost(20),
];

View File

@ -1,113 +1,41 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::GfxClear,
"gfx",
"clear",
1,
1,
0,
caps::GFX,
Determinism::Deterministic,
false,
20,
),
entry(
Syscall::GfxFillRect,
"gfx",
"fill_rect",
1,
5,
0,
caps::GFX,
Determinism::Deterministic,
false,
20,
),
entry(
Syscall::GfxDrawLine,
"gfx",
"draw_line",
1,
5,
0,
caps::GFX,
Determinism::Deterministic,
false,
5,
),
entry(
Syscall::GfxDrawCircle,
"gfx",
"draw_circle",
1,
4,
0,
caps::GFX,
Determinism::Deterministic,
false,
5,
),
entry(
Syscall::GfxDrawDisc,
"gfx",
"draw_disc",
1,
5,
0,
caps::GFX,
Determinism::Deterministic,
false,
5,
),
entry(
Syscall::GfxDrawSquare,
"gfx",
"draw_square",
1,
6,
0,
caps::GFX,
Determinism::Deterministic,
false,
5,
),
entry(
Syscall::GfxSetSprite,
"gfx",
"set_sprite",
1,
10,
1,
caps::GFX,
Determinism::Deterministic,
false,
5,
),
entry(
Syscall::GfxDrawText,
"gfx",
"draw_text",
1,
4,
0,
caps::GFX,
Determinism::Deterministic,
false,
20,
),
entry(
Syscall::GfxClear565,
"gfx",
"clear_565",
1,
1,
0,
caps::GFX,
Determinism::Deterministic,
false,
20,
),
SyscallRegistryEntry::builder(Syscall::GfxClear, "gfx", "clear")
.args(1)
.caps(caps::GFX)
.cost(20),
SyscallRegistryEntry::builder(Syscall::GfxFillRect, "gfx", "fill_rect")
.args(5)
.caps(caps::GFX)
.cost(20),
SyscallRegistryEntry::builder(Syscall::GfxDrawLine, "gfx", "draw_line")
.args(5)
.caps(caps::GFX)
.cost(5),
SyscallRegistryEntry::builder(Syscall::GfxDrawCircle, "gfx", "draw_circle")
.args(4)
.caps(caps::GFX)
.cost(5),
SyscallRegistryEntry::builder(Syscall::GfxDrawDisc, "gfx", "draw_disc")
.args(5)
.caps(caps::GFX)
.cost(5),
SyscallRegistryEntry::builder(Syscall::GfxDrawSquare, "gfx", "draw_square")
.args(6)
.caps(caps::GFX)
.cost(5),
SyscallRegistryEntry::builder(Syscall::GfxSetSprite, "gfx", "set_sprite")
.args(10)
.rets(1)
.caps(caps::GFX)
.cost(5),
SyscallRegistryEntry::builder(Syscall::GfxDrawText, "gfx", "draw_text")
.args(4)
.caps(caps::GFX)
.cost(20),
SyscallRegistryEntry::builder(Syscall::GfxClear565, "gfx", "clear_565")
.args(1)
.caps(caps::GFX)
.cost(20),
];

View File

@ -1,29 +1,14 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::LogWrite,
"log",
"write",
1,
2,
0,
caps::LOG,
Determinism::NonDeterministic,
false,
5,
),
entry(
Syscall::LogWriteTag,
"log",
"write_tag",
1,
3,
0,
caps::LOG,
Determinism::NonDeterministic,
false,
5,
),
SyscallRegistryEntry::builder(Syscall::LogWrite, "log", "write")
.args(2)
.caps(caps::LOG)
.non_deterministic()
.cost(5),
SyscallRegistryEntry::builder(Syscall::LogWriteTag, "log", "write_tag")
.args(3)
.caps(caps::LOG)
.non_deterministic()
.cost(5),
];

View File

@ -6,36 +6,7 @@ mod gfx;
mod log;
mod system;
use super::{CapFlags, Determinism, Syscall, SyscallMeta, SyscallRegistryEntry};
pub(crate) const fn entry(
syscall: Syscall,
module: &'static str,
name: &'static str,
version: u16,
arg_slots: u8,
ret_slots: u16,
caps: CapFlags,
determinism: Determinism,
may_allocate: bool,
cost_hint: u32,
) -> SyscallRegistryEntry {
SyscallRegistryEntry {
syscall,
meta: SyscallMeta {
id: syscall as u32,
module,
name,
version,
arg_slots,
ret_slots,
caps,
determinism,
may_allocate,
cost_hint,
},
}
}
use super::SyscallRegistryEntry;
pub(crate) fn all_entries() -> impl Iterator<Item = &'static SyscallRegistryEntry> {
system::ENTRIES

View File

@ -1,29 +1,11 @@
use super::entry;
use crate::syscalls::{Determinism, Syscall, SyscallRegistryEntry, caps};
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
entry(
Syscall::SystemHasCart,
"system",
"has_cart",
1,
0,
1,
caps::SYSTEM,
Determinism::Deterministic,
false,
1,
),
entry(
Syscall::SystemRunCart,
"system",
"run_cart",
1,
0,
0,
caps::SYSTEM,
Determinism::NonDeterministic,
false,
50,
),
SyscallRegistryEntry::builder(Syscall::SystemHasCart, "system", "has_cart")
.rets(1)
.caps(caps::SYSTEM),
SyscallRegistryEntry::builder(Syscall::SystemRunCart, "system", "run_cart")
.caps(caps::SYSTEM)
.non_deterministic()
.cost(50),
];

View File

@ -146,10 +146,10 @@ impl Verifier {
let func_code = &code[func_start..func_end];
// Funções vazias (sem qualquer byte de código) são consideradas válidas no verificador.
// Elas não consomem nem produzem valores na pilha e não possuem fluxo interno.
// Observação: se uma função vazia for chamada em tempo de execução e retorno/efeitos
// forem esperados, caberá ao gerador de código/linker impedir tal situação.
// Empty functions (no code bytes) are considered valid in the verifier.
// They do not consume or produce values on the stack and have no internal flow.
// Note: if an empty function is called at runtime and return/effects
// are expected, it is the responsibility of the code generator/linker to prevent this situation.
if func_code.is_empty() {
return Ok(0);
}