shape_jit/ffi/
iterator.rs1use super::super::context::JITRange;
12use super::super::jit_array::JitArray;
13use super::super::nan_boxing::*;
14use std::collections::HashMap;
15
16pub extern "C" fn jit_iter_done(iter_bits: u64, idx_bits: u64) -> u64 {
24 unsafe {
25 let idx = if is_number(idx_bits) {
26 unbox_number(idx_bits) as i64
27 } else {
28 return TAG_BOOL_TRUE; };
30
31 if idx < 0 {
32 return TAG_BOOL_TRUE;
33 }
34
35 let done = match heap_kind(iter_bits) {
36 Some(HK_ARRAY) => {
37 let arr = jit_unbox::<JitArray>(iter_bits);
38 idx as usize >= arr.len()
39 }
40 Some(HK_STRING) => {
41 let s = jit_unbox::<String>(iter_bits);
42 idx as usize >= s.chars().count()
43 }
44 Some(HK_JIT_OBJECT) => {
45 let obj = jit_unbox::<HashMap<String, u64>>(iter_bits);
47 if let (Some(&start_bits), Some(&end_bits)) = (obj.get("start"), obj.get("end")) {
48 if is_number(start_bits) && is_number(end_bits) {
49 let start = unbox_number(start_bits) as i64;
50 let end = unbox_number(end_bits) as i64;
51 let count = end - start;
52 count <= 0 || idx >= count
53 } else {
54 true
55 }
56 } else {
57 true
58 }
59 }
60 Some(HK_RANGE) => {
61 let range = jit_unbox::<JITRange>(iter_bits);
62 if is_number(range.start) && is_number(range.end) {
63 let start = unbox_number(range.start) as i64;
64 let end = unbox_number(range.end) as i64;
65 let count = end - start;
66 count <= 0 || idx >= count
67 } else {
68 true
69 }
70 }
71 _ => true, };
73
74 if done { TAG_BOOL_TRUE } else { TAG_BOOL_FALSE }
75 }
76}
77
78pub extern "C" fn jit_iter_next(iter_bits: u64, idx_bits: u64) -> u64 {
82 unsafe {
83 let idx = if is_number(idx_bits) {
84 unbox_number(idx_bits) as i64
85 } else {
86 return TAG_NULL;
87 };
88
89 if idx < 0 {
90 return TAG_NULL;
91 }
92
93 match heap_kind(iter_bits) {
94 Some(HK_ARRAY) => {
95 let arr = jit_unbox::<JitArray>(iter_bits);
96 arr.get(idx as usize).copied().unwrap_or(TAG_NULL)
97 }
98 Some(HK_STRING) => {
99 let s = jit_unbox::<String>(iter_bits);
100 if let Some(ch) = s.chars().nth(idx as usize) {
101 jit_box(HK_STRING, ch.to_string())
102 } else {
103 TAG_NULL
104 }
105 }
106 Some(HK_JIT_OBJECT) => {
107 let obj = jit_unbox::<HashMap<String, u64>>(iter_bits);
108 if let (Some(&start_bits), Some(&end_bits)) = (obj.get("start"), obj.get("end")) {
109 if is_number(start_bits) && is_number(end_bits) {
110 let start = unbox_number(start_bits) as i64;
111 let end = unbox_number(end_bits) as i64;
112 let count = end - start;
113 if count <= 0 || idx >= count {
114 TAG_NULL
115 } else {
116 box_number((start + idx) as f64)
117 }
118 } else {
119 TAG_NULL
120 }
121 } else {
122 TAG_NULL
123 }
124 }
125 Some(HK_RANGE) => {
126 let range = jit_unbox::<JITRange>(iter_bits);
127 if is_number(range.start) && is_number(range.end) {
128 let start = unbox_number(range.start) as i64;
129 let end = unbox_number(range.end) as i64;
130 let count = end - start;
131 if count <= 0 || idx >= count {
132 TAG_NULL
133 } else {
134 box_number((start + idx) as f64)
135 }
136 } else {
137 TAG_NULL
138 }
139 }
140 _ => TAG_NULL,
141 }
142 }
143}