This commit is contained in:
bQUARKz 2026-02-20 11:04:15 +00:00
parent 123d39331e
commit b7e149a1ab
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
4 changed files with 36 additions and 36 deletions

View File

@ -183,6 +183,11 @@ pub enum OpCode {
/// - Does NOT switch execution immediately; current coroutine continues. /// - Does NOT switch execution immediately; current coroutine continues.
Spawn = 0x54, Spawn = 0x54,
/// Cooperatively yields the current coroutine. Execution continues
/// until the next VM safepoint (FRAME_SYNC), where the scheduler
/// may switch to another ready coroutine.
Yield = 0x55,
// --- 6.8 Peripherals and System --- // --- 6.8 Peripherals and System ---
/// Invokes a system function (Firmware/OS). /// Invokes a system function (Firmware/OS).
/// Operand: syscall_id (u32) /// Operand: syscall_id (u32)
@ -245,6 +250,7 @@ impl TryFrom<u16> for OpCode {
0x52 => Ok(OpCode::MakeClosure), 0x52 => Ok(OpCode::MakeClosure),
0x53 => Ok(OpCode::CallClosure), 0x53 => Ok(OpCode::CallClosure),
0x54 => Ok(OpCode::Spawn), 0x54 => Ok(OpCode::Spawn),
0x55 => Ok(OpCode::Yield),
0x70 => Ok(OpCode::Syscall), 0x70 => Ok(OpCode::Syscall),
0x80 => Ok(OpCode::FrameSync), 0x80 => Ok(OpCode::FrameSync),
_ => Err(format!("Invalid OpCode: 0x{:04X}", value)), _ => Err(format!("Invalid OpCode: 0x{:04X}", value)),
@ -304,6 +310,7 @@ impl OpCode {
OpCode::MakeClosure => 8, OpCode::MakeClosure => 8,
OpCode::CallClosure => 6, OpCode::CallClosure => 6,
OpCode::Spawn => 6, OpCode::Spawn => 6,
OpCode::Yield => 1,
OpCode::Syscall => 1, OpCode::Syscall => 1,
OpCode::FrameSync => 1, OpCode::FrameSync => 1,
} }

View File

@ -498,6 +498,18 @@ impl OpCodeSpecExt for OpCode {
may_trap: false, may_trap: false,
is_safepoint: false, is_safepoint: false,
}, },
OpCode::Yield => OpcodeSpec {
name: "YIELD",
imm_bytes: 0,
pops: 0,
pushes: 0,
is_branch: false,
// Not a block terminator; effect realized at safepoint
is_terminator: false,
may_trap: false,
// Treated as a safepoint marker for cooperative scheduling
is_safepoint: true,
},
OpCode::Syscall => OpcodeSpec { OpCode::Syscall => OpcodeSpec {
name: "SYSCALL", name: "SYSCALL",
imm_bytes: 4, imm_bytes: 4,

View File

@ -84,6 +84,9 @@ pub struct VirtualMachine {
/// Capability flags granted to the currently running program/cart. /// Capability flags granted to the currently running program/cart.
/// Syscalls are capability-gated using `prometeu_hal::syscalls::SyscallMeta::caps`. /// Syscalls are capability-gated using `prometeu_hal::syscalls::SyscallMeta::caps`.
pub capabilities: prometeu_hal::syscalls::CapFlags, pub capabilities: prometeu_hal::syscalls::CapFlags,
/// Cooperative scheduler: set to true when `YIELD` opcode is executed.
/// The runtime/scheduler should only act on this at safepoints (FRAME_SYNC).
pub yield_requested: bool,
} }
@ -115,6 +118,7 @@ impl VirtualMachine {
gc_alloc_threshold: 1024, // conservative default; tests may override gc_alloc_threshold: 1024, // conservative default; tests may override
last_gc_live_count: 0, last_gc_live_count: 0,
capabilities: 0, capabilities: 0,
yield_requested: false,
} }
} }
@ -408,6 +412,17 @@ impl VirtualMachine {
self.cycles += OpCode::Trap.cycles(); self.cycles += OpCode::Trap.cycles();
return Err(LogicalFrameEndingReason::Breakpoint); return Err(LogicalFrameEndingReason::Breakpoint);
} }
OpCode::Spawn => {
// Placeholder: spawning is handled by the system runtime in a later PR.
// VM side does not switch; arguments/immediates will be handled when
// coroutine objects and ABI are fully wired. For now, it's a no-op here
// besides normal cycle accounting at the end of step.
}
OpCode::Yield => {
// Cooperative yield: record intent; actual switching only at FRAME_SYNC.
self.yield_requested = true;
// Do not end the slice here; we continue executing until a safepoint.
}
OpCode::MakeClosure => { OpCode::MakeClosure => {
// Immediate carries (fn_id, capture_count) // Immediate carries (fn_id, capture_count)
let (fn_id, cap_count) = instr let (fn_id, cap_count) = instr
@ -1127,6 +1142,8 @@ impl VirtualMachine {
} }
} }
// Clear cooperative yield request at the safepoint boundary.
self.yield_requested = false;
return Err(LogicalFrameEndingReason::FrameSync); return Err(LogicalFrameEndingReason::FrameSync);
} }
} }

View File

@ -1,39 +1,3 @@
# PR-7.4 — YIELD Instruction
## Briefing
YIELD voluntarily gives up execution.
## Target
Opcode:
`YIELD`
Semantics:
* Current coroutine moves to end of ready queue.
* Scheduler selects next coroutine at safepoint.
Switching must occur only at FRAME_SYNC.
## Checklist
* [ ] YIELD opcode implemented.
* [ ] Current coroutine enqueued.
* [ ] No mid-instruction switching.
## Tests
* Two coroutines yielding alternate deterministically.
## Junie Rules
You MAY modify VM execution loop.
You MUST NOT allow switching outside safepoints.
---
# PR-7.5 — SLEEP Instruction # PR-7.5 — SLEEP Instruction
## Briefing ## Briefing