1use wasm_encoder::{
6 CompositeInnerType, CompositeType, FieldType, FuncType, HeapType, RefType, StorageType,
7 StructType, SubType, TypeSection, ValType,
8};
9#[derive(Clone, Copy, Debug)]
10pub struct IntrinsicTypeIndices {
11 pub undefined: u32,
12 pub raw_string: u32,
13 pub vtable: u32,
14 pub object: u32,
15 pub string: u32,
16 pub boxed_number: u32,
17 pub boxed_boolean: u32,
18 pub field_names: u32,
19 pub object_shape: u32,
20 pub object_fields: u32,
21 pub to_string_fn: u32,
22 pub to_json_fn: u32,
23 pub equals_fn: u32,
24 pub hash_fn: u32,
25 pub field_getter: u32,
26 pub field_setter: u32,
27 pub raw_array: u32,
28 pub array: u32,
29 pub raw_uint8_array: u32,
30 pub uint8_array: u32,
31 pub closure: u32,
32 pub class_vtable: u32,
33 pub error_vtable: u32,
34 pub error: u32,
35 pub raw_bigint: u32,
36 pub bigint: u32,
37 pub regex_capture_array: u32,
38 pub regex_match: u32,
39 pub regex: u32,
40 pub regex_match_box: u32,
41 pub temporal_instant: u32,
42 pub temporal_duration: u32,
43 pub temporal_zdt: u32,
44 pub raw_index_array: u32,
45 pub map: u32,
46 pub set: u32,
47 pub url: u32,
48 pub fs_stat: u32,
49 pub fs_peek: u32,
50 pub fs_dir_entry: u32,
51 pub fs_info: u32,
52 pub fs_file_writer: u32,
53 pub http_response: u32,
54 pub http_download_result: u32,
55 pub session_entry: u32,
56 pub session_page: u32,
57 pub fs_mount_info: u32,
58
59 pub temporal_plain_date: u32,
60 pub temporal_plain_time: u32,
61 pub temporal_plain_date_time: u32,
62 pub temporal_plain_year_month: u32,
63 pub temporal_plain_month_day: u32,
64}
65
66pub const INTRINSIC_TYPE_COUNT: u32 = 52;
69
70pub fn declare_intrinsic_types(types: &mut TypeSection) -> IntrinsicTypeIndices {
71 let undefined = 51u32;
72 let raw_string = 0u32;
73 let vtable = 1u32;
74 let object = 2u32;
75 let string = 3u32;
76 let boxed_number = 4u32;
77 let boxed_boolean = 5u32;
78 let field_names = 6u32;
79 let object_fields = 7u32;
80 let object_shape = 8u32;
81 let to_string_fn = 9u32;
82 let to_json_fn = 10u32;
83 let equals_fn = 11u32;
84 let hash_fn = 12u32;
85 let field_getter = 13u32;
86 let field_setter = 14u32;
87 let raw_array = 15u32;
88 let array = 16u32;
89 let raw_uint8_array = 17u32;
90 let uint8_array = 18u32;
91 let closure = 19u32;
92 let class_vtable = 20u32;
99 let error_vtable = 21u32;
107 let error = 22u32;
108 let raw_bigint = 23u32;
112 let bigint = 24u32;
113 let regex_capture_array = 25u32;
119 let regex_match = 26u32;
120 let regex = 27u32;
121 let regex_match_box = 28u32;
122 let temporal_instant = 29u32;
128 let temporal_duration = 30u32;
129 let temporal_zdt = 31u32;
130 let raw_index_array = 32u32;
131 let map = 33u32;
132 let set = 34u32;
133 let url = 35u32;
134 let fs_stat = 41u32;
135 let fs_peek = 42u32;
136 let fs_dir_entry = 43u32;
137 let fs_info = 44u32;
138 let fs_file_writer = 45u32;
139 let http_response = 46u32;
140 let http_download_result = 47u32;
141 let session_entry = 48u32;
142 let session_page = 49u32;
143 let fs_mount_info = 50u32;
144
145 let temporal_plain_date = 36u32;
146 let temporal_plain_time = 37u32;
147 let temporal_plain_date_time = 38u32;
148 let temporal_plain_year_month = 39u32;
149 let temporal_plain_month_day = 40u32;
150
151 types.ty().array(&StorageType::I16, true);
154
155 types.ty().rec(vec![
159 substruct(
162 vec![
163 fieldtype_ref(to_string_fn),
164 fieldtype_ref(to_json_fn),
165 fieldtype_ref(equals_fn),
166 fieldtype_ref(hash_fn),
167 ],
168 None,
169 ),
170 substruct(vec![fieldtype_ref(vtable)], None),
171 SubType {
172 is_final: false,
173 supertype_idx: Some(object),
174 composite_type: CompositeType {
175 inner: CompositeInnerType::Struct(StructType {
176 fields: vec![
177 fieldtype_ref(vtable),
178 FieldType {
179 element_type: StorageType::Val(ref_to(raw_string)),
180 mutable: false,
181 },
182 FieldType {
183 element_type: StorageType::Val(ValType::I64),
184 mutable: true,
185 },
186 ]
187 .into_boxed_slice(),
188 }),
189 shared: false,
190 descriptor: None,
191 describes: None,
192 },
193 },
194 SubType {
195 is_final: false,
196 supertype_idx: Some(object),
197 composite_type: CompositeType {
198 inner: CompositeInnerType::Struct(StructType {
199 fields: vec![
200 fieldtype_ref(vtable),
201 FieldType {
202 element_type: StorageType::Val(ValType::F64),
203 mutable: false,
204 },
205 ]
206 .into_boxed_slice(),
207 }),
208 shared: false,
209 descriptor: None,
210 describes: None,
211 },
212 },
213 SubType {
214 is_final: false,
215 supertype_idx: Some(object),
216 composite_type: CompositeType {
217 inner: CompositeInnerType::Struct(StructType {
218 fields: vec![
219 fieldtype_ref(vtable),
220 FieldType {
221 element_type: StorageType::Val(ValType::I32),
222 mutable: false,
223 },
224 ]
225 .into_boxed_slice(),
226 }),
227 shared: false,
228 descriptor: None,
229 describes: None,
230 },
231 },
232 SubType {
234 is_final: false,
235 supertype_idx: None,
236 composite_type: CompositeType {
237 inner: CompositeInnerType::Array(wasm_encoder::ArrayType(FieldType {
238 element_type: StorageType::Val(ref_to(string)),
239 mutable: true,
240 })),
241 shared: false,
242 descriptor: None,
243 describes: None,
244 },
245 },
246 SubType {
247 is_final: false,
248 supertype_idx: None,
249 composite_type: CompositeType {
250 inner: CompositeInnerType::Array(wasm_encoder::ArrayType(FieldType {
251 element_type: StorageType::Val(ref_null(object)),
252 mutable: true,
253 })),
254 shared: false,
255 descriptor: None,
256 describes: None,
257 },
258 },
259 SubType {
260 is_final: false,
261 supertype_idx: Some(object),
262 composite_type: CompositeType {
263 inner: CompositeInnerType::Struct(StructType {
264 fields: vec![
265 fieldtype_ref(vtable),
266 FieldType {
267 element_type: StorageType::Val(ref_to(field_names)),
268 mutable: true,
269 },
270 FieldType {
271 element_type: StorageType::Val(ref_to(object_fields)),
272 mutable: true,
273 },
274 FieldType {
275 element_type: StorageType::Val(ValType::Ref(RefType::ANYREF)),
276 mutable: true,
277 },
278 ]
279 .into_boxed_slice(),
280 }),
281 shared: false,
282 descriptor: None,
283 describes: None,
284 },
285 },
286 subfunc(vec![ref_to(object)], vec![ref_to(string)]),
288 subfunc(vec![ref_to(object)], vec![ref_to(string)]),
289 subfunc(vec![ref_to(object), ref_to(object)], vec![ValType::I32]),
290 subfunc(vec![ref_to(object)], vec![ValType::I32]),
291 subfunc(
292 vec![ref_to(object_shape), ref_to(string)],
293 vec![ref_null(object)],
294 ),
295 subfunc(
296 vec![ref_to(object_shape), ref_to(string), ref_null(object)],
297 vec![],
298 ),
299 ]);
300
301 types.ty().array(
303 &StorageType::Val(ValType::Ref(RefType {
304 nullable: true,
305 heap_type: HeapType::Concrete(object),
306 })),
307 true,
308 );
309
310 types.ty().subtype(&SubType {
312 is_final: false,
313 supertype_idx: Some(object),
314 composite_type: CompositeType {
315 inner: CompositeInnerType::Struct(StructType {
316 fields: vec![
317 fieldtype_ref(vtable),
318 FieldType {
319 element_type: StorageType::Val(ref_to(raw_array)),
320 mutable: true,
321 },
322 FieldType {
323 element_type: StorageType::Val(ValType::I32),
324 mutable: true,
325 },
326 ]
327 .into_boxed_slice(),
328 }),
329 shared: false,
330 descriptor: None,
331 describes: None,
332 },
333 });
334
335 types.ty().array(&StorageType::I8, true);
339
340 types.ty().subtype(&SubType {
342 is_final: false,
343 supertype_idx: Some(object),
344 composite_type: CompositeType {
345 inner: CompositeInnerType::Struct(StructType {
346 fields: vec![
347 fieldtype_ref(vtable),
348 FieldType {
349 element_type: StorageType::Val(ref_to(raw_uint8_array)),
350 mutable: false,
351 },
352 ]
353 .into_boxed_slice(),
354 }),
355 shared: false,
356 descriptor: None,
357 describes: None,
358 },
359 });
360
361 types.ty().subtype(&SubType {
363 is_final: false,
364 supertype_idx: Some(object),
365 composite_type: CompositeType {
366 inner: CompositeInnerType::Struct(StructType {
367 fields: vec![fieldtype_ref(vtable)].into_boxed_slice(),
368 }),
369 shared: false,
370 descriptor: None,
371 describes: None,
372 },
373 });
374 types.ty().rec(vec![substruct(
377 vec![
378 fieldtype_ref(to_string_fn),
379 fieldtype_ref(to_json_fn),
380 fieldtype_ref(equals_fn),
381 fieldtype_ref(hash_fn),
382 FieldType {
383 element_type: StorageType::Val(ref_null(class_vtable)),
384 mutable: false,
385 },
386 FieldType {
387 element_type: StorageType::Val(ValType::I32),
388 mutable: false,
389 },
390 ],
391 Some(vtable),
392 )]);
393 types.ty().rec(vec![
396 substruct(
397 vec![
398 fieldtype_ref(to_string_fn),
399 fieldtype_ref(to_json_fn),
400 fieldtype_ref(equals_fn),
401 fieldtype_ref(hash_fn),
402 FieldType {
403 element_type: StorageType::Val(ref_null(class_vtable)),
404 mutable: false,
405 },
406 FieldType {
407 element_type: StorageType::Val(ValType::I32),
408 mutable: false,
409 },
410 ],
411 Some(class_vtable),
412 ),
413 substruct(
414 vec![
415 fieldtype_ref(error_vtable),
416 FieldType {
417 mutable: true,
418 ..fieldtype_ref(field_names)
419 },
420 FieldType {
421 mutable: true,
422 ..fieldtype_ref(object_fields)
423 },
424 FieldType {
425 element_type: StorageType::Val(ValType::Ref(RefType::ANYREF)),
426 mutable: true,
427 },
428 FieldType {
429 element_type: StorageType::Val(ValType::I64),
430 mutable: true,
431 },
432 ],
433 Some(object_shape),
434 ),
435 ]);
436
437 types.ty().array(&StorageType::Val(ValType::I64), true);
439
440 types.ty().subtype(&SubType {
442 is_final: false,
443 supertype_idx: Some(object),
444 composite_type: CompositeType {
445 inner: CompositeInnerType::Struct(StructType {
446 fields: vec![
447 fieldtype_ref(vtable),
448 FieldType {
449 element_type: StorageType::Val(ValType::I32),
450 mutable: false,
451 },
452 FieldType {
453 element_type: StorageType::Val(ref_to(raw_bigint)),
454 mutable: false,
455 },
456 ]
457 .into_boxed_slice(),
458 }),
459 shared: false,
460 descriptor: None,
461 describes: None,
462 },
463 });
464
465 types.ty().array(
467 &StorageType::Val(ValType::Ref(RefType {
468 nullable: true,
469 heap_type: HeapType::Concrete(raw_string),
470 })),
471 true,
472 );
473
474 types.ty().subtype(&SubType {
478 is_final: true,
479 supertype_idx: None,
480 composite_type: CompositeType {
481 inner: CompositeInnerType::Struct(StructType {
482 fields: vec![
483 FieldType {
484 element_type: StorageType::Val(ref_to(raw_string)),
485 mutable: false,
486 },
487 FieldType {
488 element_type: StorageType::Val(ValType::I32),
489 mutable: false,
490 },
491 FieldType {
492 element_type: StorageType::Val(ref_to(raw_string)),
493 mutable: false,
494 },
495 FieldType {
496 element_type: StorageType::Val(ref_to(regex_capture_array)),
497 mutable: false,
498 },
499 FieldType {
500 element_type: StorageType::Val(ref_to(regex_capture_array)),
501 mutable: false,
502 },
503 FieldType {
504 element_type: StorageType::Val(ValType::I32),
505 mutable: false,
506 },
507 ]
508 .into_boxed_slice(),
509 }),
510 shared: false,
511 descriptor: None,
512 describes: None,
513 },
514 });
515
516 types.ty().subtype(&SubType {
518 is_final: false,
519 supertype_idx: Some(object),
520 composite_type: CompositeType {
521 inner: CompositeInnerType::Struct(StructType {
522 fields: vec![
523 fieldtype_ref(vtable),
524 FieldType {
525 element_type: StorageType::Val(ValType::Ref(RefType::EXTERNREF)),
526 mutable: false,
527 },
528 FieldType {
529 element_type: StorageType::Val(ValType::I32),
530 mutable: true,
531 },
532 FieldType {
533 element_type: StorageType::Val(ref_to(string)),
534 mutable: false,
535 },
536 FieldType {
537 element_type: StorageType::Val(ref_to(string)),
538 mutable: false,
539 },
540 FieldType {
541 element_type: StorageType::Val(ValType::I32),
542 mutable: false,
543 },
544 FieldType {
545 element_type: StorageType::Val(ValType::I64),
546 mutable: true,
547 },
548 ]
549 .into_boxed_slice(),
550 }),
551 shared: false,
552 descriptor: None,
553 describes: None,
554 },
555 });
556
557 types.ty().subtype(&SubType {
559 is_final: false,
560 supertype_idx: Some(object),
561 composite_type: CompositeType {
562 inner: CompositeInnerType::Struct(StructType {
563 fields: vec![
564 fieldtype_ref(vtable),
565 FieldType {
566 element_type: StorageType::Val(ref_to(string)),
567 mutable: false,
568 },
569 FieldType {
570 element_type: StorageType::Val(ValType::I32),
571 mutable: false,
572 },
573 FieldType {
574 element_type: StorageType::Val(ref_to(string)),
575 mutable: false,
576 },
577 FieldType {
578 element_type: StorageType::Val(ref_to(regex_capture_array)),
579 mutable: false,
580 },
581 FieldType {
582 element_type: StorageType::Val(ref_to(regex_capture_array)),
583 mutable: false,
584 },
585 FieldType {
586 element_type: StorageType::Val(ValType::I64),
587 mutable: true,
588 },
589 ]
590 .into_boxed_slice(),
591 }),
592 shared: false,
593 descriptor: None,
594 describes: None,
595 },
596 });
597
598 types.ty().subtype(&SubType {
600 is_final: false,
601 supertype_idx: Some(object),
602 composite_type: CompositeType {
603 inner: CompositeInnerType::Struct(StructType {
604 fields: vec![
605 fieldtype_ref(vtable),
606 FieldType {
607 element_type: StorageType::Val(ValType::I64),
608 mutable: false,
609 },
610 FieldType {
611 element_type: StorageType::Val(ValType::I32),
612 mutable: false,
613 },
614 ]
615 .into_boxed_slice(),
616 }),
617 shared: false,
618 descriptor: None,
619 describes: None,
620 },
621 });
622
623 types.ty().subtype(&SubType {
625 is_final: false,
626 supertype_idx: Some(object),
627 composite_type: CompositeType {
628 inner: CompositeInnerType::Struct(StructType {
629 fields: vec![
630 fieldtype_ref(vtable),
631 FieldType {
632 element_type: StorageType::Val(ValType::I32),
633 mutable: false,
634 }, FieldType {
636 element_type: StorageType::Val(ValType::I32),
637 mutable: false,
638 }, FieldType {
640 element_type: StorageType::Val(ValType::I32),
641 mutable: false,
642 }, FieldType {
644 element_type: StorageType::Val(ValType::I32),
645 mutable: false,
646 }, FieldType {
648 element_type: StorageType::Val(ValType::I64),
649 mutable: false,
650 }, FieldType {
652 element_type: StorageType::Val(ValType::I64),
653 mutable: false,
654 }, FieldType {
656 element_type: StorageType::Val(ValType::I64),
657 mutable: false,
658 }, FieldType {
660 element_type: StorageType::Val(ValType::I64),
661 mutable: false,
662 }, FieldType {
664 element_type: StorageType::Val(ValType::I64),
665 mutable: false,
666 }, FieldType {
668 element_type: StorageType::Val(ValType::I64),
669 mutable: false,
670 }, ]
672 .into_boxed_slice(),
673 }),
674 shared: false,
675 descriptor: None,
676 describes: None,
677 },
678 });
679
680 types.ty().subtype(&SubType {
682 is_final: false,
683 supertype_idx: Some(object),
684 composite_type: CompositeType {
685 inner: CompositeInnerType::Struct(StructType {
686 fields: vec![
687 fieldtype_ref(vtable),
688 FieldType {
689 element_type: StorageType::Val(ValType::I64),
690 mutable: false,
691 },
692 FieldType {
693 element_type: StorageType::Val(ValType::I32),
694 mutable: false,
695 },
696 FieldType {
697 element_type: StorageType::Val(ref_to(string)),
698 mutable: false,
699 },
700 FieldType {
701 element_type: StorageType::Val(ValType::Ref(RefType {
702 nullable: false,
703 heap_type: HeapType::EXTERN,
704 })),
705 mutable: false,
706 },
707 ]
708 .into_boxed_slice(),
709 }),
710 shared: false,
711 descriptor: None,
712 describes: None,
713 },
714 });
715
716 types.ty().array(&StorageType::Val(ValType::I32), true);
720 let bucket_field = FieldType {
721 element_type: StorageType::Val(ref_to(raw_array)),
722 mutable: true,
723 };
724 let order_field = FieldType {
725 element_type: StorageType::Val(ref_to(raw_index_array)),
726 mutable: true,
727 };
728 let mutable_i32 = FieldType {
729 element_type: StorageType::Val(ValType::I32),
730 mutable: true,
731 };
732 types.ty().subtype(&SubType {
733 is_final: false,
734 supertype_idx: Some(object),
735 composite_type: CompositeType {
736 inner: CompositeInnerType::Struct(StructType {
737 fields: vec![
738 fieldtype_ref(vtable),
739 bucket_field,
740 bucket_field,
741 mutable_i32,
742 order_field,
743 mutable_i32,
744 order_field,
745 order_field,
746 FieldType {
747 element_type: StorageType::Val(ValType::I64),
748 mutable: true,
749 },
750 ]
751 .into_boxed_slice(),
752 }),
753 shared: false,
754 descriptor: None,
755 describes: None,
756 },
757 });
758 types.ty().subtype(&SubType {
759 is_final: false,
760 supertype_idx: Some(object),
761 composite_type: CompositeType {
762 inner: CompositeInnerType::Struct(StructType {
763 fields: vec![
764 fieldtype_ref(vtable),
765 bucket_field,
766 mutable_i32,
767 order_field,
768 mutable_i32,
769 order_field,
770 order_field,
771 FieldType {
772 element_type: StorageType::Val(ValType::I64),
773 mutable: true,
774 },
775 ]
776 .into_boxed_slice(),
777 }),
778 shared: false,
779 descriptor: None,
780 describes: None,
781 },
782 });
783
784 types.ty().subtype(&SubType {
789 is_final: true,
790 supertype_idx: Some(object),
791 composite_type: CompositeType {
792 inner: CompositeInnerType::Struct(StructType {
793 fields: vec![
794 fieldtype_ref(vtable),
795 fieldtype_ref(string),
796 fieldtype_ref(string),
797 FieldType {
799 element_type: StorageType::Val(ref_null(object)),
800 mutable: false,
801 },
802 fieldtype_ref(string),
803 FieldType {
804 element_type: StorageType::Val(ref_null(object)),
805 mutable: false,
806 },
807 FieldType {
809 element_type: StorageType::Val(ref_null(object)),
810 mutable: false,
811 },
812 ]
813 .into_boxed_slice(),
814 }),
815 shared: false,
816 descriptor: None,
817 describes: None,
818 },
819 });
820
821 let temporal_i32 = FieldType {
826 element_type: StorageType::Val(ValType::I32),
827 mutable: false,
828 };
829 for civil_field_count in [3usize, 4, 7, 2] {
830 let mut fields = Vec::with_capacity(civil_field_count + 1);
831 fields.push(fieldtype_ref(vtable));
832 fields.extend(std::iter::repeat_n(temporal_i32, civil_field_count));
833 types.ty().subtype(&substruct(fields, Some(object)));
834 }
835 types.ty().subtype(&substruct(
839 vec![
840 fieldtype_ref(vtable),
841 temporal_i32,
842 temporal_i32,
843 FieldType {
844 element_type: StorageType::Val(ValType::I64),
845 mutable: false,
846 },
847 ],
848 Some(object),
849 ));
850
851 let host_f64 = FieldType {
854 element_type: StorageType::Val(ValType::F64),
855 mutable: false,
856 };
857 let host_i64 = FieldType {
858 element_type: StorageType::Val(ValType::I64),
859 mutable: false,
860 };
861 let host_externref = FieldType {
862 element_type: StorageType::Val(ValType::EXTERNREF),
863 mutable: false,
864 };
865 let host_object = FieldType {
866 element_type: StorageType::Val(ref_null(object)),
867 mutable: false,
868 };
869 types.ty().subtype(&SubType {
871 is_final: true,
872 ..substruct(
873 vec![
874 fieldtype_ref(vtable),
875 fieldtype_ref(string),
876 host_f64,
877 host_f64,
878 ],
879 Some(object),
880 )
881 });
882 types.ty().subtype(&SubType {
884 is_final: true,
885 ..substruct(
886 vec![
887 fieldtype_ref(vtable),
888 fieldtype_ref(string),
889 fieldtype_ref(string),
890 fieldtype_ref(string),
891 host_f64,
892 ],
893 Some(object),
894 )
895 });
896 types.ty().subtype(&SubType {
898 is_final: true,
899 ..substruct(
900 vec![
901 fieldtype_ref(vtable),
902 fieldtype_ref(string),
903 fieldtype_ref(string),
904 fieldtype_ref(string),
905 host_f64,
906 host_i64,
907 ],
908 Some(object),
909 )
910 });
911 types.ty().subtype(&SubType {
913 is_final: true,
914 ..substruct(
915 vec![
916 fieldtype_ref(vtable),
917 fieldtype_ref(string),
918 host_f64,
919 fieldtype_ref(string),
920 fieldtype_ref(string),
921 fieldtype_ref(array),
922 host_i64,
923 ],
924 Some(object),
925 )
926 });
927 types.ty().subtype(&SubType {
929 is_final: true,
930 ..substruct(vec![fieldtype_ref(vtable), host_externref], Some(object))
931 });
932 types.ty().subtype(&SubType {
934 is_final: true,
935 ..substruct(
936 vec![
937 fieldtype_ref(vtable),
938 fieldtype_ref(string),
939 host_object,
940 temporal_i32,
941 host_f64,
942 fieldtype_ref(string),
943 fieldtype_ref(string),
944 ],
945 Some(object),
946 )
947 });
948 types.ty().subtype(&SubType {
950 is_final: true,
951 ..substruct(
952 vec![
953 fieldtype_ref(vtable),
954 host_f64,
955 fieldtype_ref(string),
956 host_f64,
957 fieldtype_ref(string),
958 fieldtype_ref(string),
959 host_f64,
960 ],
961 Some(object),
962 )
963 });
964 types.ty().subtype(&SubType {
966 is_final: true,
967 ..substruct(
968 vec![fieldtype_ref(vtable), fieldtype_ref(string), host_f64],
969 Some(object),
970 )
971 });
972 types.ty().subtype(&SubType {
974 is_final: true,
975 ..substruct(
976 vec![
977 fieldtype_ref(vtable),
978 fieldtype_ref(array),
979 FieldType {
980 element_type: StorageType::Val(ref_null(object)),
981 mutable: false,
982 },
983 ],
984 Some(object),
985 )
986 });
987 types.ty().subtype(&SubType {
989 is_final: true,
990 ..substruct(
991 vec![
992 fieldtype_ref(vtable),
993 fieldtype_ref(string),
994 fieldtype_ref(string),
995 fieldtype_ref(string),
996 fieldtype_ref(string),
997 host_f64,
998 temporal_i32,
999 ],
1000 Some(object),
1001 )
1002 });
1003
1004 types.ty().subtype(&SubType {
1007 is_final: true,
1008 ..substruct(
1009 vec![
1010 fieldtype_ref(vtable),
1011 FieldType {
1012 element_type: StorageType::Val(ValType::I64),
1013 mutable: false,
1014 },
1015 ],
1016 Some(object),
1017 )
1018 });
1019
1020 IntrinsicTypeIndices {
1021 undefined,
1022 raw_string,
1023 vtable,
1024 object,
1025 string,
1026 boxed_number,
1027 boxed_boolean,
1028 field_names,
1029 object_shape,
1030 object_fields,
1031 to_string_fn,
1032 to_json_fn,
1033 equals_fn,
1034 hash_fn,
1035 field_getter,
1036 field_setter,
1037 raw_array,
1038 array,
1039 raw_uint8_array,
1040 uint8_array,
1041 closure,
1042 class_vtable,
1043 error_vtable,
1044 error,
1045 raw_bigint,
1046 bigint,
1047 regex_capture_array,
1048 regex_match,
1049 regex,
1050 regex_match_box,
1051 temporal_instant,
1052 temporal_duration,
1053 temporal_zdt,
1054 raw_index_array,
1055 map,
1056 set,
1057 url,
1058 fs_stat,
1059 fs_peek,
1060 fs_dir_entry,
1061 fs_info,
1062 fs_file_writer,
1063 http_response,
1064 http_download_result,
1065 session_entry,
1066 session_page,
1067 fs_mount_info,
1068 temporal_plain_date,
1069 temporal_plain_time,
1070 temporal_plain_date_time,
1071 temporal_plain_year_month,
1072 temporal_plain_month_day,
1073 }
1074}
1075
1076pub(crate) fn intrinsic_supertypes(
1085 indices: IntrinsicTypeIndices,
1086) -> impl IntoIterator<Item = (u32, u32)> {
1087 [
1088 (indices.undefined, indices.object),
1089 (indices.string, indices.object),
1090 (indices.boxed_number, indices.object),
1091 (indices.boxed_boolean, indices.object),
1092 (indices.object_shape, indices.object),
1093 (indices.array, indices.object),
1094 (indices.uint8_array, indices.object),
1095 (indices.closure, indices.object),
1096 (indices.class_vtable, indices.vtable),
1097 (indices.error_vtable, indices.class_vtable),
1098 (indices.error, indices.object_shape),
1099 (indices.bigint, indices.object),
1100 (indices.regex, indices.object),
1101 (indices.regex_match_box, indices.object),
1102 (indices.temporal_instant, indices.object),
1103 (indices.temporal_duration, indices.object),
1104 (indices.temporal_zdt, indices.object),
1105 (indices.map, indices.object),
1106 (indices.set, indices.object),
1107 (indices.url, indices.object),
1108 (indices.fs_stat, indices.object),
1109 (indices.fs_peek, indices.object),
1110 (indices.fs_dir_entry, indices.object),
1111 (indices.fs_info, indices.object),
1112 (indices.fs_file_writer, indices.object),
1113 (indices.http_response, indices.object),
1114 (indices.http_download_result, indices.object),
1115 (indices.session_entry, indices.object),
1116 (indices.session_page, indices.object),
1117 (indices.fs_mount_info, indices.object),
1118 (indices.temporal_plain_date, indices.object),
1119 (indices.temporal_plain_time, indices.object),
1120 (indices.temporal_plain_date_time, indices.object),
1121 (indices.temporal_plain_year_month, indices.object),
1122 (indices.temporal_plain_month_day, indices.object),
1123 ]
1124}
1125
1126pub(crate) fn push_string_literal(
1129 f: &mut wasm_encoder::Function,
1130 intrinsics: IntrinsicTypeIndices,
1131 string_vtable_global_idx: u32,
1132 text: &str,
1133) -> Result<(), crate::compiler_error::CompilerFailure> {
1134 use wasm_encoder::Instruction;
1135 f.instruction(&Instruction::GlobalGet(string_vtable_global_idx));
1136 let mut len = 0usize;
1137 for unit in text.encode_utf16() {
1138 f.instruction(&Instruction::I32Const(i32::from(unit)));
1139 len = len.saturating_add(1);
1140 }
1141 f.instruction(&Instruction::ArrayNewFixed {
1142 array_type_index: intrinsics.raw_string,
1143 array_size: super::wasm_u32(len)?,
1144 });
1145 f.instruction(&Instruction::I64Const(0));
1146 f.instruction(&Instruction::StructNew(intrinsics.string));
1147 Ok(())
1148}
1149
1150fn ref_to(idx: u32) -> ValType {
1151 ValType::Ref(RefType {
1152 nullable: false,
1153 heap_type: HeapType::Concrete(idx),
1154 })
1155}
1156
1157fn ref_null(idx: u32) -> ValType {
1158 ValType::Ref(RefType {
1159 nullable: true,
1160 heap_type: HeapType::Concrete(idx),
1161 })
1162}
1163
1164fn fieldtype_ref(idx: u32) -> FieldType {
1165 FieldType {
1166 element_type: StorageType::Val(ref_to(idx)),
1167 mutable: false,
1168 }
1169}
1170
1171fn substruct(fields: Vec<FieldType>, supertype: Option<u32>) -> SubType {
1172 SubType {
1173 is_final: false,
1174 supertype_idx: supertype,
1175 composite_type: CompositeType {
1176 inner: CompositeInnerType::Struct(StructType {
1177 fields: fields.into_boxed_slice(),
1178 }),
1179 shared: false,
1180 descriptor: None,
1181 describes: None,
1182 },
1183 }
1184}
1185
1186fn subfunc(params: Vec<ValType>, results: Vec<ValType>) -> SubType {
1187 SubType {
1188 is_final: false,
1189 supertype_idx: None,
1190 composite_type: CompositeType {
1191 inner: CompositeInnerType::Func(FuncType::new(params, results)),
1192 shared: false,
1193 descriptor: None,
1194 describes: None,
1195 },
1196 }
1197}
1198
1199#[cfg(test)]
1200mod tests {
1201 use std::collections::BTreeMap;
1202
1203 use super::{declare_intrinsic_types, intrinsic_supertypes};
1204 use wasm_encoder::{Module, TypeSection};
1205 use wasmparser::{Parser, Payload, Validator};
1206
1207 #[test]
1208 fn intrinsic_supertypes_match_declarations() {
1209 let mut module = Module::new();
1210 let mut types = TypeSection::new();
1211 let indices = declare_intrinsic_types(&mut types);
1212 module.section(&types);
1213 let bytes = module.finish();
1214
1215 let mut declared: BTreeMap<u32, u32> = BTreeMap::new();
1216 let mut next_idx = 0u32;
1217 for payload in Parser::new(0).parse_all(&bytes) {
1218 let Payload::TypeSection(reader) = payload.expect("parse intrinsic module") else {
1219 continue;
1220 };
1221 for group in reader {
1222 for sub in group.expect("read rec group").into_types() {
1223 if let Some(parent) = sub.supertype_idx {
1224 let parent = parent
1225 .as_module_index()
1226 .expect("intrinsic supertypes are module-level indices");
1227 declared.insert(next_idx, parent);
1228 }
1229 next_idx += 1;
1230 }
1231 }
1232 }
1233
1234 let table: BTreeMap<u32, u32> = intrinsic_supertypes(indices).into_iter().collect();
1235 assert_eq!(
1236 table, declared,
1237 "intrinsic_supertypes is out of step with declare_intrinsic_types",
1238 );
1239 }
1240
1241 #[test]
1242 fn intrinsic_types_self_contained_and_validate() {
1243 let mut module = Module::new();
1244 let mut types = TypeSection::new();
1245 let indices = declare_intrinsic_types(&mut types);
1246 module.section(&types);
1247
1248 let bytes = module.finish();
1249 Validator::new()
1250 .validate_all(&bytes)
1251 .expect("intrinsic types validate as a stand-alone module");
1252
1253 assert_eq!(indices.raw_string, 0);
1254 assert_eq!(indices.vtable, 1);
1255 assert_eq!(indices.object, 2);
1256 assert_eq!(indices.string, 3);
1257 assert_eq!(indices.boxed_number, 4);
1258 assert_eq!(indices.boxed_boolean, 5);
1259 assert_eq!(indices.field_names, 6);
1260 assert_eq!(indices.object_fields, 7);
1261 assert_eq!(indices.object_shape, 8);
1262 assert_eq!(indices.to_string_fn, 9);
1263 assert_eq!(indices.to_json_fn, 10);
1264 assert_eq!(indices.equals_fn, 11);
1265 assert_eq!(indices.hash_fn, 12);
1266 assert_eq!(indices.field_getter, 13);
1267 assert_eq!(indices.field_setter, 14);
1268 assert_eq!(indices.raw_array, 15);
1269 assert_eq!(indices.array, 16);
1270 assert_eq!(indices.raw_uint8_array, 17);
1271 assert_eq!(indices.uint8_array, 18);
1272 assert_eq!(indices.closure, 19);
1273 assert_eq!(indices.class_vtable, 20);
1274 assert_eq!(indices.error_vtable, 21);
1275 assert_eq!(indices.error, 22);
1276 assert_eq!(indices.raw_bigint, 23);
1277 assert_eq!(indices.bigint, 24);
1278 assert_eq!(indices.regex_capture_array, 25);
1279 assert_eq!(indices.regex_match, 26);
1280 assert_eq!(indices.regex, 27);
1281 assert_eq!(indices.regex_match_box, 28);
1282 assert_eq!(indices.temporal_instant, 29);
1283 assert_eq!(indices.temporal_duration, 30);
1284 assert_eq!(indices.temporal_zdt, 31);
1285 assert_eq!(indices.raw_index_array, 32);
1286 assert_eq!(indices.map, 33);
1287 assert_eq!(indices.set, 34);
1288 assert_eq!(indices.url, 35);
1289 assert_eq!(indices.temporal_plain_date, 36);
1290 assert_eq!(indices.temporal_plain_time, 37);
1291 assert_eq!(indices.temporal_plain_date_time, 38);
1292 assert_eq!(indices.temporal_plain_year_month, 39);
1293 assert_eq!(indices.temporal_plain_month_day, 40);
1294 assert_eq!(indices.fs_mount_info, 50);
1295 assert_eq!(indices.undefined, 51);
1296 assert_eq!(super::INTRINSIC_TYPE_COUNT, 52);
1297 }
1298}