This commit is contained in:
bQUARKz 2026-02-18 16:14:57 +00:00
parent dc7da102c8
commit 3d4d1dc45d
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 17 additions and 57 deletions

View File

@ -16,4 +16,4 @@ pub use decoder::{decode_next, DecodeError};
pub use layout::{compute_function_layouts, FunctionLayout}; pub use layout::{compute_function_layouts, FunctionLayout};
pub use model::{BytecodeLoader, FunctionMeta, LoadError}; pub use model::{BytecodeLoader, FunctionMeta, LoadError};
pub use program_image::ProgramImage; pub use program_image::ProgramImage;
pub use value::Value; pub use value::{HeapRef, Value};

View File

@ -102,7 +102,7 @@ impl From<ProgramImage> for BytecodeModule {
Value::String(v) => ConstantPoolEntry::String(v.clone()), Value::String(v) => ConstantPoolEntry::String(v.clone()),
Value::Int32(v) => ConstantPoolEntry::Int32(*v), Value::Int32(v) => ConstantPoolEntry::Int32(*v),
Value::Bounded(v) => ConstantPoolEntry::Int32(*v as i32), Value::Bounded(v) => ConstantPoolEntry::Int32(*v as i32),
Value::Handle(_) => ConstantPoolEntry::Null, Value::HeapRef(_) => ConstantPoolEntry::Null,
}) })
.collect(); .collect();

View File

@ -1,6 +1,13 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::cmp::Ordering; use std::cmp::Ordering;
/// Opaque handle that references an object stored in the VM heap.
///
/// This is an index-based handle. It does not imply ownership and carries
/// no lifetime information. GC/allocator integration will come in later PRs.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct HeapRef(pub u32);
/// Represents any piece of data that can be stored on the VM stack or in globals. /// Represents any piece of data that can be stored on the VM stack or in globals.
/// ///
/// The PVM is "dynamically typed" at the bytecode level, meaning a single /// The PVM is "dynamically typed" at the bytecode level, meaning a single
@ -22,8 +29,8 @@ pub enum Value {
String(String), String(String),
/// Bounded 16-bit-ish integer. /// Bounded 16-bit-ish integer.
Bounded(u32), Bounded(u32),
/// A pointer to an object on the heap. /// A handle to an object on the heap (opaque reference).
Handle(usize), HeapRef(HeapRef),
/// Represents the absence of a value (equivalent to `null` or `undefined`). /// Represents the absence of a value (equivalent to `null` or `undefined`).
Null, Null,
} }
@ -43,7 +50,7 @@ impl PartialEq for Value {
(Value::Boolean(a), Value::Boolean(b)) => a == b, (Value::Boolean(a), Value::Boolean(b)) => a == b,
(Value::String(a), Value::String(b)) => a == b, (Value::String(a), Value::String(b)) => a == b,
(Value::Bounded(a), Value::Bounded(b)) => a == b, (Value::Bounded(a), Value::Bounded(b)) => a == b,
(Value::Handle(a), Value::Handle(b)) => a == b, (Value::HeapRef(a), Value::HeapRef(b)) => a == b,
(Value::Null, Value::Null) => true, (Value::Null, Value::Null) => true,
_ => false, _ => false,
} }
@ -99,7 +106,7 @@ impl Value {
Value::Bounded(b) => format!("{}b", b), Value::Bounded(b) => format!("{}b", b),
Value::Boolean(b) => b.to_string(), Value::Boolean(b) => b.to_string(),
Value::String(s) => s.clone(), Value::String(s) => s.clone(),
Value::Handle(r) => format!("[Handle {}]", r), Value::HeapRef(r) => format!("[HeapRef {}]", r.0),
Value::Null => "null".to_string(), Value::Null => "null".to_string(),
} }
} }

View File

@ -1,5 +1,5 @@
use crate::vm_fault::VmFault; use crate::vm_fault::VmFault;
use prometeu_bytecode::{TRAP_OOB, Value}; use prometeu_bytecode::{HeapRef, TRAP_OOB, Value};
pub struct HostReturn<'a> { pub struct HostReturn<'a> {
stack: &'a mut Vec<Value>, stack: &'a mut Vec<Value>,
@ -26,7 +26,8 @@ impl<'a> HostReturn<'a> {
self.stack.push(Value::Null); self.stack.push(Value::Null);
} }
pub fn push_gate(&mut self, g: usize) { pub fn push_gate(&mut self, g: usize) {
self.stack.push(Value::Handle(g)); // Temporary: cast incoming gate to HeapRef index. Real allocator will provide proper handles.
self.stack.push(Value::HeapRef(HeapRef(g as u32)));
} }
pub fn push_string(&mut self, s: String) { pub fn push_string(&mut self, s: String) {
self.stack.push(Value::String(s)); self.stack.push(Value::String(s));

View File

@ -1,52 +1,4 @@
# PR-3.1 — Introduce HeapRef Handle Type in Value Model ## PR-3.2 — Define Heap Object Header and Object Kind Tags
### Briefing
The VM must reference heap objects through opaque handles. This PR introduces a `HeapRef` (or equivalent) type and integrates it into the VM value model without implementing the GC yet.
### Target
* Add a handle-based reference type for heap objects.
* Integrate it into the `Value` representation.
### Work items
* Define a `HeapRef` struct or newtype (e.g., index-based handle).
* Add a `Value::HeapRef` (or equivalent) variant.
* Ensure stack operations can carry this value type.
* Do not allocate real objects yet; this is only the type integration.
### Acceptance checklist
* [ ] `HeapRef` type exists and is used in `Value`.
* [ ] VM compiles with the new value variant.
* [ ] No GC or allocator logic is introduced yet.
* [ ] `cargo test` passes.
### Tests
* Existing tests only.
### Junie instructions
**You MAY:**
* Add a new handle type.
* Extend the `Value` enum/struct.
**You MUST NOT:**
* Design or implement the GC algorithm here.
* Introduce object allocation logic.
* Add hidden ownership or lifetime systems.
**If unclear:**
* Ask what fields the handle should contain.
---
# PR-3.2 — Define Heap Object Header and Object Kind Tags
### Briefing ### Briefing