use shape_runtime::context::ExecutionContext;
use crate::executor::VirtualMachine;
use crate::executor::v2_handlers::v2_array_detect::{
as_v2_typed_array, concat_arrays, drop_array_n, slice_array, take_array, V2TypedArrayView,
};
use shape_value::heap_value::HeapKind;
use shape_value::{KindedSlot, NativeKind, ValueSlot, VMError};
#[inline]
pub(super) fn detect_v2_raw_string_or_decimal_receiver(
slot: &KindedSlot,
) -> Option<crate::executor::v2_handlers::v2_array_detect::V2TypedArrayView> {
use crate::executor::v2_handlers::v2_array_detect::{as_v2_typed_array, V2ElemType};
if slot.kind != NativeKind::Ptr(HeapKind::TypedArray) {
return None;
}
let view = as_v2_typed_array(slot.slot.raw(), slot.kind)?;
match view.elem_type {
V2ElemType::String | V2ElemType::Decimal => Some(view),
_ => None,
}
}
#[allow(dead_code)]
pub(super) fn v2_raw_string_decimal_surface_error(
op: &str,
view: &crate::executor::v2_handlers::v2_array_detect::V2TypedArrayView,
) -> VMError {
use crate::executor::v2_handlers::v2_array_detect::V2ElemType;
let (elem_name, kind_name) = match view.elem_type {
V2ElemType::String => ("String", "StringV2"),
V2ElemType::Decimal => ("Decimal", "DecimalV2"),
_ => ("Unknown", "Unknown"),
};
VMError::NotImplemented(format!(
"{op}: SURFACE — v2-raw TypedArray<*const {elem}Obj> receiver \
(elem_type={etype:?}, len={len}); post-gate-flip {op} body reads \
elements via v2_array_detect::read_element and pushes each as \
NativeKind::{kind} per ADR-006 §2.7.5 amendment + audit §4.1.B.4 \
migration recipe. ADR-006 §2.7.24 Q25.A SUPERSEDED. UNREACHABLE \
until A2-followup-gate-flip lands.",
op = op,
elem = elem_name,
etype = view.elem_type,
len = view.len,
kind = kind_name,
))
}
#[inline]
pub(super) fn bump_closure_share(slot: &KindedSlot) {
use shape_value::heap_value::HeapKind;
use shape_value::HeapValue;
use shape_value::NativeKind;
if let NativeKind::Ptr(HeapKind::Closure) = slot.kind {
let bits = slot.slot.raw();
if bits != 0 {
unsafe {
std::sync::Arc::increment_strong_count(bits as *const HeapValue);
}
}
}
}
#[cold]
#[inline(never)]
fn ckpt2_surface(op: &'static str, args: &[KindedSlot]) -> VMError {
let receiver_kind = if args.is_empty() {
"<no args>".to_string()
} else {
format!("{:?}", args[0].kind)
};
VMError::NotImplemented(format!(
"{op}: SURFACE — V3-S5 ckpt-2 consumer-cascade tier 1 surface. \
`TypedArrayData` enum DELETED at ckpt-1 (2026-05-15) per W12-\
typed-array-data-deletion audit §3.5 + ADR-006 §2.7.24 Q25.A \
SUPERSEDED. The previous `Arc<TypedArrayData>` receiver-recovery \
+ per-variant match-arm dispatch path (~206 references across \
11 public handlers in this file) cascade-broke at the enum \
deletion site (`crates/shape-value/src/heap_value.rs:3944`). \
Post-deletion target is the v2-raw `TypedArray<T>` flat-struct \
carrier per audit §1.2 + §A.3 + §3.1 scalar recipe + §2.2 \
heap-element variants; per-T monomorphization landing across \
ckpt-3 (array_ops/typed_array_methods/iterator_methods/array_sort\
/concat/property_access) + ckpt-4 (TypedBuffer<T> / \
HeapValue::TypedArray arm / HeapKind::TypedArray ordinal) + \
ckpt-5 (wire/json/marshal + 4-table lockstep) + ckpt-6 (JIT \
FFI). Receiver kind: {kind}. UNREACHABLE until ckpt-6 STRICT \
close. REFUSED ON SIGHT: TypedArrayData resurrection under any \
rename (Refusal #1, W12 audit §7).",
op = op,
kind = receiver_kind,
))
}
#[inline]
fn extract_view(slot: &KindedSlot) -> Option<V2TypedArrayView> {
if slot.kind != NativeKind::Ptr(HeapKind::TypedArray) {
return None;
}
as_v2_typed_array(slot.slot.raw(), slot.kind)
}
#[inline]
fn new_array_slot(ptr: *mut u8) -> KindedSlot {
KindedSlot::new(
ValueSlot::from_u64(ptr as usize as u64),
NativeKind::Ptr(HeapKind::TypedArray),
)
}
#[inline]
fn clamp_count(slot: &KindedSlot, op: &'static str, arg_name: &'static str) -> Result<u32, VMError> {
let n = slot.as_i64().ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.{}: {} must be an integer, got kind {:?}",
op, arg_name, slot.kind
))
})?;
if n < 0 {
Ok(0)
} else if n > u32::MAX as i64 {
Ok(u32::MAX)
} else {
Ok(n as u32)
}
}
pub(crate) fn handle_map_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() >= 2
&& args[1].kind != NativeKind::Ptr(HeapKind::Closure)
{
return Err(VMError::RuntimeError(format!(
"map: second argument must be a closure, got kind {:?}",
args[1].kind
)));
}
Err(ckpt2_surface("map", args))
}
pub(crate) fn handle_filter_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() >= 2
&& args[1].kind != NativeKind::Ptr(HeapKind::Closure)
{
return Err(VMError::RuntimeError(format!(
"filter: second argument must be a closure, got kind {:?}",
args[1].kind
)));
}
Err(ckpt2_surface("filter", args))
}
pub(crate) fn handle_sort_v2(
vm: &mut VirtualMachine,
args: &[KindedSlot],
ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
crate::executor::objects::array_sort::handle_sort_v2(vm, args, ctx)
}
pub(crate) fn handle_slice_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() < 2 {
return Err(VMError::RuntimeError(
"Array.slice expects 1 or 2 arguments (start, [end])".into(),
));
}
let view = extract_view(&args[0]).ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.slice: expected v2 TypedArray receiver, got kind {:?}",
args[0].kind
))
})?;
let start = clamp_count(&args[1], "slice", "start")?;
let end = if args.len() >= 3 {
clamp_count(&args[2], "slice", "end")?
} else {
view.len
};
let new_ptr = slice_array(&view, start, end);
Ok(new_array_slot(new_ptr))
}
pub(crate) fn handle_concat_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() < 2 {
return Err(VMError::RuntimeError(
"Array.concat expects 1 argument (other)".into(),
));
}
let view_a = extract_view(&args[0]).ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.concat: expected v2 TypedArray receiver, got kind {:?}",
args[0].kind
))
})?;
let view_b = extract_view(&args[1]).ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.concat: expected v2 TypedArray argument, got kind {:?}",
args[1].kind
))
})?;
let new_ptr = concat_arrays(&view_a, &view_b)
.map_err(|e| VMError::RuntimeError(format!("Array.concat: {}", e)))?;
Ok(new_array_slot(new_ptr))
}
pub(crate) fn handle_take_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() < 2 {
return Err(VMError::RuntimeError(
"Array.take expects 1 argument (n)".into(),
));
}
let view = extract_view(&args[0]).ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.take: expected v2 TypedArray receiver, got kind {:?}",
args[0].kind
))
})?;
let n = clamp_count(&args[1], "take", "n")?;
let new_ptr = take_array(&view, n);
Ok(new_array_slot(new_ptr))
}
pub(crate) fn handle_drop_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() < 2 {
return Err(VMError::RuntimeError(
"Array.drop expects 1 argument (n)".into(),
));
}
let view = extract_view(&args[0]).ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.drop: expected v2 TypedArray receiver, got kind {:?}",
args[0].kind
))
})?;
let n = clamp_count(&args[1], "drop", "n")?;
let new_ptr = drop_array_n(&view, n);
Ok(new_array_slot(new_ptr))
}
pub(crate) fn handle_skip_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() < 2 {
return Err(VMError::RuntimeError(
"Array.skip expects 1 argument (n)".into(),
));
}
let view = extract_view(&args[0]).ok_or_else(|| {
VMError::RuntimeError(format!(
"Array.skip: expected v2 TypedArray receiver, got kind {:?}",
args[0].kind
))
})?;
let n = clamp_count(&args[1], "skip", "n")?;
let new_ptr = drop_array_n(&view, n);
Ok(new_array_slot(new_ptr))
}
pub(crate) fn handle_flatten_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
Err(ckpt2_surface("flatten", args))
}
pub(crate) fn handle_flat_map_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() >= 2
&& args[1].kind != NativeKind::Ptr(HeapKind::Closure)
{
return Err(VMError::RuntimeError(format!(
"flatMap: second argument must be a closure, got kind {:?}",
args[1].kind
)));
}
Err(ckpt2_surface("flatMap", args))
}
pub(crate) fn handle_group_by_v2(
_vm: &mut VirtualMachine,
args: &[KindedSlot],
_ctx: Option<&mut ExecutionContext>,
) -> Result<KindedSlot, VMError> {
if args.len() >= 2
&& args[1].kind != NativeKind::Ptr(HeapKind::Closure)
{
return Err(VMError::RuntimeError(format!(
"groupBy: second argument must be a closure, got kind {:?}",
args[1].kind
)));
}
Err(ckpt2_surface("groupBy", args))
}