1use crate::opcodes::*;
2use crate::vm_hashmap::{VMHashMap, ValHash};
3use crate::{
4 CallFrame, Chunk, Continuation, Error, GVm, STACK_CAP, VMError, VMErrorObj, VMResult, Value,
5 from_i56,
6};
7use std::marker::PhantomData;
8use std::num::TryFromIntError;
9use std::sync::Arc;
10use unicode_segmentation::UnicodeSegmentation;
11
12impl<ENV> GVm<ENV> {
13 #[inline]
14 fn map_destructure(
15 &mut self,
16 decodes: (u16, u16, u16),
18 ) -> VMResult<()> {
20 let (dest, len, src) = decodes; if len > 0 {
22 let len = len as usize;
23 let dest = dest as usize;
24 let val = self.register(src as usize);
25 match val {
26 Value::Map(handle) => {
27 let map = self.get_map(handle);
28 for i in 0..len {
29 let key = self.register(dest + i);
30 if let Some(item) = map.get(self, key) {
31 *self.register_mut(dest + i) = item;
32 } else {
33 *self.register_mut(dest + i) = Value::Undefined;
34 }
35 }
36 }
37 Value::Vector(handle) => {
38 let vector = self.get_vector(handle);
39 for i in 0..len {
40 let key = self.register(dest + i);
41 if key.is_int() {
42 let key = key.get_int(self)?;
43 if key >= 0 && key < vector.len() as i64 {
44 *self.register_mut(dest + i) = vector[key as usize];
45 } else {
46 return Err(VMError::new_vm("seq key out of bounds"));
47 }
48 } else {
49 let mut iter = vector.iter();
50 *self.register_mut(dest + i) = Value::Undefined;
51 while let Some(v) = iter.next() {
52 if *v == key {
53 if let Some(value) = iter.next() {
54 *self.register_mut(dest + i) = *value;
55 }
56 break;
57 }
58 }
59 }
60 }
61 }
62 Value::List(handle, idx) => {
63 let vector = &self.get_vector(handle)[idx as usize..];
64 for i in 0..len {
65 let key = self.register(dest + i);
66 if key.is_int() {
67 let key = key.get_int(self)?;
68 if key >= 0 && key < vector.len() as i64 {
69 *self.register_mut(dest + i) = vector[key as usize];
70 } else {
71 return Err(VMError::new_vm("seq key out of bounds"));
72 }
73 } else {
74 let mut iter = vector.iter();
75 *self.register_mut(dest + i) = Value::Undefined;
76 while let Some(v) = iter.next() {
77 if *v == key {
78 if let Some(value) = iter.next() {
79 *self.register_mut(dest + i) = *value;
80 }
81 break;
82 }
83 }
84 }
85 }
86 }
87 Value::Pair(_) => {
88 for i in 0..len {
89 let key = self.register(dest + i);
90 if key.is_int() {
91 let key = key.get_int(self)?;
92 if key >= 0 {
93 let mut iter = val.iter(self);
94 if let Some(item) = iter.nth(key as usize) {
95 *self.register_mut(dest + i) = item;
96 } else {
97 return Err(VMError::new_vm("seq key out of bounds"));
98 }
99 } else {
100 return Err(VMError::new_vm("seq key out of bounds"));
101 }
102 } else {
103 let mut iter = val.iter(self);
104 *self.register_mut(dest + i) = Value::Undefined;
105 while let Some(v) = iter.next() {
106 if v == key {
107 if let Some(value) = iter.next() {
108 *self.register_mut(dest + i) = value;
109 }
110 break;
111 }
112 }
113 }
114 }
115 }
116 Value::Nil => {
117 for i in 0..len {
118 *self.register_mut(dest + i) = Value::Undefined;
119 }
120 }
121 _ => return Err(VMError::new_vm("not a map")),
122 }
123 }
124 Ok(())
125 }
126
127 fn get_line(&self, wide: bool, chunk: &Chunk) -> Option<u32> {
128 if wide {
129 unsafe { chunk.offset_to_line(self.ip_ptr.offset_from(get_code!(chunk)) as usize - 4) }
130 } else {
131 unsafe { chunk.offset_to_line(self.ip_ptr.offset_from(get_code!(chunk)) as usize - 2) }
132 }
133 }
134
135 fn get_string_idx(&mut self, val: Value, i: u16) -> VMResult<Value> {
136 let s = match val {
137 Value::StringConst(it) => self.get_interned(it),
138 Value::String(h) => self.get_string(h),
139 _ => panic!("Invalid call to get_string_idx!"),
140 };
141 let idx = self.register_int(i as usize)?;
142 let mut iter = UnicodeSegmentation::graphemes(s, true);
143 let ch = if idx >= 0 {
144 iter.nth(idx as usize)
145 } else {
146 iter.rev().nth(((0 - idx) - 1) as usize)
147 };
148 let v = if let Some(ch) = ch {
149 let len = ch.len();
151 if len <= 6 {
152 let mut b = [0_u8; 6];
153 b[0..len].copy_from_slice(ch.as_bytes());
154 Value::CharCluster(len as u8, b)
155 } else {
156 let h = self.alloc_string(ch.to_string());
157 Value::CharClusterLong(h.get_handle().expect("just allocated, missing handle!"))
158 }
159 } else {
160 self.make_err("vm-missing", idx.into())
161 };
162 Ok(v)
163 }
164
165 fn get(&mut self, wide: bool) -> VMResult<()> {
166 let (dest, data, i) = decode3!(self.ip_ptr, wide);
167 let data = self.register(data as usize);
168 let val = match data {
169 Value::Vector(h) => {
170 let v = self.get_vector(h);
171 let idx = self.register_int(i as usize)?;
172 let idx = if idx >= 0 { idx } else { v.len() as i64 + idx };
173 if idx < 0 {
174 let iv = idx.into();
175 self.make_err("vm-missing", iv)
176 } else if let Some(val) = v.get(idx as usize) {
177 *val
178 } else {
179 let iv = idx.into();
180 self.make_err("vm-missing", iv)
181 }
182 }
183 Value::List(h, start) => {
184 let v = self.get_vector(h);
185 let idx = self.register_int(i as usize)?;
186 if idx < 0 {
187 let iv = idx.into();
188 self.make_err("vm-missing", iv)
189 } else if let Some(val) = v.get(start as usize + idx as usize) {
190 *val
191 } else {
192 let iv = idx.into();
193 self.make_err("vm-missing", iv)
194 }
195 }
196 Value::Pair(_) => {
197 let idx = self.register_int(i as usize)?;
198 if idx >= 0 {
199 let idx = idx as usize;
200 if let Some((mut car_out, mut cdr)) = data.get_pair(self) {
201 for _ in 0..idx {
202 if let Some((car, cdr_in)) = cdr.get_pair(self) {
203 car_out = car;
204 cdr = cdr_in;
205 } else {
206 let iv = (idx as i64).into();
207 car_out = self.make_err("vm-missing", iv);
208 }
209 }
210 car_out
211 } else {
212 panic!("pair not a pair!")
213 }
214 } else {
215 return Err(VMError::new_vm(format!(
216 "GET: list requires a positive index (pair), {}.",
217 i,
218 )));
219 }
220 }
221 Value::Map(h) => {
222 let map = self.get_map(h);
223 let key = self.register(i as usize);
224 if let Some(val) = map.get(self, key) {
225 val
226 } else {
227 self.make_err("vm-missing", key)
228 }
229 }
230 Value::StringConst(_) => self.get_string_idx(data, i)?,
231 Value::String(_) => self.get_string_idx(data, i)?,
232 Value::Error(_) => data, _ => {
234 return Err(VMError::new_vm("GET: Not a compound data structure."));
235 }
236 };
237 set_register!(self, dest as usize, val);
238 Ok(())
239 }
240
241 fn set_data(&mut self, wide: bool) -> VMResult<()> {
242 let (src, data, i) = decode3!(self.ip_ptr, wide);
243 let data = self.register(data as usize);
244 let src = self.register(src as usize);
245 match data {
246 Value::Vector(h) => {
247 let idx = self.register_int(i as usize)?;
248 let v = self.get_vector_mut(h)?;
249 let idx = if idx >= 0 { idx } else { v.len() as i64 + idx };
250 if idx < 0 {
251 return Err(VMError::new_vm(format!(
252 "index out of bounds, {}/{}.",
253 i,
254 v.len()
255 )));
256 }
257 if let Some(slot) = v.get_mut(idx as usize) {
258 *slot = src;
259 } else {
260 v.resize(idx as usize + 1, Value::Nil);
261 if let Some(slot) = v.get_mut(idx as usize) {
262 *slot = src;
263 } else {
264 return Err(VMError::new_vm(
265 "Vector, index out of bounds (unable to grow vector).",
266 ));
267 }
268 }
269 }
270 Value::List(h, start) => {
271 let idx = self.register_int(i as usize)?;
272 let v = self.get_vector_mut(h)?;
273 if idx < 0 {
274 return Err(VMError::new_vm(format!(
275 "index out of bounds, {}/{}.",
276 i,
277 v.len() - start as usize,
278 )));
279 }
280 if let Some(slot) = v.get_mut(start as usize + idx as usize) {
281 *slot = src;
282 } else {
283 return Err(VMError::new_vm("index out of bounds"));
284 }
285 }
286 Value::Pair(_) => {
287 let idx = self.register_int(i as usize)?;
288 if idx >= 0 {
289 let idx = idx as usize;
290 let mut last_cdr = data;
291 for _ in 0..idx {
292 if let Some((_car, cdr_in)) = last_cdr.get_pair(self) {
293 last_cdr = cdr_in;
294 } else {
295 return Err(VMError::new_vm(format!(
296 "index out of bounds (pair), {}.",
297 i,
298 )));
299 }
300 }
301 match &last_cdr {
302 Value::Pair(handle) => {
303 let (car, _) = self.get_pair_mut(*handle)?;
304 *car = src;
305 }
306 Value::List(_, _) => return Err(VMError::new_vm("pair is read only")),
307 _ => return Err(VMError::new_vm("not a pair/conscell")),
308 }
309 } else {
310 return Err(VMError::new_vm(format!(
311 "list requires a positive index (pair), {}.",
312 i,
313 )));
314 }
315 }
316 Value::Map(h) => {
317 let key = self.register(i as usize);
318 let id = ValHash::from_value(self, key);
319 let map = self.get_map_mut(h)?;
320 map.insert_id(id, src);
321 }
322 _ => {
323 return Err(VMError::new_vm(format!(
324 "Not a compound data structure: {}.",
325 data.display_type(self)
326 )));
327 }
328 }
329 Ok(())
330 }
331
332 fn tail_builtin_exit(&self, lambda: Value) -> bool {
336 matches!(lambda, Value::Builtin(_)) && self.call_frame().is_none()
337 }
338
339 fn inc_val(&mut self, wide: bool) -> VMResult<()> {
341 let (dest, i) = decode2!(self.ip_ptr, wide);
342 match self.register(dest as usize) {
343 Value::Byte(v) => {
344 let i: u8 = i
345 .try_into()
346 .map_err(|e: TryFromIntError| VMError::new_vm(e.to_string()))?;
347 *self.register_mut(dest as usize) = Value::Byte(v + i);
348 Ok(())
349 }
350 Value::Int(v) => {
351 let v = from_i56(&v);
352 *self.register_mut(dest as usize) = (v + i as i64).into();
353 Ok(())
354 }
355 Value::Value(h) => {
357 let val = self.get_value_mut(h);
358 match val {
359 Value::Byte(v) => {
360 let i: u8 = i
361 .try_into()
362 .map_err(|e: TryFromIntError| VMError::new_vm(e.to_string()))?;
363 *val = Value::Byte(*v + i);
364 Ok(())
365 }
366 Value::Int(v) => {
367 let v = from_i56(v);
368 *val = (v + i as i64).into();
369 Ok(())
370 }
371 _ => Err(VMError::new_vm(format!(
372 "INC: Can only INC an integer type, got {:?}.",
373 val
374 ))),
375 }
376 }
377 _ => Err(VMError::new_vm(format!(
378 "INC: Can only INC an integer type, got {:?}.",
379 self.register(dest as usize)
380 ))),
381 }
382 }
383
384 fn dec_val(&mut self, wide: bool) -> VMResult<()> {
386 let (dest, i) = decode2!(self.ip_ptr, wide);
387 match self.register(dest as usize) {
388 Value::Byte(v) => {
389 let i: u8 = i
390 .try_into()
391 .map_err(|e: TryFromIntError| VMError::new_vm(e.to_string()))?;
392 *self.register_mut(dest as usize) = Value::Byte(v - i);
393 Ok(())
394 }
395 Value::Int(v) => {
396 let v = from_i56(&v);
397 *self.register_mut(dest as usize) = (v - i as i64).into();
398 Ok(())
399 }
400 Value::Value(h) => {
402 let val = self.get_value_mut(h);
403 match val {
404 Value::Byte(v) => {
405 let i: u8 = i
406 .try_into()
407 .map_err(|e: TryFromIntError| VMError::new_vm(e.to_string()))?;
408 *val = Value::Byte(*v - i);
409 Ok(())
410 }
411 Value::Int(v) => {
412 let v = from_i56(v);
413 *val = (v - i as i64).into();
414 Ok(())
415 }
416 _ => Err(VMError::new_vm(format!(
417 "INC: Can only INC an integer type, got {:?}.",
418 val
419 ))),
420 }
421 }
422 _ => Err(VMError::new_vm(format!(
423 "DEC: Can only DEC an integer type, got {:?}.",
424 self.register(dest as usize)
425 ))),
426 }
427 }
428
429 #[allow(clippy::redundant_closure_call)]
431 pub(super) fn exec_loop(
432 &mut self,
433 chunk: Arc<Chunk>,
434 skip_init: bool,
435 ) -> Result<(), (VMError, Arc<Chunk>)> {
436 let _env: PhantomData<ENV>;
437 self.make_registers();
438 let mut chunk = chunk;
439 let mut wide = false;
440 if !skip_init {
441 self.ip_ptr = get_code!(chunk);
442 if chunk.extra_regs > 0 {
444 let regs = unsafe {
445 std::slice::from_raw_parts_mut(
446 self.stack.add(self.stack_top),
447 STACK_CAP - self.stack_top,
448 )
449 };
450 for reg in regs
451 .iter_mut()
452 .skip(chunk.input_regs)
453 .take(chunk.extra_regs + 1)
454 {
455 *reg = Value::Undefined;
456 }
457 }
458 }
459 let mut opcode = NOP;
460 loop {
461 if wide && opcode != WIDE {
462 wide = false;
463 }
464 self.current_ip_ptr = self.ip_ptr;
465 opcode = decode_u8!(self.ip_ptr);
466 match opcode {
467 NOP => {}
468 HALT => {
469 return Err((VMError::new_vm("HALT: VM halted and on fire!"), chunk));
470 }
471 RET => {
472 if let Some(defer) = self.defers.pop() {
473 let first_reg = (chunk.input_regs + chunk.extra_regs + 1) as u16;
474 self.ip_ptr = self.current_ip_ptr;
475 chunk = self.make_call(defer, chunk, first_reg, 0, false)?;
476 self.make_registers();
477 } else {
478 for r in self.stack_top + 1..=self.stack_max {
480 *self.stack_mut(r) = Value::Undefined;
481 }
482 if let Some(frame) = self.call_frame() {
483 let stack_top = frame.stack_top;
484 let ip_ptr = frame.ip;
485 let current_ip = frame.current_ip;
486 let this_fn = frame.this_fn;
487 let on_error = frame.on_error;
488 chunk = frame.chunk.clone();
489 self.copy_frame_defers(); self.stack_top = stack_top;
491 self.make_registers();
492 self.stack_max = self.stack_top + chunk.input_regs + chunk.extra_regs;
493 self.ip_ptr = ip_ptr;
494 self.current_ip_ptr = current_ip;
495 self.this_fn = this_fn;
496 self.on_error = on_error;
497 } else {
498 return Ok(());
499 }
500 }
501 }
502 SRET => {
503 if let Some(defer) = self.defers.pop() {
504 let first_reg = (chunk.input_regs + chunk.extra_regs + 1) as u16;
505 self.ip_ptr = self.current_ip_ptr;
506 chunk = self.make_call(defer, chunk, first_reg, 0, false)?;
507 self.make_registers();
508 } else {
509 let src = decode1!(self.ip_ptr, wide);
510 let val = self.register(src as usize);
511 let old_top = self.stack_top;
512 for r in self.stack_top + 1..=self.stack_max {
514 *self.stack_mut(r) = Value::Undefined;
515 }
516 if let Some(frame) = self.call_frame() {
517 let stack_top = frame.stack_top;
518 let ip_ptr = frame.ip;
519 let current_ip = frame.current_ip;
520 let this_fn = frame.this_fn;
521 let on_error = frame.on_error;
522 chunk = frame.chunk.clone();
523 self.copy_frame_defers(); self.stack_top = stack_top;
525 self.make_registers();
526 self.stack_max = self.stack_top + chunk.input_regs + chunk.extra_regs;
527 self.ip_ptr = ip_ptr;
528 self.current_ip_ptr = current_ip;
529 self.this_fn = this_fn;
530 self.on_error = on_error;
531 } else {
532 *self.stack_mut(old_top) = val;
533 return Ok(());
534 }
535 *self.stack_mut(old_top) = val;
536 }
537 }
538 WIDE => wide = true,
539 MOV => {
540 let (dest, src) = decode2!(self.ip_ptr, wide);
541 let val = self.register_unref(src as usize);
543 mov_register!(self, dest as usize, val);
545 }
546 MOVI => {
547 let (dest, src) = decode2!(self.ip_ptr, wide);
548 let val = self.register_unref(src as usize);
549 let dest = self
550 .register_int(dest as usize)
551 .map_err(|e| (e, chunk.clone()))?;
552 mov_register!(self, dest as usize, val);
553 }
554 MOVII => {
555 let (dest, src) = decode2!(self.ip_ptr, wide);
556 let src = self
557 .register_int(src as usize)
558 .map_err(|e| (e, chunk.clone()))?;
559 let val = self.register_unref(src as usize);
560 mov_register!(self, dest as usize, val);
561 }
562 GET => self.get(wide).map_err(|e| (e, chunk.clone()))?,
563 SETCOL => self.set_data(wide).map_err(|e| (e, chunk.clone()))?,
564 BMOV => {
565 let (dest, src, len) = decode3!(self.ip_ptr, wide);
566 for i in 0..len as usize {
567 mov_register!(self, dest as usize + i, self.register(src as usize + i));
568 }
569 }
570 LDSC => {
571 let (dest, len, src) = decode3!(self.ip_ptr, wide);
572 if len > 0 {
573 let len = len as usize;
574 let dest = dest as usize;
575 let val = self.register(src as usize);
576 match val {
577 Value::Vector(_) | Value::Pair(_) | Value::List(_, _) | Value::Nil => {
578 let mut iter = val.iter(self);
579 for i in 0..len {
580 if let Some(item) = iter.next() {
581 *self.register_mut(dest + i) = item;
582 } else {
583 *self.register_mut(dest + i) = Value::Undefined;
584 }
585 }
586 }
587 _ => return Err((VMError::new_vm("not a sequence"), chunk)),
588 }
589 }
590 }
591 LDSCR => {
592 let (dest, len, src) = decode3!(self.ip_ptr, wide);
593 if len > 0 {
594 let len = len as usize;
595 let dest = dest as usize;
596 let val = self.register(src as usize);
597 match val {
598 Value::Vector(_) | Value::Pair(_) | Value::List(_, _) | Value::Nil => {
599 let mut iter = val.iter(self);
600 for i in 0..len - 1 {
601 if let Some(item) = iter.next() {
602 *self.register_mut(dest + i) = item;
603 } else {
604 *self.register_mut(dest + i) = Value::Undefined;
605 }
606 }
607 let rest: Vec<Value> = iter.collect();
608 if rest.is_empty() {
609 *self.register_mut(dest + (len - 1)) = Value::Nil;
610 } else {
611 *self.register_mut(dest + (len - 1)) = self.alloc_list_ro(rest);
612 }
613 }
614 _ => return Err((VMError::new_vm("not a sequence"), chunk)),
615 }
616 }
617 }
618 MDSC => {
619 let decodes = decode3!(self.ip_ptr, wide);
620 self.map_destructure(decodes)
621 .map_err(|e| (e, chunk.clone()))?;
622 }
623 COPY => {
624 let (_dest, _src) = decode2!(self.ip_ptr, wide);
625 }
627 FRZ => {
628 let target = decode1!(self.ip_ptr, wide);
629 let target = self.register(target as usize);
630 self.heap_mut().immutable(target);
631 }
632 SET => {
633 let (dest, src) = decode2!(self.ip_ptr, wide);
634 let val = self.register_unref(src as usize);
635 set_register!(self, dest as usize, val);
636 }
637 CONST => {
638 let (dest, src) = decode2!(self.ip_ptr, wide);
639 let val = chunk.constants[src as usize];
640 set_register!(self, dest as usize, val);
641 }
642 DEF => {
643 let src = decode1!(self.ip_ptr, wide);
644 let idx = if wide {
645 decode_u32!(self.ip_ptr)
646 } else {
647 decode_u16!(self.ip_ptr) as u32
648 };
649 let val = self.register(src as usize);
650 self.set_global(idx, val);
651 }
652 DEFV => {
653 let src = decode1!(self.ip_ptr, wide);
654 let idx = if wide {
655 decode_u32!(self.ip_ptr)
656 } else {
657 decode_u16!(self.ip_ptr) as u32
658 };
659 let val = self.register(src as usize);
660 if let Value::Undefined = self.globals.get(idx) {
661 self.set_global(idx, val);
662 }
663 }
664 REFI => {
665 let dest = decode1!(self.ip_ptr, wide);
666 let idx = if wide {
667 decode_u32!(self.ip_ptr)
668 } else {
669 decode_u16!(self.ip_ptr) as u32
670 };
671 mov_register!(self, dest as usize, self.globals.get(idx));
672 }
673 CLRREG => {
674 let dest = decode1!(self.ip_ptr, wide);
675 mov_register!(self, dest as usize, Value::Undefined);
676 }
677 REGT => {
678 let dest = decode1!(self.ip_ptr, wide);
679 set_register!(self, dest as usize, Value::True);
680 }
681 REGF => {
682 let dest = decode1!(self.ip_ptr, wide);
683 set_register!(self, dest as usize, Value::False);
684 }
685 REGN => {
686 let dest = decode1!(self.ip_ptr, wide);
687 set_register!(self, dest as usize, Value::Nil);
688 }
689 REGC => {
690 let dest = decode1!(self.ip_ptr, wide);
691 set_register!(self, dest as usize, Value::Undefined);
692 }
693 REGB => {
694 let (dest, i) = decode2!(self.ip_ptr, wide);
695 set_register!(self, dest as usize, Value::Byte(i as u8));
696 }
697 REGI => {
698 let (dest, i) = decode2!(self.ip_ptr, wide);
699 let i: Value = (i as i64).into();
700 set_register!(self, dest as usize, i);
701 }
702 CLOSE => {
703 let (dest, src) = decode2!(self.ip_ptr, wide);
704 let lambda = self.register_unref(src as usize);
706 let (lambda, caps) = if let Value::Lambda(h) = lambda {
707 let l = self.heap().get_lambda(h);
708 let mut caps = Vec::new();
709 if let Some(captures) = &l.captures {
710 for c in captures {
711 let r = self.register(*c as usize);
712 if let Value::Value(b) = r {
713 caps.push(b);
714 } else {
715 let val = self.new_upval(r);
716 mov_register!(self, *c as usize, val);
717 caps.push(val.get_handle().unwrap());
718 }
719 }
720 }
721 (l, caps)
722 } else {
723 return Err((
724 VMError::new_vm(format!("CLOSE: requires a lambda, got {lambda:?}.")),
725 chunk,
726 ));
727 };
728 let new_closure = self.alloc_closure(lambda, caps);
729 set_register!(self, dest as usize, new_closure);
730 }
731 CALL => {
732 let (lambda, num_args, first_reg) = decode3!(self.ip_ptr, wide);
733 let lambda = self.register(lambda as usize);
734 chunk = self.make_call(lambda, chunk, first_reg, num_args, false)?;
735 self.make_registers();
736 }
737 CALLG => {
738 let idx = if wide {
739 decode_u32!(self.ip_ptr)
740 } else {
741 decode_u16!(self.ip_ptr) as u32
742 };
743 let (num_args, first_reg) = decode2!(self.ip_ptr, wide);
744 let lambda = self.get_global(idx);
745 chunk = self.make_call(lambda, chunk, first_reg, num_args, false)?;
746 self.make_registers();
747 }
748 TCALL => {
749 let (lambda, num_args) = decode2!(self.ip_ptr, wide);
750 let lambda = self.register(lambda as usize);
751 let done = self.tail_builtin_exit(lambda);
752 chunk = self.make_call(lambda, chunk, 0, num_args, true)?;
753 if done {
754 return Ok(());
755 }
756 self.make_registers(); }
758 TCALLG => {
759 let idx = if wide {
760 decode_u32!(self.ip_ptr)
761 } else {
762 decode_u16!(self.ip_ptr) as u32
763 };
764 let num_args = decode1!(self.ip_ptr, wide);
765 let lambda = self.get_global(idx);
766 let done = self.tail_builtin_exit(lambda);
767 chunk = self.make_call(lambda, chunk, 0, num_args, true)?;
768 if done {
769 return Ok(());
770 }
771 self.make_registers(); }
773 CALLM => {
774 let (num_args, first_reg) = decode2!(self.ip_ptr, wide);
775 if let Some(this_fn) = self.this_fn {
776 chunk = self.make_call(this_fn, chunk, first_reg, num_args, false)?;
777 self.make_registers();
778 } else {
779 let line = self.get_line(wide, &chunk);
780 return Err((
781 VMError::new_vm(format!(
782 "CALLM: Not in an existing lambda call, line {}.",
783 line.unwrap_or(0)
784 )),
785 chunk,
786 ));
787 }
788 }
789 TCALLM => {
790 let num_args = decode1!(self.ip_ptr, wide);
791 if let Some(this_fn) = self.this_fn {
792 chunk = self.make_call(this_fn, chunk, 0, num_args, true)?;
793 self.make_registers(); } else {
795 let line = self.get_line(wide, &chunk);
796 return Err((
797 VMError::new_vm(format!(
798 "TCALLM: Not in an existing lambda call, line {}.",
799 line.unwrap_or(0)
800 )),
801 chunk,
802 ));
803 }
804 }
805 JMP => {
806 let jmp = decode1!(self.ip_ptr, wide);
807 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
808 }
809 JMPT => {
810 let (test, jmp) = decode2!(self.ip_ptr, wide);
811 if self.register(test as usize).is_truthy() {
812 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
813 }
814 }
815 JMPF => {
816 let (test, jmp) = decode2!(self.ip_ptr, wide);
817 if self.register(test as usize).is_falsey() {
818 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
819 }
820 }
821 JMPEQ => {
822 let (op1, op2, jmp) = decode3!(self.ip_ptr, wide);
823 let op1 = self
824 .register(op1 as usize)
825 .get_int(self)
826 .map_err(|e| (e, chunk.clone()))?;
827 let op2 = self
828 .register(op2 as usize)
829 .get_int(self)
830 .map_err(|e| (e, chunk.clone()))?;
831 if op1 == op2 {
832 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
833 }
834 }
835 JMPLT => {
836 let (op1, op2, jmp) = decode3!(self.ip_ptr, wide);
837 let op1 = self
838 .register_int(op1 as usize)
839 .map_err(|e| (e, chunk.clone()))?;
840 let op2 = self
841 .register_int(op2 as usize)
842 .map_err(|e| (e, chunk.clone()))?;
843 if op1 < op2 {
844 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
845 }
846 }
847 JMPGT => {
848 let (op1, op2, jmp) = decode3!(self.ip_ptr, wide);
849 let op1 = self
850 .register_int(op1 as usize)
851 .map_err(|e| (e, chunk.clone()))?;
852 let op2 = self
853 .register_int(op2 as usize)
854 .map_err(|e| (e, chunk.clone()))?;
855 if op1 > op2 {
856 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
857 }
858 }
859 JMPU => {
860 let (test, jmp) = decode2!(self.ip_ptr, wide);
861 if self.register(test as usize).is_undef() {
862 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
863 }
864 }
865 JMPNU => {
866 let (test, jmp) = decode2!(self.ip_ptr, wide);
867 if !self.register(test as usize).is_undef() {
868 self.ip_ptr = get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
869 }
870 }
871 JMPRU => {
872 let (test, len, jmp) = decode3!(self.ip_ptr, wide);
873 if len > 0 {
874 let test = test as usize;
875 let len = len as usize;
876 for i in 0..len {
877 if self.register(test + i).is_undef() {
878 self.ip_ptr =
879 get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
880 break;
881 }
882 }
883 }
884 }
885 JMPRNU => {
886 let (test, len, jmp) = decode3!(self.ip_ptr, wide);
887 if len > 0 {
888 let len = len as usize;
889 let test = test as usize;
890 let mut jump = true;
891 for i in 0..len {
892 if self.register(test + i).is_undef() {
893 jump = false;
894 break;
895 }
896 }
897 if jump {
898 self.ip_ptr =
899 get_code_at!(chunk, chunk.jump_table[jmp as usize] as isize);
900 }
901 }
902 }
903 EQ => {
904 let (dest, reg1, reg2) = decode3!(self.ip_ptr, wide);
905 let val = self
906 .is_identical(reg1, reg2)
907 .map_err(|e| (e, chunk.clone()))?;
908 set_register!(self, dest as usize, val);
909 }
910 EQUAL => {
911 let (dest, reg1, reg2) = decode3!(self.ip_ptr, wide);
912 let val = self.is_equal(reg1, reg2).map_err(|e| (e, chunk.clone()))?;
913 set_register!(self, dest as usize, val);
914 }
915 ISERR => {
916 let (dest, testreg) = decode2!(self.ip_ptr, wide);
917 let test = self.register_unref(testreg as usize);
918 let val = if let Value::Error(_) = test {
919 Value::True
920 } else {
921 Value::False
922 };
923 set_register!(self, dest as usize, val);
924 }
925 ISOK => {
926 let (dest, testreg) = decode2!(self.ip_ptr, wide);
927 let test = self.register_unref(testreg as usize);
928 let val = if let Value::Error(_) = test {
929 Value::False
930 } else {
931 Value::True
932 };
933 set_register!(self, dest as usize, val);
934 }
935 NOT => {
936 let (dest, val) = decode2!(self.ip_ptr, wide);
937 let val = self.register(val as usize);
938 let res = if val.is_falsey() {
939 Value::True
940 } else {
941 Value::False
942 };
943 set_register!(self, dest as usize, res);
944 }
945 ERR => {
946 let (key, val) = decode2!(self.ip_ptr, wide);
947 let key = self.register(key as usize);
948 let val = self.register(val as usize);
949 let key_str = if let Value::Keyword(i) = key {
950 self.get_interned(i)
951 } else {
952 return Err((
953 VMError::new_vm(format!("ERR: key must be a keyword, got {key:?}.")),
954 chunk,
955 ));
956 };
957 if let Value::StringConst(i) = val {
958 return Err((
959 VMError {
960 key: key_str,
961 obj: VMErrorObj::Message(self.get_interned(i).to_string()),
962 },
963 chunk,
964 ));
965 } else {
966 return Err((
967 VMError {
968 key: key_str,
969 obj: VMErrorObj::Object(val),
970 },
971 chunk,
972 ));
973 }
974 }
975 MKERR => {
976 let (dest, key, data) = decode3!(self.ip_ptr, wide);
977 let key = self.register(key as usize);
978 let data = self.register(data as usize);
979 let keyword = if let Value::Keyword(i) = key {
980 i
981 } else {
982 return Err((
983 VMError::new_vm(format!("MKERR: key must be a keyword, got {key:?}.")),
984 chunk,
985 ));
986 };
987 let err = Error { keyword, data };
988 let err = self.alloc_error(err);
989 set_register!(self, dest as usize, err);
990 }
991 CCC => {
992 let (lambda, first_reg) = decode2!(self.ip_ptr, wide);
993 let lambda = self.register(lambda as usize);
994 let mut defers = vec![Value::Undefined; self.defers.len()];
995 defers.copy_from_slice(&self.defers[..]);
996 let frame = CallFrame {
997 id: self.callframe_id, chunk: chunk.clone(),
999 ip: self.ip_ptr,
1000 current_ip: self.current_ip_ptr,
1001 stack_top: self.stack_top,
1002 this_fn: self.this_fn,
1003 defers,
1004 on_error: self.on_error,
1005 called: Value::Undefined,
1006 };
1007 let mut stack = Vec::with_capacity(self.stack_max);
1008 stack.resize(self.stack_max, Value::Undefined);
1009 stack[..].copy_from_slice(&self.stack_slice()[0..self.stack_max]);
1010 let k = Continuation {
1011 frame,
1012 arg_reg: self.stack_top + first_reg as usize, stack,
1014 };
1015 let k_obj = self.alloc_continuation(k);
1016 mov_register!(self, (first_reg + 1) as usize, k_obj);
1017 chunk = self.make_call(lambda, chunk, first_reg, 1, false)?;
1018 self.make_registers();
1019 }
1020 DFR => {
1021 let lambda = decode1!(self.ip_ptr, wide);
1022 let lambda = self.register(lambda as usize);
1023 self.defers.push(lambda);
1024 }
1025 DFRPOP => {
1026 if let Some(defer) = self.defers.pop() {
1027 let first_reg = (chunk.input_regs + chunk.extra_regs + 1) as u16;
1028 chunk = self.make_call(defer, chunk, first_reg, 0, false)?;
1029 self.make_registers();
1030 }
1031 }
1032 ONERR => {
1033 let on_error_reg = decode1!(self.ip_ptr, wide);
1034 let on_error = self.register(on_error_reg as usize);
1035 if let Some(oe) = self.on_error {
1036 mov_register!(self, on_error_reg as usize, oe);
1037 } else {
1038 mov_register!(self, on_error_reg as usize, Value::Nil);
1039 }
1040 if let Value::Nil = on_error {
1041 self.on_error = None;
1042 } else {
1043 self.on_error = Some(on_error);
1044 }
1045 }
1046 ADD => binary_math!(self, chunk, self.ip_ptr, |a, b| a + b, wide),
1047 SUB => binary_math!(self, chunk, self.ip_ptr, |a, b| a - b, wide),
1048 MUL => binary_math!(self, chunk, self.ip_ptr, |a, b| a * b, wide),
1049 DIV => div_math!(self, chunk, self.ip_ptr, wide),
1050 NUMEQ => {
1051 compare_numeric_eq!(self, chunk, self.ip_ptr, wide)
1052 }
1053 NUMLT => {
1054 compare_numeric!(self, chunk, self.ip_ptr, |a, b| a < b, wide)
1055 }
1056 NUMLTE => {
1057 compare_numeric!(self, chunk, self.ip_ptr, |a, b| a <= b, wide)
1058 }
1059 NUMGT => {
1060 compare_numeric!(self, chunk, self.ip_ptr, |a, b| a > b, wide)
1061 }
1062 NUMGTE => {
1063 compare_numeric!(self, chunk, self.ip_ptr, |a, b| a >= b, wide)
1064 }
1065 INC => self.inc_val(wide).map_err(|e| (e, chunk.clone()))?,
1066 DEC => self.dec_val(wide).map_err(|e| (e, chunk.clone()))?,
1067 CONS => {
1068 let (dest, op2, op3) = decode3!(self.ip_ptr, wide);
1069 let car = self.register(op2 as usize);
1070 let cdr = self.register(op3 as usize);
1071 let pair = self.alloc_pair(car, cdr);
1072 set_register!(self, dest as usize, pair);
1073 }
1074 CAR => {
1075 let (dest, op) = decode2!(self.ip_ptr, wide);
1076 let op = self.register(op as usize);
1077 match op {
1078 Value::Pair(_) | Value::List(_, _) => {
1079 let (car, _) = op.get_pair(self).expect("Pair not a pair?");
1080 set_register!(self, dest as usize, car);
1081 }
1082 Value::Nil => set_register!(self, dest as usize, Value::Nil),
1083 Value::Error(h) => {
1084 let err = self.get_error(h);
1085 set_register!(self, dest as usize, Value::Keyword(err.keyword));
1086 }
1087 _ => {
1088 return Err((
1089 VMError::new_vm(format!(
1090 "CAR: Not a pair/conscell. {}",
1091 op.display_value(self)
1092 )),
1093 chunk,
1094 ));
1095 }
1096 }
1097 }
1098 CDR => {
1099 let (dest, op) = decode2!(self.ip_ptr, wide);
1100 let op = self.register(op as usize);
1101 match op {
1102 Value::Pair(_) | Value::List(_, _) => {
1103 let (_, cdr) = op.get_pair(self).expect("Pair not a pair?");
1104 set_register!(self, dest as usize, cdr);
1105 }
1106 Value::Nil => set_register!(self, dest as usize, Value::Nil),
1107 Value::Error(h) => {
1108 let err = self.get_error(h);
1109 set_register!(self, dest as usize, err.data);
1110 }
1111 _ => return Err((VMError::new_vm("CDR: Not a pair/conscell."), chunk)),
1112 }
1113 }
1114 LIST => {
1115 self.pause_gc();
1116 let r = self.list(wide).map_err(|e| (e, chunk.clone()));
1117 self.unpause_gc();
1118 r?
1119 }
1120 APND => {
1121 self.pause_gc();
1122 let r = self.append(wide).map_err(|e| (e, chunk.clone()));
1123 self.unpause_gc();
1124 r?;
1125 }
1126 XAR => self.xar(wide).map_err(|e| (e, chunk.clone()))?,
1127 XDR => self.xdr(wide).map_err(|e| (e, chunk.clone()))?,
1128 VEC => {
1129 let (dest, start, end) = decode3!(self.ip_ptr, wide);
1130 if end == start {
1131 let vh = self.alloc_vector(Vec::new());
1132 set_register!(self, dest as usize, vh);
1133 } else {
1134 let mut v = Vec::new();
1135 for i in start..end {
1136 v.push(self.register(i as usize));
1137 }
1138 let vh = self.alloc_vector(v);
1139 set_register!(self, dest as usize, vh);
1140 }
1141 }
1142 MAPMK => {
1143 let (dest, start, end) = decode3!(self.ip_ptr, wide);
1144 let map = if end == start {
1145 VMHashMap::new()
1146 } else if (end - start) % 2 != 0 {
1147 return Err((
1148 VMError::new_vm(
1149 "make-hash: Invalid arguments (must be even, [key val]*)"
1150 .to_string(),
1151 ),
1152 chunk.clone(),
1153 ));
1154 } else {
1155 let mut map = VMHashMap::new();
1156 for i in (start..end).step_by(2) {
1157 map.insert(
1158 self,
1159 self.register(i as usize),
1160 self.register(i as usize + 1),
1161 );
1162 }
1163 map
1164 };
1165 let mh = self.alloc_map(map);
1166 set_register!(self, dest as usize, mh);
1167 }
1168 VECMK => {
1169 let (dest, op) = decode2!(self.ip_ptr, wide);
1170 let len = self
1171 .register(op as usize)
1172 .get_int(self)
1173 .map_err(|e| (e, chunk.clone()))?;
1174 let val = self.alloc_vector(Vec::with_capacity(len as usize));
1175 set_register!(self, dest as usize, val);
1176 }
1177 VECELS => {
1178 let (dest, op) = decode2!(self.ip_ptr, wide);
1179 let len = self
1180 .register(op as usize)
1181 .get_int(self)
1182 .map_err(|e| (e, chunk.clone()))?;
1183 if let Value::Vector(h) = self.register(dest as usize) {
1184 let v = self
1185 .heap_mut()
1186 .get_vector_mut(h)
1187 .map_err(|e| (e, chunk.clone()))?;
1188 v.resize(len as usize, Value::Undefined);
1189 }
1190 }
1191 VECPSH => {
1192 let (dest, op) = decode2!(self.ip_ptr, wide);
1193 let val = self.register(op as usize);
1194 if let Value::Vector(h) = self.register(dest as usize) {
1195 let v = self
1196 .heap_mut()
1197 .get_vector_mut(h)
1198 .map_err(|e| (e, chunk.clone()))?;
1199 v.push(val);
1200 }
1201 }
1202 VECPOP => {
1203 let (vc, dest) = decode2!(self.ip_ptr, wide);
1204 let val = if let Value::Vector(h) = self.register(vc as usize) {
1205 let v = self
1206 .heap_mut()
1207 .get_vector_mut(h)
1208 .map_err(|e| (e, chunk.clone()))?;
1209 if let Some(val) = v.pop() {
1210 val
1211 } else {
1212 return Err((VMError::new_vm("VECPOP: Vector is empty."), chunk));
1213 }
1214 } else {
1215 return Err((VMError::new_vm("VECPOP: Not a vector."), chunk));
1216 };
1217 set_register!(self, dest as usize, val);
1218 }
1219 VECMKD => {
1220 let (dest, len, dfn) = decode3!(self.ip_ptr, wide);
1221 let len = self
1222 .register(len as usize)
1223 .get_int(self)
1224 .map_err(|e| (e, chunk.clone()))?;
1225 let dfn = self.register(dfn as usize);
1226 let mut v = Vec::with_capacity(len as usize);
1227 for _ in 0..len {
1228 v.push(dfn);
1229 }
1230 let val = self.alloc_vector(v);
1231 set_register!(self, dest as usize, val);
1232 }
1233 LEN => {
1234 let (dest, v) = decode2!(self.ip_ptr, wide);
1235 let len = match self.register(v as usize) {
1236 Value::String(h) => {
1237 let mut len: i64 = 0;
1238 for _ in UnicodeSegmentation::graphemes(self.get_string(h), true) {
1239 len += 1;
1240 }
1241 len
1242 }
1243 Value::StringConst(i) => {
1244 let mut len: i64 = 0;
1245 for _ in UnicodeSegmentation::graphemes(self.get_interned(i), true) {
1246 len += 1;
1247 }
1248 len
1249 }
1250 Value::Vector(h) => self.get_vector(h).len() as i64,
1251 Value::List(h, i) => self.get_vector(h).len() as i64 - i as i64,
1252 Value::Pair(h) => {
1253 let mut len: i64 = 1;
1254 let (_, mut cdr) = self.get_pair(h);
1255 while let Value::Pair(h) = cdr {
1256 let (_, c) = self.get_pair(h);
1257 cdr = c;
1258 len += 1;
1259 }
1260 len
1261 }
1262 Value::Map(h) => self.get_map(h).len() as i64,
1263 Value::Nil | Value::False => 0,
1264 _ => 1, };
1270 set_register!(self, dest as usize, len.into());
1271 }
1272 CLR => {
1273 let v = decode1!(self.ip_ptr, wide);
1274 let val = self.register(v as usize);
1275 match val {
1276 Value::Vector(h) => {
1277 let v = self
1278 .heap_mut()
1279 .get_vector_mut(h)
1280 .map_err(|e| (e, chunk.clone()))?;
1281 v.clear();
1282 }
1283 Value::Map(h) => {
1284 self.get_map_mut(h).map_err(|e| (e, chunk.clone()))?.clear();
1285 }
1286 Value::String(h) => {
1287 self.get_string_mut(h)
1288 .map_err(|e| (e, chunk.clone()))?
1289 .clear();
1290 }
1291 Value::StringConst(_) => {
1292 return Err((
1293 VMError::new_vm("can not clear a string const".to_string()),
1294 chunk.clone(),
1295 ));
1296 }
1297 _ => {
1298 return Err((
1299 VMError::new_vm(format!(
1300 "clr: net valid for value of type {}",
1301 val.display_type(self)
1302 )),
1303 chunk.clone(),
1304 ));
1305 }
1306 }
1307 }
1308 STR => {
1309 let (dest, reg1, reg2) = decode3!(self.ip_ptr, wide);
1310 let val = self.mk_str(reg1, reg2).map_err(|e| (e, chunk.clone()))?;
1311 set_register!(self, dest as usize, val);
1312 }
1313 TYPE => {
1314 let (dest, val) = decode2!(self.ip_ptr, wide);
1315 let val = self.register(val as usize);
1316 let t = Value::Keyword(self.intern_static(val.display_type(self)));
1317 set_register!(self, dest as usize, t);
1318 }
1319 _ => {
1320 return Err((VMError::new_vm(format!("Invalid opcode {opcode}")), chunk));
1321 }
1322 }
1323 }
1325 }
1326}