1use wasm_encoder::{BlockType, Function, Instruction, ValType};
8
9use crate::types::*;
10
11pub const RT_ALLOC: u32 = 0;
19
20pub const RT_VAL_NIL: u32 = 1;
24
25pub const RT_VAL_NUMBER: u32 = 2;
41
42pub const RT_VAL_BOOL: u32 = 3;
44
45pub const RT_VAL_STRING: u32 = 4;
47
48pub const RT_VAL_LIST: u32 = 5;
50
51pub const RT_VAL_RECORD: u32 = 6;
53
54pub const RT_VAL_VARIANT: u32 = 7;
56
57pub const RT_VAL_ACTION_REF: u32 = 8;
59
60pub const RT_VAL_TAG: u32 = 9;
62
63pub const RT_VAL_GET_NUMBER: u32 = 10;
68
69pub const RT_VAL_GET_W1: u32 = 11;
71
72pub const RT_VAL_GET_W2: u32 = 12;
74
75pub const RT_VAL_EQ: u32 = 13;
77
78pub const RT_VAL_TO_STRING: u32 = 14;
81
82pub const RT_VAL_STRING_CONCAT: u32 = 15;
84
85pub const RT_VAL_ADD: u32 = 16;
87pub const RT_VAL_SUB: u32 = 17;
89pub const RT_VAL_MUL: u32 = 18;
91pub const RT_VAL_DIV: u32 = 19;
93pub const RT_VAL_MOD: u32 = 20;
95pub const RT_VAL_NEG: u32 = 21;
97pub const RT_VAL_NOT: u32 = 22;
99
100pub const RT_VAL_LT: u32 = 23;
103pub const RT_VAL_LE: u32 = 24;
104pub const RT_VAL_GT: u32 = 25;
105pub const RT_VAL_GE: u32 = 26;
106
107pub const RT_VAL_RECORD_GET: u32 = 27;
109
110pub const RT_VAL_LIST_GET: u32 = 28;
112
113pub const RT_CHECK_NAN: u32 = 29;
115
116pub const RT_MEMCMP: u32 = 30;
119
120pub const RT_FUNC_COUNT: u32 = 31;
122
123#[inline]
127pub const fn rt_func_idx(rt_offset: u32) -> u32 {
128 IMPORT_COUNT + rt_offset
129}
130
131pub fn emit_alloc(oom_ptr: u32, oom_len: u32) -> Function {
140 let mut f = Function::new(vec![
141 (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
145 f.instruction(&Instruction::GlobalGet(GLOBAL_HEAP_PTR));
147 f.instruction(&Instruction::LocalSet(1));
148 f.instruction(&Instruction::GlobalGet(GLOBAL_HEAP_PTR));
150 f.instruction(&Instruction::LocalGet(0)); f.instruction(&Instruction::I32Add);
152 f.instruction(&Instruction::LocalSet(2));
153
154 f.instruction(&Instruction::LocalGet(2));
157 f.instruction(&Instruction::MemorySize(0));
158 f.instruction(&Instruction::I32Const(16)); f.instruction(&Instruction::I32Shl);
160 f.instruction(&Instruction::I32GtU);
161 f.instruction(&Instruction::If(BlockType::Empty));
162 {
163 f.instruction(&Instruction::LocalGet(2));
165 f.instruction(&Instruction::MemorySize(0));
166 f.instruction(&Instruction::I32Const(16));
167 f.instruction(&Instruction::I32Shl);
168 f.instruction(&Instruction::I32Sub);
169 f.instruction(&Instruction::I32Const(65535));
170 f.instruction(&Instruction::I32Add);
171 f.instruction(&Instruction::I32Const(16));
172 f.instruction(&Instruction::I32ShrU);
173 f.instruction(&Instruction::LocalSet(3));
174
175 f.instruction(&Instruction::MemorySize(0));
177 f.instruction(&Instruction::LocalGet(3));
178 f.instruction(&Instruction::I32Add);
179 f.instruction(&Instruction::I32Const(MAX_MEMORY_PAGES as i32));
180 f.instruction(&Instruction::I32GtU);
181 f.instruction(&Instruction::If(BlockType::Empty));
182 {
183 f.instruction(&Instruction::I32Const(oom_ptr as i32));
185 f.instruction(&Instruction::I32Const(oom_len as i32));
186 f.instruction(&Instruction::Call(IMPORT_TRAP));
187 f.instruction(&Instruction::Unreachable);
188 }
189 f.instruction(&Instruction::End);
190
191 f.instruction(&Instruction::LocalGet(3));
193 f.instruction(&Instruction::MemoryGrow(0));
194 f.instruction(&Instruction::I32Const(-1));
196 f.instruction(&Instruction::I32Eq);
197 f.instruction(&Instruction::If(BlockType::Empty));
198 {
199 f.instruction(&Instruction::I32Const(oom_ptr as i32));
200 f.instruction(&Instruction::I32Const(oom_len as i32));
201 f.instruction(&Instruction::Call(IMPORT_TRAP));
202 f.instruction(&Instruction::Unreachable);
203 }
204 f.instruction(&Instruction::End);
205 }
206 f.instruction(&Instruction::End);
207
208 f.instruction(&Instruction::LocalGet(2));
210 f.instruction(&Instruction::GlobalSet(GLOBAL_HEAP_PTR));
211 f.instruction(&Instruction::LocalGet(1));
213 f.instruction(&Instruction::End);
214 f
215}
216
217pub fn emit_val_nil() -> Function {
219 let mut f = Function::new(vec![(1, ValType::I32)]); f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
222 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
223 f.instruction(&Instruction::LocalSet(0));
224 f.instruction(&Instruction::LocalGet(0));
226 f.instruction(&Instruction::I32Const(TAG_NIL));
227 f.instruction(&Instruction::I32Store(memarg(0, 2)));
228 f.instruction(&Instruction::LocalGet(0));
230 f.instruction(&Instruction::End);
231 f
232}
233
234pub fn emit_val_number() -> Function {
239 let mut f = Function::new(vec![(1, ValType::I32)]); f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
242 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
243 f.instruction(&Instruction::LocalSet(2));
244 f.instruction(&Instruction::LocalGet(2));
246 f.instruction(&Instruction::I32Const(TAG_NUMBER));
247 f.instruction(&Instruction::I32Store(memarg(0, 2)));
248 f.instruction(&Instruction::LocalGet(2));
250 f.instruction(&Instruction::LocalGet(0)); f.instruction(&Instruction::I32Store(memarg(4, 2)));
252 f.instruction(&Instruction::LocalGet(2));
254 f.instruction(&Instruction::LocalGet(1)); f.instruction(&Instruction::I32Store(memarg(8, 2)));
256 f.instruction(&Instruction::LocalGet(2));
258 f.instruction(&Instruction::End);
259 f
260}
261
262pub fn emit_val_bool() -> Function {
264 let mut f = Function::new(vec![(1, ValType::I32)]); f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
267 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
268 f.instruction(&Instruction::LocalSet(1));
269 f.instruction(&Instruction::LocalGet(1));
271 f.instruction(&Instruction::I32Const(TAG_BOOL));
272 f.instruction(&Instruction::I32Store(memarg(0, 2)));
273 f.instruction(&Instruction::LocalGet(1));
275 f.instruction(&Instruction::LocalGet(0));
276 f.instruction(&Instruction::I32Store(memarg(4, 2)));
277 f.instruction(&Instruction::LocalGet(1));
279 f.instruction(&Instruction::End);
280 f
281}
282
283pub fn emit_val_string() -> Function {
285 let mut f = Function::new(vec![(1, ValType::I32)]); f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
288 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
289 f.instruction(&Instruction::LocalSet(2));
290 f.instruction(&Instruction::LocalGet(2));
292 f.instruction(&Instruction::I32Const(TAG_STRING));
293 f.instruction(&Instruction::I32Store(memarg(0, 2)));
294 f.instruction(&Instruction::LocalGet(2));
296 f.instruction(&Instruction::LocalGet(0));
297 f.instruction(&Instruction::I32Store(memarg(4, 2)));
298 f.instruction(&Instruction::LocalGet(2));
300 f.instruction(&Instruction::LocalGet(1));
301 f.instruction(&Instruction::I32Store(memarg(8, 2)));
302 f.instruction(&Instruction::LocalGet(2));
304 f.instruction(&Instruction::End);
305 f
306}
307
308pub fn emit_val_list() -> Function {
310 let mut f = Function::new(vec![(1, ValType::I32)]);
311 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
312 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
313 f.instruction(&Instruction::LocalSet(2));
314 f.instruction(&Instruction::LocalGet(2));
315 f.instruction(&Instruction::I32Const(TAG_LIST));
316 f.instruction(&Instruction::I32Store(memarg(0, 2)));
317 f.instruction(&Instruction::LocalGet(2));
318 f.instruction(&Instruction::LocalGet(0));
319 f.instruction(&Instruction::I32Store(memarg(4, 2)));
320 f.instruction(&Instruction::LocalGet(2));
321 f.instruction(&Instruction::LocalGet(1));
322 f.instruction(&Instruction::I32Store(memarg(8, 2)));
323 f.instruction(&Instruction::LocalGet(2));
324 f.instruction(&Instruction::End);
325 f
326}
327
328pub fn emit_val_record() -> Function {
330 let mut f = Function::new(vec![(1, ValType::I32)]);
331 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
332 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
333 f.instruction(&Instruction::LocalSet(2));
334 f.instruction(&Instruction::LocalGet(2));
335 f.instruction(&Instruction::I32Const(TAG_RECORD));
336 f.instruction(&Instruction::I32Store(memarg(0, 2)));
337 f.instruction(&Instruction::LocalGet(2));
338 f.instruction(&Instruction::LocalGet(0));
339 f.instruction(&Instruction::I32Store(memarg(4, 2)));
340 f.instruction(&Instruction::LocalGet(2));
341 f.instruction(&Instruction::LocalGet(1));
342 f.instruction(&Instruction::I32Store(memarg(8, 2)));
343 f.instruction(&Instruction::LocalGet(2));
344 f.instruction(&Instruction::End);
345 f
346}
347
348pub fn emit_val_variant() -> Function {
350 let mut f = Function::new(vec![(1, ValType::I32)]);
351 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
352 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
353 f.instruction(&Instruction::LocalSet(2));
354 f.instruction(&Instruction::LocalGet(2));
355 f.instruction(&Instruction::I32Const(TAG_VARIANT));
356 f.instruction(&Instruction::I32Store(memarg(0, 2)));
357 f.instruction(&Instruction::LocalGet(2));
358 f.instruction(&Instruction::LocalGet(0));
359 f.instruction(&Instruction::I32Store(memarg(4, 2)));
360 f.instruction(&Instruction::LocalGet(2));
361 f.instruction(&Instruction::LocalGet(1));
362 f.instruction(&Instruction::I32Store(memarg(8, 2)));
363 f.instruction(&Instruction::LocalGet(2));
364 f.instruction(&Instruction::End);
365 f
366}
367
368pub fn emit_val_action_ref() -> Function {
370 let mut f = Function::new(vec![(1, ValType::I32)]);
371 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
372 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
373 f.instruction(&Instruction::LocalSet(1));
374 f.instruction(&Instruction::LocalGet(1));
375 f.instruction(&Instruction::I32Const(TAG_ACTION_REF));
376 f.instruction(&Instruction::I32Store(memarg(0, 2)));
377 f.instruction(&Instruction::LocalGet(1));
378 f.instruction(&Instruction::LocalGet(0));
379 f.instruction(&Instruction::I32Store(memarg(4, 2)));
380 f.instruction(&Instruction::LocalGet(1));
381 f.instruction(&Instruction::End);
382 f
383}
384
385pub fn emit_val_tag() -> Function {
387 let mut f = Function::new(vec![]);
388 f.instruction(&Instruction::LocalGet(0));
389 f.instruction(&Instruction::I32Load(memarg(0, 2)));
390 f.instruction(&Instruction::End);
391 f
392}
393
394pub fn emit_val_get_number() -> Function {
401 let mut f = Function::new(vec![]);
403 f.instruction(&Instruction::LocalGet(0));
404 f.instruction(&Instruction::I32Load(memarg(4, 2)));
405 f.instruction(&Instruction::End);
406 f
407}
408
409pub fn emit_val_get_w1() -> Function {
411 let mut f = Function::new(vec![]);
412 f.instruction(&Instruction::LocalGet(0));
413 f.instruction(&Instruction::I32Load(memarg(4, 2)));
414 f.instruction(&Instruction::End);
415 f
416}
417
418pub fn emit_val_get_w2() -> Function {
420 let mut f = Function::new(vec![]);
421 f.instruction(&Instruction::LocalGet(0));
422 f.instruction(&Instruction::I32Load(memarg(8, 2)));
423 f.instruction(&Instruction::End);
424 f
425}
426
427pub fn emit_val_eq() -> Function {
429 let mut f = Function::new(vec![
434 (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
438
439 f.instruction(&Instruction::LocalGet(0));
441 f.instruction(&Instruction::I32Load(memarg(0, 2)));
442 f.instruction(&Instruction::LocalSet(2));
443 f.instruction(&Instruction::LocalGet(1));
445 f.instruction(&Instruction::I32Load(memarg(0, 2)));
446 f.instruction(&Instruction::LocalSet(3));
447
448 f.instruction(&Instruction::LocalGet(2));
450 f.instruction(&Instruction::LocalGet(3));
451 f.instruction(&Instruction::I32Ne);
452 f.instruction(&Instruction::If(BlockType::Empty));
453 f.instruction(&Instruction::I32Const(0));
454 f.instruction(&Instruction::LocalSet(4));
455 f.instruction(&Instruction::Else);
456
457 f.instruction(&Instruction::LocalGet(2));
460 f.instruction(&Instruction::I32Const(TAG_NIL));
461 f.instruction(&Instruction::I32Eq);
462 f.instruction(&Instruction::If(BlockType::Empty));
463 f.instruction(&Instruction::I32Const(1));
464 f.instruction(&Instruction::LocalSet(4));
465 f.instruction(&Instruction::Else);
466
467 f.instruction(&Instruction::LocalGet(2));
469 f.instruction(&Instruction::I32Const(TAG_NUMBER));
470 f.instruction(&Instruction::I32Eq);
471 f.instruction(&Instruction::If(BlockType::Empty));
472 f.instruction(&Instruction::LocalGet(0));
474 f.instruction(&Instruction::I32Load(memarg(4, 2)));
475 f.instruction(&Instruction::LocalGet(1));
476 f.instruction(&Instruction::I32Load(memarg(4, 2)));
477 f.instruction(&Instruction::I32Eq);
478 f.instruction(&Instruction::LocalGet(0));
480 f.instruction(&Instruction::I32Load(memarg(8, 2)));
481 f.instruction(&Instruction::LocalGet(1));
482 f.instruction(&Instruction::I32Load(memarg(8, 2)));
483 f.instruction(&Instruction::I32Eq);
484 f.instruction(&Instruction::I32And);
485 f.instruction(&Instruction::LocalSet(4));
486 f.instruction(&Instruction::Else);
487
488 f.instruction(&Instruction::LocalGet(2));
490 f.instruction(&Instruction::I32Const(TAG_BOOL));
491 f.instruction(&Instruction::I32Eq);
492 f.instruction(&Instruction::If(BlockType::Empty));
493 f.instruction(&Instruction::LocalGet(0));
494 f.instruction(&Instruction::I32Load(memarg(4, 2)));
495 f.instruction(&Instruction::LocalGet(1));
496 f.instruction(&Instruction::I32Load(memarg(4, 2)));
497 f.instruction(&Instruction::I32Eq);
498 f.instruction(&Instruction::LocalSet(4));
499 f.instruction(&Instruction::Else);
500
501 f.instruction(&Instruction::LocalGet(2));
503 f.instruction(&Instruction::I32Const(TAG_STRING));
504 f.instruction(&Instruction::I32Eq);
505 f.instruction(&Instruction::If(BlockType::Empty));
506 f.instruction(&Instruction::LocalGet(0));
508 f.instruction(&Instruction::I32Load(memarg(8, 2)));
509 f.instruction(&Instruction::LocalGet(1));
510 f.instruction(&Instruction::I32Load(memarg(8, 2)));
511 f.instruction(&Instruction::I32Eq);
512 f.instruction(&Instruction::If(BlockType::Empty));
513 f.instruction(&Instruction::LocalGet(0));
516 f.instruction(&Instruction::I32Load(memarg(4, 2))); f.instruction(&Instruction::LocalGet(1));
518 f.instruction(&Instruction::I32Load(memarg(4, 2))); f.instruction(&Instruction::LocalGet(0));
520 f.instruction(&Instruction::I32Load(memarg(8, 2))); f.instruction(&Instruction::Call(rt_func_idx(RT_MEMCMP)));
522 f.instruction(&Instruction::LocalSet(4));
523 f.instruction(&Instruction::Else);
524 f.instruction(&Instruction::I32Const(0));
525 f.instruction(&Instruction::LocalSet(4));
526 f.instruction(&Instruction::End); f.instruction(&Instruction::Else);
528
529 f.instruction(&Instruction::LocalGet(0));
531 f.instruction(&Instruction::I32Load(memarg(4, 2)));
532 f.instruction(&Instruction::LocalGet(1));
533 f.instruction(&Instruction::I32Load(memarg(4, 2)));
534 f.instruction(&Instruction::I32Eq);
535 f.instruction(&Instruction::LocalGet(0));
536 f.instruction(&Instruction::I32Load(memarg(8, 2)));
537 f.instruction(&Instruction::LocalGet(1));
538 f.instruction(&Instruction::I32Load(memarg(8, 2)));
539 f.instruction(&Instruction::I32Eq);
540 f.instruction(&Instruction::I32And);
541 f.instruction(&Instruction::LocalSet(4));
542
543 f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::LocalGet(4));
552 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_BOOL)));
553 f.instruction(&Instruction::End);
554 f
555}
556
557pub fn emit_val_to_string(data: &DataSegmentTracker) -> Function {
562 let mut f = Function::new(vec![
565 (1, ValType::I32), (1, ValType::F64), (1, ValType::I32), (1, ValType::I64), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
575 f.instruction(&Instruction::LocalGet(0));
576 f.instruction(&Instruction::I32Load(memarg(0, 2)));
577 f.instruction(&Instruction::LocalSet(1));
578
579 f.instruction(&Instruction::LocalGet(1));
581 f.instruction(&Instruction::I32Const(TAG_STRING));
582 f.instruction(&Instruction::I32Eq);
583 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
584 f.instruction(&Instruction::LocalGet(0));
585 f.instruction(&Instruction::Else);
586
587 f.instruction(&Instruction::LocalGet(1));
589 f.instruction(&Instruction::I32Const(TAG_NUMBER));
590 f.instruction(&Instruction::I32Eq);
591 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
592
593 f.instruction(&Instruction::LocalGet(0));
595 f.instruction(&Instruction::F64Load(memarg(4, 2)));
596 f.instruction(&Instruction::LocalSet(2));
597
598 f.instruction(&Instruction::LocalGet(2));
601 f.instruction(&Instruction::LocalGet(2));
602 f.instruction(&Instruction::F64Floor);
603 f.instruction(&Instruction::F64Eq);
604 f.instruction(&Instruction::LocalGet(2));
606 f.instruction(&Instruction::LocalGet(2));
607 f.instruction(&Instruction::F64Eq);
608 f.instruction(&Instruction::I32And);
609 f.instruction(&Instruction::LocalGet(2));
611 f.instruction(&Instruction::F64Abs);
612 f.instruction(&Instruction::F64Const(9007199254740992.0)); f.instruction(&Instruction::F64Lt);
614 f.instruction(&Instruction::I32And);
615
616 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
617
618 f.instruction(&Instruction::LocalGet(2));
621 f.instruction(&Instruction::F64Const(0.0));
622 f.instruction(&Instruction::F64Lt);
623 f.instruction(&Instruction::LocalSet(3)); f.instruction(&Instruction::LocalGet(2));
627 f.instruction(&Instruction::F64Abs);
628 f.instruction(&Instruction::I64TruncF64S);
629 f.instruction(&Instruction::LocalSet(4)); f.instruction(&Instruction::I32Const(20));
633 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
634 f.instruction(&Instruction::LocalSet(5)); f.instruction(&Instruction::LocalGet(5));
638 f.instruction(&Instruction::I32Const(20));
639 f.instruction(&Instruction::I32Add);
640 f.instruction(&Instruction::LocalSet(6)); f.instruction(&Instruction::LocalGet(4));
644 f.instruction(&Instruction::I64Eqz);
645 f.instruction(&Instruction::If(BlockType::Empty));
646 f.instruction(&Instruction::LocalGet(6));
648 f.instruction(&Instruction::I32Const(1));
649 f.instruction(&Instruction::I32Sub);
650 f.instruction(&Instruction::LocalSet(6));
651 f.instruction(&Instruction::LocalGet(6));
652 f.instruction(&Instruction::I32Const(48)); f.instruction(&Instruction::I32Store8(memarg(0, 0)));
654 f.instruction(&Instruction::Else);
655
656 f.instruction(&Instruction::Block(BlockType::Empty));
658 f.instruction(&Instruction::Loop(BlockType::Empty));
659 f.instruction(&Instruction::LocalGet(4));
660 f.instruction(&Instruction::I64Eqz);
661 f.instruction(&Instruction::BrIf(1)); f.instruction(&Instruction::LocalGet(6));
665 f.instruction(&Instruction::I32Const(1));
666 f.instruction(&Instruction::I32Sub);
667 f.instruction(&Instruction::LocalSet(6));
668
669 f.instruction(&Instruction::LocalGet(6));
671 f.instruction(&Instruction::LocalGet(4));
672 f.instruction(&Instruction::I64Const(10));
673 f.instruction(&Instruction::I64RemU);
674 f.instruction(&Instruction::I32WrapI64);
675 f.instruction(&Instruction::I32Const(48)); f.instruction(&Instruction::I32Add);
677 f.instruction(&Instruction::I32Store8(memarg(0, 0)));
678
679 f.instruction(&Instruction::LocalGet(4));
681 f.instruction(&Instruction::I64Const(10));
682 f.instruction(&Instruction::I64DivU);
683 f.instruction(&Instruction::LocalSet(4));
684
685 f.instruction(&Instruction::Br(0)); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::LocalGet(3));
693 f.instruction(&Instruction::If(BlockType::Empty));
694 f.instruction(&Instruction::LocalGet(6));
695 f.instruction(&Instruction::I32Const(1));
696 f.instruction(&Instruction::I32Sub);
697 f.instruction(&Instruction::LocalSet(6));
698 f.instruction(&Instruction::LocalGet(6));
699 f.instruction(&Instruction::I32Const(45)); f.instruction(&Instruction::I32Store8(memarg(0, 0)));
701 f.instruction(&Instruction::End);
702
703 f.instruction(&Instruction::LocalGet(6)); f.instruction(&Instruction::LocalGet(5));
707 f.instruction(&Instruction::I32Const(20));
708 f.instruction(&Instruction::I32Add);
709 f.instruction(&Instruction::LocalGet(6));
710 f.instruction(&Instruction::I32Sub); f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
712
713 f.instruction(&Instruction::Else);
714 f.instruction(&Instruction::I32Const(data.value_ptr as i32));
716 f.instruction(&Instruction::I32Const(data.value_len as i32));
717 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
718 f.instruction(&Instruction::End); f.instruction(&Instruction::Else);
721
722 f.instruction(&Instruction::LocalGet(1));
724 f.instruction(&Instruction::I32Const(TAG_BOOL));
725 f.instruction(&Instruction::I32Eq);
726 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
727 f.instruction(&Instruction::LocalGet(0));
728 f.instruction(&Instruction::I32Load(memarg(4, 2)));
729 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
730 f.instruction(&Instruction::I32Const(data.true_ptr as i32));
732 f.instruction(&Instruction::I32Const(data.true_len as i32));
733 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
734 f.instruction(&Instruction::Else);
735 f.instruction(&Instruction::I32Const(data.false_ptr as i32));
737 f.instruction(&Instruction::I32Const(data.false_len as i32));
738 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
739 f.instruction(&Instruction::End);
740 f.instruction(&Instruction::Else);
741
742 f.instruction(&Instruction::LocalGet(1));
744 f.instruction(&Instruction::I32Const(TAG_NIL));
745 f.instruction(&Instruction::I32Eq);
746 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
747 f.instruction(&Instruction::I32Const(data.nil_ptr as i32));
748 f.instruction(&Instruction::I32Const(data.nil_len as i32));
749 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
750 f.instruction(&Instruction::Else);
751
752 f.instruction(&Instruction::I32Const(data.value_ptr as i32));
754 f.instruction(&Instruction::I32Const(data.value_len as i32));
755 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
756
757 f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::End);
763 f
764}
765
766pub fn emit_val_string_concat() -> Function {
770 let mut f = Function::new(vec![
771 (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
776
777 f.instruction(&Instruction::LocalGet(0));
779 f.instruction(&Instruction::I32Load(memarg(8, 2)));
780 f.instruction(&Instruction::LocalSet(2));
781 f.instruction(&Instruction::LocalGet(1));
783 f.instruction(&Instruction::I32Load(memarg(8, 2)));
784 f.instruction(&Instruction::LocalSet(3));
785 f.instruction(&Instruction::LocalGet(2));
787 f.instruction(&Instruction::LocalGet(3));
788 f.instruction(&Instruction::I32Add);
789 f.instruction(&Instruction::LocalSet(5));
790
791 f.instruction(&Instruction::LocalGet(5));
793 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
794 f.instruction(&Instruction::LocalSet(4));
795
796 f.instruction(&Instruction::LocalGet(4)); f.instruction(&Instruction::LocalGet(0));
799 f.instruction(&Instruction::I32Load(memarg(4, 2))); f.instruction(&Instruction::LocalGet(2)); f.instruction(&Instruction::MemoryCopy { src_mem: 0, dst_mem: 0 });
802
803 f.instruction(&Instruction::LocalGet(4));
805 f.instruction(&Instruction::LocalGet(2));
806 f.instruction(&Instruction::I32Add); f.instruction(&Instruction::LocalGet(1));
808 f.instruction(&Instruction::I32Load(memarg(4, 2))); f.instruction(&Instruction::LocalGet(3)); f.instruction(&Instruction::MemoryCopy { src_mem: 0, dst_mem: 0 });
811
812 f.instruction(&Instruction::LocalGet(4));
814 f.instruction(&Instruction::LocalGet(5));
815 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_STRING)));
816
817 f.instruction(&Instruction::End);
818 f
819}
820
821fn emit_arith_binop(op: Instruction<'static>) -> Function {
829 let mut f = Function::new(vec![
830 (1, ValType::I32), ]);
832
833 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
835 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
836 f.instruction(&Instruction::LocalSet(2));
837
838 f.instruction(&Instruction::LocalGet(2));
840 f.instruction(&Instruction::I32Const(TAG_NUMBER));
841 f.instruction(&Instruction::I32Store(memarg(0, 2)));
842
843 f.instruction(&Instruction::LocalGet(2));
846 f.instruction(&Instruction::LocalGet(0));
847 f.instruction(&Instruction::F64Load(memarg(4, 3)));
848 f.instruction(&Instruction::LocalGet(1));
849 f.instruction(&Instruction::F64Load(memarg(4, 3)));
850 f.instruction(&op);
851 f.instruction(&Instruction::F64Store(memarg(4, 3)));
852
853 f.instruction(&Instruction::LocalGet(2));
855 f.instruction(&Instruction::End);
856 f
857}
858
859pub fn emit_val_add() -> Function {
860 emit_arith_binop(Instruction::F64Add)
861}
862pub fn emit_val_sub() -> Function {
863 emit_arith_binop(Instruction::F64Sub)
864}
865pub fn emit_val_mul() -> Function {
866 emit_arith_binop(Instruction::F64Mul)
867}
868
869pub fn emit_val_div(trap_msg_ptr: u32, trap_msg_len: u32) -> Function {
871 let mut f = Function::new(vec![
872 (1, ValType::I32), (1, ValType::F64), (1, ValType::F64), ]);
876
877 f.instruction(&Instruction::LocalGet(1));
879 f.instruction(&Instruction::F64Load(memarg(4, 3)));
880 f.instruction(&Instruction::LocalSet(3));
881
882 f.instruction(&Instruction::LocalGet(3));
884 f.instruction(&Instruction::F64Const(0.0));
885 f.instruction(&Instruction::F64Eq);
886 f.instruction(&Instruction::If(BlockType::Empty));
887 f.instruction(&Instruction::I32Const(trap_msg_ptr as i32));
888 f.instruction(&Instruction::I32Const(trap_msg_len as i32));
889 f.instruction(&Instruction::Call(IMPORT_TRAP));
890 f.instruction(&Instruction::Unreachable);
891 f.instruction(&Instruction::End);
892
893 f.instruction(&Instruction::LocalGet(0));
895 f.instruction(&Instruction::F64Load(memarg(4, 3)));
896 f.instruction(&Instruction::LocalGet(3));
897 f.instruction(&Instruction::F64Div);
898 f.instruction(&Instruction::LocalSet(4));
899
900 f.instruction(&Instruction::LocalGet(4));
902 f.instruction(&Instruction::LocalGet(4));
903 f.instruction(&Instruction::F64Ne);
904 f.instruction(&Instruction::If(BlockType::Empty));
905 f.instruction(&Instruction::I32Const(trap_msg_ptr as i32));
906 f.instruction(&Instruction::I32Const(trap_msg_len as i32));
907 f.instruction(&Instruction::Call(IMPORT_TRAP));
908 f.instruction(&Instruction::Unreachable);
909 f.instruction(&Instruction::End);
910
911 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
913 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
914 f.instruction(&Instruction::LocalSet(2));
915 f.instruction(&Instruction::LocalGet(2));
916 f.instruction(&Instruction::I32Const(TAG_NUMBER));
917 f.instruction(&Instruction::I32Store(memarg(0, 2)));
918 f.instruction(&Instruction::LocalGet(2));
919 f.instruction(&Instruction::LocalGet(4));
920 f.instruction(&Instruction::F64Store(memarg(4, 3)));
921 f.instruction(&Instruction::LocalGet(2));
922 f.instruction(&Instruction::End);
923 f
924}
925
926pub fn emit_val_mod() -> Function {
928 let mut f = Function::new(vec![
930 (1, ValType::I32), (1, ValType::F64), (1, ValType::F64), ]);
934
935 f.instruction(&Instruction::LocalGet(0));
936 f.instruction(&Instruction::F64Load(memarg(4, 3)));
937 f.instruction(&Instruction::LocalSet(3));
938 f.instruction(&Instruction::LocalGet(1));
939 f.instruction(&Instruction::F64Load(memarg(4, 3)));
940 f.instruction(&Instruction::LocalSet(4));
941
942 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
944 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
945 f.instruction(&Instruction::LocalSet(2));
946 f.instruction(&Instruction::LocalGet(2));
947 f.instruction(&Instruction::I32Const(TAG_NUMBER));
948 f.instruction(&Instruction::I32Store(memarg(0, 2)));
949
950 f.instruction(&Instruction::LocalGet(2));
951 f.instruction(&Instruction::LocalGet(3)); f.instruction(&Instruction::LocalGet(3)); f.instruction(&Instruction::LocalGet(4)); f.instruction(&Instruction::F64Div);
955 f.instruction(&Instruction::F64Floor);
956 f.instruction(&Instruction::LocalGet(4)); f.instruction(&Instruction::F64Mul);
958 f.instruction(&Instruction::F64Sub);
959 f.instruction(&Instruction::F64Store(memarg(4, 3)));
960
961 f.instruction(&Instruction::LocalGet(2));
962 f.instruction(&Instruction::End);
963 f
964}
965
966pub fn emit_val_neg() -> Function {
968 let mut f = Function::new(vec![
969 (1, ValType::I32), ]);
971 f.instruction(&Instruction::I32Const(VALUE_SIZE as i32));
972 f.instruction(&Instruction::Call(rt_func_idx(RT_ALLOC)));
973 f.instruction(&Instruction::LocalSet(1));
974 f.instruction(&Instruction::LocalGet(1));
975 f.instruction(&Instruction::I32Const(TAG_NUMBER));
976 f.instruction(&Instruction::I32Store(memarg(0, 2)));
977 f.instruction(&Instruction::LocalGet(1));
978 f.instruction(&Instruction::LocalGet(0));
979 f.instruction(&Instruction::F64Load(memarg(4, 3)));
980 f.instruction(&Instruction::F64Neg);
981 f.instruction(&Instruction::F64Store(memarg(4, 3)));
982 f.instruction(&Instruction::LocalGet(1));
983 f.instruction(&Instruction::End);
984 f
985}
986
987pub fn emit_val_not() -> Function {
989 let mut f = Function::new(vec![
990 (1, ValType::I32), ]);
992 f.instruction(&Instruction::LocalGet(0));
994 f.instruction(&Instruction::I32Load(memarg(4, 2)));
995 f.instruction(&Instruction::I32Eqz);
996 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_BOOL)));
997 f.instruction(&Instruction::End);
998 f
999}
1000
1001fn emit_cmp(op: Instruction<'static>) -> Function {
1003 let mut f = Function::new(vec![]);
1004 f.instruction(&Instruction::LocalGet(0));
1006 f.instruction(&Instruction::F64Load(memarg(4, 3)));
1007 f.instruction(&Instruction::LocalGet(1));
1008 f.instruction(&Instruction::F64Load(memarg(4, 3)));
1009 f.instruction(&op);
1010 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_BOOL)));
1011 f.instruction(&Instruction::End);
1012 f
1013}
1014
1015pub fn emit_val_lt() -> Function {
1016 emit_cmp(Instruction::F64Lt)
1017}
1018pub fn emit_val_le() -> Function {
1019 emit_cmp(Instruction::F64Le)
1020}
1021pub fn emit_val_gt() -> Function {
1022 emit_cmp(Instruction::F64Gt)
1023}
1024pub fn emit_val_ge() -> Function {
1025 emit_cmp(Instruction::F64Ge)
1026}
1027
1028pub fn emit_val_record_get() -> Function {
1033 let mut f = Function::new(vec![
1034 (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), (1, ValType::I32), ]);
1040
1041 f.instruction(&Instruction::LocalGet(0));
1043 f.instruction(&Instruction::I32Load(memarg(4, 2)));
1044 f.instruction(&Instruction::LocalSet(3));
1045 f.instruction(&Instruction::LocalGet(0));
1047 f.instruction(&Instruction::I32Load(memarg(8, 2)));
1048 f.instruction(&Instruction::LocalSet(4));
1049
1050 f.instruction(&Instruction::I32Const(0));
1052 f.instruction(&Instruction::LocalSet(7));
1053 f.instruction(&Instruction::I32Const(0));
1055 f.instruction(&Instruction::LocalSet(5));
1056
1057 f.instruction(&Instruction::Block(BlockType::Empty)); f.instruction(&Instruction::Loop(BlockType::Empty));
1060
1061 f.instruction(&Instruction::LocalGet(5));
1063 f.instruction(&Instruction::LocalGet(4));
1064 f.instruction(&Instruction::I32GeU);
1065 f.instruction(&Instruction::BrIf(1));
1066
1067 f.instruction(&Instruction::LocalGet(3));
1069 f.instruction(&Instruction::LocalGet(5));
1070 f.instruction(&Instruction::I32Const(12));
1071 f.instruction(&Instruction::I32Mul);
1072 f.instruction(&Instruction::I32Add);
1073 f.instruction(&Instruction::LocalSet(6));
1074
1075 f.instruction(&Instruction::LocalGet(6));
1077 f.instruction(&Instruction::I32Load(memarg(4, 2))); f.instruction(&Instruction::LocalGet(2)); f.instruction(&Instruction::I32Eq);
1080 f.instruction(&Instruction::If(BlockType::Empty));
1081 f.instruction(&Instruction::LocalGet(6));
1083 f.instruction(&Instruction::I32Load(memarg(0, 2))); f.instruction(&Instruction::LocalGet(1)); f.instruction(&Instruction::LocalGet(2)); f.instruction(&Instruction::Call(rt_func_idx(RT_MEMCMP)));
1087 f.instruction(&Instruction::If(BlockType::Empty));
1088 f.instruction(&Instruction::LocalGet(6));
1090 f.instruction(&Instruction::I32Load(memarg(8, 2)));
1091 f.instruction(&Instruction::LocalSet(7));
1092 f.instruction(&Instruction::Br(3)); f.instruction(&Instruction::End);
1094 f.instruction(&Instruction::End);
1095
1096 f.instruction(&Instruction::LocalGet(5));
1098 f.instruction(&Instruction::I32Const(1));
1099 f.instruction(&Instruction::I32Add);
1100 f.instruction(&Instruction::LocalSet(5));
1101 f.instruction(&Instruction::Br(0));
1102
1103 f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::LocalGet(7));
1108 f.instruction(&Instruction::I32Eqz);
1109 f.instruction(&Instruction::If(BlockType::Empty));
1110 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_NIL)));
1111 f.instruction(&Instruction::LocalSet(7));
1112 f.instruction(&Instruction::End);
1113
1114 f.instruction(&Instruction::LocalGet(7));
1115 f.instruction(&Instruction::End);
1116 f
1117}
1118
1119pub fn emit_val_list_get() -> Function {
1121 let mut f = Function::new(vec![
1122 (1, ValType::I32), (1, ValType::I32), ]);
1125 f.instruction(&Instruction::LocalGet(0));
1127 f.instruction(&Instruction::I32Load(memarg(4, 2)));
1128 f.instruction(&Instruction::LocalSet(2));
1129 f.instruction(&Instruction::LocalGet(0));
1131 f.instruction(&Instruction::I32Load(memarg(8, 2)));
1132 f.instruction(&Instruction::LocalSet(3));
1133
1134 f.instruction(&Instruction::LocalGet(1));
1136 f.instruction(&Instruction::LocalGet(3));
1137 f.instruction(&Instruction::I32GeU);
1138 f.instruction(&Instruction::If(BlockType::Result(ValType::I32)));
1139 f.instruction(&Instruction::Call(rt_func_idx(RT_VAL_NIL)));
1140 f.instruction(&Instruction::Else);
1141 f.instruction(&Instruction::LocalGet(2));
1143 f.instruction(&Instruction::LocalGet(1));
1144 f.instruction(&Instruction::I32Const(4));
1145 f.instruction(&Instruction::I32Mul);
1146 f.instruction(&Instruction::I32Add);
1147 f.instruction(&Instruction::I32Load(memarg(0, 2)));
1148 f.instruction(&Instruction::End);
1149
1150 f.instruction(&Instruction::End);
1151 f
1152}
1153
1154pub fn emit_check_nan(trap_msg_ptr: u32, trap_msg_len: u32) -> Function {
1156 let mut f = Function::new(vec![
1157 (1, ValType::F64), ]);
1159 f.instruction(&Instruction::LocalGet(0));
1161 f.instruction(&Instruction::I32Load(memarg(0, 2)));
1162 f.instruction(&Instruction::I32Const(TAG_NUMBER));
1163 f.instruction(&Instruction::I32Eq);
1164 f.instruction(&Instruction::If(BlockType::Empty));
1165 f.instruction(&Instruction::LocalGet(0));
1167 f.instruction(&Instruction::F64Load(memarg(4, 3)));
1168 f.instruction(&Instruction::LocalSet(1));
1169 f.instruction(&Instruction::LocalGet(1));
1171 f.instruction(&Instruction::LocalGet(1));
1172 f.instruction(&Instruction::F64Ne);
1173 f.instruction(&Instruction::If(BlockType::Empty));
1174 f.instruction(&Instruction::I32Const(trap_msg_ptr as i32));
1175 f.instruction(&Instruction::I32Const(trap_msg_len as i32));
1176 f.instruction(&Instruction::Call(IMPORT_TRAP));
1177 f.instruction(&Instruction::Unreachable);
1178 f.instruction(&Instruction::End);
1179 f.instruction(&Instruction::End);
1180 f.instruction(&Instruction::LocalGet(0));
1182 f.instruction(&Instruction::End);
1183 f
1184}
1185
1186pub fn emit_memcmp() -> Function {
1191 let mut f = Function::new(vec![
1192 (1, ValType::I32), ]);
1194 f.instruction(&Instruction::LocalGet(2));
1198 f.instruction(&Instruction::I32Eqz);
1199 f.instruction(&Instruction::If(BlockType::Empty));
1200 f.instruction(&Instruction::I32Const(1));
1201 f.instruction(&Instruction::Return);
1202 f.instruction(&Instruction::End);
1203
1204 f.instruction(&Instruction::LocalGet(0));
1206 f.instruction(&Instruction::LocalGet(1));
1207 f.instruction(&Instruction::I32Eq);
1208 f.instruction(&Instruction::If(BlockType::Empty));
1209 f.instruction(&Instruction::I32Const(1));
1210 f.instruction(&Instruction::Return);
1211 f.instruction(&Instruction::End);
1212
1213 f.instruction(&Instruction::I32Const(0));
1215 f.instruction(&Instruction::LocalSet(3));
1216
1217 f.instruction(&Instruction::Block(BlockType::Empty)); f.instruction(&Instruction::Loop(BlockType::Empty)); f.instruction(&Instruction::LocalGet(3));
1223 f.instruction(&Instruction::LocalGet(2));
1224 f.instruction(&Instruction::I32GeU);
1225 f.instruction(&Instruction::BrIf(1)); f.instruction(&Instruction::LocalGet(0));
1229 f.instruction(&Instruction::LocalGet(3));
1230 f.instruction(&Instruction::I32Add);
1231 f.instruction(&Instruction::I32Load8U(memarg(0, 0)));
1232
1233 f.instruction(&Instruction::LocalGet(1));
1235 f.instruction(&Instruction::LocalGet(3));
1236 f.instruction(&Instruction::I32Add);
1237 f.instruction(&Instruction::I32Load8U(memarg(0, 0)));
1238
1239 f.instruction(&Instruction::I32Ne);
1241 f.instruction(&Instruction::If(BlockType::Empty));
1242 f.instruction(&Instruction::I32Const(0));
1243 f.instruction(&Instruction::Return);
1244 f.instruction(&Instruction::End);
1245
1246 f.instruction(&Instruction::LocalGet(3));
1248 f.instruction(&Instruction::I32Const(1));
1249 f.instruction(&Instruction::I32Add);
1250 f.instruction(&Instruction::LocalSet(3));
1251
1252 f.instruction(&Instruction::Br(0));
1254
1255 f.instruction(&Instruction::End); f.instruction(&Instruction::End); f.instruction(&Instruction::I32Const(1));
1260 f.instruction(&Instruction::End);
1261 f
1262}
1263
1264pub(crate) fn memarg(offset: u64, align: u32) -> wasm_encoder::MemArg {
1270 wasm_encoder::MemArg {
1271 offset,
1272 align,
1273 memory_index: 0,
1274 }
1275}
1276
1277pub struct DataSegmentTracker {
1282 pub true_ptr: u32,
1283 pub true_len: u32,
1284 pub false_ptr: u32,
1285 pub false_len: u32,
1286 pub nil_ptr: u32,
1287 pub nil_len: u32,
1288 pub value_ptr: u32,
1289 pub value_len: u32,
1290 pub gas_exhausted_ptr: u32,
1291 pub gas_exhausted_len: u32,
1292 pub div_by_zero_ptr: u32,
1293 pub div_by_zero_len: u32,
1294 pub nan_ptr: u32,
1295 pub nan_len: u32,
1296 pub assert_failed_ptr: u32,
1297 pub assert_failed_len: u32,
1298 pub invariant_failed_ptr: u32,
1299 pub invariant_failed_len: u32,
1300 pub unwrap_failed_ptr: u32,
1301 pub unwrap_failed_len: u32,
1302 pub oom_ptr: u32,
1303 pub oom_len: u32,
1304 pub next_offset: u32,
1306}
1307
1308impl Default for DataSegmentTracker {
1309 fn default() -> Self {
1310 Self::new()
1311 }
1312}
1313
1314impl DataSegmentTracker {
1315 pub fn new() -> Self {
1317 let mut offset = 0u32;
1318
1319 let true_ptr = offset;
1320 let true_len = 4u32; offset += true_len;
1322
1323 let false_ptr = offset;
1324 let false_len = 5u32; offset += false_len;
1326
1327 let nil_ptr = offset;
1328 let nil_len = 3u32; offset += nil_len;
1330
1331 let value_ptr = offset;
1332 let value_len = 7u32; offset += value_len;
1334
1335 let gas_exhausted_ptr = offset;
1336 let gas_exhausted_len = 13u32; offset += gas_exhausted_len;
1338
1339 let div_by_zero_ptr = offset;
1340 let div_by_zero_len = 16u32; offset += div_by_zero_len;
1342
1343 let nan_ptr = offset;
1344 let nan_len = 10u32; offset += nan_len;
1346
1347 let assert_failed_ptr = offset;
1348 let assert_failed_len = 16u32; offset += assert_failed_len;
1350
1351 let invariant_failed_ptr = offset;
1352 let invariant_failed_len = 18u32; offset += invariant_failed_len;
1354
1355 let unwrap_failed_ptr = offset;
1356 let unwrap_failed_len = 14u32; offset += unwrap_failed_len;
1358
1359 let oom_ptr = offset;
1360 let oom_len = 13u32; offset += oom_len;
1362
1363 Self {
1364 true_ptr,
1365 true_len,
1366 false_ptr,
1367 false_len,
1368 nil_ptr,
1369 nil_len,
1370 value_ptr,
1371 value_len,
1372 gas_exhausted_ptr,
1373 gas_exhausted_len,
1374 div_by_zero_ptr,
1375 div_by_zero_len,
1376 nan_ptr,
1377 nan_len,
1378 assert_failed_ptr,
1379 assert_failed_len,
1380 invariant_failed_ptr,
1381 invariant_failed_len,
1382 unwrap_failed_ptr,
1383 unwrap_failed_len,
1384 oom_ptr,
1385 oom_len,
1386 next_offset: offset,
1387 }
1388 }
1389
1390 pub fn data_bytes(&self) -> Vec<u8> {
1392 let mut buf = Vec::new();
1393 buf.extend_from_slice(b"true");
1394 buf.extend_from_slice(b"false");
1395 buf.extend_from_slice(b"nil");
1396 buf.extend_from_slice(b"[value]");
1397 buf.extend_from_slice(b"gas exhausted");
1398 buf.extend_from_slice(b"division by zero");
1399 buf.extend_from_slice(b"NaN result");
1400 buf.extend_from_slice(b"assertion failed");
1401 buf.extend_from_slice(b"invariant violated");
1402 buf.extend_from_slice(b"unwrap on Err!");
1403 buf.extend_from_slice(b"out of memory");
1404 buf
1405 }
1406
1407 pub fn intern_string(&mut self, s: &str) -> (u32, u32) {
1410 let ptr = self.next_offset;
1411 let len = s.len() as u32;
1412 self.next_offset += len;
1413 (ptr, len)
1414 }
1415}