1macro_rules! char_as_cell {
6 ($c: expr) => {
7 HeapCellValue::from_bytes(AtomCell::new_char_inlined($c).into_bytes())
8 };
9}
10
11macro_rules! fixnum_as_cell {
12 ($n: expr) => {
13 HeapCellValue::from_bytes($n.into_bytes())
14 };
15}
16
17macro_rules! integer_as_cell {
18 ($n: expr) => {{
19 match $n {
20 Number::Float(_) => unreachable!(),
21 Number::Fixnum(n) => fixnum_as_cell!(n),
22 Number::Rational(r) => typed_arena_ptr_as_cell!(r),
23 Number::Integer(n) => typed_arena_ptr_as_cell!(n),
24 }
25 }};
26}
27
28macro_rules! empty_list_as_cell {
29 () => {
30 atom_as_cell!(atom!("[]"))
32 };
33}
34
35macro_rules! atom_as_cell {
36 ($atom:expr) => {
37 HeapCellValue::from_bytes(AtomCell::build_with($atom.index, 0).into_bytes())
38 };
39 ($atom:expr, $arity:expr) => {
40 HeapCellValue::from_bytes(AtomCell::build_with($atom.index, $arity as u8).into_bytes())
41 };
42}
43
44macro_rules! cell_as_atom {
45 ($cell:expr) => {
46 AtomCell::from_bytes($cell.into_bytes()).get_name()
47 };
48}
49
50macro_rules! cell_as_atom_cell {
51 ($cell:expr) => {
52 AtomCell::from_bytes($cell.into_bytes())
53 };
54}
55
56macro_rules! cell_as_f64_offset {
57 ($cell:expr) => {{
58 let offset = $cell.get_value() as usize;
59 F64Offset::from(offset)
60 }};
61}
62
63macro_rules! cell_as_code_index_offset {
64 ($cell:expr) => {{
65 let offset = $cell.get_value() as usize;
66 CodeIndexOffset::from(offset)
67 }};
68}
69
70macro_rules! cell_as_untyped_arena_ptr {
71 ($cell:expr) => {
72 UntypedArenaPtr::from_bytes($cell.to_untyped_arena_ptr_bytes())
73 };
74}
75
76macro_rules! pstr_loc_as_cell {
77 ($h:expr) => {
78 HeapCellValue::build_with(HeapCellValueTag::PStrLoc, $h as u64)
79 };
80}
81
82macro_rules! list_loc_as_cell {
83 ($h:expr) => {
84 HeapCellValue::build_with(HeapCellValueTag::Lis, $h as u64)
85 };
86}
87
88macro_rules! str_loc_as_cell {
89 ($h:expr) => {
90 HeapCellValue::build_with(HeapCellValueTag::Str, $h as u64)
91 };
92}
93
94macro_rules! stack_loc {
95 (OrFrame, $b:expr, $idx:expr) => ({
96 $b + prelude_size::<OrFrame>() + $idx * std::mem::size_of::<HeapCellValue>()
97 });
98 (AndFrame, $e:expr, $idx:expr) => ({
99 $e + prelude_size::<AndFrame>() + ($idx - 1) * std::mem::size_of::<HeapCellValue>()
100 });
101}
102
103macro_rules! stack_loc_as_cell {
104 (OrFrame, $b:expr, $idx:expr) => {
105 stack_loc_as_cell!(stack_loc!(OrFrame, $b, $idx))
106 };
107 (AndFrame, $b:expr, $idx:expr) => {
108 stack_loc_as_cell!(stack_loc!(AndFrame, $b, $idx))
109 };
110 ($h:expr) => {
111 HeapCellValue::build_with(HeapCellValueTag::StackVar, $h as u64)
112 };
113}
114
115macro_rules! heap_loc_as_cell {
116 ($h:expr) => {
117 HeapCellValue::build_with(HeapCellValueTag::Var, $h as u64)
118 };
119}
120
121macro_rules! attr_var_as_cell {
122 ($h:expr) => {
123 HeapCellValue::build_with(HeapCellValueTag::AttrVar, $h as u64)
124 };
125}
126
127#[allow(unused)]
128macro_rules! attr_var_loc_as_cell {
129 ($h:expr) => {
130 HeapCellValue::build_with(HeapCellValueTag::AttrVar, $h as u64)
131 };
132}
133
134macro_rules! typed_arena_ptr_as_cell {
135 ($ptr:expr) => {
136 raw_ptr_as_cell!($ptr.header_ptr())
137 };
138}
139
140macro_rules! raw_ptr_as_cell {
141 ($ptr:expr) => {{
142 let ptr: *const _ = $ptr;
144 HeapCellValue::from_ptr_addr(ptr.expose_provenance())
148 }};
149}
150
151macro_rules! untyped_arena_ptr_as_cell {
152 ($ptr:expr) => {
153 HeapCellValue::from_bytes(UntypedArenaPtr::into_bytes($ptr))
154 };
155}
156
157macro_rules! stream_as_cell {
158 ($ptr:expr) => {
159 raw_ptr_as_cell!($ptr.as_ptr())
160 };
161}
162
163macro_rules! cell_as_stream {
164 ($cell:expr) => {{
165 let ptr = cell_as_untyped_arena_ptr!($cell);
166 Stream::from_tag(ptr.get_tag(), ptr)
167 }};
168}
169
170macro_rules! cell_as_load_state_payload {
171 ($cell:expr) => {{
172 let ptr = cell_as_untyped_arena_ptr!($cell);
173 unsafe { ptr.as_typed_ptr::<LiveLoadState>() }
174 }};
175}
176
177macro_rules! match_untyped_arena_ptr_pat_body {
178 ($ptr:ident, Integer, $n:ident, $code:expr) => {{
179 let $n = unsafe { $ptr.as_typed_ptr::<Integer>() };
180 #[allow(unused_braces)]
181 $code
182 }};
183 ($ptr:ident, Rational, $n:ident, $code:expr) => {{
184 let $n = unsafe { $ptr.as_typed_ptr::<Rational>() };
185 #[allow(unused_braces)]
186 $code
187 }};
188 ($ptr:ident, OssifiedOpDir, $n:ident, $code:expr) => {{
189 let $n = unsafe { $ptr.as_typed_ptr::<OssifiedOpDir>() };
190 #[allow(unused_braces)]
191 $code
192 }};
193 ($ptr:ident, LiveLoadState, $n:ident, $code:expr) => {{
194 let $n = unsafe { $ptr.as_typed_ptr::<LiveLoadState>() };
195 #[allow(unused_braces)]
196 $code
197 }};
198 ($ptr:ident, Stream, $s:ident, $code:expr) => {{
199 let $s = Stream::from_tag($ptr.get_tag(), $ptr);
200 #[allow(unused_braces)]
201 $code
202 }};
203 ($ptr:ident, TcpListener, $listener:ident, $code:expr) => {{
204 #[allow(unused_mut)]
205 let mut $listener = unsafe { $ptr.as_typed_ptr::<TcpListener>() };
206 #[allow(unused_braces)]
207 $code
208 }};
209 ($ptr:ident, HttpListener, $listener:ident, $code:expr) => {{
210 #[allow(unused_mut)]
211 let mut $listener = unsafe { $ptr.as_typed_ptr::<HttpListener>() };
212 #[allow(unused_braces)]
213 $code
214 }};
215 ($ptr:ident, HttpResponse, $listener:ident, $code:expr) => {{
216 #[allow(unused_mut)]
217 let mut $listener = unsafe { $ptr.as_typed_ptr::<HttpResponse>() };
218 #[allow(unused_braces)]
219 $code
220 }};
221 ($ptr:ident, PipeReader, $listener:ident, $code:expr) => {{
222 #[allow(unused_mut)]
223 let mut $listener = unsafe { $ptr.as_typed_ptr::<PipeReader>() };
224 #[allow(unused_braces)]
225 $code
226 }};
227 ($ptr:ident, PipeWriter, $listener:ident, $code:expr) => {{
228 #[allow(unused_mut)]
229 let mut $listener = unsafe { $ptr.as_typed_ptr::<PipeWriter>() };
230 #[allow(unused_braces)]
231 $code
232 }};
233 ($ptr:ident, ChildProcess, $listener:ident, $code:expr) => {{
234 #[allow(unused_mut)]
235 let mut $listener = unsafe { $ptr.as_typed_ptr::<std::process::Child>() };
236 #[allow(unused_braces)]
237 $code
238 }};
239 ($ptr:ident, $($tags:tt)|+, $s:ident, $code:expr) => {{
240 let $s = Stream::from_tag($ptr.get_tag(), $ptr);
241 #[allow(unused_braces)]
242 $code
243 }};
244}
245
246macro_rules! match_untyped_arena_ptr_pat {
247 (Stream) => {
248 ArenaHeaderTag::InputFileStream
249 | ArenaHeaderTag::OutputFileStream
250 | ArenaHeaderTag::NamedTcpStream
251 | ArenaHeaderTag::NamedTlsStream
252 | ArenaHeaderTag::HttpReadStream
253 | ArenaHeaderTag::HttpWriteStream
254 | ArenaHeaderTag::ReadlineStream
255 | ArenaHeaderTag::StaticStringStream
256 | ArenaHeaderTag::ByteStream
257 | ArenaHeaderTag::CallbackStream
258 | ArenaHeaderTag::InputChannelStream
259 | ArenaHeaderTag::StandardOutputStream
260 | ArenaHeaderTag::StandardErrorStream
261 | ArenaHeaderTag::PipeReader
262 | ArenaHeaderTag::PipeWriter
263 };
264 ($tag:ident) => {
265 ArenaHeaderTag::$tag
266 };
267}
268
269macro_rules! match_untyped_arena_ptr {
270 ($ptr:expr, $( ($(ArenaHeaderTag::$tag:tt)|+, $n:ident) => $code:block $(,)?)+ $(_ => $misc_code:expr $(,)?)?) => ({
271 let ptr_id = $ptr;
272
273 #[allow(clippy::toplevel_ref_arg)]
274 match ptr_id.get_tag() {
275 $($(match_untyped_arena_ptr_pat!($tag) => {
276 match_untyped_arena_ptr_pat_body!(ptr_id, $tag, $n, $code)
277 })+)+
278 $(_ => $misc_code)?
279 }
280 });
281}
282
283macro_rules! read_heap_cell_pat_body {
284 ($cell:ident, Cons, $n:ident, $code:expr) => {{
285 let $n = cell_as_untyped_arena_ptr!($cell);
286 #[allow(unused_braces)]
287 $code
288 }};
289 ($cell:ident, F64Offset, $n:ident, $code:expr) => {{
290 let $n = cell_as_f64_offset!($cell);
291 #[allow(unused_braces)]
292 $code
293 }};
294 ($cell:ident, CodeIndexOffset, $n:ident, $code:expr) => {{
295 let $n = cell_as_code_index_offset!($cell);
296 #[allow(unused_braces)]
297 $code
298 }};
299 ($cell:ident, Atom, ($name:ident, $arity:ident), $code:expr) => {{
300 let ($name, $arity) = cell_as_atom_cell!($cell).get_name_and_arity();
301 #[allow(unused_braces)]
302 $code
303 }};
304 ($cell:ident, Fixnum, $value:ident, $code:expr) => {{
305 let $value = Fixnum::from_bytes($cell.into_bytes());
306 #[allow(unused_braces)]
307 $code
308 }};
309 ($cell:ident, CutPoint, $value:ident, $code:expr) => {{
310 let $value = Fixnum::from_bytes($cell.into_bytes());
311 #[allow(unused_braces)]
312 $code
313 }};
314 ($cell:ident, Fixnum | CutPoint, $value:ident, $code:expr) => {{
315 let $value = Fixnum::from_bytes($cell.into_bytes());
316 #[allow(unused_braces)]
317 $code
318 }};
319 ($cell:ident, CutPoint | Fixnum, $value:ident, $code:expr) => {{
320 let $value = Fixnum::from_bytes($cell.into_bytes());
321 #[allow(unused_braces)]
322 $code
323 }};
324 ($cell:ident, $($tags:tt)|+, $value:ident, $code:expr) => {{
325 let $value = $cell.get_value() as usize;
326 #[allow(unused_braces)]
327 $code
328 }};
329}
330
331macro_rules! read_heap_cell_pat {
332 (($(HeapCellValueTag::$tag:tt)|+, $n:tt)) => {
333 $(HeapCellValueTag::$tag)|+
334 };
335 (($(HeapCellValueTag::$tag:tt)|+)) => {
336 $(HeapCellValueTag::$tag)|+
337 };
338 (_) => { _ };
339}
340
341macro_rules! read_heap_cell_pat_expander {
342 ($cell_id:ident, ($(HeapCellValueTag::$tag:tt)|+, $n:tt), $code:block) => ({
343 read_heap_cell_pat_body!($cell_id, $($tag)|+, $n, $code)
344 });
345 ($cell_id:ident, ($(HeapCellValueTag::$tag:tt)|+), $code:block) => ({
346 $code
347 });
348 ($cell_id:ident, _, $code:block) => ({
349 $code
350 });
351}
352
353macro_rules! read_heap_cell {
354 ($cell:expr, $($pat:tt $(if $guard_expr:expr)? => $code:block $(,)?)+) => ({
355 let cell_id = $cell;
356
357 match cell_id.get_tag() {
358 $(read_heap_cell_pat!($pat) $(if $guard_expr)? => {
359 read_heap_cell_pat_expander!(cell_id, $pat, $code)
360 })+
361 }
362 });
363}
364
365macro_rules! compare_number_instr {
366 ($cmp: expr, $at_1: expr, $at_2: expr) => {{
367 $cmp.set_terms($at_1, $at_2);
368 ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp)).to_instr()
369 }};
370}
371
372macro_rules! interm {
373 ($n: expr) => {
374 ArithmeticTerm::Interm($n)
375 };
376}
377
378macro_rules! ar_reg {
379 ($r: expr) => {
380 ArithmeticTerm::Reg($r)
381 };
382}
383
384macro_rules! unmark_cell_bits {
385 ($e:expr) => {{
386 let mut result = $e;
387
388 result.set_mark_bit(false);
389 result.set_forwarding_bit(false);
390
391 result
392 }};
393}
394
395macro_rules! index_store {
396 ($code_dir:expr, $op_dir:expr, $modules:expr) => {
397 IndexStore {
398 code_dir: $code_dir,
399 extensible_predicates: ExtensiblePredicates::with_hasher(FxBuildHasher::default()),
400 local_extensible_predicates: LocalExtensiblePredicates::with_hasher(
401 FxBuildHasher::default(),
402 ),
403 global_variables: GlobalVarDir::with_hasher(FxBuildHasher::default()),
404 goal_expansion_indices: GoalExpansionIndices::with_hasher(FxBuildHasher::default()),
405 meta_predicates: MetaPredicateDir::with_hasher(FxBuildHasher::default()),
406 modules: $modules,
407 op_dir: $op_dir,
408 streams: StreamDir::new(),
409 stream_aliases: StreamAliasDir::with_hasher(FxBuildHasher::default()),
410 }
411 };
412}
413
414macro_rules! unify {
415 ($machine_st:expr, $($value:expr),*) => {{
416 $($machine_st.pdl.push($value);)*
417 $machine_st.unify()
418 }};
419}
420
421macro_rules! unify_fn {
422 ($machine_st:expr, $($value:expr),*) => {{
423 $($machine_st.pdl.push($value);)*
424 ($machine_st.unify_fn)(&mut $machine_st)
425 }};
426}
427
428macro_rules! unify_with_occurs_check {
429 ($machine_st:expr, $($value:expr),*) => {{
430 $($machine_st.pdl.push($value);)*
431 $machine_st.unify_with_occurs_check()
432 }};
433}
434
435macro_rules! compare_term_test {
436 ($machine_st:expr, $e1:expr, $e2:expr) => {{
437 $machine_st.pdl.push($e2);
438 $machine_st.pdl.push($e1);
439
440 $machine_st.compare_term_test(VarComparison::Distinct)
441 }};
442 ($machine_st:expr, $e1:expr, $e2:expr, $var_comparison:expr) => {{
443 $machine_st.pdl.push($e2);
444 $machine_st.pdl.push($e1);
445
446 $machine_st.compare_term_test($var_comparison)
447 }};
448}
449
450macro_rules! step_or_resource_error {
451 ($machine_st:expr, $val:expr) => {{
452 match $val {
453 Ok(r) => r,
454 Err(err_loc) => {
455 $machine_st.throw_resource_error(err_loc);
456 return;
457 }
458 }
459 }};
460 ($machine_st:expr, $val:expr, $fail:block) => {{
461 match $val {
462 Ok(r) => r,
463 Err(err_loc) => {
464 $machine_st.throw_resource_error(err_loc);
465 $fail
466 }
467 }
468 }};
469}
470
471macro_rules! resource_error_call_result {
472 ($machine_st:expr, $val:expr) => {
473 step_or_resource_error!($machine_st, $val, {
474 return Err(vec![]);
475 })
476 };
477}
478
479macro_rules! heap_index {
480 ($idx:expr) => {
481 ($idx) * std::mem::size_of::<HeapCellValue>()
482 };
483}
484
485macro_rules! cell_index {
486 ($idx:expr) => {
487 (($idx) / std::mem::size_of::<HeapCellValue>())
488 };
489}