use crate::{
bytecode::{Instruction, OpCode, Operand},
executor::{LoopContext, VirtualMachine},
};
use crate::executor::vm_impl::stack::drop_with_kind;
use shape_value::datatable::DataTable;
use shape_value::heap_value::{HashMapKindedRef, HeapKind, TableViewData};
use shape_value::{NativeKind, VMError};
use std::sync::Arc;
#[cold]
fn ckpt4_surface(op: &str, detail: &str) -> VMError {
VMError::NotImplemented(format!(
"{op} SURFACE (V3-S5 ckpt-4 wholesale rewrite, 2026-05-15): \
{detail}. The deleted typed-array-data enum + `Buf<T>` / \
aligned-typed-buf wrapper layer were retired wholesale at \
V3-S5 ckpt-1..ckpt-4 per W12-typed-array-data-deletion-audit \
§3.5 + §B + ADR-006 §2.7.24 Q25.A SUPERSEDED; the per-arm \
dispatch graph has no discriminator until the v2-raw \
`TypedArray<T>` per-element-kind rebuild lands in a downstream \
wave. Refusal #1 binding."
))
}
#[inline(always)]
fn decode_iter_idx(bits: u64, kind: NativeKind) -> Result<i64, VMError> {
if kind.is_integer_family() {
return Ok(bits as i64);
}
match kind {
NativeKind::Float64 | NativeKind::NullableFloat64 => {
Ok(f64::from_bits(bits) as i64)
}
NativeKind::Bool => Ok(bits as i64),
_ => Err(VMError::TypeError {
expected: "number",
got: "non-numeric idx",
}),
}
}
impl VirtualMachine {
#[inline(always)]
pub(in crate::executor) fn exec_loops(
&mut self,
instruction: &Instruction,
) -> Result<(), VMError> {
use OpCode::*;
match instruction.opcode {
LoopStart => self.op_loop_start(instruction)?,
LoopEnd => self.op_loop_end()?,
Break => self.op_break()?,
Continue => self.op_continue()?,
IterNext => self.op_iter_next()?,
IterDone => self.op_iter_done()?,
_ => unreachable!(
"exec_loops called with non-loop opcode: {:?}",
instruction.opcode
),
}
Ok(())
}
pub(in crate::executor) fn op_loop_start(
&mut self,
instruction: &Instruction,
) -> Result<(), VMError> {
if let Some(Operand::Offset(end_offset)) = instruction.operand {
let end = (self.ip as i32 + end_offset) as usize;
self.loop_stack.push(LoopContext {
start: self.ip,
end,
});
#[cfg(feature = "jit")]
{
let loop_ip = self.ip.saturating_sub(1);
if let Some(func_id) = self.current_function_id() {
self.check_osr_back_edge(func_id, loop_ip);
if self.try_osr_entry(func_id, loop_ip)? {
self.loop_stack.pop();
return Ok(());
}
}
}
}
Ok(())
}
pub(in crate::executor) fn op_loop_end(&mut self) -> Result<(), VMError> {
self.loop_stack.pop();
Ok(())
}
pub(in crate::executor) fn op_break(&mut self) -> Result<(), VMError> {
if let Some(loop_ctx) = self.loop_stack.last() {
self.ip = loop_ctx.end;
Ok(())
} else {
Err(VMError::RuntimeError("break outside of loop".to_string()))
}
}
pub(in crate::executor) fn op_continue(&mut self) -> Result<(), VMError> {
if let Some(loop_ctx) = self.loop_stack.last() {
self.ip = loop_ctx.start;
Ok(())
} else {
Err(VMError::RuntimeError(
"continue outside of loop".to_string(),
))
}
}
pub(in crate::executor) fn op_iter_done(&mut self) -> Result<(), VMError> {
let (idx_bits, idx_kind) = self.pop_kinded()?;
let (iter_bits, iter_kind) = self.pop_kinded()?;
let idx = decode_iter_idx(idx_bits, idx_kind)?;
if let Some(view) =
crate::executor::v2_handlers::v2_array_detect::as_v2_typed_array(iter_bits, iter_kind)
{
let done = idx < 0 || idx as u32 >= view.len;
drop_with_kind(idx_bits, idx_kind);
drop_with_kind(iter_bits, iter_kind);
return self.push_kinded(done as u64, NativeKind::Bool);
}
let done_result: Result<bool, VMError> = match iter_kind {
NativeKind::Ptr(HeapKind::TypedArray) => {
Err(ckpt4_surface(
"op_iter_done",
"iteration over legacy Arc<TypedArrayData> carrier",
))
}
NativeKind::Ptr(HeapKind::String) | NativeKind::String => {
let arc = unsafe { Arc::<String>::from_raw(iter_bits as *const String) };
let len = arc.len();
let _ = Arc::into_raw(arc);
Ok(idx < 0 || idx as usize >= len)
}
NativeKind::Ptr(HeapKind::DataTable) => {
let arc = unsafe { Arc::<DataTable>::from_raw(iter_bits as *const DataTable) };
let len = arc.row_count();
let _ = Arc::into_raw(arc);
Ok(idx < 0 || idx as usize >= len)
}
NativeKind::Ptr(HeapKind::TableView) => {
let arc = unsafe {
Arc::<TableViewData>::from_raw(iter_bits as *const TableViewData)
};
let result = match arc.as_ref() {
TableViewData::TypedTable { table, .. } => {
Ok(idx < 0 || idx as usize >= table.row_count())
}
_ => Err(VMError::NotImplemented(
"op_iter_done SURFACE: TableViewData::{RowView,ColumnRef,\
IndexedTable} iteration — phase-2c, see ADR-006 §2.7.4"
.to_string(),
)),
};
let _ = Arc::into_raw(arc);
result
}
NativeKind::Ptr(HeapKind::HashMap) => {
let arc = unsafe {
Arc::<HashMapKindedRef>::from_raw(iter_bits as *const HashMapKindedRef)
};
let len = arc.len();
let _ = Arc::into_raw(arc);
Ok(idx < 0 || idx as usize >= len)
}
_ => Err(VMError::NotImplemented(format!(
"op_iter_done SURFACE: iter_kind={:?} not supported as iterator \
in the kinded API (legacy Array/Range/Iterator HeapValue \
variants deleted) — phase-2c, see ADR-006 §2.7.4",
iter_kind
))),
};
drop_with_kind(idx_bits, idx_kind);
drop_with_kind(iter_bits, iter_kind);
let done = done_result?;
self.push_kinded(done as u64, NativeKind::Bool)
}
pub(in crate::executor) fn op_iter_next(&mut self) -> Result<(), VMError> {
let (idx_bits, idx_kind) = self.pop_kinded()?;
let (iter_bits, iter_kind) = self.pop_kinded()?;
let idx = decode_iter_idx(idx_bits, idx_kind)?;
if let Some(view) =
crate::executor::v2_handlers::v2_array_detect::as_v2_typed_array(iter_bits, iter_kind)
{
use crate::executor::v2_handlers::v2_array_detect::V2ElemType;
use shape_value::v2::typed_array::TypedArray;
if idx < 0 || idx as u32 >= view.len {
drop_with_kind(idx_bits, idx_kind);
drop_with_kind(iter_bits, iter_kind);
return self.push_kinded(Self::NONE_BITS, NativeKind::Bool);
}
let i = idx as u32;
let push_result = match view.elem_type {
V2ElemType::I64 => {
let arr = view.ptr as *const TypedArray<i64>;
let v = unsafe { TypedArray::<i64>::get_unchecked(arr, i) };
self.push_kinded(v as u64, NativeKind::Int64)
}
V2ElemType::I32 => {
let arr = view.ptr as *const TypedArray<i32>;
let v = unsafe { TypedArray::<i32>::get_unchecked(arr, i) };
self.push_kinded(v as i64 as u64, NativeKind::Int64)
}
V2ElemType::F64 => {
let arr = view.ptr as *const TypedArray<f64>;
let v = unsafe { TypedArray::<f64>::get_unchecked(arr, i) };
self.push_kinded(v.to_bits(), NativeKind::Float64)
}
V2ElemType::Bool => {
let arr = view.ptr as *const TypedArray<u8>;
let v = unsafe { TypedArray::<u8>::get_unchecked(arr, i) };
self.push_kinded((v != 0) as u64, NativeKind::Bool)
}
V2ElemType::I8 => {
let arr = view.ptr as *const TypedArray<i8>;
let v = unsafe { TypedArray::<i8>::get_unchecked(arr, i) };
self.push_kinded(v as i64 as u64, NativeKind::Int8)
}
V2ElemType::U8 => {
let arr = view.ptr as *const TypedArray<u8>;
let v = unsafe { TypedArray::<u8>::get_unchecked(arr, i) };
self.push_kinded(v as u64, NativeKind::UInt8)
}
V2ElemType::I16 => {
let arr = view.ptr as *const TypedArray<i16>;
let v = unsafe { TypedArray::<i16>::get_unchecked(arr, i) };
self.push_kinded(v as i64 as u64, NativeKind::Int16)
}
V2ElemType::U16 => {
let arr = view.ptr as *const TypedArray<u16>;
let v = unsafe { TypedArray::<u16>::get_unchecked(arr, i) };
self.push_kinded(v as u64, NativeKind::UInt16)
}
V2ElemType::U32 => {
let arr = view.ptr as *const TypedArray<u32>;
let v = unsafe { TypedArray::<u32>::get_unchecked(arr, i) };
self.push_kinded(v as u64, NativeKind::UInt32)
}
V2ElemType::F32 => {
let arr = view.ptr as *const TypedArray<f32>;
let v = unsafe { TypedArray::<f32>::get_unchecked(arr, i) };
self.push_kinded(v.to_bits() as u64, NativeKind::Float32)
}
V2ElemType::Char => {
let arr = view.ptr as *const TypedArray<char>;
let v = unsafe { TypedArray::<char>::get_unchecked(arr, i) };
self.push_kinded(v as u32 as u64, NativeKind::Char)
}
V2ElemType::String => {
use shape_value::v2::refcount::v2_retain;
use shape_value::v2::string_obj::StringObj;
let arr = view.ptr as *const TypedArray<*const StringObj>;
let elem_ptr = unsafe { TypedArray::<*const StringObj>::get_unchecked(arr, i) };
unsafe { v2_retain(&(*elem_ptr).header) };
self.push_kinded(elem_ptr as u64, NativeKind::StringV2)
}
V2ElemType::Decimal => {
use shape_value::v2::decimal_obj::DecimalObj;
use shape_value::v2::refcount::v2_retain;
let arr = view.ptr as *const TypedArray<*const DecimalObj>;
let elem_ptr = unsafe { TypedArray::<*const DecimalObj>::get_unchecked(arr, i) };
unsafe { v2_retain(&(*elem_ptr).header) };
self.push_kinded(elem_ptr as u64, NativeKind::DecimalV2)
}
V2ElemType::TypedObject => {
use shape_value::heap_value::TypedObjectStorage;
use shape_value::v2::refcount::v2_retain;
let arr = view.ptr as *const TypedArray<*const TypedObjectStorage>;
let elem_ptr = unsafe {
TypedArray::<*const TypedObjectStorage>::get_unchecked(arr, i)
};
unsafe { v2_retain(&(*elem_ptr).header) };
self.push_kinded(
elem_ptr as u64,
NativeKind::Ptr(HeapKind::TypedObject),
)
}
};
drop_with_kind(idx_bits, idx_kind);
drop_with_kind(iter_bits, iter_kind);
return push_result;
}
let push_result: Result<(), VMError> = match iter_kind {
NativeKind::Ptr(HeapKind::TypedArray) => {
let _ = idx; Err(ckpt4_surface(
"op_iter_next",
"iteration over legacy Arc<TypedArrayData> carrier",
))
}
NativeKind::Ptr(HeapKind::String) | NativeKind::String => {
let arc = unsafe { Arc::<String>::from_raw(iter_bits as *const String) };
let result = if idx < 0 {
self.push_kinded(Self::NONE_BITS, NativeKind::Bool)
} else {
match arc.chars().nth(idx as usize) {
Some(c) => self.push_kinded(c as u64, NativeKind::Char),
None => self.push_kinded(Self::NONE_BITS, NativeKind::Bool),
}
};
let _ = Arc::into_raw(arc);
result
}
NativeKind::Ptr(HeapKind::DataTable) => {
Err(VMError::NotImplemented(
"op_iter_next SURFACE: DataTable row materialization \
— phase-2c, see ADR-006 §2.7.4 \
(RowView carrier pending kinded redesign)"
.to_string(),
))
}
NativeKind::Ptr(HeapKind::TableView) => {
Err(VMError::NotImplemented(
"op_iter_next SURFACE: TableView row materialization \
— phase-2c, see ADR-006 §2.7.4 \
(RowView carrier pending kinded redesign)"
.to_string(),
))
}
NativeKind::Ptr(HeapKind::HashMap) => {
Err(VMError::NotImplemented(
"op_iter_next SURFACE: direct HashMap iteration is not \
supported — use `for entry in m.entries()` instead. \
Phase-2c, see ADR-006 §2.7.4"
.to_string(),
))
}
_ => Err(VMError::NotImplemented(format!(
"op_iter_next SURFACE: iter_kind={:?} not supported as iterator \
in the kinded API (legacy Array/Range/Iterator HeapValue \
variants deleted) — phase-2c, see ADR-006 §2.7.4",
iter_kind
))),
};
drop_with_kind(idx_bits, idx_kind);
drop_with_kind(iter_bits, iter_kind);
push_result
}
}