diff --git a/crates/console/prometeu-bytecode/src/opcode.rs b/crates/console/prometeu-bytecode/src/opcode.rs index 676d8333..dafb35de 100644 --- a/crates/console/prometeu-bytecode/src/opcode.rs +++ b/crates/console/prometeu-bytecode/src/opcode.rs @@ -171,6 +171,18 @@ pub enum OpCode { /// - Injects hidden arg0 = closure_ref, followed by user args as arg1..argN. CallClosure = 0x53, + // --- 7.x Concurrency / Coroutines --- + /// Spawns a new coroutine to run a function with arguments. + /// Operands: fn_id (u32), arg_count (u32) + /// Semantics: + /// - Pops `arg_count` arguments from the current operand stack (top-first), + /// preserving user order as arg1..argN for the callee. + /// - Allocates a new Coroutine object with its own stack and a single entry frame + /// pointing at `fn_id`. + /// - Enqueues the coroutine into the scheduler ready queue. + /// - Does NOT switch execution immediately; current coroutine continues. + Spawn = 0x54, + // --- 6.8 Peripherals and System --- /// Invokes a system function (Firmware/OS). /// Operand: syscall_id (u32) @@ -232,6 +244,7 @@ impl TryFrom for OpCode { 0x51 => Ok(OpCode::Ret), 0x52 => Ok(OpCode::MakeClosure), 0x53 => Ok(OpCode::CallClosure), + 0x54 => Ok(OpCode::Spawn), 0x70 => Ok(OpCode::Syscall), 0x80 => Ok(OpCode::FrameSync), _ => Err(format!("Invalid OpCode: 0x{:04X}", value)), @@ -290,6 +303,7 @@ impl OpCode { OpCode::Ret => 4, OpCode::MakeClosure => 8, OpCode::CallClosure => 6, + OpCode::Spawn => 6, OpCode::Syscall => 1, OpCode::FrameSync => 1, } diff --git a/crates/console/prometeu-bytecode/src/opcode_spec.rs b/crates/console/prometeu-bytecode/src/opcode_spec.rs index 01f5fb36..950d2b93 100644 --- a/crates/console/prometeu-bytecode/src/opcode_spec.rs +++ b/crates/console/prometeu-bytecode/src/opcode_spec.rs @@ -486,6 +486,18 @@ impl OpCodeSpecExt for OpCode { may_trap: true, is_safepoint: false, }, + OpCode::Spawn => OpcodeSpec { + name: "SPAWN", + // Two u32 immediates: fn_id and arg_count + imm_bytes: 8, + // Dynamic pops depends on arg_count; keep 0 here in spec layer + pops: 0, + pushes: 0, + is_branch: false, + is_terminator: false, + may_trap: false, + is_safepoint: false, + }, OpCode::Syscall => OpcodeSpec { name: "SYSCALL", imm_bytes: 4, diff --git a/files/TODOs.md b/files/TODOs.md index 754d2384..a10ae540 100644 --- a/files/TODOs.md +++ b/files/TODOs.md @@ -1,43 +1,3 @@ -# PR-7.3 — SPAWN Instruction - -## Briefing - -SPAWN creates a new coroutine and schedules it. - -## Target - -Introduce opcode: - -`SPAWN fn_id, arg_count` - -Semantics: - -* Pop `arg_count` args. -* Create new coroutine object. -* Initialize its stack/frame with entry fn. -* Push coroutine handle onto ready queue. - -Current coroutine continues execution. - -## Checklist - -* [ ] SPAWN opcode exists. -* [ ] Coroutine created. -* [ ] Scheduled in ready queue. -* [ ] No immediate context switch. - -## Tests - -* Spawn coroutine and verify it appears in ready queue. - -## Junie Rules - -You MAY modify interpreter dispatch. -You MUST NOT switch execution immediately. -If entry frame layout unclear, STOP and ask. - ---- - # PR-7.4 — YIELD Instruction ## Briefing