Skip to main content

shape_vm/executor/
vm_impl_part3.rs

1use super::*;
2
3impl VirtualMachine {
4    pub fn create_typed_enum(
5        &self,
6        enum_name: &str,
7        variant_name: &str,
8        payload: Vec<ValueWord>,
9    ) -> Option<ValueWord> {
10        let nb_payload: Vec<ValueWord> = payload.into_iter().map(|v| v).collect();
11        self.create_typed_enum_nb(enum_name, variant_name, nb_payload)
12            .map(|nb| nb.clone())
13    }
14
15    /// Create a TypedObject enum value using ValueWord payload directly.
16    pub fn create_typed_enum_nb(
17        &self,
18        enum_name: &str,
19        variant_name: &str,
20        payload: Vec<ValueWord>,
21    ) -> Option<ValueWord> {
22        let schema = self.program.type_schema_registry.get(enum_name)?;
23        let enum_info = schema.get_enum_info()?;
24        let variant_id = enum_info.variant_id(variant_name)?;
25
26        // Build slots: slot 0 = variant_id, slot 1+ = payload
27        let slot_count = 1 + enum_info.max_payload_fields() as usize;
28        let mut slots = Vec::with_capacity(slot_count);
29        let mut heap_mask: u64 = 0;
30
31        // Slot 0: variant discriminator is an i64 field (`__variant`).
32        slots.push(ValueSlot::from_int(variant_id as i64));
33
34        // Payload slots
35        for (i, nb) in payload.into_iter().enumerate() {
36            let slot_idx = 1 + i;
37            match nb.tag() {
38                shape_value::NanTag::F64 => {
39                    slots.push(ValueSlot::from_number(nb.as_f64().unwrap_or(0.0)))
40                }
41                shape_value::NanTag::I48 => {
42                    slots.push(ValueSlot::from_number(nb.as_i64().unwrap_or(0) as f64))
43                }
44                shape_value::NanTag::Bool => {
45                    slots.push(ValueSlot::from_bool(nb.as_bool().unwrap_or(false)))
46                }
47                shape_value::NanTag::None => slots.push(ValueSlot::none()),
48                _ => {
49                    if let Some(hv) = nb.as_heap_ref() {
50                        slots.push(ValueSlot::from_heap(hv.clone()));
51                        heap_mask |= 1u64 << slot_idx;
52                    } else {
53                        // Function/ModuleFunction/Unit/other inline types: store as int slot
54                        let id = nb
55                            .as_function()
56                            .or_else(|| nb.as_module_function().map(|u| u as u16))
57                            .unwrap_or(0);
58                        slots.push(ValueSlot::from_int(id as i64));
59                    }
60                }
61            }
62        }
63
64        // Fill remaining payload slots with None
65        while slots.len() < slot_count {
66            slots.push(ValueSlot::none());
67        }
68
69        Some(ValueWord::from_heap_value(HeapValue::TypedObject {
70            schema_id: schema.id as u64,
71            slots: slots.into_boxed_slice(),
72            heap_mask,
73        }))
74    }
75
76    // --- ValueWord-direct stack ops for hot paths ---
77
78    /// Push a ValueWord value directly (no ValueWord conversion).
79    ///
80    /// Hot path: single bounds check + write.  The stack growth and overflow
81    /// checks are split into a cold `push_vw_slow` to keep the hot path tight.
82    #[inline(always)]
83    pub(crate) fn push_vw(&mut self, value: ValueWord) -> Result<(), VMError> {
84        if self.sp >= self.stack.len() {
85            return self.push_vw_slow(value);
86        }
87        self.stack[self.sp] = value;
88        self.sp += 1;
89        Ok(())
90    }
91
92    /// Cold path for push_vw: grow the stack or return StackOverflow.
93    #[cold]
94    #[inline(never)]
95    pub(super) fn push_vw_slow(&mut self, value: ValueWord) -> Result<(), VMError> {
96        if self.sp >= self.config.max_stack_size {
97            return Err(VMError::StackOverflow);
98        }
99        let new_len = self.sp * 2 + 1;
100        self.stack.reserve(new_len - self.stack.len());
101        while self.stack.len() < new_len {
102            self.stack.push(ValueWord::none());
103        }
104        self.stack[self.sp] = value;
105        self.sp += 1;
106        Ok(())
107    }
108
109    /// Pop a ValueWord value directly (no ValueWord conversion).
110    ///
111    /// Uses `ptr::read` to take ownership of the value, then writes a
112    /// ValueWord::none() sentinel via raw pointer to prevent double-free on
113    /// Vec drop — avoiding bounds checks and the full `mem::replace` protocol.
114    ///
115    /// The underflow check is retained for safety but marked cold so the
116    /// branch predictor always predicts the fast path (sp > 0).
117    #[inline(always)]
118    pub(super) fn pop_vw(&mut self) -> Result<ValueWord, VMError> {
119        if self.sp == 0 {
120            return Self::pop_vw_underflow();
121        }
122        self.sp -= 1;
123        // SAFETY: sp was > 0 before decrement, so self.sp is a valid index
124        // into self.stack (which is pre-allocated to at least DEFAULT_STACK_CAPACITY).
125        // We take ownership via ptr::read and immediately overwrite the slot with
126        // a None sentinel so the Vec destructor won't double-free any heap ValueWord.
127        unsafe {
128            let ptr = self.stack.as_mut_ptr().add(self.sp);
129            let val = std::ptr::read(ptr);
130            // Write ValueWord::none() bit pattern directly. This is TAG_BASE | (TAG_NONE << 48)
131            // = 0xFFFB_0000_0000_0000. It's a non-heap tagged value so Drop is a no-op.
132            std::ptr::write(ptr as *mut u64, 0xFFFB_0000_0000_0000u64);
133            Ok(val)
134        }
135    }
136
137    #[cold]
138    #[inline(never)]
139    pub(super) fn pop_vw_underflow() -> Result<ValueWord, VMError> {
140        Err(VMError::StackUnderflow)
141    }
142
143    /// Pop and materialize a ValueWord from the stack (convenience for tests and legacy callers).
144    pub fn pop(&mut self) -> Result<ValueWord, VMError> {
145        Ok(self.pop_vw()?.clone())
146    }
147
148    // ===== Builtin Dispatch =====
149
150    pub(super) fn op_builtin_call(
151        &mut self,
152        instruction: &Instruction,
153        ctx: Option<&mut shape_runtime::context::ExecutionContext>,
154    ) -> Result<(), VMError> {
155        if let Some(Operand::Builtin(builtin)) = instruction.operand {
156            let mut ctx = ctx;
157            match builtin {
158                // Math builtins (15)
159                BuiltinFunction::Abs => {
160                    let args = self.pop_builtin_args()?;
161                    let result = self.builtin_abs(args)?;
162                    self.push_vw(result)?;
163                }
164                BuiltinFunction::Sqrt => {
165                    let args = self.pop_builtin_args()?;
166                    let result = self.builtin_sqrt(args)?;
167                    self.push_vw(result)?;
168                }
169                BuiltinFunction::Ln => {
170                    let args = self.pop_builtin_args()?;
171                    let result = self.builtin_ln(args)?;
172                    self.push_vw(result)?;
173                }
174                BuiltinFunction::Pow => {
175                    let args = self.pop_builtin_args()?;
176                    let result = self.builtin_pow(args)?;
177                    self.push_vw(result)?;
178                }
179                BuiltinFunction::Exp => {
180                    let args = self.pop_builtin_args()?;
181                    let result = self.builtin_exp(args)?;
182                    self.push_vw(result)?;
183                }
184                BuiltinFunction::Log => {
185                    let args = self.pop_builtin_args()?;
186                    let result = self.builtin_log(args)?;
187                    self.push_vw(result)?;
188                }
189                BuiltinFunction::Floor => {
190                    let args = self.pop_builtin_args()?;
191                    let result = self.builtin_floor(args)?;
192                    self.push_vw(result)?;
193                }
194                BuiltinFunction::Ceil => {
195                    let args = self.pop_builtin_args()?;
196                    let result = self.builtin_ceil(args)?;
197                    self.push_vw(result)?;
198                }
199                BuiltinFunction::Round => {
200                    let args = self.pop_builtin_args()?;
201                    let result = self.builtin_round(args)?;
202                    self.push_vw(result)?;
203                }
204                BuiltinFunction::Sin => {
205                    let args = self.pop_builtin_args()?;
206                    let result = self.builtin_sin(args)?;
207                    self.push_vw(result)?;
208                }
209                BuiltinFunction::Cos => {
210                    let args = self.pop_builtin_args()?;
211                    let result = self.builtin_cos(args)?;
212                    self.push_vw(result)?;
213                }
214                BuiltinFunction::Tan => {
215                    let args = self.pop_builtin_args()?;
216                    let result = self.builtin_tan(args)?;
217                    self.push_vw(result)?;
218                }
219                BuiltinFunction::Asin => {
220                    let args = self.pop_builtin_args()?;
221                    let result = self.builtin_asin(args)?;
222                    self.push_vw(result)?;
223                }
224                BuiltinFunction::Acos => {
225                    let args = self.pop_builtin_args()?;
226                    let result = self.builtin_acos(args)?;
227                    self.push_vw(result)?;
228                }
229                BuiltinFunction::Atan => {
230                    let args = self.pop_builtin_args()?;
231                    let result = self.builtin_atan(args)?;
232                    self.push_vw(result)?;
233                }
234                // Stats builtins (3)
235                BuiltinFunction::Min => {
236                    let args = self.pop_builtin_args()?;
237                    let result = self.builtin_min(args)?;
238                    self.push_vw(result)?;
239                }
240                BuiltinFunction::Max => {
241                    let args = self.pop_builtin_args()?;
242                    let result = self.builtin_max(args)?;
243                    self.push_vw(result)?;
244                }
245                BuiltinFunction::StdDev => {
246                    let args = self.pop_builtin_args()?;
247                    let result = self.builtin_stddev(args)?;
248                    self.push_vw(result)?;
249                }
250                // Array builtins (6)
251                BuiltinFunction::Push => {
252                    let args = self.pop_builtin_args()?;
253                    let result = self.builtin_push(args)?;
254                    self.push_vw(result)?;
255                }
256                BuiltinFunction::Pop => {
257                    let args = self.pop_builtin_args()?;
258                    let result = self.builtin_pop(args)?;
259                    self.push_vw(result)?;
260                }
261                BuiltinFunction::First => {
262                    let args = self.pop_builtin_args()?;
263                    let result = self.builtin_first(args)?;
264                    self.push_vw(result)?;
265                }
266                BuiltinFunction::Last => {
267                    let args = self.pop_builtin_args()?;
268                    let result = self.builtin_last(args)?;
269                    self.push_vw(result)?;
270                }
271                BuiltinFunction::Zip => {
272                    let args = self.pop_builtin_args()?;
273                    let result = self.builtin_zip(args)?;
274                    self.push_vw(result)?;
275                }
276                BuiltinFunction::Len => {
277                    let args = self.pop_builtin_args()?;
278                    let result = self.builtin_len(args)?;
279                    self.push_vw(result)?;
280                }
281                BuiltinFunction::Filled => {
282                    let args = self.pop_builtin_args()?;
283                    let result = self.builtin_filled(args)?;
284                    self.push_vw(result)?;
285                }
286                // Utility builtins (2)
287                BuiltinFunction::Format => {
288                    let args = self.pop_builtin_args()?;
289                    let result = self.builtin_format(args)?;
290                    self.push_vw(result)?;
291                }
292                // BuiltinFunction::Throw removed: Shape uses Result types
293                BuiltinFunction::Range => {
294                    let args = self.pop_builtin_args()?;
295                    let result = self.builtin_range(args)?;
296                    self.push_vw(result)?;
297                }
298                BuiltinFunction::Slice => {
299                    let args = self.pop_builtin_args()?;
300                    let result = self.builtin_slice(args)?;
301                    self.push_vw(result)?;
302                }
303                BuiltinFunction::Map => {
304                    let args = self.pop_builtin_args()?;
305                    let result = self.builtin_map(args, ctx)?;
306                    self.push_vw(result)?;
307                }
308                BuiltinFunction::Filter => {
309                    let args = self.pop_builtin_args()?;
310                    let result = self.builtin_filter(args, ctx)?;
311                    self.push_vw(result)?;
312                }
313                BuiltinFunction::Reduce => {
314                    let args = self.pop_builtin_args()?;
315                    let result = self.builtin_reduce(args, ctx)?;
316                    self.push_vw(result)?;
317                }
318                BuiltinFunction::ForEach => {
319                    let args = self.pop_builtin_args()?;
320                    let result = self.builtin_for_each(args, ctx)?;
321                    self.push_vw(result)?;
322                }
323                BuiltinFunction::Find => {
324                    let args = self.pop_builtin_args()?;
325                    let result = self.builtin_find(args, ctx)?;
326                    self.push_vw(result)?;
327                }
328                BuiltinFunction::FindIndex => {
329                    let args = self.pop_builtin_args()?;
330                    let result = self.builtin_find_index(args, ctx)?;
331                    self.push_vw(result)?;
332                }
333                BuiltinFunction::Some => {
334                    let args = self.pop_builtin_args()?;
335                    let result = self.builtin_some(args, ctx)?;
336                    self.push_vw(result)?;
337                }
338                BuiltinFunction::Every => {
339                    let args = self.pop_builtin_args()?;
340                    let result = self.builtin_every(args, ctx)?;
341                    self.push_vw(result)?;
342                }
343                BuiltinFunction::Print => {
344                    let args = self.pop_builtin_args()?;
345                    let result = self.builtin_print(args, ctx)?;
346                    self.push_vw(result)?;
347                }
348                BuiltinFunction::Snapshot => {
349                    let args = self.pop_builtin_args()?;
350                    let result = self.builtin_snapshot(args, ctx)?;
351                    self.push_vw(result)?;
352                }
353                BuiltinFunction::Exit => {
354                    let args = self.pop_builtin_args()?;
355                    let result = self.builtin_exit(args)?;
356                    self.push_vw(result)?;
357                }
358                BuiltinFunction::ObjectRest => {
359                    let args = self.pop_builtin_args()?;
360                    let result = self.builtin_object_rest(args)?;
361                    self.push_vw(result)?;
362                }
363                BuiltinFunction::IsNumber => {
364                    let args = self.pop_builtin_args()?;
365                    let result = self.builtin_is_number(args)?;
366                    self.push_vw(result)?;
367                }
368                BuiltinFunction::IsString => {
369                    let args = self.pop_builtin_args()?;
370                    let result = self.builtin_is_string(args)?;
371                    self.push_vw(result)?;
372                }
373                BuiltinFunction::IsBool => {
374                    let args = self.pop_builtin_args()?;
375                    let result = self.builtin_is_bool(args)?;
376                    self.push_vw(result)?;
377                }
378                BuiltinFunction::IsArray => {
379                    let args = self.pop_builtin_args()?;
380                    let result = self.builtin_is_array(args)?;
381                    self.push_vw(result)?;
382                }
383                BuiltinFunction::IsObject => {
384                    let args = self.pop_builtin_args()?;
385                    let result = self.builtin_is_object(args)?;
386                    self.push_vw(result)?;
387                }
388                BuiltinFunction::IsDataRow => {
389                    let args = self.pop_builtin_args()?;
390                    let result = self.builtin_is_data_row(args)?;
391                    self.push_vw(result)?;
392                }
393                b @ (BuiltinFunction::ToString
394                | BuiltinFunction::ToNumber
395                | BuiltinFunction::ToBool
396                | BuiltinFunction::IntoInt
397                | BuiltinFunction::IntoNumber
398                | BuiltinFunction::IntoDecimal
399                | BuiltinFunction::IntoBool
400                | BuiltinFunction::IntoString
401                | BuiltinFunction::TryIntoInt
402                | BuiltinFunction::TryIntoNumber
403                | BuiltinFunction::TryIntoDecimal
404                | BuiltinFunction::TryIntoBool
405                | BuiltinFunction::TryIntoString) => {
406                    let args = self.pop_builtin_args()?;
407                    let result = self.dispatch_conversion_builtin(b, args)?;
408                    self.push_vw(result)?;
409                }
410                b @ (BuiltinFunction::NativePtrSize
411                | BuiltinFunction::NativePtrNewCell
412                | BuiltinFunction::NativePtrFreeCell
413                | BuiltinFunction::NativePtrReadPtr
414                | BuiltinFunction::NativePtrWritePtr
415                | BuiltinFunction::NativeTableFromArrowC
416                | BuiltinFunction::NativeTableFromArrowCTyped
417                | BuiltinFunction::NativeTableBindType) => {
418                    let args = self.pop_builtin_args()?;
419                    let result = self.dispatch_native_interop_builtin(b, args)?;
420                    self.push_vw(result)?;
421                }
422                BuiltinFunction::FormatValueWithMeta => {
423                    let args = self.pop_builtin_args()?;
424                    let result = self.builtin_format_with_meta(args, ctx)?;
425                    self.push_vw(result)?;
426                }
427                BuiltinFunction::FormatValueWithSpec => {
428                    let args = self.pop_builtin_args()?;
429                    let result = self.builtin_format_with_spec(args, ctx)?;
430                    self.push_vw(result)?;
431                }
432                BuiltinFunction::TypeOf => {
433                    let args: Vec<ValueWord> = vec![]; // TypeOf uses self.pop_vw() internally
434                    let result = self.builtin_type_of(args)?;
435                    self.push_vw(result)?;
436                }
437                b @ (BuiltinFunction::IntrinsicVecAbs
438                | BuiltinFunction::IntrinsicVecSqrt
439                | BuiltinFunction::IntrinsicVecLn
440                | BuiltinFunction::IntrinsicVecExp
441                | BuiltinFunction::IntrinsicVecAdd
442                | BuiltinFunction::IntrinsicVecSub
443                | BuiltinFunction::IntrinsicVecMul
444                | BuiltinFunction::IntrinsicVecDiv
445                | BuiltinFunction::IntrinsicVecMax
446                | BuiltinFunction::IntrinsicVecMin
447                | BuiltinFunction::IntrinsicVecSelect) => {
448                    return self.handle_vector_intrinsic(b, ctx.as_deref_mut());
449                }
450                b @ (BuiltinFunction::IntrinsicMatMulVec | BuiltinFunction::IntrinsicMatMulMat) => {
451                    return self.handle_matrix_intrinsic(b, ctx.as_deref_mut());
452                }
453                BuiltinFunction::SomeCtor => {
454                    let args = self.pop_builtin_args()?;
455                    let result = self.builtin_some_ctor(args)?;
456                    self.push_vw(result)?;
457                }
458                BuiltinFunction::OkCtor => {
459                    let args = self.pop_builtin_args()?;
460                    let result = self.builtin_ok_ctor(args)?;
461                    self.push_vw(result)?;
462                }
463                BuiltinFunction::ErrCtor => {
464                    let args = self.pop_builtin_args()?;
465                    let result = self.builtin_err_ctor(args)?;
466                    self.push_vw(result)?;
467                }
468                BuiltinFunction::HashMapCtor => {
469                    let _args = self.pop_builtin_args()?;
470                    self.push_vw(ValueWord::empty_hashmap())?;
471                }
472                BuiltinFunction::SetCtor => {
473                    let args = self.pop_builtin_args()?;
474                    if args.is_empty() {
475                        self.push_vw(ValueWord::empty_set())?;
476                    } else if args.len() == 1 {
477                        // Set(array) — initialize from array
478                        if let Some(arr) = args[0].as_array() {
479                            self.push_vw(ValueWord::from_set(arr.to_vec()))?;
480                        } else {
481                            // Single non-array item — wrap in set
482                            self.push_vw(ValueWord::from_set(vec![args[0].clone()]))?;
483                        }
484                    } else {
485                        // Set(a, b, c) — multiple args become set items
486                        self.push_vw(ValueWord::from_set(args))?;
487                    }
488                }
489                BuiltinFunction::DequeCtor => {
490                    let args = self.pop_builtin_args()?;
491                    if args.is_empty() {
492                        self.push_vw(ValueWord::empty_deque())?;
493                    } else if args.len() == 1 {
494                        // Deque(array) — initialize from array
495                        if let Some(arr) = args[0].as_array() {
496                            self.push_vw(ValueWord::from_deque(arr.to_vec()))?;
497                        } else {
498                            // Single non-array item
499                            self.push_vw(ValueWord::from_deque(vec![args[0].clone()]))?;
500                        }
501                    } else {
502                        // Deque(a, b, c)
503                        self.push_vw(ValueWord::from_deque(args))?;
504                    }
505                }
506                BuiltinFunction::PriorityQueueCtor => {
507                    let args = self.pop_builtin_args()?;
508                    if args.is_empty() {
509                        self.push_vw(ValueWord::empty_priority_queue())?;
510                    } else if args.len() == 1 {
511                        if let Some(arr) = args[0].as_array() {
512                            self.push_vw(ValueWord::from_priority_queue(arr.to_vec()))?;
513                        } else {
514                            self.push_vw(ValueWord::from_priority_queue(vec![args[0].clone()]))?;
515                        }
516                    } else {
517                        self.push_vw(ValueWord::from_priority_queue(args))?;
518                    }
519                }
520                BuiltinFunction::ControlFold => {
521                    let args = self.pop_builtin_args()?;
522                    let result = self.builtin_control_fold(args, ctx)?;
523                    self.push_vw(result)?;
524                }
525                // Delegate ALL intrinsics to helper method
526                b @ (BuiltinFunction::IntrinsicSum
527                | BuiltinFunction::IntrinsicMean
528                | BuiltinFunction::IntrinsicMin
529                | BuiltinFunction::IntrinsicMax
530                | BuiltinFunction::IntrinsicStd
531                | BuiltinFunction::IntrinsicVariance
532                | BuiltinFunction::IntrinsicRandom
533                | BuiltinFunction::IntrinsicRandomInt
534                | BuiltinFunction::IntrinsicRandomSeed
535                | BuiltinFunction::IntrinsicRandomNormal
536                | BuiltinFunction::IntrinsicRandomArray
537                | BuiltinFunction::IntrinsicDistUniform
538                | BuiltinFunction::IntrinsicDistLognormal
539                | BuiltinFunction::IntrinsicDistExponential
540                | BuiltinFunction::IntrinsicDistPoisson
541                | BuiltinFunction::IntrinsicDistSampleN
542                | BuiltinFunction::IntrinsicBrownianMotion
543                | BuiltinFunction::IntrinsicGbm
544                | BuiltinFunction::IntrinsicOuProcess
545                | BuiltinFunction::IntrinsicRandomWalk
546                | BuiltinFunction::IntrinsicRollingSum
547                | BuiltinFunction::IntrinsicRollingMean
548                | BuiltinFunction::IntrinsicRollingStd
549                | BuiltinFunction::IntrinsicRollingMin
550                | BuiltinFunction::IntrinsicRollingMax
551                | BuiltinFunction::IntrinsicEma
552                | BuiltinFunction::IntrinsicLinearRecurrence
553                | BuiltinFunction::IntrinsicShift
554                | BuiltinFunction::IntrinsicDiff
555                | BuiltinFunction::IntrinsicPctChange
556                | BuiltinFunction::IntrinsicFillna
557                | BuiltinFunction::IntrinsicCumsum
558                | BuiltinFunction::IntrinsicCumprod
559                | BuiltinFunction::IntrinsicClip
560                | BuiltinFunction::IntrinsicCorrelation
561                | BuiltinFunction::IntrinsicCovariance
562                | BuiltinFunction::IntrinsicPercentile
563                | BuiltinFunction::IntrinsicMedian
564                | BuiltinFunction::IntrinsicCharCode
565                | BuiltinFunction::IntrinsicFromCharCode
566                | BuiltinFunction::IntrinsicSeries) => {
567                    return self.handle_intrinsic_builtin(b, ctx.as_deref_mut());
568                }
569                BuiltinFunction::EvalTimeRef => {
570                    return Err(VMError::NotImplemented(
571                        "eval_time_ref() (VM-only mode)".to_string(),
572                    ));
573                }
574                BuiltinFunction::EvalDateTimeExpr => {
575                    return self.handle_eval_datetime_expr(ctx);
576                }
577                BuiltinFunction::EvalDataDateTimeRef => {
578                    // DataReference type removed - this operation is no longer supported
579                    return Err(VMError::RuntimeError(
580                        "DataReference type has been removed".to_string(),
581                    ));
582                }
583                BuiltinFunction::EvalDataSet => {
584                    // DataRow type removed - this operation is no longer supported
585                    return Err(VMError::RuntimeError(
586                        "DataRow type has been removed".to_string(),
587                    ));
588                }
589                BuiltinFunction::EvalDataRelative => {
590                    // DataReference type removed - this operation is no longer supported
591                    return Err(VMError::RuntimeError(
592                        "DataReference type has been removed".to_string(),
593                    ));
594                }
595                BuiltinFunction::EvalDataRelativeRange => {
596                    // DataReference type removed - this operation is no longer supported
597                    return Err(VMError::RuntimeError(
598                        "DataReference type has been removed".to_string(),
599                    ));
600                }
601
602                // Window functions - these delegate to the runtime WindowExecutor
603                // In VM mode, window functions are evaluated differently than in JIT
604                b @ (BuiltinFunction::WindowRowNumber
605                | BuiltinFunction::WindowRank
606                | BuiltinFunction::WindowDenseRank
607                | BuiltinFunction::WindowNtile
608                | BuiltinFunction::WindowLag
609                | BuiltinFunction::WindowLead
610                | BuiltinFunction::WindowFirstValue
611                | BuiltinFunction::WindowLastValue
612                | BuiltinFunction::WindowNthValue
613                | BuiltinFunction::WindowSum
614                | BuiltinFunction::WindowAvg
615                | BuiltinFunction::WindowMin
616                | BuiltinFunction::WindowMax
617                | BuiltinFunction::WindowCount) => {
618                    return self.handle_window_functions(b);
619                }
620
621                // JOIN operation
622                BuiltinFunction::JoinExecute => {
623                    return self.handle_join_execute();
624                }
625
626                // Reflection
627                BuiltinFunction::Reflect => {
628                    return self.builtin_reflect();
629                }
630
631                // Content string builtins
632                BuiltinFunction::MakeContentText => {
633                    let args = self.pop_builtin_args()?;
634                    let result = self.builtin_make_content_text(args)?;
635                    self.push_vw(result)?;
636                }
637                BuiltinFunction::MakeContentFragment => {
638                    let args = self.pop_builtin_args()?;
639                    let result = self.builtin_make_content_fragment(args)?;
640                    self.push_vw(result)?;
641                }
642                BuiltinFunction::ApplyContentStyle => {
643                    let args = self.pop_builtin_args()?;
644                    let result = self.builtin_apply_content_style(args)?;
645                    self.push_vw(result)?;
646                }
647
648                // DateTime constructor builtins
649                BuiltinFunction::DateTimeNow => {
650                    let result = ValueWord::from_time(chrono::Local::now().fixed_offset());
651                    self.push_vw(result)?;
652                }
653                BuiltinFunction::DateTimeUtc => {
654                    let result = ValueWord::from_time_utc(chrono::Utc::now());
655                    self.push_vw(result)?;
656                }
657                BuiltinFunction::DateTimeParse => {
658                    let args = self.pop_builtin_args()?;
659                    let result = self.builtin_datetime_parse(args)?;
660                    self.push_vw(result)?;
661                }
662                BuiltinFunction::DateTimeFromEpoch => {
663                    let args = self.pop_builtin_args()?;
664                    let result = self.builtin_datetime_from_epoch(args)?;
665                    self.push_vw(result)?;
666                }
667
668                // Concurrency primitive constructors
669                BuiltinFunction::MutexCtor => {
670                    let args = self.pop_builtin_args()?;
671                    let inner_value = args.into_iter().next().unwrap_or_else(ValueWord::none);
672                    self.push_vw(ValueWord::from_mutex(inner_value))?;
673                }
674                BuiltinFunction::AtomicCtor => {
675                    let args = self.pop_builtin_args()?;
676                    let init_val = args.first().and_then(|nb| nb.as_i64()).unwrap_or(0);
677                    self.push_vw(ValueWord::from_atomic(init_val))?;
678                }
679                BuiltinFunction::LazyCtor => {
680                    let args = self.pop_builtin_args()?;
681                    let initializer = args.into_iter().next().unwrap_or_else(ValueWord::none);
682                    self.push_vw(ValueWord::from_lazy(initializer))?;
683                }
684                BuiltinFunction::ChannelCtor => {
685                    let _args = self.pop_builtin_args()?;
686                    let (sender, receiver) = shape_value::heap_value::ChannelData::new_pair();
687                    let arr = vec![
688                        ValueWord::from_channel(sender),
689                        ValueWord::from_channel(receiver),
690                    ];
691                    self.push_vw(ValueWord::from_array(std::sync::Arc::new(arr)))?;
692                }
693
694                // Additional math builtins
695                BuiltinFunction::Sign => {
696                    let args = self.pop_builtin_args()?;
697                    let result = self.builtin_sign(args)?;
698                    self.push_vw(result)?;
699                }
700                BuiltinFunction::Gcd => {
701                    let args = self.pop_builtin_args()?;
702                    let result = self.builtin_gcd(args)?;
703                    self.push_vw(result)?;
704                }
705                BuiltinFunction::Lcm => {
706                    let args = self.pop_builtin_args()?;
707                    let result = self.builtin_lcm(args)?;
708                    self.push_vw(result)?;
709                }
710                BuiltinFunction::Hypot => {
711                    let args = self.pop_builtin_args()?;
712                    let result = self.builtin_hypot(args)?;
713                    self.push_vw(result)?;
714                }
715                BuiltinFunction::Clamp => {
716                    let args = self.pop_builtin_args()?;
717                    let result = self.builtin_clamp(args)?;
718                    self.push_vw(result)?;
719                }
720                BuiltinFunction::IsNaN => {
721                    let args = self.pop_builtin_args()?;
722                    let result = self.builtin_is_nan(args)?;
723                    self.push_vw(result)?;
724                }
725                BuiltinFunction::IsFinite => {
726                    let args = self.pop_builtin_args()?;
727                    let result = self.builtin_is_finite(args)?;
728                    self.push_vw(result)?;
729                }
730
731                // Json navigation helpers
732                BuiltinFunction::JsonObjectGet => {
733                    let args = self.pop_builtin_args()?;
734                    let result = self.builtin_json_object_get(args)?;
735                    self.push_vw(result)?;
736                }
737                BuiltinFunction::JsonArrayAt => {
738                    let args = self.pop_builtin_args()?;
739                    let result = self.builtin_json_array_at(args)?;
740                    self.push_vw(result)?;
741                }
742                BuiltinFunction::JsonObjectKeys => {
743                    let args = self.pop_builtin_args()?;
744                    let result = self.builtin_json_object_keys(args)?;
745                    self.push_vw(result)?;
746                }
747                BuiltinFunction::JsonArrayLen => {
748                    let args = self.pop_builtin_args()?;
749                    let result = self.builtin_json_array_len(args)?;
750                    self.push_vw(result)?;
751                }
752                BuiltinFunction::JsonObjectLen => {
753                    let args = self.pop_builtin_args()?;
754                    let result = self.builtin_json_object_len(args)?;
755                    self.push_vw(result)?;
756                }
757            }
758        } else {
759            return Err(VMError::InvalidOperand);
760        }
761        Ok(())
762    }
763
764    // Runtime bridge functions (pop_builtin_args, eval_runtime_*) moved to builtins/runtime_bridge.rs
765    // map_runtime_error and type_of_name moved to module_registry module
766
767    // ===== Exception Handling Operations =====
768    // handle_exception moved to exceptions/mod.rs
769
770    // ===== Slice and Null Coalescing Operations =====
771
772    // ===== Loop Control Operations =====
773
774    // ===== Helper Methods =====
775    // binary_arithmetic, eval_runtime_binary_op_value, binary_comparison moved to arithmetic/mod.rs
776}