Repository: evanw/miniffi Branch: main Commit: 6bb24fb5d5e3 Files: 815 Total size: 2.4 MB Directory structure: gitextract_elwbkvg6/ ├── Cargo.toml ├── LICENSE.md ├── README.md └── src/ ├── ast.rs ├── cpp.rs ├── lib.rs ├── rust.rs ├── scan.rs ├── swift.rs ├── tests/ │ ├── cases/ │ │ ├── demo_app.rs │ │ ├── demo_const.rs │ │ ├── demo_derive_eq.rs │ │ ├── demo_enum.rs │ │ ├── demo_keyword.rs │ │ ├── demo_order.rs │ │ ├── demo_trait.rs │ │ ├── fn_basic.rs │ │ ├── fn_basic_void.rs │ │ ├── fn_box_in.rs │ │ ├── fn_box_out.rs │ │ ├── fn_combo_in.rs │ │ ├── fn_combo_out.rs │ │ ├── fn_enum_in.rs │ │ ├── fn_enum_out.rs │ │ ├── fn_nested_in.rs │ │ ├── fn_nested_out.rs │ │ ├── fn_option_in.rs │ │ ├── fn_option_out.rs │ │ ├── fn_payload_in.rs │ │ ├── fn_payload_out.rs │ │ ├── fn_string.rs │ │ ├── fn_struct_in.rs │ │ ├── fn_struct_out.rs │ │ ├── fn_tuple_in.rs │ │ ├── fn_tuple_out.rs │ │ ├── fn_vec_in.rs │ │ ├── fn_vec_out.rs │ │ ├── mod.rs │ │ ├── trait_enum.rs │ │ ├── trait_export.rs │ │ ├── trait_export_import.rs │ │ ├── trait_export_nested.rs │ │ ├── trait_import.rs │ │ ├── trait_import_export.rs │ │ ├── trait_import_nested.rs │ │ ├── trait_import_struct_in.rs │ │ ├── trait_import_tuple_in.rs │ │ └── trait_string.rs │ ├── cpp.rs │ ├── mod.rs │ ├── snapshots/ │ │ ├── cpp_demo_app_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_app_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_const_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_const_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_derive_eq_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_derive_eq_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_enum_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_enum_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_keyword_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_keyword_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_order_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_order_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_trait_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_demo_trait_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_basic_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_basic_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_basic_void_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_basic_void_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_box_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_box_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_box_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_box_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_combo_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_combo_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_combo_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_combo_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_enum_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_enum_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_enum_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_enum_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_nested_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_nested_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_nested_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_nested_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_option_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_option_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_option_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_option_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_payload_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_payload_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_payload_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_payload_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_string_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_string_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_struct_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_struct_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_struct_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_struct_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_tuple_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_tuple_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_tuple_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_tuple_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_vec_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_vec_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_vec_out_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_fn_vec_out_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_enum_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_enum_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_export_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_export_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_export_import_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_export_import_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_export_nested_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_export_nested_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_export_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_export_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_nested_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_nested_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_struct_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_struct_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_tuple_in_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_import_tuple_in_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_string_2021/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── cpp_trait_string_2024/ │ │ │ ├── ffi.cpp │ │ │ ├── ffi.h │ │ │ └── miniffi.rs │ │ ├── swift_demo_app_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_app_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_const_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_const_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_derive_eq_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_derive_eq_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_enum_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_enum_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_keyword_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_keyword_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_order_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_order_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_trait_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_demo_trait_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_basic_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_basic_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_basic_void_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_basic_void_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_box_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_box_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_box_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_box_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_combo_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_combo_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_combo_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_combo_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_enum_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_enum_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_enum_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_enum_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_nested_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_nested_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_nested_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_nested_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_option_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_option_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_option_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_option_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_payload_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_payload_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_payload_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_payload_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_string_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_string_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_struct_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_struct_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_struct_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_struct_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_tuple_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_tuple_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_tuple_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_tuple_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_vec_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_vec_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_vec_out_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_fn_vec_out_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_enum_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_enum_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_export_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_export_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_export_import_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_export_import_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_export_nested_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_export_nested_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_export_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_export_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_nested_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_nested_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_struct_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_struct_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_tuple_in_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_import_tuple_in_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_string_2021/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── swift_trait_string_2024/ │ │ │ ├── ffi.h │ │ │ ├── ffi.swift │ │ │ └── miniffi.rs │ │ ├── wasm_demo_app_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_app_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_const_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_const_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_derive_eq_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_derive_eq_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_enum_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_enum_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_keyword_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_keyword_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_order_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_order_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_trait_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_demo_trait_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_basic_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_basic_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_basic_void_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_basic_void_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_box_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_box_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_box_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_box_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_combo_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_combo_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_combo_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_combo_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_enum_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_enum_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_enum_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_enum_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_nested_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_nested_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_nested_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_nested_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_option_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_option_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_option_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_option_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_payload_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_payload_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_payload_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_payload_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_string_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_string_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_struct_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_struct_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_struct_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_struct_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_tuple_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_tuple_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_tuple_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_tuple_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_vec_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_vec_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_vec_out_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_fn_vec_out_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_enum_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_enum_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_export_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_export_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_export_import_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_export_import_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_export_nested_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_export_nested_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_export_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_export_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_nested_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_nested_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_struct_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_struct_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_tuple_in_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_import_tuple_in_2024/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ ├── wasm_trait_string_2021/ │ │ │ ├── ffi.d.mts │ │ │ ├── ffi.mjs │ │ │ ├── ffi.mts │ │ │ └── miniffi.rs │ │ └── wasm_trait_string_2024/ │ │ ├── ffi.d.mts │ │ ├── ffi.mjs │ │ ├── ffi.mts │ │ └── miniffi.rs │ ├── swift.rs │ ├── warnings.rs │ └── wasm.rs ├── util.rs └── wasm.rs ================================================ FILE CONTENTS ================================================ ================================================ FILE: Cargo.toml ================================================ [package] name = "miniffi" version = "0.1.0" edition = "2021" license = "MIT" repository = "https://github.com/evanw/miniffi" description = "A simple but opinionated FFI system" exclude = ["src/tests"] [dependencies] proc-macro2 = { version = "1.0.60", features = ["span-locations"] } syn = { version = "2.0.0", default-features = false, features = ["full", "parsing", "printing"] } ================================================ FILE: LICENSE.md ================================================ Copyright 2025 Evan Wallace Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # miniffi > [!WARNING] > This project is on its first release. I'm still trying out the idea. It has > not been used in production. This is a simple but opinionated FFI system for Rust. It allows you to call Rust code from other languages, and vice versa. Some design principles: - Intended for writing platform-agnostic Rust with platform-specific details in the host language - FFI support is split into data (structs passed by copy) and code (traits passed by reference) - Rather than have a separate schema language, the public API in your `lib.rs` is your schema - The generated binding code is compact, dependency-free, and straightforward to integrate with ## Supported Features - Primitive types (`bool`, `i32`, `f64`, `String`, etc.) - Tuples - Structs - Enums - Top-level constants - Top-level functions - Traits (must be either `Box` or `Rc`) - `Vec` - `Option` - `Box` ## Available Targets - JavaScript/TypeScript (WASM) - Swift - C++ ## Example After setting everything up, using miniffi looks something like this. The following example Rust code (in `lib.rs`) demonstrates passing code and data back and forth between Rust and the host language: ```rs pub enum Level { Warning, Error, } pub trait Logger { fn log(&self, level: Level, text: &str); } pub trait Demo { fn run(&self, logger: Box); } pub fn get_demo() -> Box { struct DemoImpl; impl Demo for DemoImpl { fn run(&self, logger: Box) { logger.log(Level::Warning, "example"); } } Box::new(DemoImpl) } // This includes the binding code generated by miniffi include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); ``` Unlike other FFI systems, there are no annotations required to expose something from `lib.rs` to the host language other than using `pub` to mark things public. The miniffi build script parses `lib.rs`, extracts the supported parts of the public API, and generates FFI binding code both for Rust (the `miniffi.rs` file referenced above) and for the host language. Calling that example Rust code might look like this: In JavaScript/TypeScript: ```js import * as rust from "./miniffi.js" import fs from "fs" await rust.instantiate(fs.readFileSync( "./target/wasm32-unknown-unknown/debug/example.wasm")) rust.get_demo().run({ log(level, text) { if (level === rust.Level.Error) console.error("ERROR:", text) else if (level === rust.Level.Warning) console.warn("WARNING:", text) } }) ``` In Swift: ```swift class LoggerImpl : Logger { func log(_ level: Level, _ text: String) { if level == .Error { print("ERROR:", text) } else if level == .Warning { print("WARNING:", text) } } } get_demo().run(LoggerImpl()) ``` In C++: ```c++ #include #include "ffi.h" struct LoggerImpl : rust::Logger { void log(rust::Level level, std::string text) { if (level == rust::Level::Error) std::cout << "ERROR: " << text << std::endl; else if (level == rust::Level::Warning) std::cout << "WARNING: " << text << std::endl; } }; int main() { rust::get_demo()->run(std::make_unique()); return 0; } ``` More information about how to use miniffi can be found in the [documentation](https://docs.rs/miniffi/latest/miniffi/). ## Similar Projects These projects are much further along, and you may want to use them instead: - [UniFFI](https://github.com/mozilla/uniffi-rs) - [Diplomat](https://github.com/rust-diplomat/diplomat) - [Interoptopus](https://github.com/ralfbiedert/interoptopus) ================================================ FILE: src/ast.rs ================================================ use super::*; use std::collections::HashSet; use std::fmt::Write; pub struct AST { pub structs: Vec, pub enums: Vec, pub traits: Vec, pub consts: Vec, pub fns: Vec, } impl AST { pub fn rename_keywords(&mut self, keywords: &[&str]) { let keywords: HashSet<_> = keywords.iter().map(|x| *x).collect(); let mut names = NameSet::default(); for k in &keywords { names.add(k.to_string()); } // Avoid the "_" symbol in Rust names.add("_".to_string()); let rename_keywords_in_fn = move |f: &mut RustFn| { // Avoid cloning the set in the common case if !f .args .iter() .chain(f.returns.iter()) .any(|x| names.contains(x.name.as_str())) { return; } // Rename all relevant local identifiers let mut names = names.clone(); for arg in &mut f.args { arg.name = names.create(&arg.name); } if let Some(ret) = &mut f.returns { ret.name = names.create(&ret.name); } }; for f in &mut self.fns { rename_keywords_in_fn(f); } for t in &mut self.traits { for f in &mut t.fns { rename_keywords_in_fn(f); } } } } pub struct RustStruct { pub name: String, pub fields: Vec, pub derives_partial_eq: bool, } pub struct RustEnum { pub name: String, pub variants: Vec, pub derives_partial_eq: bool, } impl RustEnum { pub fn has_fields(&self) -> bool { self.variants.iter().any(|v| !v.fields.is_empty()) } } pub struct RustVariant { pub name: String, pub discriminant: i32, pub fields: Vec, } pub struct RustTrait { pub name: String, pub fns: Vec, } #[derive(Clone)] pub struct RustField { pub name: String, pub ty: RustType, } pub struct RustConst { pub name: String, pub ty: RustType, pub val: RustVal, } pub struct RustFn { pub name: String, pub args: Vec, pub returns: Option, } #[derive(Clone)] pub struct RustArg { pub name: String, pub ty: RustType, } #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum RustPtr { Box, Rc, } impl RustPtr { pub fn path(&self) -> &'static str { match self { RustPtr::Box => "Box", RustPtr::Rc => "std::rc::Rc", } } } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum RustType { Pair { rust: Box, other: Box, }, Verbatim(String), Bool, U8, U16, U32, Usize, U64, I8, I16, I32, Isize, I64, F32, F64, RefStr, OwnStr, Struct(usize), Enum(usize), DynTrait(usize), Ptr(RustPtr, Box), Vector(Box), Tuple(Vec), Optional(Box), ForeignHandle, } #[derive(Clone, Debug, PartialEq)] pub enum RustVal { Bool(bool), U8(u8), U16(u16), U32(u32), U64(u64), I8(i8), I16(i16), I32(i32), I64(i64), F32(f32), F64(f64), Str(String), } pub fn append_type_name_hint(out: &mut String, ast: &AST, ty: &RustType) { use RustType::*; match ty { Pair { rust, .. } => append_type_name_hint(out, ast, rust), Verbatim(text) => out.push_str(text), Bool => out.push_str("bool"), U8 => out.push_str("u8"), U16 => out.push_str("u16"), U32 => out.push_str("u32"), Usize => out.push_str("usize"), U64 => out.push_str("u64"), I8 => out.push_str("i8"), I16 => out.push_str("i16"), I32 => out.push_str("i32"), Isize => out.push_str("isize"), I64 => out.push_str("i64"), F32 => out.push_str("f32"), F64 => out.push_str("f64"), RefStr => out.push_str("str"), OwnStr => out.push_str("string"), Struct(index) => out.push_str(&ast.structs[*index].name), Enum(index) => out.push_str(&ast.enums[*index].name), DynTrait(index) => { out.push_str("dyn_"); out.push_str(&ast.traits[*index].name); } Ptr(kind, inner) => { out.push_str(match kind { RustPtr::Box => "box_", RustPtr::Rc => "rc_", }); append_type_name_hint(out, ast, &inner); } Vector(inner) => { out.push_str("vec_"); append_type_name_hint(out, ast, &inner); } Tuple(types) => { for (i, ty) in types.iter().enumerate() { if i > 0 { out.push_str("_"); } append_type_name_hint(out, ast, ty); } } Optional(inner) => { out.push_str("option_"); append_type_name_hint(out, ast, &inner); } ForeignHandle => out.push_str("ptr"), } } pub fn append_type_name_hints(out: &mut String, ast: &AST, types: &[RustType]) { let mut i = 0; while i < types.len() { if i > 0 { out.push('_'); } let ty = &types[i]; let mut counter = 1; i += 1; while i < types.len() && ty == &types[i] { counter += 1; i += 1; } if counter > 1 { _ = write!(out, "{counter}_"); } append_type_name_hint(out, ast, ty); } } ================================================ FILE: src/cpp.rs ================================================ use super::*; use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::hash::Hash; use std::rc::Rc; /// Use this target when the host language is C++. /// /// This needs to generate a source file (`.cpp`, `.cc`, etc.) and a header /// file (`.hpp`, `.h`, etc.). By default, the files will be named /// `miniffi.cpp` and `miniffi.h` and will be written to the directory /// containing your `Cargo.toml` file. You can customize these paths before /// calling [`build`](Target::build): /// /// ```no_run /// use miniffi::*; /// /// fn main() { /// CppTarget::new() /// .write_source_to("../app/rust.cpp") /// .write_header_to("../app/rust.h") /// .build(); /// } /// ``` /// /// Generated bindings for calling your Rust code from C++ will be placed in /// the `rust` namespace. For example, if your `src/lib.rs` looks like this: /// /// ```no_run /// pub fn add(left: u64, right: u64) -> u64 { /// left + right /// } /// /// # macro_rules! env { ($a:expr) => { $a } } /// # macro_rules! include { ($a:expr) => { $a } } /// include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); /// ``` /// /// You can call that from C++ like this: /// /// ```c++ /// #include /// #include "miniffi.h" /// /// int main() { /// std::cout << "1 + 2 = " << rust::add(1, 2) << std::endl; /// return 0; /// } /// ``` /// /// The generated code tries to map Rust types into the corresponding types /// from the C++ standard template library: /// /// | Rust type | C++ type | /// |-------------|--------------------------------------| /// | `String` | `std::string` | /// | `Vec` | `std::vector` | /// | `(A, B)` | `std::tuple` *(since C++11)* | /// | `Box` | `std::unique_ptr` *(since C++11)* | /// | `Rc` | `std::shared_ptr` *(since C++11)* | /// | `Option` | `std::optional` *(since C++17)* | /// /// Enums without fields are turned into a C++ enum struct: /// /// /// /// ///
RustC++
/// /// ``` /// // Exported enum in Rust /// pub enum Color { /// Window, /// Text, /// } /// /// // Example usage /// let color = Color::Text; /// let hex = match color { /// Color::Window => 0x353535, /// Color::Text => 0xD2991D, /// }; /// ``` /// /// /// /// ```c++ /// // Generated enum in C++ /// enum struct Color : int32_t { /// Window = 0, /// Text = 1, /// }; /// /// // Example usage /// auto color = Color::Text; /// int hex; /// if (color == Color::Window) /// hex = 0x353535; /// else if (color == Color::Text) /// hex = 0xD2991D; /// else /// std::abort(); /// ``` /// ///
/// /// Enums with fields use `std::variant` from C++17: /// /// /// /// ///
RustC++
/// /// ``` /// // Exported enum in Rust /// pub enum Color { /// Window, /// Text, /// RGB(u8, u8, u8), /// } /// /// // Example usage /// let color = Color::RGB(255, 0, 0); /// let hex = match color { /// Color::Window => 0x353535, /// Color::Text => 0xD2991D, /// Color::RGB(r, g, b) => /// u32::from_le_bytes([b, g, r, 0]), /// }; /// ``` /// /// /// /// ```c++ /// // Generated enum in C++ (approximately) /// struct Color : std::variant<...> { /// struct Window {}; /// struct Text {}; /// struct RGB { uint8_t _0, _1, _2; }; /// template bool is(); /// template T* as(); /// }; /// /// // Example usage /// Color color{ Color::RGB{ 255, 0, 0 } }; /// int hex; /// if (color.is()) /// hex = 0x353535; /// else if (color.is()) /// hex = 0xD2991D; /// else if (auto x = color.as()) /// hex = (x->_0 << 16) | (x->_1 << 8) | x->_2; /// else /// std::abort(); /// ``` /// ///
/// /// ## Using the command line /// /// If you are using C++ from the command line, then you can call Rust from /// C++ by compiling the generated `.cpp` file and linking that along with the /// compiled Rust code to the rest of your C++. For example: /// /// ```text /// # Build the Rust code /// cargo rustc --crate-type=staticlib /// /// # Build the C++ code /// c++ -std=c++17 main.cpp miniffi.cpp ./target/debug/libexample.a /// ``` pub struct CppTarget { common_options: CommonOptions, namespace: String, source_path: PathBuf, header_path: PathBuf, } impl CppTarget { pub fn new() -> CppTarget { CppTarget { common_options: CommonOptions::default(), namespace: "rust".to_string(), source_path: "miniffi.cpp".into(), header_path: "miniffi.h".into(), } } pub fn write_source_to>(mut self, path: T) -> Self { self.source_path = path.into(); self } pub fn write_header_to>(mut self, path: T) -> Self { self.header_path = path.into(); self } } pub const CPP_KEYWORDS: &[&str] = &[ "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t", "class", "compl", "concept", "const", "consteval", "constexpr", "constinit", "const_cast", "continue", "contract_assert", "co_await", "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "reflexpr", "register", "reinterpret_cast", "requires", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq", ]; #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] enum HeaderGroup { Include, ForwardDecl, Other, Constants, } #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] enum SourceGroup { Include, MultiRet, ExternCDecl, ExternCImpl, Anonymous, Other, } impl Compile for CppTarget { fn common_options(&mut self) -> &mut CommonOptions { &mut self.common_options } fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec { let syntax = RustSyntax::with_edition(self.common_options.edition); let mut rust_helpers = HelperSet::<(), String>::default(); let mut source_helpers = HelperSet::::default(); let mut header_helpers = HelperSet::::default(); add_common_rust_helpers(&syntax, &mut rust_helpers); ast.rename_keywords(CPP_KEYWORDS); for (name, code) in [ ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ("", "#include \n"), ] { source_helpers.add_group(SourceGroup::Include, name, code); header_helpers.add_group(HeaderGroup::Include, name, code); } source_helpers .add_group( SourceGroup::ExternCDecl, "_ffi_alloc", "void* _ffi_alloc(uintptr_t len);\n", ) .add_dep_group(SourceGroup::Include, ""); source_helpers .add_group( SourceGroup::ExternCDecl, "_ffi_dealloc", "void _ffi_dealloc(const void* ptr, uintptr_t capacity);\n", ) .add_dep_group(SourceGroup::Include, ""); source_helpers .add_group( SourceGroup::Anonymous, "_ffi_read", r#" template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } "#, ) .add_dep_group(SourceGroup::Include, ""); source_helpers .add_group( SourceGroup::Anonymous, "_ffi_write", r#" template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } "#, ) .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::Include, ""); source_helpers .add_group( SourceGroup::Anonymous, "_ffi_vec_to_rust", r" const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } ", ) .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::ExternCDecl, "_ffi_alloc"); source_helpers .add_group( SourceGroup::Anonymous, "_ffi_string_to_rust", r" const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } ", ) .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::ExternCDecl, "_ffi_alloc"); source_helpers .add_group( SourceGroup::Anonymous, "_ffi_string_from_rust", r" std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } ", ) .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::Include, "") .add_dep_group(SourceGroup::ExternCDecl, "_ffi_dealloc"); // Forward declarations for t in &ast.traits { header_helpers .add_group( HeaderGroup::ForwardDecl, &t.name, format!("struct {};\n", t.name), ) .set_is_forward_decl(); } for s in &ast.structs { header_helpers .add_group( HeaderGroup::ForwardDecl, &s.name, format!("struct {};\n", s.name), ) .set_is_forward_decl(); } for e in &ast.enums { header_helpers .add_group( HeaderGroup::ForwardDecl, &e.name, format!("struct {};\n", e.name), ) .set_is_forward_decl(); } // Traits for t in &ast.traits { let mut deps = HashSet::new(); let mut code = String::new(); _ = write!(code, "\nstruct {} {{\n", t.name); _ = write!(code, " virtual ~{}() {{}}\n", t.name); for f in &t.fns { code.push_str(" virtual "); CppTypeCtx { cpp: &mut code, ast: &ast, deps: &mut deps, include_group: HeaderGroup::Include, decl_groups: Some(DeclGroups { forward: HeaderGroup::ForwardDecl, full: HeaderGroup::Other, }), loc: TypeLoc::InsideRustNamespace, ns: &self.namespace, } .append_cpp_signature( f.returns.as_ref().map(|r| &r.ty), &f.name, None, &f.args, ); code.push_str(" = 0;\n"); } code.push_str("};\n"); header_helpers .add_group(HeaderGroup::Other, &t.name, code) .add_forward_decl_group(HeaderGroup::ForwardDecl, &t.name) .add_deps_group(deps) .mark_used(); } // Enums for e in &ast.enums { let mut code = String::new(); let mut enum_deps = HashSet::new(); if !e.has_fields() { // Enums without fields are just integers _ = write!(code, "\nenum struct {} : int32_t", e.name); code.push_str(" {\n"); for v in &e.variants { if v.discriminant == std::i32::MIN { // Avoid a Visual C++ warning _ = write!(code, " {} = {} - 1,\n", v.name, v.discriminant + 1); } else { _ = write!(code, " {} = {},\n", v.name, v.discriminant); } } code.push_str("};\n"); } else { // Enums with fields map to "std::variant" _ = write!(code, "\nstruct {} : std::variant {\n"); for v in &e.variants { _ = write!( code, " using {} = detail::{}__{};\n", v.name, e.name, v.name ); } _ = write!(code, " using std::variant::operator =;\n"); code.push_str( " template bool is() const { return std::holds_alternative(*this); }\n", ); code.push_str( " template const T* as() const { return std::get_if(this); }\n", ); code.push_str( " template T* as() { return std::get_if(this); }\n", ); code.push_str("};\n"); enum_deps.insert((HeaderGroup::Include, "".to_string())); // Declarations for the variants need to be written out separately let mut detail = String::new(); let mut detail_deps = HashSet::new(); let detail_name = format!("detail::{}", e.name); _ = write!(detail, "\nnamespace detail {{\n"); for v in &e.variants { _ = write!(detail, "\nstruct {}__{} {{\n", e.name, v.name); for f in &v.fields { detail.push_str(" "); CppTypeCtx { cpp: &mut detail, ast: &ast, deps: &mut detail_deps, include_group: HeaderGroup::Include, decl_groups: Some(DeclGroups { forward: HeaderGroup::ForwardDecl, full: HeaderGroup::Other, }), loc: TypeLoc::InsideRustNamespace, ns: &self.namespace, } .append_cpp_type(&f.ty, CppDecl::Full); _ = write!( detail, " {}{};\n", with_digit_prefix(&f.name), cpp_struct_field_init(&ast, &f.ty) ); } if e.derives_partial_eq { generate_operator_eq( &mut source_helpers, &format!("{}::detail", self.namespace), &format!("{}__{}", e.name, v.name), &v.fields, &mut detail, ); } detail.push_str("};\n"); } _ = write!(detail, "\n}} // namespace detail\n"); header_helpers .add_group(HeaderGroup::Other, &detail_name, detail) .add_deps_group(detail_deps); enum_deps.insert((HeaderGroup::Other, detail_name)); } header_helpers .add_group(HeaderGroup::Other, &e.name, code) .add_deps_group(enum_deps) .mark_used(); } // Structs for s in &ast.structs { let mut deps = HashSet::new(); let mut code = String::new(); _ = write!(code, "\nstruct {}", s.name); code.push_str(" {\n"); for f in &s.fields { code.push_str(" "); CppTypeCtx { cpp: &mut code, ast: &ast, deps: &mut deps, include_group: HeaderGroup::Include, decl_groups: Some(DeclGroups { forward: HeaderGroup::ForwardDecl, full: HeaderGroup::Other, }), loc: TypeLoc::InsideRustNamespace, ns: &self.namespace, } .append_cpp_type(&f.ty, CppDecl::Full); _ = write!( code, " {}{};\n", with_digit_prefix(&f.name), cpp_struct_field_init(&ast, &f.ty) ); } if s.derives_partial_eq { generate_operator_eq( &mut source_helpers, &self.namespace, &s.name, &s.fields, &mut code, ); } code.push_str("};\n"); header_helpers .add_group(HeaderGroup::Other, &s.name, code) .add_forward_decl_group(HeaderGroup::ForwardDecl, &s.name) .add_deps_group(deps) .mark_used(); } // Constants for c in &ast.consts { let mut deps = HashSet::new(); let mut code = String::new(); CppTypeCtx { cpp: &mut code, ast: &ast, deps: &mut deps, include_group: HeaderGroup::Include, decl_groups: Some(DeclGroups { forward: HeaderGroup::ForwardDecl, full: HeaderGroup::Other, }), loc: TypeLoc::ForConstant, ns: &self.namespace, } .append_cpp_type(&c.ty, CppDecl::Full); _ = write!(code, " const {} = ", c.name); append_cpp_val(&mut code, &c.val); code.push_str(";\n"); header_helpers .add_group(HeaderGroup::Constants, &c.name, code) .add_deps_group(deps) .mark_used(); } let mut ctx = CppCtx { syntax, namespace: self.namespace.clone(), rust_helpers, source_helpers, header_helpers, ..CppCtx::default() }; let mut header_fn_decls = String::new(); // Functions for f in &ast.fns { generate_cpp_to_rust_fn(&ast, &mut ctx, f, &mut header_fn_decls, None); } // Determine the path from the source to the header let path_to_header = path_relative_from( &self.header_path, &self.source_path.parent().unwrap_or(Path::new("")), ); let path_to_header = path_to_header.as_ref().unwrap_or(&self.header_path); let path_to_header = format!("{:?}", path_to_header.display()); // Assemble the Rust code let mut rust = format!("// {DO_NOT_EDIT_COMMENT}\n"); for it in ctx.rust_helpers.code_in_order() { rust.push_str(it); } // Assemble the C++ header let mut includes = HashSet::new(); let mut header = format!("// {DO_NOT_EDIT_COMMENT}\n"); let header_code = ctx.header_helpers.code_by_group_in_order(); header.push_str("\n#pragma once\n"); if let Some(code) = header_code.get(&HeaderGroup::Include) { header.push('\n'); for it in code { includes.insert(it); header.push_str(it); } } header.push_str("\nnamespace rust {\n"); if let Some(code) = header_code.get(&HeaderGroup::ForwardDecl) { header.push('\n'); for it in code { header.push_str(it); } } if let Some(code) = header_code.get(&HeaderGroup::Other) { for it in code { header.push_str(it); } } if let Some(code) = header_code.get(&HeaderGroup::Constants) { header.push('\n'); for it in code { header.push_str(it); } } header.push_str(&header_fn_decls); header.push_str("\n} // namespace rust\n"); // Assemble the C++ source let mut source = format!("// {DO_NOT_EDIT_COMMENT}\n"); let source_code = ctx.source_helpers.code_by_group_in_order(); _ = write!(source, "\n#include {path_to_header}\n"); if let Some(code) = source_code.get(&SourceGroup::Include) { for it in code { if !includes.contains(it) { source.push_str(it); } } } if let Some(code) = source_code.get(&SourceGroup::MultiRet) { for it in code { source.push_str(it); } } if let Some(code) = source_code.get(&SourceGroup::ExternCDecl) { source.push_str("\nextern \"C\" {\n\n"); for it in code { source.push_str(it); } source.push_str("\n} // extern \"C\"\n"); } if let Some(code) = source_code.get(&SourceGroup::Anonymous) { source.push_str("\nnamespace {\n"); for it in code { source.push_str(it); } source.push_str("\n} // namespace\n"); } if let Some(code) = source_code.get(&SourceGroup::ExternCImpl) { source.push_str("\nextern \"C\" {\n"); for it in code { source.push_str(it); } source.push_str("\n} // extern \"C\"\n"); } if let Some(code) = source_code.get(&SourceGroup::Other) { for it in code { source.push_str(it); } } vec![ FileData { path: rust_path, contents: rust, }, FileData { path: self.source_path.clone(), contents: source, }, FileData { path: self.header_path.clone(), contents: header, }, ] } } // C++ struct fields without an initializer are uninitialized, which means they // start off being random garbage. This can lead to undefined behavior and // security vulnerabilities. Always initialize all struct fields to avoid that. fn cpp_struct_field_init(ast: &AST, ty: &RustType) -> &'static str { use RustType::*; match ty { Bool => " = false", U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 => " = 0", F32 => " = 0.0f", F64 => " = 0.0", Enum(enum_index) if !ast.enums[*enum_index].has_fields() => "{}", _ => "", } } #[derive(Default)] struct CppCtx { syntax: RustSyntax, namespace: String, helper_names: NameSet, rust_helpers: HelperSet<(), String>, header_helpers: HelperSet, source_helpers: HelperSet, multi_ret_helpers: HashMap, String>, trait_to_rust_helpers: HashMap<(RustPtr, usize), String>, trait_to_cpp_helpers: HashMap<(RustPtr, usize), String>, vec_to_rust_helpers: HashMap, vec_to_cpp_helpers: HashMap, box_to_rust_helpers: HashMap, box_to_cpp_helpers: HashMap, enum_to_rust_helpers: HashMap, enum_to_cpp_helpers: HashMap, } #[derive(Default)] struct Transform { cpp: FnBuilder, rust: FnBuilder, ffi_args: Vec, buf: Option>, buf_status: BufStatus, buf_ref: &'static str, } struct TraitInfo<'a> { t: &'a RustTrait, kind: RustPtr, } impl TraitInfo<'_> { fn self_type(&self, ns: &str) -> RustType { RustType::Verbatim(match self.kind { RustPtr::Box => format!("{ns}::{}*", self.t.name), RustPtr::Rc => format!("std::shared_ptr<{ns}::{}>*", self.t.name), }) } fn cpp_name(&self) -> String { format!("_ffi_{:?}_{}", self.kind, self.t.name) } } fn generate_cpp_to_rust_fn( ast: &AST, ctx: &mut CppCtx, f: &RustFn, header: &mut String, trait_info: Option, ) { let ffi_name = ctx.helper_names.create(&match &trait_info { None => format!("_ffi_fn_{}", f.name), Some(info) => format!("_ffi_{:?}_{}__{}", info.kind, info.t.name, f.name), }); let mut names = NameSet::default(); for arg in &f.args { names.add(arg.name.clone()); } if let Some(ret) = &f.returns { names.add(ret.name.clone()); } let mut source_deps = HashSet::new(); // Transform the arguments let mut arg_tfm = Transform::default(); if let Some(info) = &trait_info { arg_tfm.rust.line(format!( "let _self = unsafe {{ &*(_self as *const {}) }};", info.kind.path(), info.t.name )); } for arg in &f.args { arg_tfm.cpp.mark_pure(&arg.name); transform_to_rust( ast, ctx, &mut names, &mut arg_tfm, &arg.name, &arg.ty, &mut source_deps, ); } arg_tfm.cpp.insert_deferred_lines_here(); // Generate the Rust call to the FFI function let mut rust_call = String::new(); if trait_info.is_some() { rust_call.push_str("_self."); } _ = write!(rust_call, "{}(", f.name); rust_call.push_str(&arg_tfm.rust.find_args(&f.args, RefInline)); rust_call.push(')'); // Transform the result let mut ret_tfm = Transform::default(); if let Some(ret) = &f.returns { ret_tfm.rust.decl(&ret.name, rust_call); transform_to_cpp( ast, ctx, &mut names, &mut ret_tfm, &ret.name, &ret.ty, &mut source_deps, ); } else { rust_call.push(';'); ret_tfm.rust.line(rust_call); } // Generate the C++ call to the FFI function let mut cpp_call = format!("{ffi_name}("); if trait_info.is_some() { cpp_call.push_str("_self"); if !arg_tfm.ffi_args.is_empty() { cpp_call.push_str(", "); } } cpp_call.push_str(&arg_tfm.cpp.find_args(&arg_tfm.ffi_args, RefStdMove)); cpp_call.push(')'); // Header { let mut header_deps = HashSet::new(); if trait_info.is_none() { header.push('\n'); } CppTypeCtx { cpp: header, ast, deps: &mut header_deps, include_group: HeaderGroup::Include, decl_groups: None, loc: match trait_info { None => TypeLoc::InsideRustNamespace, Some(_) => TypeLoc::OutsideRustNamespace, }, ns: &ctx.namespace, } .append_cpp_signature(f.returns.as_ref().map(|r| &r.ty), &f.name, None, &f.args); header.push_str(";\n"); ctx.header_helpers.mark_all_used_group(header_deps); } // Source: Other { // Handle the return values let mut fb = arg_tfm.cpp; match &ret_tfm.ffi_args[..] { [] => { cpp_call.push(';'); fb.line(cpp_call); } [arg] => fb.decl(&arg.name, cpp_call), _ => { let ret = names.create("multi_ret"); fb.decl(&ret, cpp_call); for (i, arg) in ret_tfm.ffi_args.iter().enumerate() { fb.decl(&arg.name, format!("{ret}._{i}")); } } }; fb.extend(ret_tfm.cpp); fb.insert_deferred_lines_here(); if let Some(ret) = &f.returns { let code = fb.find(&ret.name, &ret.ty, RefInline).code; fb.line(format!("return {code};")); } // Write out the final function let mut source = String::new(); let fn_name = &match &trait_info { None => format!("{}::{}", ctx.namespace, f.name), Some(info) => format!("{}::{}", info.cpp_name(), f.name), }; source.push('\n'); CppTypeCtx { cpp: &mut source, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_signature(f.returns.as_ref().map(|r| &r.ty), fn_name, None, &f.args); source.push_str(" {\n"); fb.write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); source.push_str("}\n"); source_deps.insert((SourceGroup::ExternCDecl, ffi_name.clone())); ctx.source_helpers .add_group(SourceGroup::Other, &fn_name, source) .add_deps_group(source_deps) .mark_used(); } // Source: ExternCDecl { let mut source_deps = HashSet::new(); let mut source = String::new(); let return_ty = match &ret_tfm.ffi_args[..] { [] => None, [arg] => Some(Cow::Borrowed(&arg.ty)), _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); source_deps.insert((SourceGroup::MultiRet, ty_name.clone())); Some(Cow::Owned(RustType::Verbatim(ty_name))) } }; CppTypeCtx { cpp: &mut source, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_signature( return_ty.as_deref(), &ffi_name, trait_info .as_ref() .map(|_| RustArg { name: "_self".into(), ty: RustType::ForeignHandle, }) .as_ref(), &arg_tfm.ffi_args, ); source.push_str(";\n"); ctx.source_helpers .add_group(SourceGroup::ExternCDecl, &ffi_name, source) .add_deps_group(source_deps); } // Rust { // Handle the return values let mut fb = arg_tfm.rust; fb.extend(ret_tfm.rust); fb.insert_deferred_lines_here(); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { let code = fb.find(&arg.name, &arg.ty, RefInline).code; fb.line(code); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); let args = fb.find_args(&ret_tfm.ffi_args, RefInline); fb.line(format!("{ty_name}({args})")); } } // Write out the final function let mut rust = String::new(); _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle()); _ = write!(rust, "extern \"C\" fn {ffi_name}("); if trait_info.is_some() { rust.push_str("_self: *const u8"); } for (i, arg) in arg_tfm.ffi_args.iter().enumerate() { if trait_info.is_some() || i > 0 { rust.push_str(", "); } _ = write!(rust, "{}: ", arg.name); append_rust_type(&mut rust, ast, &arg.ty); } rust.push(')'); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { rust.push_str(" -> "); append_rust_type(&mut rust, ast, &arg.ty); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust, " -> {ty_name}"); } } rust.push_str(" {\n"); fb.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&ffi_name, rust).mark_used(); } } fn generate_rust_to_cpp_fn( ast: &AST, ctx: &mut CppCtx, kind: RustPtr, t: &RustTrait, f: &RustFn, rust: &mut String, ) { let ffi_name = ctx .helper_names .create(&format!("_ffi_cpp_{kind:?}_{}__{}", t.name, f.name)); let mut names = NameSet::default(); for arg in &f.args { names.add(arg.name.clone()); } if let Some(ret) = &f.returns { names.add(ret.name.clone()); } let mut source_deps = HashSet::new(); // Transform the arguments let mut arg_tfm = Transform::default(); for arg in &f.args { arg_tfm.rust.mark_pure(&arg.name); transform_to_cpp( ast, ctx, &mut names, &mut arg_tfm, &arg.name, &arg.ty, &mut source_deps, ); } arg_tfm.rust.insert_deferred_lines_here(); // Generate the C++ call to the API function let mut cpp_call = String::new(); cpp_call.push_str(match kind { RustPtr::Box => "_self", RustPtr::Rc => "_self->get()", }); _ = write!(cpp_call, "->{}(", f.name); cpp_call.push_str(&arg_tfm.cpp.find_args(&f.args, RefStdMove)); cpp_call.push(')'); // Transform the result let mut ret_tfm = Transform::default(); if let Some(ret) = &f.returns { ret_tfm.cpp.decl(&ret.name, cpp_call); transform_to_rust( ast, ctx, &mut names, &mut ret_tfm, &ret.name, &ret.ty, &mut source_deps, ); } else { cpp_call.push(';'); ret_tfm.cpp.line(cpp_call); } // Generate the Rust call to the FFI function let mut rust_call = format!("unsafe {{ {ffi_name}(self.0"); if !arg_tfm.ffi_args.is_empty() { rust_call.push_str(", "); } rust_call.push_str(&arg_tfm.rust.find_args(&arg_tfm.ffi_args, RefInline)); rust_call.push_str(") }"); // Rust { // Handle the return values let mut fb = arg_tfm.rust; match &ret_tfm.ffi_args[..] { [] => { rust_call.push(';'); fb.line(rust_call); } [arg] => fb.decl(&arg.name, rust_call), _ => { let ret = names.create("multi_ret"); fb.decl(&ret, rust_call); for (i, arg) in ret_tfm.ffi_args.iter().enumerate() { fb.decl(&arg.name, format!("{ret}.{i}")); } } }; fb.extend(ret_tfm.rust); fb.insert_deferred_lines_here(); if let Some(ret) = &f.returns { let code = fb.find(&ret.name, &ret.ty, RefInline).code; fb.line(code); } // Write out the final function _ = write!(rust, "\n fn {}(&self", f.name); for arg in &f.args { _ = write!(rust, ", {}: ", arg.name); append_rust_type(rust, ast, &arg.ty); } rust.push(')'); if let Some(returns) = &f.returns { rust.push_str(" -> "); append_rust_type(rust, ast, &returns.ty); } rust.push_str(" {\n"); _ = write!( rust, " {} \"C\" {{ fn {ffi_name}(_: *const u8", ctx.syntax.unsafe_extern() ); for arg in &arg_tfm.ffi_args { _ = write!(rust, ", {}: ", arg.name); append_rust_type(rust, ast, &arg.ty); } match &ret_tfm.ffi_args[..] { [] => rust.push(')'), [arg] => { rust.push_str(") -> "); append_rust_type(rust, ast, &arg.ty); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust, ") -> {ty_name}"); } } rust.push_str("; }\n"); fb.write_to_rust(ast, rust, " "); rust.push_str(" }\n"); } // Source: ExternCImpl { // Handle the return values let mut fb = arg_tfm.cpp; fb.extend(ret_tfm.cpp); fb.insert_deferred_lines_here(); let return_ty = match &ret_tfm.ffi_args[..] { [] => None, [arg] => { let code = fb.find(&arg.name, &arg.ty, RefInline).code; fb.line(format!("return {code};")); Some(Cow::Borrowed(&arg.ty)) } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); let args = fb.find_args(&ret_tfm.ffi_args, RefStdMove); fb.line(format!("return {ty_name}{{{args}}};")); source_deps.insert((SourceGroup::MultiRet, ty_name.clone())); Some(Cow::Owned(RustType::Verbatim(ty_name))) } }; // Write out the final function let mut source = String::new(); source.push('\n'); CppTypeCtx { cpp: &mut source, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_signature( return_ty.as_deref(), &ffi_name, Some(&RustArg { name: "_self".into(), ty: TraitInfo { t, kind }.self_type(&ctx.namespace), }), &arg_tfm.ffi_args, ); source.push_str(" {\n"); fb.write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); source.push_str("}\n"); ctx.source_helpers .add_group(SourceGroup::ExternCImpl, &ffi_name, source) .add_deps_group(source_deps) .mark_used(); } } fn generate_operator_eq( source_helpers: &mut HelperSet, ns: &str, name: &str, fields: &[RustField], header: &mut String, ) { use RustType::*; fn cpp_type_contains_box(ty: &RustType) -> bool { match ty { Pair { other, .. } => cpp_type_contains_box(other), Vector(inner_ty) => cpp_type_contains_box(inner_ty), Optional(inner_ty) => cpp_type_contains_box(inner_ty), Ptr(kind, inner_ty) if *kind == RustPtr::Box => match &**inner_ty { DynTrait(_) => false, _ => true, }, Tuple(types) => types.iter().any(cpp_type_contains_box), _ => false, } } fn emit_eq( parts: &mut Vec, ty: &RustType, a: &str, b: &str, source_deps: &mut HashSet<(SourceGroup, String)>, ) { if !cpp_type_contains_box(ty) { parts.push(format!("{a} == {b}")); return; } match ty { Pair { other, .. } => emit_eq(parts, other, a, b, source_deps), Tuple(types) => { for (i, item_ty) in types.iter().enumerate() { let a = format!("std::get<{i}>({a})"); let b = format!("std::get<{i}>({b})"); emit_eq(parts, item_ty, &a, &b, source_deps); } } Ptr(_, inner_ty) => { let a = format!("*{a}"); let b = format!("*{b}"); emit_eq(parts, inner_ty, &a, &b, source_deps); } Optional(inner_ty) => { let mut inner_parts = Vec::new(); let inner_a = format!("*{a}"); let inner_b = format!("*{b}"); emit_eq(&mut inner_parts, inner_ty, &inner_a, &inner_b, source_deps); parts.push(if inner_parts.is_empty() { format!("!{a} == !{b}") } else { format!("({a} && {b} ? {} : !{a} && !{b})", inner_parts.join(" && ")) }); } Vector(inner_ty) => { let mut inner_parts = Vec::new(); emit_eq(&mut inner_parts, inner_ty, "a", "b", source_deps); parts.push(if inner_parts.is_empty() { format!("{a}.size() == {b}.size()") } else { source_deps.insert((SourceGroup::Include, "".into())); // For "std::equal" let a = if a.starts_with('*') { Cow::Owned(format!("({a})")) } else { Cow::Borrowed(a) }; let b = if b.starts_with('*') { Cow::Owned(format!("({b})")) } else { Cow::Borrowed(b) }; format!( "std::equal({a}.begin(), {a}.end(), {b}.begin(), {b}.end(), \ [](const auto& a, const auto& b) {{ return {}; }})", inner_parts.join(" && ") ) }); } _ => parts.push(format!("{a} == {b}")), } } let mut names = NameSet::default(); for f in fields { names.add(with_digit_prefix(&f.name).to_string()); } let other = names.create( &name .chars() .next() .unwrap() .to_ascii_lowercase() .to_string(), ); let mut parts = Vec::new(); let mut source_deps = HashSet::new(); for f in fields { let a = with_digit_prefix(&f.name); let b = format!("{other}.{a}"); emit_eq(&mut parts, &f.ty, &a, &b, &mut source_deps); } if parts.is_empty() { _ = write!( header, " bool operator == (const {name}&) const {{ return true; }}\n" ); } else { let mut source = format!("\nbool {ns}::{name}::operator == (const {ns}::{name}& {other}) const {{\n"); if parts.len() == 1 || parts.iter().map(|x| x.len()).sum::() < 100 { _ = write!(source, " return {};\n", parts.join(" && ")); } else { source.push_str(" return ("); for (i, part) in parts.iter().enumerate() { if i > 0 { source.push_str(" &&"); } source.push_str("\n "); source.push_str(part); } source.push_str("\n );\n"); } source.push_str("}\n"); _ = write!(header, " bool operator == (const {name}&) const;\n"); source_helpers .add_group(SourceGroup::Other, &format!("{name}::operator =="), source) .add_deps_group(source_deps) .mark_used(); } _ = write!( header, " bool operator != (const {name}& {other}) const {{ return !(*this == {other}); }}\n" ); } fn transform_to_rust( ast: &AST, ctx: &mut CppCtx, names: &mut NameSet, tfm: &mut Transform, name: &str, ty: &RustType, source_deps: &mut HashSet<(SourceGroup, String)>, ) { use RustType::*; fn add_ffi_arg( ast: &AST, ctx: &mut CppCtx, tfm: &mut Transform, source_deps: &mut HashSet<(SourceGroup, String)>, name: &str, ty: &RustType, ) { match tfm.buf_status { BufStatus::Outside => tfm.ffi_args.push(RustArg { name: name.to_string(), ty: ty.clone(), }), BufStatus::Inside => { let buf = tfm.buf.as_ref().unwrap(); // C++ (write) let code = tfm.cpp.find(name, ty, RefStdMove).code; tfm.cpp .line(format!("_ffi_write({code}, {});", buf.buf_name())); source_deps.insert((SourceGroup::Anonymous, "_ffi_write".into())); // Rust (read) let mut rust = "_ffi_read::<".to_string(); append_rust_type(&mut rust, ast, ty); _ = write!(rust, ">({}{})", tfm.buf_ref, buf.end_name()); tfm.rust.decl(name, rust); ctx.rust_helpers.mark_used("_ffi_read"); } } } match ty { Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => add_ffi_arg(ast, ctx, tfm, source_deps, name, ty), RefStr | OwnStr => { let cpp_code = tfm.cpp.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let len_name = names.create(&format!("{name}_len")); let opt_ref = match ty { RefStr => "&", _ => "", }; tfm.cpp.line(format!("uintptr_t {len_name};")); tfm.cpp.line(format!( "const void* {ptr_name} = _ffi_string_to_rust({cpp_code}, {len_name});" )); ctx.source_helpers .mark_used_group(SourceGroup::Anonymous, "_ffi_string_to_rust"); add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ForeignHandle); add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize); let len_code = tfm.rust.find(&len_name, &Usize, RefInline).code; let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.rust.decl( name, format!("{opt_ref}_ffi_string_from_host({ptr_code}, {len_code})"), ); ctx.rust_helpers.mark_used("_ffi_string_from_host"); } Enum(enum_index) => { let e = &ast.enums[*enum_index]; let (cpp_helper, rust_helper) = enum_to_rust_helper(ast, ctx, *enum_index); if !e.has_fields() { let cpp = tfm.cpp.find(name, ty, RefInline); let raw_name = names.create(&format!("{name}_raw")); tfm.cpp .maybe_pure_decl(cpp.pure, &raw_name, format!("int32_t({})", cpp.code)); add_ffi_arg(ast, ctx, tfm, source_deps, &raw_name, &I32); tfm.rust.decl(name, format!("{rust_helper}({raw_name})")); } else { let cpp = tfm.cpp.find(name, ty, RefStdMove); let buf = ensure_cpp_buf(ctx, names, tfm, source_deps); tfm.cpp .line(format!("{cpp_helper}({}, {});", cpp.code, buf.buf_name())); source_deps.insert((SourceGroup::Anonymous, cpp_helper)); tfm.rust.decl( name, format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()), ); } } Struct(struct_index) => { let cpp = tfm.cpp.find(name, ty, RefMany); let s = &ast.structs[*struct_index]; let mut item_names = Vec::new(); for f in &s.fields { let item_name = names.create(&format!("{name}_{}", f.name)); tfm.cpp.maybe_pure_decl( cpp.pure, &item_name, format!("{}.{}", cpp.code, with_digit_prefix(&f.name)), ); transform_to_rust(ast, ctx, names, tfm, &item_name, &f.ty, source_deps); item_names.push(item_name.into()); } if s.fields.is_empty() { // Avoid an unused variable warning in C++ let code = tfm.cpp.find(name, ty, RefInline).code; tfm.cpp.line(format!("(void){code};")); } rust_decl_ctor(&mut tfm.rust, name, &s.name, &s.fields, item_names); } Tuple(types) => { let cpp = tfm.cpp.find(name, ty, RefMany); let mut item_args = Vec::new(); for (i, item_ty) in types.iter().enumerate() { let item_name = names.create(&format!("{name}_{i}")); tfm.cpp.maybe_pure_decl( cpp.pure, &item_name, format!("std::get<{i}>({})", cpp.code), ); transform_to_rust(ast, ctx, names, tfm, &item_name, &item_ty, source_deps); item_args.push(RustArg { name: item_name, ty: item_ty.clone(), }); } if types.is_empty() { // Avoid an unused variable warning in C++ let code = tfm.cpp.find(name, ty, RefInline).code; tfm.cpp.line(format!("(void){code};")); } let mut rust_code = tfm.rust.find_args(&item_args, RefInline); if types.len() == 1 { rust_code.push(','); } tfm.rust.decl(name, format!("({rust_code})")); } Ptr(kind, inner_ty) => { if let DynTrait(trait_index) = &**inner_ty { let cpp_code = tfm.cpp.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let rust_helper = trait_to_rust_helper(ast, ctx, *trait_index, *kind); let cpp_code = match kind { RustPtr::Box => format!("{cpp_code}.release()"), RustPtr::Rc => format!( "new std::shared_ptr<{}::{}>({cpp_code})", ctx.namespace, ast.traits[*trait_index].name ), }; tfm.cpp.decl(&ptr_name, cpp_code); add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ForeignHandle); let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.rust.decl( name, format!("{}::new({rust_helper}({ptr_code}))", kind.path()), ); } else if *kind == RustPtr::Box { let cpp_code = tfm.cpp.find(name, ty, RefMany).code; let (cpp_helper, rust_helper) = box_to_rust_helper(ast, ctx, inner_ty); let buf = ensure_cpp_buf(ctx, names, tfm, source_deps); tfm.cpp.line(format!( "{cpp_helper}(std::move(*{cpp_code}), {});", buf.buf_name() )); source_deps.insert((SourceGroup::Anonymous, cpp_helper)); tfm.rust.decl( name, format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()), ); } else { unreachable!() } } Vector(inner_ty) => { let cpp_code = tfm.cpp.find(name, ty, RefMany).code; let len_name = names.create(&format!("{name}_len")); let (cpp_helper, rust_helper) = vec_to_rust_helper(ast, ctx, inner_ty); let buf = ensure_cpp_buf(ctx, names, tfm, source_deps); tfm.cpp.decl(&len_name, format!("{cpp_code}.size()")); add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize); tfm.cpp.line(format!( "{cpp_helper}(std::move({cpp_code}), {});", buf.buf_name() )); source_deps.insert((SourceGroup::Anonymous, cpp_helper)); let len_code = tfm.rust.find(&len_name, ty, RefInline).code; tfm.rust.decl( name, format!( "{rust_helper}({len_code}, {}{})", tfm.buf_ref, buf.end_name() ), ); } Optional(inner_ty) => { let cpp_code = tfm.cpp.find(name, ty, RefMany).code; let has_name = names.create(&format!("has_{name}")); let val_name = names.create(&format!("{name}_val")); ensure_cpp_buf(ctx, names, tfm, source_deps); tfm.cpp.decl(&has_name, format!("{cpp_code}.has_value()")); add_ffi_arg(ast, ctx, tfm, source_deps, &has_name, &Bool); let mut rust = FnBuilder::default(); tfm.cpp.line(format!("if ({has_name}) {{")); tfm.cpp.pure_decl(&val_name, format!("{cpp_code}.value()")); { let old = tfm.buf_status; tfm.buf_status = BufStatus::Inside; std::mem::swap(&mut tfm.rust, &mut rust); transform_to_rust(ast, ctx, names, tfm, &val_name, inner_ty, source_deps); std::mem::swap(&mut tfm.rust, &mut rust); tfm.buf_status = old; } tfm.cpp.line("}".into()); let has_code = tfm.rust.find(&has_name, ty, RefInline).code; let val_code = rust.find(&val_name, ty, RefInline).code; if rust.is_empty() { tfm.rust .decl(name, format!("{has_code}.then(|| {val_code})")); } else { rust.insert_deferred_lines_here(); rust.line(val_code); tfm.rust.line(format!("let {name} = {has_code}.then(|| {{")); tfm.rust.extend(rust); tfm.rust.line("});".to_string()); } } Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(), } } fn transform_to_cpp( ast: &AST, ctx: &mut CppCtx, names: &mut NameSet, tfm: &mut Transform, name: &str, ty: &RustType, source_deps: &mut HashSet<(SourceGroup, String)>, ) { use RustType::*; fn add_ffi_arg( ast: &AST, ctx: &mut CppCtx, tfm: &mut Transform, source_deps: &mut HashSet<(SourceGroup, String)>, name: &str, ty: &RustType, ) { match tfm.buf_status { BufStatus::Outside => tfm.ffi_args.push(RustArg { name: name.to_string(), ty: ty.clone(), }), BufStatus::Inside => { let buf = tfm.buf.as_ref().unwrap(); // Rust (write) let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!( "_ffi_write({code}, {}{});", tfm.buf_ref, buf.buf_name() )); ctx.rust_helpers.mark_used("_ffi_write"); // C++ (read) let mut source = "_ffi_read<".to_string(); CppTypeCtx { cpp: &mut source, ast, deps: source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(ty, CppDecl::Full); _ = write!(source, ">({})", buf.end_name()); tfm.cpp.decl(name, source); source_deps.insert((SourceGroup::Anonymous, "_ffi_read".into())); } } } match ty { Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => add_ffi_arg(ast, ctx, tfm, source_deps, name, ty), RefStr | OwnStr => { let mut rust_code = tfm.rust.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let len_name = names.create(&format!("{name}_len")); let cap_name = names.create(&format!("{name}_cap")); let ptr_ty = Pair { rust: ForeignHandle.into(), other: Verbatim("const char*".into()).into(), }; if let RefStr = ty { rust_code.push_str(".into()"); } tfm.rust.line(format!( "let ({ptr_name}, {len_name}, {cap_name}) = _ffi_string_to_host({rust_code});" )); ctx.rust_helpers.mark_used("_ffi_string_to_host"); add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ptr_ty); add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize); add_ffi_arg(ast, ctx, tfm, source_deps, &cap_name, &Usize); tfm.cpp.decl( name, format!("_ffi_string_from_rust({ptr_name}, {len_name}, {cap_name})"), ); source_deps.insert((SourceGroup::Anonymous, "_ffi_string_from_rust".into())); } Enum(enum_index) => { let rust = tfm.rust.find(name, ty, RefInline); let e = &ast.enums[*enum_index]; if !e.has_fields() { let raw_name = names.create(&format!("{name}_raw")); tfm.rust .maybe_pure_decl(rust.pure, &raw_name, format!("{} as i32", rust.code)); add_ffi_arg(ast, ctx, tfm, source_deps, &raw_name, &I32); tfm.cpp .decl(name, format!("{}::{}({raw_name})", ctx.namespace, e.name)); } else { let (cpp_helper, rust_helper) = enum_to_cpp_helper(ast, ctx, *enum_index); let buf = ensure_rust_buf(ctx, names, tfm, source_deps); tfm.rust.line(format!( "{rust_helper}({}, {}{});", rust.code, tfm.buf_ref, buf.buf_name() )); tfm.cpp .decl(name, format!("{cpp_helper}({})", buf.end_name())); source_deps.insert((SourceGroup::Anonymous, cpp_helper)); } } Struct(struct_index) => { let rust = tfm.rust.find(name, ty, RefMany); let s = &ast.structs[*struct_index]; let mut item_args = Vec::new(); for f in &s.fields { let item_name = names.create(&format!("{name}_{}", f.name)); tfm.rust.maybe_pure_decl( rust.pure, &item_name, format!("{}.{}", rust.code, f.name), ); transform_to_cpp(ast, ctx, names, tfm, &item_name, &f.ty, source_deps); item_args.push(RustArg { name: item_name, ty: f.ty.clone(), }); } if s.fields.is_empty() { // Avoid an unused variable warning in Rust let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!("_ = {code};")); } let fields = tfm.cpp.find_args(&item_args, RefStdMove); tfm.cpp .decl(name, format!("{}::{}{{{fields}}}", ctx.namespace, s.name)); } Tuple(types) => { let rust = tfm.rust.find(name, ty, RefMany); let mut item_args = Vec::new(); for (i, item_ty) in types.iter().enumerate() { let item_name = names.create(&format!("{name}_{i}")); tfm.rust .maybe_pure_decl(rust.pure, &item_name, format!("{}.{i}", rust.code)); transform_to_cpp(ast, ctx, names, tfm, &item_name, &item_ty, source_deps); item_args.push(RustArg { name: item_name, ty: item_ty.clone(), }); } if types.is_empty() { tfm.cpp.decl(name, "std::tuple<>()".to_string()); // Avoid an unused variable warning in Rust let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!("_ = {code};")); } else { let cpp_code = tfm.cpp.find_args(&item_args, RefStdMove); tfm.cpp.decl( name, match types.len() { 1 => cpp_code, _ => format!("std::make_tuple({cpp_code})"), }, ); } } Ptr(kind, inner_ty) => { if let DynTrait(trait_index) = &**inner_ty { let rust_code = tfm.rust.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let cpp_helper = trait_to_cpp_helper(ast, ctx, *trait_index, *kind); tfm.rust.decl( &ptr_name, format!("Box::into_raw(Box::new({rust_code})) as *const u8"), ); add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ForeignHandle); tfm.cpp.decl( name, match kind { RustPtr::Box => { let mut cpp_type = String::new(); CppTypeCtx { cpp: &mut cpp_type, ast, deps: source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(inner_ty, CppDecl::Forward); format!("std::unique_ptr<{cpp_type}>(new {cpp_helper}({ptr_name}))") } RustPtr::Rc => format!("std::make_shared<{cpp_helper}>({ptr_name})"), }, ); } else if *kind == RustPtr::Box { let rust_code = tfm.rust.find(name, ty, RefMany).code; let (cpp_helper, rust_helper) = box_to_cpp_helper(ast, ctx, inner_ty); let buf = ensure_rust_buf(ctx, names, tfm, source_deps); tfm.rust.line(format!( "{rust_helper}(*{rust_code}, {}{});", tfm.buf_ref, buf.buf_name() )); tfm.cpp .decl(name, format!("{cpp_helper}({})", buf.end_name())); source_deps.insert((SourceGroup::Anonymous, cpp_helper)); } else { unreachable!() } } Vector(inner_ty) => { let rust_code = tfm.rust.find(name, ty, RefMany).code; let len_name = names.create(&format!("{name}_len")); let (cpp_helper, rust_helper) = vec_to_cpp_helper(ast, ctx, inner_ty); let buf = ensure_rust_buf(ctx, names, tfm, source_deps); tfm.rust.decl(&len_name, format!("{rust_code}.len()")); add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize); tfm.rust.line(format!( "{rust_helper}({rust_code}, {}{});", tfm.buf_ref, buf.buf_name() )); let len_code = tfm.cpp.find(&len_name, ty, RefMany).code; tfm.cpp.decl( name, format!("{cpp_helper}({len_code}, {})", buf.end_name()), ); source_deps.insert((SourceGroup::Anonymous, cpp_helper)); } Optional(inner_ty) => { let rust_code = tfm.rust.find(name, ty, RefMany).code; let has_name = names.create(&format!("has_{name}")); let val_name = names.create(&format!("{name}_val")); ensure_rust_buf(ctx, names, tfm, source_deps); tfm.rust.decl(&has_name, format!("{rust_code}.is_some()")); add_ffi_arg(ast, ctx, tfm, source_deps, &has_name, &Bool); let mut cpp = FnBuilder::default(); tfm.rust .line(format!("if let Some({val_name}) = {rust_code} {{")); { let old = tfm.buf_status; tfm.buf_status = BufStatus::Inside; std::mem::swap(&mut tfm.cpp, &mut cpp); transform_to_cpp(ast, ctx, names, tfm, &val_name, inner_ty, source_deps); std::mem::swap(&mut tfm.cpp, &mut cpp); tfm.buf_status = old; } tfm.rust.line("}".into()); let has_code = tfm.cpp.find(&has_name, ty, RefInline).code; let mut val_code = cpp.find(&val_name, ty, RefInline).code; val_code = format!("std::make_optional({val_code})"); if cpp.is_empty() { tfm.cpp .decl(name, format!("{has_code} ? {val_code} : std::nullopt")); } else { let mut cpp_ty = String::new(); CppTypeCtx { cpp: &mut cpp_ty, ast, deps: source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(ty, CppDecl::Full); cpp.insert_deferred_lines_here(); cpp.line(format!("{name} = {val_code};")); tfm.cpp.line(format!("{cpp_ty} {name};")); tfm.cpp.line(format!("if ({has_code}) {{")); tfm.cpp.extend(cpp); tfm.cpp.line("}".to_string()); } } Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(), } } fn ensure_cpp_buf( ctx: &mut CppCtx, names: &mut NameSet, tfm: &mut Transform, source_deps: &mut HashSet<(SourceGroup, String)>, ) -> Rc { if let Some(buf) = &tfm.buf { return buf.clone(); } let buf_name = names.create("buf"); let ptr_name = names.create("buf_ptr"); let end_name = names.create("buf_end"); let buf = SharedBuf::new(&buf_name, &end_name); // C++ (write) tfm.cpp.line(format!("std::vector {buf_name};")); tfm.cpp .defer_decl(&ptr_name, format!("_ffi_vec_to_rust({buf_name})")); source_deps.insert((SourceGroup::Anonymous, "_ffi_vec_to_rust".into())); // Rust (read) tfm.rust.line_alt( // Avoid a warning about an unnecessarily mutable variable format!("let {end_name} = {ptr_name};"), format!("let mut {end_name} = {ptr_name};"), buf.is_buf_name_used_flag(), ); tfm.rust .defer_line(format!("_ffi_buf_from_host({ptr_name}, {end_name});")); ctx.rust_helpers.mark_used("_ffi_buf_from_host"); // FFI tfm.buf = Some(buf.clone()); tfm.buf_ref = "&mut "; tfm.ffi_args.push(RustArg { name: ptr_name, ty: RustType::ForeignHandle, }); buf } fn ensure_rust_buf( ctx: &mut CppCtx, names: &mut NameSet, tfm: &mut Transform, source_deps: &mut HashSet<(SourceGroup, String)>, ) -> Rc { if let Some(buf) = &tfm.buf { return buf.clone(); } let buf_name = names.create("buf"); let ptr_name = names.create("buf_ptr"); let end_name = names.create("buf_end"); let cap_name = names.create("buf_cap"); let buf = SharedBuf::new(&buf_name, &end_name); // Rust (write) tfm.rust.line_alt( // Avoid a warning about an unnecessarily mutable variable format!("let {buf_name} = Vec::::new();"), format!("let mut {buf_name} = Vec::::new();"), buf.is_buf_name_used_flag(), ); tfm.rust.defer_line(format!( "let ({ptr_name}, {cap_name}) = _ffi_buf_to_host({buf_name});" )); ctx.rust_helpers.mark_used("_ffi_buf_to_host"); // C++ (read) tfm.cpp.line_alt( "".to_string(), format!("auto {end_name} = (const uint8_t*){ptr_name};"), buf.is_end_name_used_flag(), ); tfm.cpp .defer_line(format!("_ffi_dealloc({ptr_name}, {cap_name});")); source_deps.insert((SourceGroup::ExternCDecl, "_ffi_dealloc".into())); // FFI tfm.buf = Some(buf.clone()); tfm.buf_ref = "&mut "; tfm.ffi_args.push(RustArg { name: ptr_name, ty: RustType::ForeignHandle, }); tfm.ffi_args.push(RustArg { name: cap_name, ty: RustType::Usize, }); buf } fn vec_to_rust_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.vec_to_rust_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_vec_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let cpp_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_cpp")); let cpp_name_decl = format!("{cpp_name}[decl]"); // This must be done first to avoid a stack overflow ctx.vec_to_rust_helpers .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let vec_name = locals.create("items"); let item_name = locals.create("item"); let end_name = locals.create("end"); let len_name = locals.create("len"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let mut source_deps = HashSet::new(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.cpp.mark_pure(&item_name); transform_to_rust( ast, ctx, &mut locals, &mut tfm, &item_name, &inner_ty, &mut source_deps, ); let item_code = tfm.rust.find(&item_name, inner_ty, RefInline).code; tfm.rust.line(format!("{vec_name}.push({item_code});")); // Source (forward declaration) let mut cpp_ty = String::new(); { let mut source_deps = HashSet::new(); CppTypeCtx { cpp: &mut cpp_ty, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(inner_ty, CppDecl::Full); let source = format!( "\nvoid {cpp_name}(std::vector<{cpp_ty}>&& {vec_name}, std::vector& {buf_name});\n" ); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name_decl, source) .set_is_forward_decl(); } // Source { let mut source = format!( "\nvoid {cpp_name}(std::vector<{cpp_ty}>&& {vec_name}, std::vector& {buf_name}) {{\n" ); if !tfm.cpp.is_empty() { _ = write!(source, " for (auto&& {item_name} : {vec_name}) {{\n"); tfm.cpp .write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); source.push_str(" }\n"); } source.push_str("}\n"); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl) .add_deps_group(source_deps); } // Rust { let mut rust = String::new(); let mut item_ty = String::new(); let end_name = buf.final_end_name_for_rust(); append_rust_type(&mut item_ty, ast, inner_ty); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({len_name}: usize, {end_name}: &mut *const u8) -> Vec<{item_ty}> {{\n" ); _ = write!( rust, " let mut {vec_name} = Vec::<{item_ty}>::with_capacity({len_name});\n" ); _ = write!(rust, " for _ in 0..{len_name} {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); _ = write!(rust, " {vec_name}\n"); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } (cpp_name, rust_name) } fn vec_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.vec_to_cpp_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_vec_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let cpp_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_cpp")); let cpp_name_decl = format!("{cpp_name}[decl]"); // This must be done first to avoid a stack overflow ctx.vec_to_cpp_helpers .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let vec_name = locals.create("items"); let item_name = locals.create("item"); let end_name = locals.create("end"); let len_name = locals.create("len"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let mut source_deps = HashSet::new(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.rust.mark_pure(&item_name); transform_to_cpp( ast, ctx, &mut locals, &mut tfm, &item_name, &inner_ty, &mut source_deps, ); let item_code = tfm.cpp.find(&item_name, inner_ty, RefStdMove).code; tfm.cpp .line(format!("{vec_name}.emplace_back({item_code});")); // Rust { let mut rust = String::new(); let buf_name = buf.final_buf_name_for_rust(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({vec_name}: Vec<"); append_rust_type(&mut rust, ast, inner_ty); _ = write!(rust, ">, {buf_name}: &mut Vec) {{\n"); if !tfm.rust.is_empty() { _ = write!(rust, " for {item_name} in {vec_name} {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } // Source (forward declaration) let mut cpp_ty = String::new(); { let mut source_deps = HashSet::new(); CppTypeCtx { cpp: &mut cpp_ty, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(inner_ty, CppDecl::Full); let source = format!( "\nstd::vector<{cpp_ty}> {cpp_name}(uintptr_t {len_name}, const uint8_t*& {end_name});\n" ); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name_decl, source) .set_is_forward_decl(); } // Source { let mut source = String::new(); _ = write!( source, " std::vector<{cpp_ty}> {cpp_name}(uintptr_t {len_name}, const uint8_t*& {end_name}) {{ std::vector<{cpp_ty}> {vec_name}; {vec_name}.reserve({len_name}); while ({vec_name}.size() < {len_name}) {{ " ); tfm.cpp .write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); source.push_str(" }\n"); _ = write!(source, " return {vec_name};\n"); source.push_str("}\n"); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl) .add_deps_group(source_deps); } (cpp_name, rust_name) } fn trait_to_rust_helper(ast: &AST, ctx: &mut CppCtx, trait_index: usize, kind: RustPtr) -> String { if let Some(result) = ctx.trait_to_rust_helpers.get(&(kind, trait_index)) { return result.clone(); } let t = &ast.traits[trait_index]; let rust_name = format!("_ffi_rs_{kind:?}_{}", t.name); let drop_name = format!("_ffi_cpp_drop_{kind:?}_{}", t.name); // This must be done first to avoid a stack overflow ctx.trait_to_rust_helpers .insert((kind, trait_index), rust_name.clone()); // Source: ExternCImpl { let mut source = String::new(); let mut source_deps = HashSet::new(); source.push('\n'); CppTypeCtx { cpp: &mut source, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_signature( None, &drop_name, None, &[RustArg { name: "self".to_string(), ty: TraitInfo { t, kind }.self_type(&ctx.namespace), }], ); source.push_str(" {\n"); source.push_str(" delete self;\n"); source.push_str("}\n"); ctx.source_helpers .add_group(SourceGroup::ExternCImpl, &drop_name, source) .add_deps_group(source_deps) .mark_used(); } // Rust { let mut rust = String::new(); allow_non_camel_case_types(&mut rust, &rust_name); _ = write!(rust, "\nstruct {rust_name}(*const u8);\n"); _ = write!(rust, "\nimpl Drop for {rust_name} {{\n"); rust.push_str(" fn drop(&mut self) {\n"); _ = write!( rust, " {} \"C\" {{ fn {drop_name}(_: *const u8); }}\n", ctx.syntax.unsafe_extern() ); _ = write!(rust, " unsafe {{ {drop_name}(self.0) }};\n"); rust.push_str(" }\n"); rust.push_str("}\n"); _ = write!(rust, "\nimpl {} for {rust_name} {{", t.name); for f in &t.fns { generate_rust_to_cpp_fn(ast, ctx, kind, t, f, &mut rust); } rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } rust_name } fn trait_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, trait_index: usize, kind: RustPtr) -> String { if let Some(result) = ctx.trait_to_cpp_helpers.get(&(kind, trait_index)) { return result.clone(); } let t = &ast.traits[trait_index]; let drop_name = format!("_ffi_drop_{kind:?}_{}", t.name); let cpp_name = TraitInfo { t, kind }.cpp_name(); // This must be done first to avoid a stack overflow ctx.trait_to_cpp_helpers .insert((kind, trait_index), cpp_name.clone()); // Source: ExternCDecl { let mut source = String::new(); let mut source_deps = HashSet::new(); CppTypeCtx { cpp: &mut source, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_signature( None, &drop_name, None, &[RustArg { name: "ptr".to_string(), ty: RustType::ForeignHandle, }], ); source.push_str(";\n"); ctx.source_helpers .add_group(SourceGroup::ExternCDecl, &drop_name, source) .add_deps_group(source_deps); } // Source: Anonymous { let mut source = String::new(); _ = write!( source, "\nstruct {cpp_name} final : {}::{} {{\n", ctx.namespace, t.name ); _ = write!( source, " {cpp_name}(const void* ptr) : _self(ptr) {{}}\n" ); _ = write!( source, " virtual ~{cpp_name}() {{ {drop_name}(_self); }}\n" ); for f in &t.fns { let info = Some(TraitInfo { t, kind }); source.push_str(" virtual "); generate_cpp_to_rust_fn(ast, ctx, f, &mut source, info); } source.push_str(" const void* _self;\n"); source.push_str("};\n"); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_dep_group(SourceGroup::ExternCDecl, &drop_name) .mark_used(); } // Rust { let mut rust = String::new(); _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle()); _ = write!(rust, "extern \"C\" fn {drop_name}(ptr: *const u8) {{\n"); _ = write!( rust, " drop(unsafe {{ Box::from_raw(ptr as *mut {}) }});\n", kind.path(), t.name ); rust.push_str("}\n"); ctx.rust_helpers.add(&drop_name, rust).mark_used(); } cpp_name } fn box_to_rust_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.box_to_rust_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_box_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let cpp_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_cpp")); let cpp_name_decl = format!("{cpp_name}[decl]"); // This must be done first to avoid a stack overflow ctx.box_to_rust_helpers .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let end_name = locals.create("end"); let buf_name = locals.create("buf"); // Transform the value let mut tfm = Transform::default(); let mut source_deps = HashSet::new(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.cpp.mark_pure(&val_name); transform_to_rust( ast, ctx, &mut locals, &mut tfm, &val_name, &inner_ty, &mut source_deps, ); let val_code = tfm.rust.find(&val_name, inner_ty, RefInline).code; tfm.rust.line(format!("Box::new({val_code})")); // Source (forward declaration) let mut cpp_ty = String::new(); { CppTypeCtx { cpp: &mut cpp_ty, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(inner_ty, CppDecl::Full); ctx.source_helpers .add_group( SourceGroup::Anonymous, &cpp_name_decl, format!( "\nvoid {cpp_name}({cpp_ty} {val_name}, std::vector& {buf_name});\n" ), ) .set_is_forward_decl(); } // Source { let mut source = String::new(); _ = write!( source, "\nvoid {cpp_name}({cpp_ty} {val_name}, std::vector& {buf_name}) {{\n" ); tfm.cpp .write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); source.push_str("}\n"); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl) .add_deps_group(source_deps); } // Rust { let mut rust = String::new(); let mut item_ty = String::new(); let end_name = buf.final_end_name_for_rust(); append_rust_type(&mut item_ty, ast, inner_ty); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({end_name}: &mut *const u8) -> Box<{item_ty}> {{\n" ); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } (cpp_name, rust_name) } fn box_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.box_to_cpp_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_box_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let cpp_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_cpp")); let cpp_name_decl = format!("{cpp_name}[decl]"); // This must be done first to avoid a stack overflow ctx.box_to_cpp_helpers .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let end_name = locals.create("end"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let mut source_deps = HashSet::new(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.rust.mark_pure(&val_name); transform_to_cpp( ast, ctx, &mut locals, &mut tfm, &val_name, &inner_ty, &mut source_deps, ); let val_code = tfm.cpp.find(&val_name, inner_ty, RefStdMove).code; // Rust { let mut rust = String::new(); let buf_name = buf.final_buf_name_for_rust(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({val_name}: "); append_rust_type(&mut rust, ast, inner_ty); _ = write!(rust, ", {buf_name}: &mut Vec) {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } // Source (forward declaration) let mut cpp_ty = String::new(); { CppTypeCtx { cpp: &mut cpp_ty, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(inner_ty, CppDecl::Full); ctx.source_helpers .add_group( SourceGroup::Anonymous, &cpp_name_decl, format!("\nstd::unique_ptr<{cpp_ty}> {cpp_name}(const uint8_t*& {end_name});\n"), ) .set_is_forward_decl(); } // Source { let mut source = String::new(); _ = write!( source, "\nstd::unique_ptr<{cpp_ty}> {cpp_name}(const uint8_t*& {end_name}) {{\n" ); tfm.cpp .write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); _ = write!( source, " return std::make_unique<{cpp_ty}>({val_code});\n" ); source.push_str("}\n"); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl) .add_deps_group(source_deps); } (cpp_name, rust_name) } fn enum_to_rust_helper(ast: &AST, ctx: &mut CppCtx, enum_index: usize) -> (String, String) { if let Some(result) = ctx.enum_to_rust_helpers.get(&enum_index) { return result.clone(); } let e = &ast.enums[enum_index]; let base_name = format!("_ffi_enum_{}", e.name); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_cpp")); let cpp_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let cpp_name_decl = format!("{cpp_name}[decl]"); // This must be done first to avoid a stack overflow ctx.enum_to_rust_helpers .insert(enum_index, (cpp_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); let end_name = locals.create("end"); let it_name = locals.create("it"); let mut branches = Vec::new(); let mut source_deps = HashSet::new(); // Enums without fields are just integers if !e.has_fields() { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({val_name}: i32) -> {} {{\n", e.name); _ = write!(rust, " match {val_name} {{\n"); for v in &e.variants { _ = write!( rust, " {} => {}::{},\n", v.discriminant, e.name, v.name ); } rust.push_str(" _ => panic!(),\n"); rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); return (cpp_name, rust_name); } struct Branch { tfm: Transform, fields: Vec, } // Transform all fields for each variant in a separate branch for v in &e.variants { let mut branch_locals = locals.clone(); let mut fields = Vec::new(); let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; for f in &v.fields { let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len())); tfm.cpp.pure_decl( &field_name, format!("{it_name}->{}", with_digit_prefix(&f.name)), ); transform_to_rust( ast, ctx, &mut branch_locals, &mut tfm, &field_name, &f.ty, &mut source_deps, ); fields.push(field_name); } rust_decl_ctor( &mut tfm.rust, &val_name, &format!("{}::{}", e.name, v.name), &v.fields, fields.iter().map(|x| Cow::Borrowed(x.as_str())).collect(), ); branches.push(Branch { tfm, fields }); } // Source (forward declaration) { ctx.source_helpers .add_group( SourceGroup::Anonymous, &cpp_name_decl, format!( "\nvoid {cpp_name}({}::{} {val_name}, std::vector& {buf_name});\n", ctx.namespace, e.name ), ) .set_is_forward_decl(); } // Source { let mut source = String::new(); let mut is_first = true; _ = write!( source, "\nvoid {cpp_name}({}::{} {val_name}, std::vector& {buf_name}) {{", ctx.namespace, e.name ); for (v, branch) in e.variants.iter().zip(&mut branches) { source.push_str(if is_first { "\n " } else { " else " }); is_first = false; if branch.fields.is_empty() { _ = write!( source, "if ({val_name}.is<{}::{}::{}>()) {{\n", ctx.namespace, e.name, v.name ); } else { _ = write!( source, "if (auto {it_name} = {val_name}.as<{}::{}::{}>()) {{\n", ctx.namespace, e.name, v.name ); } _ = write!( source, " _ffi_write(int32_t({}), {buf_name});\n", v.discriminant ); source_deps.insert((SourceGroup::Anonymous, "_ffi_write".into())); branch .tfm .cpp .write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); source.push_str(" }"); } if is_first { source.push_str(" abort();\n"); } else { source.push_str(" else {\n abort();\n }"); } source_deps.insert((SourceGroup::Include, "".into())); // For "abort" source.push_str("\n}\n"); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl) .add_deps_group(source_deps) .mark_used(); } // Rust { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({end_name}: &mut *const u8) -> {} {{\n", e.name ); _ = write!(rust, " match _ffi_read::({end_name}) {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { let val_code = branch .tfm .rust .find(&val_name, &RustType::Enum(enum_index), RefInline) .code; if branch.tfm.rust.is_empty() { let val_code = format!("{} => {val_code},", v.discriminant); branch.tfm.rust.line(val_code); branch.tfm.rust.write_to_rust(ast, &mut rust, " "); } else { _ = write!(rust, " {} => {{", v.discriminant); branch.tfm.rust.line(val_code); branch .tfm .rust .write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } } rust.push_str(" _ => panic!(),\n"); rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers .add(&rust_name, rust) .add_dep("_ffi_read") .mark_used(); } (cpp_name, rust_name) } fn enum_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, enum_index: usize) -> (String, String) { if let Some(result) = ctx.enum_to_cpp_helpers.get(&enum_index) { return result.clone(); } let e = &ast.enums[enum_index]; let base_name = format!("_ffi_enum_{}", e.name); let cpp_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_cpp")); let cpp_name_decl = format!("{cpp_name}[decl]"); // This must be done first to avoid a stack overflow ctx.enum_to_cpp_helpers .insert(enum_index, (cpp_name.clone(), rust_name.clone())); struct Branch { tfm: Transform, fields: Vec, } let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); let end_name = locals.create("end"); let mut branches = Vec::new(); let mut source_deps = HashSet::new(); // Transform all fields for each variant in a separate branch for v in &e.variants { let mut branch_locals = locals.clone(); let mut fields = Vec::new(); let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; for f in &v.fields { let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len())); tfm.rust.mark_pure(&field_name); transform_to_cpp( ast, ctx, &mut branch_locals, &mut tfm, &field_name, &f.ty, &mut source_deps, ); fields.push(field_name); } let args = tfm.cpp.find_args( &v.fields .iter() .zip(&fields) .map(|(f, name)| RustArg { name: name.clone(), ty: f.ty.clone(), }) .collect(), RefStdMove, ); tfm.cpp.decl( &val_name, format!( "{}::{}{{{}::{}::{}{{{args}}}}}", ctx.namespace, e.name, ctx.namespace, e.name, v.name ), ); branches.push(Branch { tfm, fields }); } // Rust { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({val_name}: {}, {buf_name}: &mut Vec) {{\n", e.name ); _ = write!(rust, " match {val_name} {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { _ = write!(rust, " {}::{}", e.name, v.name); if v.fields.iter().any(|f| starts_with_digit(&f.name)) { rust.push_str("("); for (i, name) in branch.fields.iter().enumerate() { rust.push_str(if i > 0 { ", " } else { "" }); rust.push_str(name); } rust.push_str(")"); } else if !v.fields.is_empty() { rust.push_str(" {"); for (i, (f, name)) in v.fields.iter().zip(&branch.fields).enumerate() { rust.push_str(if i > 0 { ", " } else { " " }); if f.name != *name { _ = write!(rust, "{}: ", f.name); } rust.push_str(name); } rust.push_str(" }"); } if branch.tfm.rust.is_empty() { _ = write!( rust, " => _ffi_write({} as i32, {buf_name}),\n", v.discriminant ); } else { rust.push_str(" => {\n"); _ = write!( rust, " _ffi_write({} as i32, {buf_name});\n", v.discriminant ); branch .tfm .rust .write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } } rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers .add(&rust_name, rust) .add_dep("_ffi_write") .mark_used(); } // Source (forward declaration) { ctx.source_helpers .add_group( SourceGroup::Anonymous, &cpp_name_decl, format!( "\n{}::{} {cpp_name}(const uint8_t*& {end_name});\n", ctx.namespace, e.name ), ) .set_is_forward_decl(); } // Source { let mut source = String::new(); _ = write!( source, "\n{}::{} {cpp_name}(const uint8_t*& {end_name}) {{\n", ctx.namespace, e.name ); _ = write!(source, " switch (_ffi_read({end_name})) {{\n",); for (v, branch) in e.variants.iter().zip(&mut branches) { let val_code = branch .tfm .cpp .find(&val_name, &RustType::Enum(enum_index), RefInline) .code; let needs_block = !branch.tfm.cpp.is_empty(); branch.tfm.cpp.line(format!("return {val_code};")); if needs_block { _ = write!(source, " case {}: {{\n", v.discriminant); } else { _ = write!(source, " case {}:\n", v.discriminant); } branch .tfm .cpp .write_to_cpp(ctx, ast, &mut source_deps, &mut source, " "); if needs_block { source.push_str(" }\n"); } } source.push_str(" default:\n abort();\n"); source_deps.insert((SourceGroup::Include, "".into())); // For "abort" source.push_str(" }\n"); source.push_str("}\n"); source_deps.insert((SourceGroup::Anonymous, "_ffi_read".into())); ctx.source_helpers .add_group(SourceGroup::Anonymous, &cpp_name, source) .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl) .add_deps_group(source_deps) .mark_used(); } (cpp_name, rust_name) } fn multi_ret_helper(ast: &AST, ctx: &mut CppCtx, args: &[RustArg]) -> String { let types: Vec<_> = args.iter().map(|arg| arg.ty.clone()).collect(); if let Some(result) = ctx.multi_ret_helpers.get(&types) { return result.clone(); } let mut ty_name = "_ffi_ret_".to_string(); append_type_name_hints(&mut ty_name, ast, &types); let ty_name = ctx.helper_names.create(&ty_name); // Source { let mut source = String::new(); let mut source_deps = HashSet::new(); _ = write!(source, "\nstruct {ty_name} {{\n"); for (i, ty) in types.iter().enumerate() { source.push_str(" "); CppTypeCtx { cpp: &mut source, ast, deps: &mut source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(ty, CppDecl::Full); _ = write!(source, " _{i};\n"); } source.push_str("};\n"); ctx.source_helpers .add_group(SourceGroup::MultiRet, &ty_name, source) .add_deps_group(source_deps) .mark_used(); } // Rust { let mut rust = String::new(); _ = write!(rust, "\n#[repr(C)]\nstruct {ty_name}("); for (i, ty) in types.iter().enumerate() { if i > 0 { rust.push_str(", "); } append_rust_type(&mut rust, ast, ty); } rust.push_str(");\n"); ctx.rust_helpers.add(&ty_name, rust).mark_used(); } ctx.multi_ret_helpers.insert(types, ty_name.clone()); ty_name } // For something like "std::vector foo;" C++ just needs a forward // declaration. The reason is something like this: The member "foo" only holds // a pointer to "Foo", so the compiler doesn't need detailed information about // "Foo" such as its size and alignment. We use "CppDecl::Forward" to model // this, which we switch to when we're inside of "std::vector". // // However, for something like "Foo foo;" C++ needs a full declaration. The // reason is something like this: The member "foo" is stored inline, so the // compiler needs detailed information about "Foo" such as its size and // alignment. We use "CppDecl::Full" to model this, which we use for top-level // struct member declarations. // // This distinction can matter for mutually-recursive types. Consider the // following types "Foo" and "Bar": // // struct Foo { // Bar bar; // }; // // struct Bar { // std::vector foo; // }; // // We can't compile this by picking a declaration order. We also can't compile // this by having each one just depend on the forward declaration of the other, // "Foo" actually depends on the full declaration of "Bar". The end result // needs to at least have the following things, in order: // // struct Foo; // // struct Bar { // std::vector foo; // }; // // struct Foo { // Bar bar; // }; // // Isn't C++ great? #[derive(Clone, Copy)] enum CppDecl { Forward, Full, } struct DeclGroups { forward: G, full: G, } impl DeclGroups { fn select(&self, decl: CppDecl) -> G { match decl { CppDecl::Forward => self.forward, CppDecl::Full => self.full, } } } #[derive(Eq, PartialEq)] enum TypeLoc { OutsideRustNamespace, InsideRustNamespace, ForConstant, } struct CppTypeCtx<'a, G: Clone + Copy + Eq + Hash> { cpp: &'a mut String, ast: &'a AST, deps: &'a mut HashSet<(G, String)>, include_group: G, decl_groups: Option>, loc: TypeLoc, ns: &'a str, } impl CppTypeCtx<'_, G> { fn append_cpp_signature( &mut self, returns: Option<&RustType>, name: &str, receiver: Option<&RustArg>, args: &[RustArg], ) { // Emit the return type if let Some(returns) = returns { self.append_cpp_type(returns, CppDecl::Full); self.cpp.push(' '); } else { self.cpp.push_str("void "); } // The function name goes in the middle in C self.cpp.push_str(name); // Emit the arguments self.cpp.push('('); if let Some(receiver) = receiver { self.append_cpp_type(&receiver.ty, CppDecl::Full); self.cpp.push(' '); self.cpp.push_str(&receiver.name); } for (i, arg) in args.iter().enumerate() { if receiver.is_some() || i > 0 { self.cpp.push_str(", "); } self.append_cpp_type(&arg.ty, CppDecl::Full); self.cpp.push(' '); self.cpp.push_str(&arg.name); } self.cpp.push(')'); } fn append_cpp_type(&mut self, ty: &RustType, decl: CppDecl) { use RustType::*; match ty { Pair { other, .. } => self.append_cpp_type(other, decl), Verbatim(text) => self.cpp.push_str(text), Bool => self.cpp.push_str("bool"), U8 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("uint8_t"); } U16 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("uint16_t"); } U32 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("uint32_t"); } Usize => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("uintptr_t"); } U64 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("uint64_t"); } I8 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("int8_t"); } I16 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("int16_t"); } I32 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("int32_t"); } Isize => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("intptr_t"); } I64 => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("int64_t"); } F32 => self.cpp.push_str("float"), F64 => self.cpp.push_str("double"), ForeignHandle => self.cpp.push_str("const void*"), RefStr | OwnStr => { if self.loc == TypeLoc::ForConstant { self.deps .insert((self.include_group, "".into())); self.cpp.push_str("std::string_view"); } else { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("std::string"); } } Struct(index) => { let name = &self.ast.structs[*index].name; if let Some(groups) = &self.decl_groups { self.deps.insert((groups.select(decl), name.into())); } if self.loc == TypeLoc::OutsideRustNamespace { _ = write!(self.cpp, "{}::", self.ns); } self.cpp.push_str(name); } Enum(index) => { let name = &self.ast.enums[*index].name; if let Some(groups) = &self.decl_groups { self.deps.insert((groups.select(decl), name.into())); } if self.loc == TypeLoc::OutsideRustNamespace { _ = write!(self.cpp, "{}::", self.ns); } self.cpp.push_str(name); } DynTrait(index) => { let name = &self.ast.traits[*index].name; if let Some(groups) = &self.decl_groups { self.deps.insert((groups.select(decl), name.into())); } if self.loc == TypeLoc::OutsideRustNamespace { _ = write!(self.cpp, "{}::", self.ns); } self.cpp.push_str(name); } Tuple(types) => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("std::tuple<"); for (i, ty) in types.iter().enumerate() { if i > 0 { self.cpp.push_str(", "); } self.append_cpp_type(ty, CppDecl::Full); } self.cpp.push('>'); } Ptr(kind, inner) => match kind { RustPtr::Box => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("std::unique_ptr<"); self.append_cpp_type(inner, CppDecl::Forward); self.cpp.push('>'); } RustPtr::Rc => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("std::shared_ptr<"); self.append_cpp_type(inner, CppDecl::Forward); self.cpp.push('>'); } }, Vector(inner) => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("std::vector<"); self.append_cpp_type(inner, CppDecl::Forward); self.cpp.push('>'); } Optional(inner) => { self.deps.insert((self.include_group, "".into())); self.cpp.push_str("std::optional<"); self.append_cpp_type(inner, CppDecl::Full); self.cpp.push('>'); } } } } fn append_cpp_val(cpp: &mut String, val: &RustVal) { use RustVal::*; match val { Bool(x) => _ = write!(cpp, "{x}"), U8(x) => _ = write!(cpp, "{x}u"), U16(x) => _ = write!(cpp, "{x}u"), U32(x) => _ = write!(cpp, "{x}u"), U64(x) => _ = write!(cpp, "{x}ull"), I8(x) => _ = write!(cpp, "{x}"), I16(x) => _ = write!(cpp, "{x}"), I32(x) => { if *x == std::i32::MIN { // Avoid a Visual C++ warning _ = write!(cpp, "{} - 1", x + 1); } else { _ = write!(cpp, "{x}"); } } I64(x) => { if *x == std::i64::MIN { // Avoid a clang warning _ = write!(cpp, "{}ll - 1", x + 1); } else { _ = write!(cpp, "{x}ll"); } } F32(x) => _ = write!(cpp, "{x:?}f"), F64(x) => _ = write!(cpp, "{x:?}"), Str(x) => { cpp.push_str("std::string_view("); append_cpp_quoted(cpp, x); _ = write!(cpp, ", {})", x.len()); } } } fn append_cpp_quoted(cpp: &mut String, text: &str) { cpp.push('"'); for c in text.chars() { match c { '\t' => cpp.push_str("\\t"), '\n' => cpp.push_str("\\n"), '\r' => cpp.push_str("\\r"), '\\' => cpp.push_str("\\\\"), '\"' => cpp.push_str("\\\""), c if (c as u32) < 0x20 => { _ = write!(cpp, "\\{:03o}", c as u32); } _ => cpp.push(c), } } cpp.push('"'); } impl FnBuilder { fn write_to_cpp( &mut self, ctx: &CppCtx, ast: &AST, source_deps: &mut HashSet<(SourceGroup, String)>, out: &mut String, base_indent: &str, ) { let mut indent = 0; let mut callback = |line: &str| { if line.starts_with(&['}', ']', ')']) { indent -= 1; } _ = write!(out, "{base_indent}{}{line}\n", " ".repeat(indent)); if line.ends_with(&['{', '[', '(']) { indent += 1; } }; for line in self.take_lines() { match line { Line::Plain(text) => { text.split('\n').for_each(&mut callback); } Line::PlainAlt(when_false, when_true, flag) => match flag.get() { false if when_false.is_empty() => continue, false => when_false.split('\n').for_each(&mut callback), true => when_true.split('\n').for_each(&mut callback), }, Line::Decl(name, ty, text) => { let mut decl_ty = String::new(); match ty { None => decl_ty.push_str("auto"), Some(ty) => CppTypeCtx { cpp: &mut decl_ty, ast, deps: source_deps, include_group: SourceGroup::Include, decl_groups: None, loc: TypeLoc::OutsideRustNamespace, ns: &ctx.namespace, } .append_cpp_type(&ty, CppDecl::Full), } let text = format!("{decl_ty} {name} = {text};"); text.split('\n').for_each(&mut callback); } } } } } ================================================ FILE: src/lib.rs ================================================ //! This is a simple but opinionated FFI system for Rust. It allows you to call //! Rust code from other languages, and vice versa. Some design principles: //! //! - Intended for writing platform-agnostic Rust with platform-specific details in the host language //! - FFI support is split into data (structs passed by copy) and code (traits passed by reference) //! - Rather than have a separate schema language, the public API in your `lib.rs` is your schema //! - The generated binding code is compact, dependency-free, and straightforward to integrate with //! //! ## Supported Features //! //! - Primitive types (`bool`, `i32`, `f64`, `String`, etc.) //! - Tuples //! - Structs //! - Enums //! - Top-level constants //! - Top-level functions //! - Traits (must be either `Box` or `Rc`) //! - `Vec` //! - `Option` //! - `Box` //! //! ## Simple Usage //! //! To get up and running: //! //! 1. Add `miniffi` to your `[build-dependencies]` in `Cargo.toml`: //! //! ```text //! cargo add --build miniffi //! ``` //! //! 2. Add the following code to the end of your `src/lib.rs` file: //! //! ``` //! # macro_rules! env { ($a:expr) => { $a } } //! # macro_rules! include { ($a:expr) => { $a } } //! include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); //! ``` //! //! 3. Add a `build.rs` script that calls [`build`](Target::build) on at least one [`Target`]: //! //! ```no_run //! use miniffi::*; //! //! fn main() { //! CppTarget::new().build(); //! } //! ``` //! //! 4. Import the generated bindings from the host language (see each target for details) //! //! ## Advanced Usage //! //! You can only build for one target at a time. However, the flexibility of //! build scripts means you can use the same build script for different targets //! in different situations using your own custom logic. //! //! For example, you may want to build for different host languages depending //! on the value of cargo's `--target` flag: //! //! ```no_run //! use miniffi::*; //! //! fn main() { //! let target = std::env::var("TARGET").unwrap(); //! if target == "wasm32-unknown-unknown" { //! WasmTarget::new() //! .write_ts_to("../web/rust.ts") //! .set_panic_hook() //! .build(); //! } else if target == "aarch64-apple-darwin" { //! SwiftTarget::new() //! .write_swift_to("../macos/rust.swift") //! .write_header_to("../macos/rust.h") //! .build(); //! } else if target == "x86_64-pc-windows-msvc" { //! CppTarget::new() //! .write_source_to("../windows/rust.cpp") //! .write_header_to("../windows/rust.h") //! .build(); //! } else { //! NullTarget::new().build(); //! } //! } //! ``` mod ast; mod cpp; mod rust; mod scan; mod swift; mod util; mod wasm; use ast::*; use rust::*; use std::fmt::Write; use std::path::{Path, PathBuf}; use syn::spanned::Spanned; use util::*; pub use cpp::CppTarget; pub use swift::SwiftTarget; pub use wasm::WasmTarget; use crate::scan::make_warning; #[cfg(test)] mod tests; const DO_NOT_EDIT_COMMENT: &str = concat!( "This file was generated by miniffi v", env!("CARGO_PKG_VERSION"), ". Do not edit." ); /// The common trait for all language-specific targets. /// /// The following targets are available: /// /// - [`CppTarget`] for C++ /// - [`SwiftTarget`] for Swift /// - [`WasmTarget`] for JavaScript/TypeScript /// - [`NullTarget`] otherwise /// /// Typical usage involves creating a target with `new()`, chaining some /// methods to configure it, and then calling [`build`](Target::build). pub trait Target { /// Call this on the desired target from your `build.rs` script to generate /// the FFI bindings. It automatically locates your `src/lib.rs` file using /// the directory containing your `Cargo.toml` manifest, parses it to /// determine your packages public API, and then generates FFI bindings for /// that API. /// /// This will always generate the file `miniffi.rs` along with some /// additional files that are target-dependent. For example, the /// [`SwiftTarget`] additionally generates a `.swift` file and a `.h` file. /// The `miniffi.rs` file will be written inside of cargo's `target` /// directory, and is normally not something you'll need to think about too /// much (other than referencing it via `include!` in your `lib.rs` file). /// The other target-dependent files are intended to be included by you /// into the host language project. For example, you might add the `.swift` /// and `.h` files from the [`SwiftTarget`] to your Xcode project. You /// should probably also add all generated files to your `.gitignore` so /// they are not checked into source control as they are automatically /// generated. /// /// The returned [`BuildResult`] will be configured to automatically print /// some instructions for cargo when it is dropped. Typical usage involves /// just calling `build()` on the target without storing the return value. /// But you can use the return value to inspect the results of the build. /// You can also modify the return value to disable the printing of cargo /// instructions on drop if you need different behavior instead. fn build(&self) -> BuildResult { fn fail(error: &str) -> BuildResult { let mut result = BuildResult::default(); result.errors.push(error.into()); return result; } let Ok(input_dir) = std::env::var("CARGO_MANIFEST_DIR") else { return fail("missing environment variable: CARGO_MANIFEST_DIR"); }; let Ok(output_dir) = std::env::var("OUT_DIR") else { return fail("missing environment variable: OUT_DIR"); }; let input_path = PathBuf::from(input_dir).join("src").join("lib.rs"); let output_path = PathBuf::from(output_dir).join("miniffi.rs"); match std::fs::read_to_string(&input_path) { Err(err) => BuildResult { errors: vec![format!("Failed to read from {input_path:?}: {err}")], warnings: Vec::new(), input_path, output_files: Vec::new(), finish_on_drop: true, }, Ok(contents) => { let input_file = FileData { path: input_path, contents, }; let mut result = self.build_custom(input_file, output_path); result.finish_on_drop = true; result } } } /// This is the same as [`build`](Target::build) but without any of the /// cargo-specific logic (automatically locating and reading `src/lib.rs` /// and automatically printing out instructions for cargo). This can be /// useful for running miniffi outside of a cargo build script. If you're /// writing a cargo build script, you likely want to call /// [`build`](Target::build) instead. fn build_custom(&self, input_file: FileData, output_path: PathBuf) -> BuildResult; /// Set the edition for the generated Rust code. This can be necessary /// because different editions of Rust use different syntax. fn rust_edition(self, year: usize) -> Self; } /// Holds the result of calling [`build`](Target::build) or /// [`build_custom`](Target::build_custom). May print out cargo /// instructions and/or write files when dropped. /// /// Typically you can just call `.build()` on a target and not use the return /// value. But the return value is available if you need to inspect or modify /// the build results. /// /// The result returned from [`build`](Target::build) has `finish_on_drop` set /// to true which means it will print out cargo instructions and write output /// files when dropped. If you don't want this behavior (perhaps you need /// something else to happen instead), then you should set `finish_on_drop` to /// false before dropping the build result. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct BuildResult { pub input_path: PathBuf, pub output_files: Vec, pub errors: Vec, pub warnings: Vec, pub finish_on_drop: bool, } impl BuildResult { /// Certain Rust features are not supported by miniffi. Using those /// features will generate a warning and cause the relevant code to be /// omitted from the FFI bindings. If you would like for these warnings /// to be errors instead (perhaps you want CI to fail when this happens), /// you can chain this method off of [`build`](Target::build): /// /// ```no_run /// use miniffi::*; /// /// fn main() { /// CppTarget::new() /// .build() /// .convert_warnings_to_errors(); /// } /// ``` /// /// Doing this can have undesirable side effects. Because cargo build /// scripts run before your crate builds, a build script error stops the /// build before your crate is built. This can cause IDE features to stop /// working without an obvious cause since some Rust IDE plugins don't /// surface build script errors. pub fn convert_warnings_to_errors(mut self) -> Self { self.errors .extend(self.warnings.drain(..).map(|w| w.to_human_string())); self } /// This does the following: /// /// - Write all output files to the file system /// - Print `cargo:rerun-if-changed` lines for all files relevant to the build /// - Print `cargo::error` lines for everything in `errors` /// - Print `cargo:warning` lines for everything in `warnings` /// - Set `self.finish_on_drop` to `false` to avoid finishing on [`drop`](BuildResult::drop) pub fn finish(&mut self) { // Note: Cargo changed the directive prefix syntax from "cargo:" to // "cargo::" in version 0.78.0. The older syntax is mostly still // respected, so use it instead for better compatibility. The one // exception is that "cargo::error" was added after this but support // for "cargo:error" was not added. So this deliberately uses // "cargo::error" for errors. Older versions of rust will print an // error message when encountering "cargo::" at all so these will // still print an error. // https://github.com/rust-lang/cargo/commit/d45969a781a78e95215aba19898f397235c36b7c // https://github.com/rust-lang/cargo/commit/4f744776795eb3ccaf46530b0e37056c23641323 println!("cargo:rerun-if-changed={}", self.input_path.display()); for file in &mut self.output_files { println!("cargo:rerun-if-changed={}", file.path.display()); write_file(&file.path, &file.contents, &mut self.errors); } for error in &self.errors { println!( "cargo::error=[miniffi] {}", error .split('\n') .collect::>() .join("\ncargo::error=") ); } for warning in &self.warnings { println!( "cargo:warning=[miniffi] {}", warning .to_human_string() .split('\n') .collect::>() .join("\ncargo:warning=") ); } self.finish_on_drop = false; } } impl Drop for BuildResult { /// If `finish_on_drop` is true, dropping a `BuildResult` runs `finish()` /// before the drop. If `finish_on_drop` is false, then dropping a /// `BuildResult` does nothing. fn drop(&mut self) { if self.finish_on_drop { self.finish(); } } } /// Part of a [`BuildResult`]. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Warning { pub path: PathBuf, pub line: usize, pub column: usize, pub len: usize, pub message: String, pub code: String, pub note: String, } impl Warning { /// Returns a single-line string containing the file location and message. /// Similar to Rust's "short" message format. For example: /// /// ```text /// /home/user/foo/src/lib.rs:42:11: unsupported type `AtomicBool` for field `flag` /// ``` pub fn to_short_string(&self) -> String { format!( "{}:{}:{}: {}{}", self.path.display(), self.line, self.column, self.message, match self.note.as_str() { "" => String::new(), note => format!(" ({note})"), } ) } /// Returns a multi-line string containing the file location, message, and /// the relevant line of code. Similar to Rust's "human" message format. /// For example: /// /// ```text /// unsupported type `AtomicBool` for field `flag` /// --> /home/user/foo/src/lib.rs:42:11 /// | /// 42 | flag: AtomicBool, /// | ^^^^^^^^^^ /// ``` pub fn to_human_string(&self) -> String { let line = self.line.to_string(); let indent = " ".repeat(line.len()); format!( "{}\n{indent}--> {}:{}:{}\n{indent} |\n{line} | {}\n{indent} |{}{}{}{}\n", self.message, self.path.display(), self.line, self.column, self.code, " ".repeat(self.column), "^".repeat(self.len.max(1)), if self.note.is_empty() { "" } else { " " }, self.note ) } } /// Part of a [`BuildResult`]. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct FileData { pub path: PathBuf, pub contents: String, } struct CommonOptions { edition: usize, } impl Default for CommonOptions { fn default() -> CommonOptions { CommonOptions { edition: 2024 } } } trait Compile { fn common_options(&mut self) -> &mut CommonOptions; fn compile(&self, ast: AST, rust_path: PathBuf) -> Vec; } impl Target for T { fn rust_edition(mut self, year: usize) -> Self { self.common_options().edition = year; self } fn build_custom(&self, input_file: FileData, output_path: PathBuf) -> BuildResult { let mut output_files = Vec::new(); let mut errors = Vec::new(); let mut warnings = Vec::new(); if !input_file.contents.contains("miniffi.rs") { let code = r#"include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));"#; let file = input_file .path .file_name() .unwrap_or(input_file.path.as_os_str()); errors.push(format!("Please add this to the end of {file:?}: {code}")); } match syn::parse_file(&input_file.contents) { Err(err) => { let message = format!("{err}"); warnings.push(make_warning(&input_file, message, "", err.span())); } Ok(ast) => { let ast = scan::scan_ast(&input_file, &ast, &mut warnings); output_files = self.compile(ast, output_path); } } BuildResult { input_path: input_file.path, output_files, errors, warnings, finish_on_drop: false, } } } /// Use this target when there is no host language. /// /// The null target creates an empty `miniffi.rs` file. That can be useful if /// you want to build FFI support for some configurations and not others. /// /// For example, the following `build.rs` script only builds FFI support when /// targeting WASM (such as with `cargo build --target=wasm32-unknown-unknown`) /// and not otherwise (such as running tests with `cargo test`): /// /// ```no_run /// use miniffi::*; /// /// fn main() { /// let target = std::env::var("TARGET").unwrap(); /// if target == "wasm32-unknown-unknown" { /// WasmTarget::new().build(); /// } else { /// NullTarget::new().build(); /// } /// } /// ``` pub struct NullTarget { common_options: CommonOptions, } impl NullTarget { pub fn new() -> NullTarget { NullTarget { common_options: CommonOptions::default(), } } } impl Compile for NullTarget { fn common_options(&mut self) -> &mut CommonOptions { &mut self.common_options } fn compile(&self, _ast: AST, rust_path: PathBuf) -> Vec { vec![FileData { path: rust_path, contents: String::new(), }] } } fn write_file(path: &Path, contents: &str, errors: &mut Vec) { if let Some(parent) = path.parent() { if let Err(err) = std::fs::create_dir_all(parent) { errors.push(format!("Failed to create directory {parent:?}: {err}")); } } if let Ok(existing) = std::fs::read(&path) { if existing == contents.as_bytes() { return; // Avoid unnecessary rebuilds } } if let Err(err) = std::fs::write(&path, contents) { errors.push(format!("Failed to write to {path:?}: {err}")); } } ================================================ FILE: src/rust.rs ================================================ use super::*; use std::borrow::Cow; #[derive(Default)] pub struct RustSyntax { edition: usize, } impl RustSyntax { pub fn with_edition(edition: usize) -> RustSyntax { RustSyntax { edition } } pub fn unsafe_no_mangle(&self) -> &'static str { if self.edition >= 2024 { "#[unsafe(no_mangle)]" } else { "#[no_mangle]" } } pub fn unsafe_extern(&self) -> &'static str { if self.edition >= 2024 { "unsafe extern" } else { "extern" } } } pub fn append_rust_type(rust: &mut String, ast: &AST, ty: &RustType) { use RustType::*; match ty { Pair { rust: inner, .. } => append_rust_type(rust, ast, inner), Verbatim(text) => rust.push_str(text), Bool => rust.push_str("bool"), U8 => rust.push_str("u8"), U16 => rust.push_str("u16"), U32 => rust.push_str("u32"), Usize => rust.push_str("usize"), U64 => rust.push_str("u64"), I8 => rust.push_str("i8"), I16 => rust.push_str("i16"), I32 => rust.push_str("i32"), Isize => rust.push_str("isize"), I64 => rust.push_str("i64"), F32 => rust.push_str("f32"), F64 => rust.push_str("f64"), RefStr => rust.push_str("&str"), OwnStr => rust.push_str("String"), Struct(index) => rust.push_str(&ast.structs[*index].name), Enum(index) => rust.push_str(&ast.enums[*index].name), DynTrait(index) => { rust.push_str("dyn "); rust.push_str(&ast.traits[*index].name); } Ptr(kind, inner) => { rust.push_str(kind.path()); rust.push('<'); append_rust_type(rust, ast, &inner); rust.push('>'); } Vector(inner) => { rust.push_str("Vec<"); append_rust_type(rust, ast, &inner); rust.push('>'); } Tuple(types) => { rust.push('('); for (i, ty) in types.iter().enumerate() { append_rust_type(rust, ast, ty); if i + 1 < types.len() { rust.push_str(", "); } else if types.len() == 1 { rust.push(','); } } rust.push(')'); } Optional(inner) => { rust.push_str("Option<"); append_rust_type(rust, ast, &inner); rust.push('>'); } ForeignHandle => rust.push_str("*const u8"), } } pub fn append_rust_default_val(rust: &mut String, ast: &AST, ty: &RustType) { use RustType::*; match ty { Bool => rust.push_str("false"), U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 => rust.push_str("0"), F32 | F64 => rust.push_str("0.0"), RefStr => rust.push_str("\"\""), OwnStr => rust.push_str("String::new()"), Struct(index) => { let s = &ast.structs[*index]; rust.push_str(&s.name); if s.fields.is_empty() { rust.push_str(" {}"); } else { rust.push_str(" { "); for (i, f) in s.fields.iter().enumerate() { if i > 0 { rust.push_str(", "); } rust.push_str(&f.name); rust.push_str(": "); append_rust_default_val(rust, ast, &f.ty); } rust.push_str(" }"); } } Tuple(types) => { rust.push('('); for (i, ty) in types.iter().enumerate() { append_rust_default_val(rust, ast, ty); if i + 1 < types.len() { rust.push_str(", "); } else if types.len() == 1 { rust.push(','); } } rust.push(')'); } ForeignHandle => rust.push_str("std::ptr::null()"), _ => rust.push_str("unreachable!()"), } } impl FnBuilder { pub fn write_to_rust(&mut self, ast: &AST, out: &mut String, base_indent: &str) { let mut indent = 0; let mut callback = |line: &str| { if line.starts_with(&['}', ']', ')']) { indent -= 1; } _ = write!(out, "{base_indent}{}{line}\n", " ".repeat(indent)); if line.ends_with(&['{', '[', '(']) { indent += 1; } }; for line in self.take_lines() { match line { Line::Plain(text) => { text.split('\n').for_each(&mut callback); } Line::PlainAlt(when_false, when_true, flag) => match flag.get() { false if when_false.is_empty() => continue, false => when_false.split('\n').for_each(&mut callback), true => when_true.split('\n').for_each(&mut callback), }, Line::Decl(name, ty, text) => { let mut decl_ty = String::new(); if let Some(ty) = ty { decl_ty.push_str(": "); append_rust_type(&mut decl_ty, ast, &ty); } let text = format!("let {name}{decl_ty} = {text};"); text.split('\n').for_each(&mut callback); } } } } } pub fn is_snake_case(name: &str) -> bool { let name = name.trim_matches('_'); !name.contains("__") && !name.chars().any(char::is_uppercase) } pub fn is_camel_case(name: &str) -> bool { let name = name.trim_matches('_'); let mut chars = name.chars(); !chars.next().map(char::is_lowercase).unwrap_or(false) && !name.contains("__") && !name.chars().zip(chars).any(|(a, b)| { let has_case = |c: char| c.to_uppercase().next() != c.to_lowercase().next(); (has_case(a) && b == '_') || (a == '_' && has_case(b)) }) } pub fn allow_non_snake_case(rust: &mut String, name: &str) { if !is_snake_case(name) { rust.push_str("\n#[allow(non_snake_case)]"); } } pub fn allow_non_camel_case_types(rust: &mut String, name: &str) { if !is_camel_case(name) { rust.push_str("\n#[allow(non_camel_case_types)]"); } } pub fn rust_decl_ctor( rust: &mut FnBuilder, var_name: &str, ctor_name: &str, fields: &Vec, item_names: Vec>, ) { if fields.is_empty() { rust.decl(var_name, ctor_name.to_string()); } else if fields.iter().any(|arg| starts_with_digit(&arg.name)) { let args = rust.find_args( &fields .iter() .zip(item_names) .map(|(f, name)| RustArg { name: name.to_string(), ty: f.ty.clone(), }) .collect(), RefInline, ); rust.decl(var_name, format!("{ctor_name}({args})")); } else { let fields = rust.find_fields( fields, item_names, RefInline, &format!("{ctor_name} {{ "), " }", ); rust.decl(var_name, fields); } } pub fn add_common_rust_helpers(syntax: &RustSyntax, helpers: &mut HelperSet<(), String>) { helpers.add( "_ffi_read", r" fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ", ); helpers.add( "_ffi_write", r" fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ", ); helpers.add( "_ffi_alloc", format!( r#" {} extern "C" fn _ffi_alloc(len: usize) -> *const u8 {{ Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 }} "#, syntax.unsafe_no_mangle() ), ); helpers.add( "_ffi_dealloc", format!( r#" {} extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {{ drop(unsafe {{ Vec::from_raw_parts(ptr, 0, capacity) }}); }} "#, syntax.unsafe_no_mangle() ), ); helpers .add( "_ffi_string_from_host", r" fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } ", ) .add_dep("_ffi_alloc"); helpers .add( "_ffi_string_to_host", r" fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ", ) .add_dep("_ffi_dealloc"); helpers .add( "_ffi_buf_from_host", r" fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } ", ) .add_dep("_ffi_alloc"); helpers .add( "_ffi_buf_to_host", r" fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } ", ) .add_dep("_ffi_dealloc"); } ================================================ FILE: src/scan.rs ================================================ use super::*; use std::collections::HashSet; use syn::{Attribute, Fields, ext::IdentExt}; pub fn scan_ast(file: &FileData, parsed: &syn::File, warnings: &mut Vec) -> AST { use syn::{Item, Visibility::Public}; let mut ast = AST { structs: Vec::new(), enums: Vec::new(), traits: Vec::new(), consts: Vec::new(), fns: Vec::new(), }; // Pass 1: Scan for type names for item in &parsed.items { match item { Item::Struct(item) => { let Public(_) = item.vis else { continue }; ast.structs.push(RustStruct { name: item.ident.unraw().to_string(), fields: Vec::new(), derives_partial_eq: derives_partial_eq(&item.attrs), }); } Item::Enum(item) => { let Public(_) = item.vis else { continue }; ast.enums.push(RustEnum { name: item.ident.unraw().to_string(), variants: Vec::new(), derives_partial_eq: derives_partial_eq(&item.attrs), }); } Item::Trait(item) => { let Public(_) = item.vis else { continue }; ast.traits.push(RustTrait { name: item.ident.unraw().to_string(), fns: Vec::new(), }); } _ => continue, } } // Pass 2: Scan for type contents 'next_item: for item in &parsed.items { match item { Item::Struct(item) => { let Public(_) = item.vis else { continue }; let name = item.ident.unraw().to_string(); let fields = match parse_fields(file, &ast, &item.fields, ("struct", &name)) { Ok(fields) => fields, Err(warning) => { warnings.push(warning); continue; } }; for s in &mut ast.structs { if s.name == name { s.fields = fields; break; } } } Item::Enum(item) => { let Public(_) = item.vis else { continue }; let enum_name = item.ident.unraw().to_string(); let mut variants = Vec::new(); let mut discriminant = 0; for v in &item.variants { let name = v.ident.unraw().to_string(); let full_name = format!("{enum_name}::{name}"); let fields = match parse_fields(file, &ast, &v.fields, ("variant", &full_name)) { Ok(fields) => fields, Err(warning) => { warnings.push(warning); continue 'next_item; } }; if let Some((_, expr)) = &v.discriminant { if let Some(value) = expr_to_numeric_literal(expr) { discriminant = value; } else { warnings.push(unsupported( file, "discriminant", expr.span(), ("variant", &name), Some(("enum", &enum_name)), "must be an integer literal", )); } } variants.push(RustVariant { name, discriminant, fields, }); discriminant = discriminant.wrapping_add(1); } for e in &mut ast.enums { if e.name == enum_name { e.variants = variants; break; } } } _ => continue, } } // Prune infinitely-sized types so the code generators don't stack overflow for i in 0..ast.structs.len() { for j in 0..ast.structs[i].fields.len() { if is_infinite_size(&ast, &ast.structs[i].fields[j].ty) { ast.structs[i].fields[j].ty = RustType::Tuple(Vec::new()); } } } // Pass 3: Scan for code 'next_item: for item in &parsed.items { match item { Item::Const(item) => { let Public(_) = item.vis else { continue }; let name = item.ident.unraw().to_string(); let Some(ty) = to_rust_type(&ast, &item.ty) else { warnings.push(unsupported( file, "type", item.ty.span(), ("constant", &name), None, "", )); continue; }; let Some(val) = to_rust_val(&item.expr, &ty) else { warnings.push(unsupported( file, "value", item.expr.span(), ("constant", &name), None, "only literals are supported", )); continue; }; ast.consts.push(RustConst { name, ty, val }); } Item::Fn(item) => { let Public(_) = item.vis else { continue }; let f = match to_rust_fn(file, &ast, &item.sig, None) { Ok(f) => f, Err(warning) => { warnings.push(warning); continue 'next_item; } }; ast.fns.push(f); } Item::Trait(item) => { let Public(_) = item.vis else { continue }; let name = item.ident.unraw().to_string(); let mut fns = Vec::new(); for item in &item.items { let syn::TraitItem::Fn(item) = item else { warnings.push(unsupported( file, "item", item.span(), ("trait", &name), None, "only functions are supported", )); continue 'next_item; }; let f = match to_rust_fn(file, &ast, &item.sig, Some(&name)) { Ok(f) => f, Err(warning) => { warnings.push(warning); continue 'next_item; } }; fns.push(f); } for t in &mut ast.traits { if t.name == name { t.fns = fns; break; } } } _ => continue, } } ast } // Detect "#[derive(PartialEq)]" fn derives_partial_eq(attrs: &[Attribute]) -> bool { for attr in attrs { if let syn::Meta::List(syn::MetaList { path, .. }) = &attr.meta { if path.is_ident("derive") { let mut found = false; _ = attr.parse_nested_meta(|meta| { if meta.path.is_ident("PartialEq") { found = true; } Ok(()) }); if found { return true; } } } } false } fn parse_fields( file: &FileData, ast: &AST, fields: &Fields, extra: (&str, &str), ) -> Result, Warning> { let mut result = Vec::new(); match fields { syn::Fields::Unit => {} syn::Fields::Unnamed(item) => { for (i, field) in item.unnamed.iter().enumerate() { let name = format!("{i}"); let Some(ty) = to_rust_type(&ast, &field.ty) else { return Err(unsupported( file, "type", field.ty.span(), ("field", &name), Some(extra), "", )); }; result.push(RustField { name, ty }); } } syn::Fields::Named(item) => { for field in &item.named { let name = field.ident.as_ref().unwrap().to_string(); let Some(ty) = to_rust_type(&ast, &field.ty) else { return Err(unsupported( file, "type", field.ty.span(), ("field", &name), Some(extra), "", )); }; result.push(RustField { name, ty }); } } } Ok(result) } fn to_rust_fn( file: &FileData, ast: &AST, sig: &syn::Signature, trait_name: Option<&str>, ) -> Result { let name = sig.ident.unraw().to_string(); let mut args = Vec::new(); let mut self_span = None; let extra = trait_name.map(|name| ("trait", name)); for arg in &sig.inputs { match arg { syn::FnArg::Typed(arg) => { let Some(name) = pat_to_single_ident(&arg.pat) else { return Err(unsupported( file, "pattern", arg.pat.span(), ("function", &name), None, "only identifiers are supported", )); }; let Some(ty) = to_rust_type(ast, &arg.ty) else { return Err(unsupported( file, "type", arg.ty.span(), ("argument", &name), extra, "", )); }; args.push(RustArg { name, ty }); } syn::FnArg::Receiver(arg) => { if arg.reference.is_none() || arg.colon_token.is_some() || arg.mutability.is_some() { return Err(unsupported( file, "receiver", arg.span(), ("argument", &name), extra, "use `&self` instead", )); } self_span = Some(arg.self_token.span()); } } } // All trait methods must have a "self" receiver match (trait_name, self_span) { (Some(trait_name), None) => { return Err(unsupported( file, "function", sig.ident.span(), ("trait", trait_name), None, "methods on public traits must use `&self`", )); } (None, Some(self_span)) => { return Err(unsupported( file, "argument", self_span, ("function", &name), extra, "", )); } _ => {} } let returns = match &sig.output { syn::ReturnType::Default => None, syn::ReturnType::Type(_, ty) => { let Some(ty) = to_rust_type(ast, &ty) else { return Err(unsupported( file, "return type", ty.span(), ("function", &name), extra, "", )); }; let mut names = NameSet::default(); for arg in &args { names.add(arg.name.clone()); } let name = names.create("ret"); Some(RustArg { name, ty }) } }; Ok(RustFn { name, args, returns, }) } fn to_rust_type(ast: &AST, ty: &syn::Type) -> Option { if let Some(ident) = type_to_single_ident(ty) { return match () { () if ident == "bool" => Some(RustType::Bool), () if ident == "u8" => Some(RustType::U8), () if ident == "u16" => Some(RustType::U16), () if ident == "u32" => Some(RustType::U32), () if ident == "usize" => Some(RustType::Usize), () if ident == "u64" => Some(RustType::U64), () if ident == "i8" => Some(RustType::I8), () if ident == "i16" => Some(RustType::I16), () if ident == "i32" => Some(RustType::I32), () if ident == "isize" => Some(RustType::Isize), () if ident == "i64" => Some(RustType::I64), () if ident == "f32" => Some(RustType::F32), () if ident == "f64" => Some(RustType::F64), () if ident == "String" => Some(RustType::OwnStr), _ => { if let Some((i, _)) = ast .structs .iter() .enumerate() .find(|(_, s)| ident == &s.name) { Some(RustType::Struct(i)) } else if let Some((i, _)) = ast.enums.iter().enumerate().find(|(_, e)| ident == &e.name) { Some(RustType::Enum(i)) } else { None } } }; } if let Some((name, inner)) = type_to_single_ident_with_argument(ast, ty) { return if name == "Rc" || name == "rc::Rc" || name == "std::rc::Rc" { match &inner { RustType::DynTrait(_) => Some(RustType::Ptr(RustPtr::Rc, inner.into())), _ => None, } } else if name == "Box" || name == "boxed::Box" || name == "std::boxed::Box" { Some(RustType::Ptr(RustPtr::Box, inner.into())) } else if name == "Vec" || name == "vec::Vec" || name == "std::vec::Vec" { Some(RustType::Vector(inner.into())) } else if name == "Option" || name == "option::Option" || name == "std::option::Option" { Some(RustType::Optional(inner.into())) } else { None }; } match ty { syn::Type::Tuple(syn::TypeTuple { elems, .. }) => { let mut types = Vec::new(); for elem in elems { types.push(to_rust_type(ast, elem)?); } Some(RustType::Tuple(types)) } syn::Type::Reference(syn::TypeReference { mutability: None, elem, .. }) => { if let Some(ident) = type_to_single_ident(elem) { match () { () if ident == "str" => Some(RustType::RefStr), _ => None, } } else { None } } syn::Type::TraitObject(syn::TypeTraitObject { bounds, .. }) if bounds.len() == 1 => { if let syn::TypeParamBound::Trait(syn::TraitBound { path, .. }) = &bounds[0] { if let Some(ident) = path.get_ident() { if let Some((i, _)) = ast .traits .iter() .enumerate() .find(|(_, t)| ident == &t.name) { Some(RustType::DynTrait(i)) } else { None } } else { None } } else { None } } _ => None, } } fn to_rust_val(expr: &syn::Expr, ty: &RustType) -> Option { match expr { syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Bool(lit), .. }) => match ty { RustType::Bool => Some(RustVal::Bool(lit.value())), _ => None, }, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }) => match ty { RustType::U8 => Some(RustVal::U8(lit.base10_parse().ok()?)), RustType::U16 => Some(RustVal::U16(lit.base10_parse().ok()?)), RustType::U32 => Some(RustVal::U32(lit.base10_parse().ok()?)), RustType::U64 => Some(RustVal::U64(lit.base10_parse().ok()?)), RustType::I8 => Some(RustVal::I8(lit.base10_parse().ok()?)), RustType::I16 => Some(RustVal::I16(lit.base10_parse().ok()?)), RustType::I32 => Some(RustVal::I32(lit.base10_parse().ok()?)), RustType::I64 => Some(RustVal::I64(lit.base10_parse().ok()?)), _ => None, }, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Float(lit), .. }) => match ty { RustType::F32 => Some(RustVal::F32(lit.base10_parse().ok()?)), RustType::F64 => Some(RustVal::F64(lit.base10_parse().ok()?)), _ => None, }, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit), .. }) => match ty { RustType::RefStr => Some(RustVal::Str(lit.value())), _ => None, }, syn::Expr::Unary(syn::ExprUnary { op: syn::UnOp::Neg(_), expr, .. }) => match &**expr { syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }) => match ty { RustType::I8 => Some(RustVal::I8( format!("-{}", lit.base10_digits()).parse().ok()?, )), RustType::I16 => Some(RustVal::I16( format!("-{}", lit.base10_digits()).parse().ok()?, )), RustType::I32 => Some(RustVal::I32( format!("-{}", lit.base10_digits()).parse().ok()?, )), RustType::I64 => Some(RustVal::I64( format!("-{}", lit.base10_digits()).parse().ok()?, )), _ => None, }, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Float(lit), .. }) => match ty { RustType::F32 => Some(RustVal::F32( format!("-{}", lit.base10_digits()).parse().ok()?, )), RustType::F64 => Some(RustVal::F64( format!("-{}", lit.base10_digits()).parse().ok()?, )), _ => None, }, _ => None, }, _ => None, } } fn expr_to_numeric_literal(expr: &syn::Expr) -> Option where T: std::str::FromStr, ::Err: std::fmt::Display, { match expr { // Positive syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }) => lit.base10_parse().ok(), // Negative syn::Expr::Unary(syn::ExprUnary { op: syn::UnOp::Neg(_), expr, .. }) => match &**expr { syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }) => format!("-{}", lit.base10_digits()).parse().ok(), _ => None, }, _ => None, } } fn path_to_string_with_argument(ast: &AST, path: &syn::Path) -> Option<(String, RustType)> { let last = path.segments.last()?; let syn::PathArguments::AngleBracketed(inner) = &last.arguments else { return None; }; if inner.args.len() == 1 { if let syn::GenericArgument::Type(ty) = &inner.args[0] { if let Some(inner) = to_rust_type(ast, ty) { let mut name = String::new(); for (i, segment) in path.segments.iter().enumerate() { if i + 1 < path.segments.len() { let syn::PathArguments::None = segment.arguments else { return None; }; } if i > 0 { name.push_str("::"); } name.push_str(&segment.ident.unraw().to_string()); } return Some((name, inner)); } } } None } fn type_to_single_ident(ty: &syn::Type) -> Option<&syn::Ident> { if let syn::Type::Path(syn::TypePath { qself: None, path }) = ty { return path.get_ident(); } None } fn type_to_single_ident_with_argument(ast: &AST, ty: &syn::Type) -> Option<(String, RustType)> { if let syn::Type::Path(syn::TypePath { qself: None, path }) = ty { return path_to_string_with_argument(ast, path); } None } fn pat_to_single_ident(pat: &syn::Pat) -> Option { match pat { syn::Pat::Ident(syn::PatIdent { ident, .. }) => Some(ident.unraw().to_string()), syn::Pat::Wild(_) => Some("_".to_string()), _ => None, } } fn unsupported( file: &FileData, what: &str, span: proc_macro2::Span, outer: (&str, &str), extra: Option<(&str, &str)>, note: &str, ) -> Warning { let text = match span.source_text() { None => what.into(), Some(text) => format!("{what} `{text}`"), }; let mut message = format!("unsupported {text} for {} `{}`", outer.0, outer.1); if let Some((what, name)) = extra { _ = write!(message, " in {what} `{name}`"); } make_warning(file, message, note, span) } pub fn make_warning( file: &FileData, message: String, note: &str, span: proc_macro2::Span, ) -> Warning { let start = span.start(); let end = span.end(); let line = start.line; let column = start.column + 1; let code = file .contents .lines() .skip(line.saturating_sub(1)) .next() .unwrap_or("") .to_string(); let len = if end.line == start.line { code.len().min(end.column) } else { code.len() } .saturating_sub(start.column); Warning { path: file.path.clone(), line, column, len, message, code, note: note.to_string(), } } fn is_infinite_size(ast: &AST, ty: &RustType) -> bool { fn visit(ast: &AST, ty: &RustType, visited: &mut HashSet) -> bool { use RustType::*; match ty { Struct(struct_index) => { if visited.contains(ty) { return true; } visited.insert(ty.clone()); ast.structs[*struct_index] .fields .iter() .any(|f| visit(ast, &f.ty, visited)) } Tuple(types) => types.iter().any(|ty| visit(ast, ty, visited)), Optional(inner) => visit(ast, inner, visited), _ => false, } } visit(ast, ty, &mut HashSet::new()) } ================================================ FILE: src/swift.rs ================================================ use super::*; use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::rc::Rc; /// Use this target when the host language is Swift. /// /// This needs to generate a `.swift` file and a `.h` file. By default, the /// files will be named `miniffi.swift` and `miniffi.h` and will be written to /// the directory containing your `Cargo.toml` file. You can customize these /// paths before calling [`build`](Target::build): /// /// ```no_run /// use miniffi::*; /// /// fn main() { /// SwiftTarget::new() /// .write_swift_to("../app/rust.swift") /// .write_header_to("../app/rust.h") /// .build(); /// } /// ``` /// /// If your `src/lib.rs` looks like this: /// /// ```no_run /// pub fn add(left: u64, right: u64) -> u64 { /// left + right /// } /// /// # macro_rules! env { ($a:expr) => { $a } } /// # macro_rules! include { ($a:expr) => { $a } } /// include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); /// ``` /// /// You can call that from Swift like this: /// /// ```text /// print("1 + 2 =", add(1, 2)) /// ``` /// /// Even though Swift is the host language, the `.h` file is necessary because /// Swift lacks syntax for specifying certain interactions with the C ABI that /// Rust uses. Instead of building those features into Swift itself, Apple has /// decided to make those features work by passing a C header to the Swift /// compiler instead. This is called using an "Objective-C bridging header" /// even though it has nothing to do with Objective-C in this case. /// /// ## Using the command line /// /// If you are using Swift from the command line, then you can call Rust from /// Swift by adding the generated `.swift` file, passing the generated `.h` /// file as the Objective-C bridging header, and also linking to the compiled /// Rust code. For example: /// /// ```text /// # Build the Rust code /// cargo rustc --crate-type=staticlib /// /// # Build the Swift code /// swiftc main.swift miniffi.swift -import-objc-header miniffi.h ./target/debug/libexample.a /// ``` /// /// ## Using Xcode /// /// If you're using Swift from Xcode, then the process is more complicated. /// There are also various ways to do this. Here's the process I use: /// /// 1. Create a `Makefile` to build your Rust code /// /// Put the following in a file called `Makefile` in your Rust crate: /// /// ```makefile /// Debug: /// cargo rustc --crate-type=staticlib /// /// Release: /// cargo rustc --crate-type=staticlib --release /// ``` /// /// Using an additional script like this makes our life easier later since /// we can reference it from the `xcodeproj` settings. Note that these /// indents are intentionally tab characters, not spaces (`make` requires /// tab characters). /// /// 2. Tell Xcode to compile the generated code /// /// Run `make` to cause the build script to run, which will generate /// `miniffi.swift` and `miniffi.h`. Then in Xcode, add `miniffi.swift` and /// `miniffi.h` to your project (make sure they are referenced, not copied). /// /// Include `miniffi.h` in your Objective-C Bridging Header. If you already /// have a bridging header, use `#include` to include `miniffi.h` there. /// Otherwise you can go to the **Build Settings** tab in your `xcodeproj` /// settings and set **Objective-C Bridging Header** directly to `miniffi.h`. /// /// 3. Tell Xcode to link with the compiled Rust code /// /// In the **Build Settings** tab of your `xcodeproj` settings, expand /// **Library Search Paths** into separate **Debug** and **Release** rows. /// Set the **Debug** path to `./target/debug` and the **Release** path to /// `./target/release`. /// /// Go to the **Build Phases** tab of your `xcodeproj` settings. Expand /// **Link Binary With Libraries**, click the `+` button, click /// **Add Other...** > **Add Files...**, and select the /// `./target/debug/libexample.a` file that you built earlier. /// /// At this point, you should now be able to compile and run your Xcode /// project and call Rust from Swift! But there's one more step you'll /// likely want to do... /// /// 4. Tell Xcode to rebuild your Rust code automatically /// /// In the **Build Settings** tab of your `xcodeproj` settings, set /// **User Scripts Sandboxing** to No. We will be building your Rust code /// which exists on the file system, so we need file system access. /// /// Go to the **Build Phases** tab of your `xcodeproj` settings. Use the `+` /// button to add a **New Run Script Phase** and drag it before the /// **Compile Sources** phase. Expand it and use the following shell script: /// /// ```sh /// export PATH="$HOME/.cargo/bin:$PATH" /// make "$CONFIGURATION" /// ``` /// /// You can also uncheck the **Based on dependency analysis** checkbox to /// disable an Xcode warning. /// /// Using `$CONFIGURATION` in combination with the `Makefile` means the /// **Debug** build configuration in Xcode will build your Rust code in debug /// mode (without the `--release` flag), and the **Release** build /// configuration in Xcode will build your rust code in release mode (with /// the `--release` flag). The `export PATH` is necessary because Xcode /// doesn't use your `$PATH` and won't be able to find the `cargo` binary /// otherwise. pub struct SwiftTarget { common_options: CommonOptions, swift_path: PathBuf, header_path: PathBuf, } impl SwiftTarget { pub fn new() -> SwiftTarget { SwiftTarget { common_options: CommonOptions::default(), swift_path: "miniffi.swift".into(), header_path: "miniffi.h".into(), } } pub fn write_swift_to>(mut self, path: T) -> Self { self.swift_path = path.into(); self } pub fn write_header_to>(mut self, path: T) -> Self { self.header_path = path.into(); self } } pub const SWIFT_KEYWORDS: &[&str] = &[ "Any", "as", "associatedtype", "associativity", "async", "await", "borrowing", "break", "case", "catch", "catch", "class", "consuming", "continue", "convenience", "default", "defer", "deinit", "didSet", "do", "dynamic", "else", "enum", "extension", "fallthrough", "false", "fileprivate", "final", "for", "func", "get", "guard", "if", "import", "in", "indirect", "infix", "init", "inout", "internal", "is", "lazy", "left", "let", "mutating", "nil", "none", "nonisolated", "nonmutating", "open", "operator", "optional", "override", "package", "postfix", "precedence", "precedencegroup", "prefix", "private", "protocol", "Protocol", "public", "repeat", "required", "rethrows", "rethrows", "return", "right", "self", "Self", "set", "some", "static", "struct", "subscript", "super", "switch", "throw", "throw", "throws", "true", "try", "Type", "typealias", "unowned", "var", "weak", "where", "while", "willSet", ]; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] enum HeaderGroup { Include, Other, } impl Compile for SwiftTarget { fn common_options(&mut self) -> &mut CommonOptions { &mut self.common_options } fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec { let syntax = RustSyntax::with_edition(self.common_options.edition); let mut rust_helpers = HelperSet::<(), String>::default(); let mut swift_helpers = HelperSet::<(), String>::default(); let mut header_helpers = HelperSet::::default(); // Also need to escape C++ keywords for the Objective-C bridging header let all_keywords: Vec<_> = SWIFT_KEYWORDS .iter() .chain(cpp::CPP_KEYWORDS.iter()) .map(|x| *x) .collect(); add_common_rust_helpers(&syntax, &mut rust_helpers); ast.rename_keywords(&all_keywords); header_helpers.add_group( HeaderGroup::Include, "", "\n#include \n", ); header_helpers .add_group( HeaderGroup::Other, "_ffi_alloc", "\nvoid* _ffi_alloc(intptr_t len);\n", ) .add_dep_group(HeaderGroup::Include, ""); header_helpers .add_group( HeaderGroup::Other, "_ffi_dealloc", "\nvoid _ffi_dealloc(const void* ptr, uintptr_t capacity);\n", ) .add_dep_group(HeaderGroup::Include, ""); swift_helpers.add( "_ffi_read", r#" private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } "#, ); swift_helpers.add( "_ffi_write", r#" private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } "#, ); swift_helpers.add( "_ffi_swift_drop", r#" @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } "#, ); swift_helpers.add( "_ffi_vec_to_rust", r" private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } ", ); swift_helpers.add( "_ffi_string_to_rust", r" private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } ", ); swift_helpers.add( "_ffi_string_from_rust", r" private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } ", ); let mut rust = format!("// {DO_NOT_EDIT_COMMENT}\n"); let mut swift = format!("// {DO_NOT_EDIT_COMMENT}\n"); // Traits for t in &ast.traits { _ = write!(swift, "\nprotocol {}: AnyObject {{\n", t.name); for f in &t.fns { _ = write!(swift, " func {}(", f.name); for (i, arg) in f.args.iter().enumerate() { if i > 0 { swift.push_str(", "); } _ = write!(swift, "_ {}: ", arg.name); append_swift_type(&mut swift, &ast, &arg.ty); } swift.push(')'); if let Some(returns) = &f.returns { swift.push_str(" -> "); append_swift_type(&mut swift, &ast, &returns.ty); } swift.push('\n'); } swift.push_str("}\n"); } // Enums for (i, e) in ast.enums.iter().enumerate() { if !e.has_fields() { // Enums without fields are just integers _ = write!(swift, "\nenum {}: Int32", e.name); swift.push_str(" {\n"); for v in &e.variants { _ = write!(swift, " case {} = {}\n", v.name, v.discriminant); } swift.push_str("}\n"); } else { // Enums with fields map directly to Swift enums _ = write!(swift, "\nenum {}", e.name); if e.derives_partial_eq { swift.push_str(" : Equatable"); } swift.push_str(" {\n"); for v in &e.variants { let indirect = match swift_variant_needs_indirect(&ast, i, v) { false => "", true => "indirect ", }; _ = write!(swift, " {indirect}case {}", v.name); if !v.fields.is_empty() { swift.push('('); for (j, f) in v.fields.iter().enumerate() { if j > 0 { swift.push_str(", "); } if !starts_with_digit(&f.name) { _ = write!(swift, "{}: ", f.name); } append_swift_type(&mut swift, &ast, &f.ty); } swift.push(')'); } swift.push('\n'); } if e.derives_partial_eq && e.variants .iter() .any(|v| v.fields.iter().any(|f| swift_type_contains_tuple(&f.ty))) { swift.push_str(&generate_operator_eq_enum(e)); } swift.push_str("}\n"); } } // Structs for (i, s) in ast.structs.iter().enumerate() { let use_class = swift_type_is_infinite_size(&ast, &RustType::Struct(i)); let keyword = if use_class { "class" } else { "struct" }; _ = write!(swift, "\n{keyword} {}", s.name); if s.derives_partial_eq { swift.push_str(" : Equatable"); } swift.push_str(" {\n"); for f in &s.fields { _ = write!(swift, " var {}: ", with_digit_prefix(&f.name)); append_swift_type(&mut swift, &ast, &f.ty); swift.push('\n'); } if use_class { swift.push_str(&generate_init(&ast, s)); } if s.derives_partial_eq && (use_class || s.fields.iter().any(|f| swift_type_contains_tuple(&f.ty))) { swift.push_str(&generate_operator_eq_struct(s)); } swift.push_str("}\n"); } // Constants if !ast.consts.is_empty() { swift.push('\n'); for c in &ast.consts { _ = write!(swift, "let {}: ", c.name); append_swift_type(&mut swift, &ast, &c.ty); swift.push_str(" = "); append_swift_val(&mut swift, &c.val); swift.push('\n'); } } let mut ctx = SwiftCtx { syntax, rust_helpers, swift_helpers, header_helpers, ..SwiftCtx::default() }; // Functions for f in &ast.fns { generate_swift_to_rust_fn(&ast, &mut ctx, f, &mut swift, None); } for it in ctx.rust_helpers.code_in_order() { rust.push_str(it); } for it in ctx.swift_helpers.code_in_order() { swift.push_str(it); } let header_code = ctx.header_helpers.code_by_group_in_order(); let mut header = format!("// {DO_NOT_EDIT_COMMENT}\n"); header.push_str("\n#pragma once\n"); if let Some(code) = header_code.get(&HeaderGroup::Include) { for it in code { header.push_str(it); } } header.push_str("\n#ifdef __cplusplus\n"); header.push_str("extern \"C\" {\n"); header.push_str("#endif\n"); if let Some(code) = header_code.get(&HeaderGroup::Other) { for it in code { header.push_str(it); } } header.push_str("\n#ifdef __cplusplus\n"); header.push_str("}\n"); header.push_str("#endif\n"); vec![ FileData { path: rust_path, contents: rust, }, FileData { path: self.swift_path.clone(), contents: swift, }, FileData { path: self.header_path.clone(), contents: header, }, ] } } fn swift_type_contains_tuple(ty: &RustType) -> bool { use RustType::*; match ty { Pair { other, .. } => swift_type_contains_tuple(other), Vector(inner_ty) => swift_type_contains_tuple(inner_ty), Optional(inner_ty) => swift_type_contains_tuple(inner_ty), Ptr(_, inner_ty) => swift_type_contains_tuple(inner_ty), Tuple(types) => types.len() != 1, _ => false, } } fn generate_init(ast: &AST, s: &RustStruct) -> String { let mut swift = "\n init(".to_string(); for (i, f) in s.fields.iter().enumerate() { if i > 0 { swift.push_str(", "); } swift.push_str(&f.name); swift.push_str(": "); append_swift_type(&mut swift, ast, &f.ty); } swift.push_str(") {\n"); for f in &s.fields { _ = write!(swift, " self.{} = {}\n", f.name, f.name); } swift.push_str(" }\n"); swift } fn emit_eq(parts: &mut Vec, ty: &RustType, a: &str, b: &str) { use RustType::*; if !swift_type_contains_tuple(ty) { parts.push(format!("{a} == {b}")); return; } match ty { Pair { other, .. } => emit_eq(parts, other, a, b), Ptr(_, inner_ty) => emit_eq(parts, inner_ty, a, b), // Unfortunately tuples in Swift don't currently implement // "Equatable", so structs containing tuples cannot automatically // derive "Equatable". There have been many attempts to fix this // but somehow it's still broken? Works fine in other languages. // Gotta work around it ourselves... Tuple(types) if types.len() != 1 => { for (i, ty) in types.iter().enumerate() { let a = format!("{a}.{i}"); let b = format!("{b}.{i}"); emit_eq(parts, ty, &a, &b); } } Optional(inner_ty) => { let mut inner_parts = Vec::new(); emit_eq(&mut inner_parts, inner_ty, "a", "b"); parts.push(if inner_parts.is_empty() { format!("({a} != nil) == ({b} != nil)") } else { format!( "{{ if let a = {a}, let b = {b} {{ {} }} else {{ {a} == nil && {b} == nil }} }}()", inner_parts.join(" && ") ) }); } Vector(inner_ty) => { let mut inner_parts = Vec::new(); emit_eq(&mut inner_parts, inner_ty, "a", "b"); parts.push(if inner_parts.is_empty() { format!("{a}.count == {b}.count") } else { format!( "{a}.elementsEqual({b}, by: {{ a, b in {} }})", inner_parts.join(" && ") ) }); } _ => parts.push(format!("{a} == {b}")), } } fn emit_eq_return(parts: &[String], base_indent: &str) -> String { if parts.is_empty() { "return true".to_string() } else if parts.len() == 1 || parts.iter().map(|x| x.len()).sum::() < 100 { format!("return {}", parts.join(" && ")) } else { let mut swift = "return (".to_string(); for (i, part) in parts.iter().enumerate() { if i > 0 { swift.push_str(" &&"); } _ = write!(swift, "\n{base_indent} {part}"); } _ = write!(swift, "\n{base_indent})"); swift } } fn generate_operator_eq_struct(s: &RustStruct) -> String { let mut swift = String::new(); let mut parts = Vec::new(); for f in &s.fields { let name = with_digit_prefix(&f.name); let a = format!("a.{}", name); let b = format!("b.{}", name); emit_eq(&mut parts, &f.ty, &a, &b); } _ = write!( swift, "\n static func == (a: {}, b: {}) -> Bool {{\n", s.name, s.name ); _ = write!(swift, " {}\n", emit_eq_return(&parts, " ")); swift.push_str(" }\n"); swift } fn generate_operator_eq_enum(e: &RustEnum) -> String { let mut locals = NameSet::default(); let mut swift = String::new(); locals.add("a".to_string()); locals.add("b".to_string()); _ = write!( swift, "\n static func == (a: {}, b: {}) -> Bool {{\n", e.name, e.name ); swift.push_str(" switch (a, b) {\n"); for v in &e.variants { if v.fields.is_empty() { _ = write!(swift, " case (.{}, .{}):\n", v.name, v.name); swift.push_str(" return true\n"); continue; } let mut branch_locals = locals.clone(); let mut a_names = Vec::new(); let mut b_names = Vec::new(); let mut parts = Vec::new(); _ = write!(swift, " case let (.{}(", v.name); for (i, f) in v.fields.iter().enumerate() { if i > 0 { swift.push_str(", "); } if !starts_with_digit(&f.name) { _ = write!(swift, "{}: ", f.name); } let name = branch_locals.create(&format!("a{}", f.name)); swift.push_str(&name); a_names.push(name); } _ = write!(swift, "), .{}(", v.name); for (i, f) in v.fields.iter().enumerate() { if i > 0 { swift.push_str(", "); } if !starts_with_digit(&f.name) { _ = write!(swift, "{}: ", f.name); } let name = branch_locals.create(&format!("b{}", f.name)); swift.push_str(&name); b_names.push(name); } for ((a, b), f) in a_names.iter().zip(&b_names).zip(&v.fields) { emit_eq(&mut parts, &f.ty, a, b); } swift.push_str(")):\n"); _ = write!( swift, " {}\n", emit_eq_return(&parts, " ") ); } swift.push_str(" default:\n"); swift.push_str(" return false\n"); swift.push_str(" }\n"); swift.push_str(" }\n"); swift } #[derive(Default)] struct SwiftCtx { syntax: RustSyntax, helper_names: NameSet, rust_helpers: HelperSet<(), String>, swift_helpers: HelperSet<(), String>, header_helpers: HelperSet, multi_ret_helpers: HashMap, String>, trait_to_rust_helpers: HashMap, trait_to_swift_helpers: HashMap<(RustPtr, usize), String>, vec_to_rust_helpers: HashMap, vec_to_swift_helpers: HashMap, box_to_rust_helpers: HashMap, box_to_swift_helpers: HashMap, enum_to_rust_helpers: HashMap, enum_to_swift_helpers: HashMap, } #[derive(Default)] struct Transform { swift: FnBuilder, rust: FnBuilder, ffi_args: Vec, buf: Option>, buf_status: BufStatus, buf_ref: &'static str, } struct TraitInfo<'a> { t: &'a RustTrait, kind: RustPtr, } fn generate_swift_to_rust_fn( ast: &AST, ctx: &mut SwiftCtx, f: &RustFn, swift: &mut String, trait_info: Option, ) { let ffi_name = ctx.helper_names.create(&match &trait_info { None => format!("_ffi_fn_{}", f.name), Some(info) => format!("_ffi_{:?}_{}__{}", info.kind, info.t.name, f.name), }); let mut names = NameSet::default(); for arg in &f.args { names.add(arg.name.clone()); } if let Some(ret) = &f.returns { names.add(ret.name.clone()); } // Transform the arguments let mut arg_tfm = Transform::default(); if let Some(info) = &trait_info { arg_tfm.rust.line(format!( "let _self = unsafe {{ &*(_self as *const {}) }};", info.kind.path(), info.t.name )); } for arg in &f.args { arg_tfm.swift.mark_pure(&arg.name); transform_to_rust(ast, ctx, &mut names, &mut arg_tfm, &arg.name, &arg.ty); } arg_tfm.swift.insert_deferred_lines_here(); // Generate the Rust call to the FFI function let mut rust_call = String::new(); if trait_info.is_some() { rust_call.push_str("_self."); } _ = write!(rust_call, "{}(", f.name); rust_call.push_str(&arg_tfm.rust.find_args(&f.args, RefInline)); rust_call.push(')'); // Transform the result let mut ret_tfm = Transform::default(); if let Some(ret) = &f.returns { ret_tfm.rust.decl(&ret.name, rust_call); transform_to_swift(ast, ctx, &mut names, &mut ret_tfm, &ret.name, &ret.ty); } else { rust_call.push(';'); ret_tfm.rust.line(rust_call); } // Generate the Swift call to the FFI function let mut swift_call = format!("{ffi_name}("); if trait_info.is_some() { swift_call.push_str("_ffi"); if !arg_tfm.ffi_args.is_empty() { swift_call.push_str(", "); } } swift_call.push_str(&arg_tfm.swift.find_args(&arg_tfm.ffi_args, RefInline)); swift_call.push(')'); // Header { let mut header = String::new(); let mut header_deps = HashSet::new(); let return_ty = match &ret_tfm.ffi_args[..] { [] => None, [value] => Some(Cow::Borrowed(&value.ty)), _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); header_deps.insert((HeaderGroup::Other, ty_name.clone())); Some(Cow::Owned(RustType::Verbatim(ty_name))) } }; header.push('\n'); append_c_signature( &mut header, &mut header_deps, return_ty.as_deref(), &ffi_name, trait_info.as_ref().map(|_| &RustType::ForeignHandle), &arg_tfm.ffi_args, ); header.push_str(";\n"); ctx.header_helpers .add_group(HeaderGroup::Other, &ffi_name, header) .add_deps_group(header_deps) .mark_used(); } // Swift { // Handle the return values let mut fb = arg_tfm.swift; match &ret_tfm.ffi_args[..] { [] => fb.line(swift_call), [arg] => fb.decl(&arg.name, swift_call), _ => { let ret = names.create("multi_ret"); fb.decl(&ret, swift_call); for (i, arg) in ret_tfm.ffi_args.iter().enumerate() { fb.decl(&arg.name, format!("{ret}._{i}")); } } }; // Return from the function fb.extend(ret_tfm.swift); fb.insert_deferred_lines_here(); if let Some(ret) = &f.returns { let code = fb.find(&ret.name, &ret.ty, RefInline).code; fb.line(format!("return {code}")); } // Write out the final function let indent = match &trait_info { None => " ", Some(_) => " ", }; _ = write!(swift, "\n{}func {}(", &indent[4..], f.name); for (i, arg) in f.args.iter().enumerate() { if i > 0 { swift.push_str(", "); } _ = write!(swift, "_ {}: ", arg.name); append_swift_type(swift, ast, &arg.ty); } swift.push(')'); if let Some(returns) = &f.returns { swift.push_str(" -> "); append_swift_type(swift, ast, &returns.ty); } swift.push_str(" {\n"); fb.write_to_swift(ast, swift, indent); _ = write!(swift, "{}}}\n", &indent[4..]); } // Rust { // Return from the function let mut fb = arg_tfm.rust; fb.extend(ret_tfm.rust); fb.insert_deferred_lines_here(); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { let code = fb.find(&arg.name, &arg.ty, RefInline).code; fb.line(code); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); let args = fb.find_args(&ret_tfm.ffi_args, RefInline); fb.line(format!("{ty_name}({args})")); } } // Write out the final function let mut rust = String::new(); _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle()); _ = write!(rust, "extern \"C\" fn {ffi_name}("); if trait_info.is_some() { rust.push_str("_self: *const u8"); } for (i, arg) in arg_tfm.ffi_args.iter().enumerate() { if trait_info.is_some() || i > 0 { rust.push_str(", "); } _ = write!(rust, "{}: ", arg.name); append_rust_type(&mut rust, ast, &arg.ty); } rust.push(')'); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { rust.push_str(" -> "); append_rust_type(&mut rust, ast, &arg.ty); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust, " -> {ty_name}"); } } rust.push_str(" {\n"); fb.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&ffi_name, rust).mark_used(); } } fn generate_rust_to_swift_fn( ast: &AST, ctx: &mut SwiftCtx, t: &RustTrait, f: &RustFn, rust: &mut String, ) { let ffi_name = ctx .helper_names .create(&format!("_ffi_swift_{}__{}", t.name, f.name)); let mut names = NameSet::default(); for arg in &f.args { names.add(arg.name.clone()); } if let Some(ret) = &f.returns { names.add(ret.name.clone()); } // Transform the arguments let mut arg_tfm = Transform::default(); let self_code = format!( "Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! {}", t.name ); arg_tfm.swift.line(format!("let _self = {self_code}")); for arg in &f.args { arg_tfm.rust.mark_pure(&arg.name); transform_to_swift(ast, ctx, &mut names, &mut arg_tfm, &arg.name, &arg.ty); } arg_tfm.rust.insert_deferred_lines_here(); // Generate the Swift call to the FFI function let mut swift_call = format!("_self.{}(", f.name); swift_call.push_str(&arg_tfm.swift.find_args(&f.args, RefInline)); swift_call.push(')'); // Transform the result let mut ret_tfm = Transform::default(); if let Some(ret) = &f.returns { ret_tfm.swift.decl(&ret.name, swift_call); transform_to_rust(ast, ctx, &mut names, &mut ret_tfm, &ret.name, &ret.ty); } else { ret_tfm.swift.line(swift_call); } // Generate the Rust call to the FFI function let mut rust_call = format!("unsafe {{ {ffi_name}(self.0"); if !arg_tfm.ffi_args.is_empty() { rust_call.push_str(", "); } rust_call.push_str(&arg_tfm.rust.find_args(&arg_tfm.ffi_args, RefInline)); rust_call.push_str(") }"); // Rust { // Handle the return values let mut fb = arg_tfm.rust; match &ret_tfm.ffi_args[..] { [] => { rust_call.push(';'); fb.line(rust_call); } [arg] => fb.decl(&arg.name, rust_call), _ => { let ret = names.create("multi_ret"); fb.decl(&ret, rust_call); for (i, arg) in ret_tfm.ffi_args.iter().enumerate() { fb.decl(&arg.name, format!("{ret}.{i}")); } } }; // Return from the function fb.extend(ret_tfm.rust); fb.insert_deferred_lines_here(); if let Some(ret) = &f.returns { let code = fb.find(&ret.name, &ret.ty, RefInline).code; fb.line(code); } // Write out the final function _ = write!(rust, "\n fn {}(&self", f.name); for arg in &f.args { _ = write!(rust, ", {}: ", arg.name); append_rust_type(rust, ast, &arg.ty); } rust.push(')'); if let Some(returns) = &f.returns { rust.push_str(" -> "); append_rust_type(rust, ast, &returns.ty); } rust.push_str(" {\n"); _ = write!( rust, " {} \"C\" {{ fn {ffi_name}(_: *const u8", ctx.syntax.unsafe_extern() ); for arg in &arg_tfm.ffi_args { _ = write!(rust, ", {}: ", arg.name); append_rust_type(rust, ast, &arg.ty); } match &ret_tfm.ffi_args[..] { [] => rust.push(')'), [arg] => { rust.push_str(") -> "); append_rust_type(rust, ast, &arg.ty); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust, ") -> {ty_name}"); } } rust.push_str("; }\n"); fb.write_to_rust(ast, rust, " "); rust.push_str(" }\n"); } // Swift { // Return from the function let mut fb = arg_tfm.swift; fb.extend(ret_tfm.swift); fb.insert_deferred_lines_here(); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { let code = fb.find(&arg.name, &arg.ty, RefInline).code; fb.line(format!("return {code}")); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); let args = fb.find_fields( &ret_tfm .ffi_args .iter() .enumerate() .map(|(i, arg)| RustField { name: format!("_{i}"), ty: arg.ty.clone(), }) .collect(), ret_tfm .ffi_args .iter() .map(|arg| arg.name.as_str().into()) .collect(), RefInline, &format!("return {ty_name}("), ")", ); fb.line(args); } } // Write out the final function let mut swift = "\n@_cdecl(".to_string(); append_swift_quoted(&mut swift, &ffi_name); _ = write!(swift, ")\nfunc {ffi_name}(_self: UnsafeRawPointer?"); for arg in &arg_tfm.ffi_args { _ = write!(swift, ", {}: ", arg.name); append_swift_type(&mut swift, ast, &arg.ty); } swift.push(')'); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { swift.push_str(" -> "); append_swift_type(&mut swift, ast, &arg.ty); } _ => { let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(swift, " -> {ty_name}"); } } swift.push_str(" {\n"); fb.write_to_swift(ast, &mut swift, " "); swift.push_str("}\n"); ctx.swift_helpers.add(&ffi_name, swift).mark_used(); } } fn transform_to_rust( ast: &AST, ctx: &mut SwiftCtx, names: &mut NameSet, tfm: &mut Transform, name: &str, ty: &RustType, ) { use RustType::*; fn add_ffi_arg(ast: &AST, ctx: &mut SwiftCtx, tfm: &mut Transform, name: &str, ty: &RustType) { match tfm.buf_status { BufStatus::Outside => tfm.ffi_args.push(RustArg { name: name.to_string(), ty: ty.clone(), }), BufStatus::Inside => { let buf = tfm.buf.as_ref().unwrap(); // Swift (write) let code = tfm.swift.find(name, ty, RefInline).code; tfm.swift .line(format!("_ffi_write({code}, &{})", buf.buf_name())); ctx.swift_helpers.mark_used("_ffi_write"); // Rust (read) let mut rust = "_ffi_read::<".to_string(); append_rust_type(&mut rust, ast, ty); _ = write!(rust, ">({}{})", tfm.buf_ref, buf.end_name()); tfm.rust.decl(name, rust); ctx.rust_helpers.mark_used("_ffi_read"); } } } match ty { Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => add_ffi_arg(ast, ctx, tfm, name, ty), RefStr | OwnStr => { let swift_code = tfm.swift.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let len_name = names.create(&format!("{name}_len")); let opt_ref = match ty { RefStr => "&", _ => "", }; tfm.swift.line(format!( "let ({ptr_name}, {len_name}) = _ffi_string_to_rust({swift_code});" )); ctx.header_helpers .mark_used_group(HeaderGroup::Other, "_ffi_alloc"); ctx.swift_helpers.mark_used("_ffi_string_to_rust"); add_ffi_arg(ast, ctx, tfm, &ptr_name, &ForeignHandle); add_ffi_arg(ast, ctx, tfm, &len_name, &Usize); let len_code = tfm.rust.find(&len_name, &Usize, RefInline).code; let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.rust.decl( name, format!("{opt_ref}_ffi_string_from_host({ptr_code}, {len_code})"), ); ctx.rust_helpers.mark_used("_ffi_string_from_host"); } Enum(enum_index) => { let swift = tfm.swift.find(name, ty, RefInline); let e = &ast.enums[*enum_index]; let (swift_helper, rust_helper) = enum_to_rust_helper(ast, ctx, *enum_index); if !e.has_fields() { let raw_name = names.create(&format!("{name}_raw")); tfm.swift.maybe_pure_decl( swift.pure, &raw_name, format!("{}.rawValue", swift.code), ); add_ffi_arg(ast, ctx, tfm, &raw_name, &I32); tfm.rust.decl(name, format!("{rust_helper}({raw_name})")); } else { let buf = ensure_swift_buf(ctx, names, tfm); tfm.swift.line(format!( "{swift_helper}({}, &{})", swift.code, buf.buf_name() )); tfm.rust.decl( name, format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()), ); } } Struct(struct_index) => { let swift = tfm.swift.find(name, ty, RefMany); let s = &ast.structs[*struct_index]; let mut item_names = Vec::new(); for f in &s.fields { let item_name = names.create(&format!("{name}_{}", f.name)); tfm.swift.maybe_pure_decl( swift.pure, &item_name, format!("{}.{}", swift.code, with_digit_prefix(&f.name)), ); transform_to_rust(ast, ctx, names, tfm, &item_name, &f.ty); item_names.push(item_name.into()); } rust_decl_ctor(&mut tfm.rust, name, &s.name, &s.fields, item_names); } Tuple(types) => { let swift = tfm.swift.find(name, ty, RefMany); let mut item_args = Vec::new(); for (i, item_ty) in types.iter().enumerate() { let item_name = names.create(&format!("{name}_{i}")); let swift_code = match types.len() { 1 => tfm.swift.find(name, item_ty, RefInline).code, _ => format!("{}.{i}", swift.code), }; tfm.swift .maybe_pure_decl(swift.pure, &item_name, swift_code); transform_to_rust(ast, ctx, names, tfm, &item_name, &item_ty); item_args.push(RustArg { name: item_name, ty: item_ty.clone(), }); } let mut rust_code = tfm.rust.find_args(&item_args, RefInline); if types.len() == 1 { rust_code.push(','); } tfm.rust.decl(name, format!("({rust_code})")); } Ptr(kind, inner_ty) => { if let DynTrait(trait_index) = &**inner_ty { let swift_code = tfm.swift.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let rust_helper = trait_to_rust_helper(ast, ctx, *trait_index); let swift_code = format!( "UnsafeRawPointer(Unmanaged.passRetained({swift_code} as AnyObject).toOpaque())" ); tfm.swift.decl(&ptr_name, swift_code); add_ffi_arg(ast, ctx, tfm, &ptr_name, &ForeignHandle); let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.rust.decl( name, format!("{}::new({rust_helper}({ptr_code}))", kind.path()), ); } else if *kind == RustPtr::Box { let swift_code = tfm.swift.find(name, ty, RefMany).code; let (swift_helper, rust_helper) = box_to_rust_helper(ast, ctx, inner_ty); let buf = ensure_swift_buf(ctx, names, tfm); tfm.swift .line(format!("{swift_helper}({swift_code}, &{})", buf.buf_name())); tfm.rust.decl( name, format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()), ); } else { unreachable!() } } Vector(inner_ty) => { let swift_code = tfm.swift.find(name, ty, RefMany).code; let len_name = names.create(&format!("{name}_len")); let (swift_helper, rust_helper) = vec_to_rust_helper(ast, ctx, inner_ty); let buf = ensure_swift_buf(ctx, names, tfm); tfm.swift .decl(&len_name, format!("UInt({swift_code}.count)")); add_ffi_arg(ast, ctx, tfm, &len_name, &Usize); tfm.swift .line(format!("{swift_helper}({swift_code}, &{})", buf.buf_name())); let len_code = tfm.rust.find(&len_name, ty, RefInline).code; tfm.rust.decl( name, format!( "{rust_helper}({len_code}, {}{})", tfm.buf_ref, buf.end_name() ), ); } Optional(inner_ty) => { let swift_code = tfm.swift.find(name, ty, RefMany).code; let has_name = names.create(&format!("has_{name}")); let val_name = names.create(&format!("{name}_val")); ensure_swift_buf(ctx, names, tfm); tfm.swift.decl(&has_name, format!("{swift_code} != nil")); add_ffi_arg(ast, ctx, tfm, &has_name, &Bool); let mut rust = FnBuilder::default(); let branch = format!("if let {val_name} = {swift_code} {{"); tfm.swift.line(branch.clone()); { let old = tfm.buf_status; tfm.buf_status = BufStatus::Inside; std::mem::swap(&mut tfm.rust, &mut rust); transform_to_rust(ast, ctx, names, tfm, &val_name, inner_ty); std::mem::swap(&mut tfm.rust, &mut rust); tfm.buf_status = old; } match tfm.swift.pop_line_if(|x| x == &Line::Plain(branch)) { None => tfm.swift.line("}".into()), Some(_) => {} // Avoid an unused variable warning in Swift } let has_code = tfm.rust.find(&has_name, ty, RefInline).code; let val_code = rust.find(&val_name, ty, RefInline).code; if rust.is_empty() { tfm.rust .decl(name, format!("{has_code}.then(|| {val_code})")); } else { rust.insert_deferred_lines_here(); rust.line(val_code); tfm.rust.line(format!("let {name} = {has_code}.then(|| {{")); tfm.rust.extend(rust); tfm.rust.line("});".to_string()); } } Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(), } } fn transform_to_swift( ast: &AST, ctx: &mut SwiftCtx, names: &mut NameSet, tfm: &mut Transform, name: &str, ty: &RustType, ) { use RustType::*; fn add_ffi_arg(ast: &AST, ctx: &mut SwiftCtx, tfm: &mut Transform, name: &str, ty: &RustType) { match tfm.buf_status { BufStatus::Outside => tfm.ffi_args.push(RustArg { name: name.to_string(), ty: ty.clone(), }), BufStatus::Inside => { let buf = tfm.buf.as_ref().unwrap(); // Rust (write) let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!( "_ffi_write({code}, {}{});", tfm.buf_ref, buf.buf_name() )); ctx.rust_helpers.mark_used("_ffi_write"); // Swift (read) let mut swift = String::new(); _ = write!(swift, "_ffi_read(&{}) as ", buf.end_name()); append_swift_type(&mut swift, ast, ty); tfm.swift.decl(name, swift); ctx.swift_helpers.mark_used("_ffi_read"); } } } match ty { Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => add_ffi_arg(ast, ctx, tfm, name, ty), RefStr | OwnStr => { let mut rust_code = tfm.rust.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let len_name = names.create(&format!("{name}_len")); let cap_name = names.create(&format!("{name}_cap")); if let RefStr = ty { rust_code.push_str(".into()"); } tfm.rust.line(format!( "let ({ptr_name}, {len_name}, {cap_name}) = _ffi_string_to_host({rust_code});" )); ctx.rust_helpers.mark_used("_ffi_string_to_host"); add_ffi_arg(ast, ctx, tfm, &ptr_name, &ForeignHandle); add_ffi_arg(ast, ctx, tfm, &len_name, &Usize); add_ffi_arg(ast, ctx, tfm, &cap_name, &Usize); let cap_code = tfm.swift.find(&cap_name, &Usize, RefInline).code; let len_code = tfm.swift.find(&len_name, &Usize, RefInline).code; let ptr_code = tfm.swift.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.swift.decl( name, format!("_ffi_string_from_rust({ptr_code}, Int({len_code}), {cap_code})"), ); ctx.swift_helpers.mark_used("_ffi_string_from_rust"); ctx.header_helpers .mark_used_group(HeaderGroup::Other, "_ffi_dealloc"); } Enum(enum_index) => { let rust = tfm.rust.find(name, ty, RefInline); let e = &ast.enums[*enum_index]; if !e.has_fields() { let raw_name = names.create(&format!("{name}_raw")); tfm.rust .maybe_pure_decl(rust.pure, &raw_name, format!("{} as i32", rust.code)); add_ffi_arg(ast, ctx, tfm, &raw_name, &I32); tfm.swift .decl(name, format!("{}(rawValue: {raw_name})!", e.name)); } else { let (swift_helper, rust_helper) = enum_to_swift_helper(ast, ctx, *enum_index); let buf = ensure_rust_buf(ctx, names, tfm); tfm.rust.line(format!( "{rust_helper}({}, {}{});", rust.code, tfm.buf_ref, buf.buf_name() )); tfm.swift .decl(name, format!("{swift_helper}(&{})", buf.end_name())); } } Struct(struct_index) => { let rust = tfm.rust.find(name, ty, RefMany); let s = &ast.structs[*struct_index]; let mut item_names = Vec::new(); for f in &s.fields { let item_name = names.create(&format!("{name}_{}", f.name)); tfm.rust.maybe_pure_decl( rust.pure, &item_name, format!("{}.{}", rust.code, f.name), ); transform_to_swift(ast, ctx, names, tfm, &item_name, &f.ty); item_names.push(item_name.into()); } if s.fields.is_empty() { // Avoid an unused variable warning in Rust let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!("_ = {code};")); } let fields = tfm.swift.find_fields( &s.fields .iter() .map(|f| RustField { name: with_digit_prefix(&f.name).into_owned(), ty: f.ty.clone(), }) .collect(), item_names, RefInline, &format!("{}(", s.name), ")", ); tfm.swift.decl(name, fields); } Tuple(types) => { let rust = tfm.rust.find(name, ty, RefMany); let mut item_args = Vec::new(); for (i, item_ty) in types.iter().enumerate() { let item_name = names.create(&format!("{name}_{i}")); tfm.rust .maybe_pure_decl(rust.pure, &item_name, format!("{}.{i}", rust.code)); transform_to_swift(ast, ctx, names, tfm, &item_name, &item_ty); item_args.push(RustArg { name: item_name, ty: item_ty.clone(), }); } if types.is_empty() { tfm.swift.pure_decl(name, "()".to_string()); // Avoid an unused variable warning in Rust let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!("_ = {code};")); } else { let swift_code = tfm.swift.find_args(&item_args, RefInline); tfm.swift.decl( name, match types.len() { 1 => swift_code, _ => format!("({swift_code})"), }, ); } } Ptr(kind, inner_ty) => { if let DynTrait(trait_index) = &**inner_ty { let rust_code = tfm.rust.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let swift_helper = trait_to_swift_helper(ast, ctx, *trait_index, *kind); tfm.rust.decl( &ptr_name, format!("Box::into_raw(Box::new({rust_code})) as *const u8"), ); add_ffi_arg(ast, ctx, tfm, &ptr_name, &ForeignHandle); let ptr_code = tfm.swift.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.swift.decl(name, format!("{swift_helper}({ptr_code})")); } else if *kind == RustPtr::Box { let rust_code = tfm.rust.find(name, ty, RefMany).code; let (swift_helper, rust_helper) = box_to_swift_helper(ast, ctx, inner_ty); let buf = ensure_rust_buf(ctx, names, tfm); tfm.rust.line(format!( "{rust_helper}(*{rust_code}, {}{});", tfm.buf_ref, buf.buf_name() )); tfm.swift .decl(name, format!("{swift_helper}(&{})", buf.end_name())); } else { unreachable!() } } Vector(inner_ty) => { let rust_code = tfm.rust.find(name, ty, RefMany).code; let len_name = names.create(&format!("{name}_len")); let (swift_helper, rust_helper) = vec_to_swift_helper(ast, ctx, inner_ty); let buf = ensure_rust_buf(ctx, names, tfm); tfm.rust.decl(&len_name, format!("{rust_code}.len()")); add_ffi_arg(ast, ctx, tfm, &len_name, &Usize); tfm.rust.line(format!( "{rust_helper}({rust_code}, {}{});", tfm.buf_ref, buf.buf_name() )); let len_code = tfm.swift.find(&len_name, ty, RefInline).code; tfm.swift.decl( name, format!("{swift_helper}(Int({len_code}), &{})", buf.end_name()), ); } Optional(inner_ty) => { let rust_code = tfm.rust.find(name, ty, RefMany).code; let has_name = names.create(&format!("has_{name}")); let val_name = names.create(&format!("{name}_val")); ensure_rust_buf(ctx, names, tfm); tfm.rust.decl(&has_name, format!("{rust_code}.is_some()")); add_ffi_arg(ast, ctx, tfm, &has_name, &Bool); let mut swift = FnBuilder::default(); tfm.rust .line(format!("if let Some({val_name}) = {rust_code} {{")); { let old = tfm.buf_status; tfm.buf_status = BufStatus::Inside; std::mem::swap(&mut tfm.swift, &mut swift); transform_to_swift(ast, ctx, names, tfm, &val_name, inner_ty); std::mem::swap(&mut tfm.swift, &mut swift); tfm.buf_status = old; } tfm.rust.line("}".into()); let has_code = tfm.swift.find(&has_name, ty, RefInline).code; let mut val_code = swift.find(&val_name, ty, RefInline).code; if let Optional(_) = &**inner_ty { val_code = format!("Optional.some({val_code})"); } if swift.is_empty() { tfm.swift .decl(name, format!("{has_code} ? {val_code} : nil")); } else { let mut swift_ty = String::new(); append_swift_type(&mut swift_ty, ast, ty); swift.insert_deferred_lines_here(); swift.line(format!("{name} = {val_code}")); tfm.swift.line(format!("var {name}: {swift_ty} = nil")); tfm.swift.line(format!("if {has_code} {{")); tfm.swift.extend(swift); tfm.swift.line("}".to_string()); } } Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(), } } fn ensure_swift_buf(ctx: &mut SwiftCtx, names: &mut NameSet, tfm: &mut Transform) -> Rc { if let Some(buf) = &tfm.buf { return buf.clone(); } let buf_name = names.create("buf"); let ptr_name = names.create("buf_ptr"); let end_name = names.create("buf_end"); let buf = SharedBuf::new(&buf_name, &end_name); // Swift (write) tfm.swift.line_alt( format!("let {buf_name} = ContiguousArray()"), format!("var {buf_name} = ContiguousArray()"), buf.is_buf_name_used_flag(), ); tfm.swift .defer_decl(&ptr_name, format!("_ffi_vec_to_rust({buf_name})")); ctx.swift_helpers.mark_used("_ffi_vec_to_rust"); ctx.header_helpers .mark_used_group(HeaderGroup::Other, "_ffi_alloc"); // Rust (read) tfm.rust.line_alt( // Avoid a warning about an unnecessarily mutable variable format!("let {end_name} = {ptr_name};"), format!("let mut {end_name} = {ptr_name};"), buf.is_buf_name_used_flag(), ); tfm.rust .defer_line(format!("_ffi_buf_from_host({ptr_name}, {end_name});")); ctx.rust_helpers.mark_used("_ffi_buf_from_host"); // FFI tfm.buf = Some(buf.clone()); tfm.buf_ref = "&mut "; tfm.ffi_args.push(RustArg { name: ptr_name, ty: RustType::ForeignHandle, }); buf } fn ensure_rust_buf(ctx: &mut SwiftCtx, names: &mut NameSet, tfm: &mut Transform) -> Rc { if let Some(buf) = &tfm.buf { return buf.clone(); } let buf_name = names.create("buf"); let ptr_name = names.create("buf_ptr"); let end_name = names.create("buf_end"); let cap_name = names.create("buf_cap"); let buf = SharedBuf::new(&buf_name, &end_name); // Rust (write) tfm.rust.line_alt( // Avoid a warning about an unnecessarily mutable variable format!("let {buf_name} = Vec::::new();"), format!("let mut {buf_name} = Vec::::new();"), buf.is_buf_name_used_flag(), ); tfm.rust.defer_line(format!( "let ({ptr_name}, {cap_name}) = _ffi_buf_to_host({buf_name});" )); ctx.rust_helpers.mark_used("_ffi_buf_to_host"); // Swift (read) tfm.swift.line_alt( "".to_string(), format!("var {end_name} = {ptr_name}!"), buf.is_end_name_used_flag(), ); tfm.swift .defer_line(format!("_ffi_dealloc({ptr_name}, {cap_name})")); ctx.header_helpers .mark_used_group(HeaderGroup::Other, "_ffi_dealloc"); // FFI tfm.buf = Some(buf.clone()); tfm.buf_ref = "&mut "; tfm.ffi_args.push(RustArg { name: ptr_name, ty: RustType::ForeignHandle, }); tfm.ffi_args.push(RustArg { name: cap_name, ty: RustType::Usize, }); buf } fn vec_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.vec_to_rust_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_vec_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let swift_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_swift")); // This must be done first to avoid a stack overflow ctx.vec_to_rust_helpers .insert(inner_ty.clone(), (swift_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let vec_name = locals.create("items"); let item_name = locals.create("item"); let end_name = locals.create("end"); let len_name = locals.create("len"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.swift.mark_pure(&item_name); transform_to_rust(ast, ctx, &mut locals, &mut tfm, &item_name, &inner_ty); let item_code = tfm.rust.find(&item_name, inner_ty, RefInline).code; tfm.rust.line(format!("{vec_name}.push({item_code});")); // Swift { let mut swift = String::new(); _ = write!(swift, "\nprivate func {swift_name}(_ {vec_name}: ["); append_swift_type(&mut swift, ast, inner_ty); _ = write!(swift, "], _ {buf_name}: inout ContiguousArray) {{\n"); if !tfm.swift.is_empty() { _ = write!(swift, " for {item_name} in {vec_name} {{\n"); tfm.swift.write_to_swift(ast, &mut swift, " "); swift.push_str(" }\n"); } swift.push_str("}\n"); ctx.swift_helpers.add(&swift_name, swift).mark_used(); } // Rust { let mut rust = String::new(); let mut item_ty = String::new(); let end_name = buf.final_end_name_for_rust(); append_rust_type(&mut item_ty, ast, inner_ty); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({len_name}: usize, {end_name}: &mut *const u8) -> Vec<{item_ty}> {{\n" ); _ = write!( rust, " let mut {vec_name} = Vec::<{item_ty}>::with_capacity({len_name});\n" ); _ = write!(rust, " for _ in 0..{len_name} {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); _ = write!(rust, " {vec_name}\n"); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } (swift_name, rust_name) } fn vec_to_swift_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.vec_to_swift_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_vec_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let swift_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_swift")); // This must be done first to avoid a stack overflow ctx.vec_to_swift_helpers .insert(inner_ty.clone(), (swift_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let vec_name = locals.create("items"); let item_name = locals.create("item"); let end_name = locals.create("end"); let len_name = locals.create("len"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.rust.mark_pure(&item_name); transform_to_swift(ast, ctx, &mut locals, &mut tfm, &item_name, &inner_ty); let item_code = tfm.swift.find(&item_name, inner_ty, RefInline).code; tfm.swift.line(format!("{vec_name}.append({item_code})")); // Rust { let mut rust = String::new(); let buf_name = buf.final_buf_name_for_rust(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({vec_name}: Vec<"); append_rust_type(&mut rust, ast, inner_ty); _ = write!(rust, ">, {buf_name}: &mut Vec) {{\n"); if !tfm.rust.is_empty() { _ = write!(rust, " for {item_name} in {vec_name} {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } // Swift { let mut swift = String::new(); _ = write!( swift, "\nprivate func {swift_name}(_ {len_name}: Int, _ {end_name}: inout UnsafeRawPointer) -> [" ); append_swift_type(&mut swift, ast, inner_ty); swift.push_str("] {\n"); _ = write!(swift, " var {vec_name}: ["); append_swift_type(&mut swift, ast, inner_ty); swift.push_str("] = []\n"); _ = write!(swift, " {vec_name}.reserveCapacity({len_name})\n"); _ = write!(swift, " while {vec_name}.count < {len_name} {{\n"); tfm.swift.write_to_swift(ast, &mut swift, " "); swift.push_str(" }\n"); _ = write!(swift, " return {vec_name}\n"); swift.push_str("}\n"); ctx.swift_helpers.add(&swift_name, swift).mark_used(); } (swift_name, rust_name) } fn trait_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, trait_index: usize) -> String { if let Some(result) = ctx.trait_to_rust_helpers.get(&trait_index) { return result.clone(); } let t = &ast.traits[trait_index]; let rust_name = format!("_ffi_rs_{}", t.name); // This must be done first to avoid a stack overflow ctx.trait_to_rust_helpers .insert(trait_index, rust_name.clone()); // Rust { let mut rust = String::new(); allow_non_camel_case_types(&mut rust, &rust_name); _ = write!(rust, "\nstruct {rust_name}(*const u8);\n"); _ = write!(rust, "\nimpl Drop for {rust_name} {{\n"); rust.push_str(" fn drop(&mut self) {\n"); _ = write!( rust, " {} \"C\" {{ fn _ffi_swift_drop(_: *const u8); }}\n", ctx.syntax.unsafe_extern() ); _ = write!(rust, " unsafe {{ _ffi_swift_drop(self.0) }};\n"); rust.push_str(" }\n"); rust.push_str("}\n"); _ = write!(rust, "\nimpl {} for {rust_name} {{", t.name); for f in &t.fns { generate_rust_to_swift_fn(ast, ctx, t, f, &mut rust); } rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); ctx.swift_helpers.mark_used("_ffi_swift_drop"); } rust_name } fn trait_to_swift_helper( ast: &AST, ctx: &mut SwiftCtx, trait_index: usize, kind: RustPtr, ) -> String { if let Some(result) = ctx.trait_to_swift_helpers.get(&(kind, trait_index)) { return result.clone(); } let t = &ast.traits[trait_index]; let drop_name = format!("_ffi_rs_drop_{kind:?}_{}", t.name); let swift_name = format!("_ffi_{kind:?}_{}", t.name); // This must be done first to avoid a stack overflow ctx.trait_to_swift_helpers .insert((kind, trait_index), swift_name.clone()); // Swift { let mut swift = String::new(); _ = write!(swift, "\nprivate class {swift_name} : {} {{\n", t.name); swift.push_str(" private var _ffi: UnsafeRawPointer?\n"); swift.push_str("\n init(_ ptr: UnsafeRawPointer?) {\n"); swift.push_str(" _ffi = ptr\n"); swift.push_str(" }\n"); swift.push_str("\n deinit {\n"); _ = write!(swift, " {drop_name}(_ffi)\n"); swift.push_str(" }\n"); for f in &t.fns { let info = Some(TraitInfo { t, kind }); generate_swift_to_rust_fn(ast, ctx, f, &mut swift, info); } swift.push_str("}\n"); ctx.swift_helpers.add(&swift_name, swift).mark_used(); } // Header { let mut header = String::new(); let mut header_deps = HashSet::new(); header.push('\n'); append_c_signature( &mut header, &mut header_deps, None, &drop_name, None, &[RustArg { name: "ptr".to_string(), ty: RustType::ForeignHandle, }], ); header.push_str(";\n"); ctx.header_helpers .add_group(HeaderGroup::Other, &drop_name, header) .add_deps_group(header_deps) .mark_used(); } // Rust { let mut rust = String::new(); _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle()); _ = write!(rust, "extern \"C\" fn {drop_name}(ptr: *const u8) {{\n"); _ = write!( rust, " drop(unsafe {{ Box::from_raw(ptr as *mut {}) }});\n", kind.path(), t.name ); rust.push_str("}\n"); ctx.rust_helpers.add(&drop_name, rust).mark_used(); } swift_name } fn box_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.box_to_rust_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_box_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let swift_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_swift")); // This must be done first to avoid a stack overflow ctx.box_to_rust_helpers .insert(inner_ty.clone(), (swift_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let end_name = locals.create("end"); let buf_name = locals.create("buf"); // Transform the value let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.swift.mark_pure(&val_name); transform_to_rust(ast, ctx, &mut locals, &mut tfm, &val_name, &inner_ty); let val_code = tfm.rust.find(&val_name, inner_ty, RefInline).code; tfm.rust.line(format!("Box::new({val_code})")); // Swift { let mut swift = String::new(); _ = write!(swift, "\nprivate func {swift_name}(_ {val_name}: "); append_swift_type(&mut swift, ast, inner_ty); _ = write!(swift, ", _ {buf_name}: inout ContiguousArray) {{\n"); tfm.swift.write_to_swift(ast, &mut swift, " "); swift.push_str("}\n"); ctx.swift_helpers.add(&swift_name, swift).mark_used(); } // Rust { let mut rust = String::new(); let mut item_ty = String::new(); let end_name = buf.final_end_name_for_rust(); append_rust_type(&mut item_ty, ast, inner_ty); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({end_name}: &mut *const u8) -> Box<{item_ty}> {{\n" ); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } (swift_name, rust_name) } fn box_to_swift_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.box_to_swift_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_box_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let swift_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_swift")); // This must be done first to avoid a stack overflow ctx.box_to_swift_helpers .insert(inner_ty.clone(), (swift_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let end_name = locals.create("end"); let buf_name = locals.create("buf"); // Transform the value let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.rust.mark_pure(&val_name); transform_to_swift(ast, ctx, &mut locals, &mut tfm, &val_name, &inner_ty); let val_code = tfm.swift.find(&val_name, inner_ty, RefInline).code; tfm.swift.line(format!("return {val_code}")); // Rust { let mut rust = String::new(); let buf_name = buf.final_buf_name_for_rust(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({val_name}: "); append_rust_type(&mut rust, ast, inner_ty); _ = write!(rust, ", {buf_name}: &mut Vec) {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } // Swift { let mut swift = String::new(); _ = write!( swift, "\nprivate func {swift_name}(_ {end_name}: inout UnsafeRawPointer) -> " ); append_swift_type(&mut swift, ast, inner_ty); swift.push_str(" {\n"); tfm.swift.write_to_swift(ast, &mut swift, " "); swift.push_str("}\n"); ctx.swift_helpers.add(&swift_name, swift).mark_used(); } (swift_name, rust_name) } fn enum_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, enum_index: usize) -> (String, String) { if let Some(result) = ctx.enum_to_rust_helpers.get(&enum_index) { return result.clone(); } let e = &ast.enums[enum_index]; let base_name = format!("_ffi_enum_{}", e.name); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_swift")); let swift_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); // This must be done first to avoid a stack overflow ctx.enum_to_rust_helpers .insert(enum_index, (swift_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); let end_name = locals.create("end"); let mut branches = Vec::new(); // Enums without fields are just integers if !e.has_fields() { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({val_name}: i32) -> {} {{\n", e.name); _ = write!(rust, " match {val_name} {{\n"); for v in &e.variants { _ = write!( rust, " {} => {}::{},\n", v.discriminant, e.name, v.name ); } rust.push_str(" _ => panic!(),\n"); rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); return (swift_name, rust_name); } struct Branch { tfm: Transform, fields: Vec, } // Transform all fields for each variant in a separate branch for v in &e.variants { let mut branch_locals = locals.clone(); let mut fields = Vec::new(); let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; for f in &v.fields { let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len())); tfm.swift.mark_pure(&field_name); transform_to_rust(ast, ctx, &mut branch_locals, &mut tfm, &field_name, &f.ty); fields.push(field_name); } rust_decl_ctor( &mut tfm.rust, &val_name, &format!("{}::{}", e.name, v.name), &v.fields, fields.iter().map(|x| Cow::Borrowed(x.as_str())).collect(), ); branches.push(Branch { tfm, fields }); } // Swift { let mut swift = String::new(); _ = write!( swift, "\nprivate func {swift_name}(_ {val_name}: {}, _ {buf_name}: inout ContiguousArray) {{\n", e.name ); _ = write!(swift, " switch {val_name} {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { if branch.fields.is_empty() { _ = write!(swift, " case .{}:\n", v.name); } else { _ = write!(swift, " case let .{}(", v.name); for (i, f) in branch.fields.iter().enumerate() { if i > 0 { swift.push_str(", "); } swift.push_str(&f); } swift.push_str("):\n"); } _ = write!( swift, " _ffi_write({} as Int32, &{buf_name})\n", v.discriminant ); branch.tfm.swift.write_to_swift(ast, &mut swift, " "); } swift.push_str(" }\n"); swift.push_str("}\n"); ctx.swift_helpers.add(&swift_name, swift).mark_used(); } // Rust { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({end_name}: &mut *const u8) -> {} {{\n", e.name ); _ = write!(rust, " match _ffi_read::({end_name}) {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { let val_code = branch .tfm .rust .find(&val_name, &RustType::Enum(enum_index), RefInline) .code; if branch.tfm.rust.is_empty() { let val_code = format!("{} => {val_code},", v.discriminant); branch.tfm.rust.line(val_code); branch.tfm.rust.write_to_rust(ast, &mut rust, " "); } else { _ = write!(rust, " {} => {{", v.discriminant); branch.tfm.rust.line(val_code); branch .tfm .rust .write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } } rust.push_str(" _ => panic!(),\n"); rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers .add(&rust_name, rust) .add_dep("_ffi_read") .mark_used(); } (swift_name, rust_name) } fn enum_to_swift_helper(ast: &AST, ctx: &mut SwiftCtx, enum_index: usize) -> (String, String) { if let Some(result) = ctx.enum_to_swift_helpers.get(&enum_index) { return result.clone(); } let e = &ast.enums[enum_index]; let base_name = format!("_ffi_enum_{}", e.name); let swift_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_swift")); // This must be done first to avoid a stack overflow ctx.enum_to_swift_helpers .insert(enum_index, (swift_name.clone(), rust_name.clone())); struct Branch { tfm: Transform, fields: Vec, } let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); let end_name = locals.create("end"); let mut branches = Vec::new(); // Transform all fields for each variant in a separate branch for v in &e.variants { let mut branch_locals = locals.clone(); let mut fields = Vec::new(); let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; for f in &v.fields { let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len())); tfm.rust.mark_pure(&field_name); transform_to_swift(ast, ctx, &mut branch_locals, &mut tfm, &field_name, &f.ty); fields.push(field_name); } let val_code = tfm.swift.find_fields( &v.fields .iter() .map(|f| RustField { name: match starts_with_digit(&f.name) { false => f.name.clone(), true => "".to_string(), }, ty: f.ty.clone(), }) .collect(), fields.iter().map(|x| Cow::Borrowed(x.as_str())).collect(), RefInline, "(", ")", ); tfm.swift.decl( &val_name, match v.fields.len() { 0 => format!(".{}", v.name), _ => format!(".{}{}", v.name, val_code), }, ); branches.push(Branch { tfm, fields }); } // Rust { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({val_name}: {}, {buf_name}: &mut Vec) {{\n", e.name ); _ = write!(rust, " match {val_name} {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { _ = write!(rust, " {}::{}", e.name, v.name); if v.fields.iter().any(|f| starts_with_digit(&f.name)) { rust.push_str("("); for (i, name) in branch.fields.iter().enumerate() { rust.push_str(if i > 0 { ", " } else { "" }); rust.push_str(name); } rust.push_str(")"); } else if !v.fields.is_empty() { rust.push_str(" {"); for (i, (f, name)) in v.fields.iter().zip(&branch.fields).enumerate() { rust.push_str(if i > 0 { ", " } else { " " }); if f.name != *name { _ = write!(rust, "{}: ", f.name); } rust.push_str(name); } rust.push_str(" }"); } if branch.tfm.rust.is_empty() { _ = write!( rust, " => _ffi_write({} as i32, {buf_name}),\n", v.discriminant ); } else { rust.push_str(" => {\n"); _ = write!( rust, " _ffi_write({} as i32, {buf_name});\n", v.discriminant ); branch .tfm .rust .write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } } rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers .add(&rust_name, rust) .add_dep("_ffi_write") .mark_used(); } // Swift { let mut swift = String::new(); _ = write!( swift, "\nprivate func {swift_name}(_ {end_name}: inout UnsafeRawPointer) -> {} {{\n", e.name ); _ = write!(swift, " switch _ffi_read(&{end_name}) as Int32 {{\n",); for (v, branch) in e.variants.iter().zip(&mut branches) { let val_code = branch .tfm .swift .find(&val_name, &RustType::Enum(enum_index), RefInline) .code; if branch.tfm.swift.is_empty() { let val_code = format!("case {}: return {val_code}", v.discriminant); branch.tfm.swift.line(val_code); branch.tfm.swift.write_to_swift(ast, &mut swift, " "); } else { _ = write!(swift, " case {}:\n", v.discriminant); branch.tfm.swift.line(format!("return {val_code}")); branch .tfm .swift .write_to_swift(ast, &mut swift, " "); } } swift.push_str(" default: fatalError()\n"); swift.push_str(" }\n"); swift.push_str("}\n"); ctx.swift_helpers .add(&swift_name, swift) .add_dep("_ffi_read") .mark_used(); } (swift_name, rust_name) } fn multi_ret_helper(ast: &AST, ctx: &mut SwiftCtx, args: &[RustArg]) -> String { let types: Vec<_> = args.iter().map(|arg| arg.ty.clone()).collect(); if let Some(result) = ctx.multi_ret_helpers.get(&types) { return result.clone(); } // Construct the name for the new type let mut ty_name = "_ffi_ret_".to_string(); append_type_name_hints(&mut ty_name, ast, &types); let ty_name = ctx.helper_names.create(&ty_name); // Header { let mut header = String::new(); let mut header_deps = HashSet::new(); header.push_str("\ntypedef struct {\n"); for (i, ty) in types.iter().enumerate() { header.push_str(" "); append_c_type(&mut header, &mut header_deps, ty); _ = write!(header, " _{i};\n"); } _ = write!(header, "}} {ty_name};\n"); ctx.header_helpers .add_group(HeaderGroup::Other, &ty_name, header) .add_deps_group(header_deps) .mark_used(); } // Rust { let mut rust = String::new(); _ = write!(rust, "\n#[repr(C)]\nstruct {ty_name}("); for (i, ty) in types.iter().enumerate() { if i > 0 { rust.push_str(", "); } append_rust_type(&mut rust, ast, ty); } rust.push_str(");\n"); ctx.rust_helpers.add(&ty_name, rust).mark_used(); } ctx.multi_ret_helpers.insert(types, ty_name.clone()); ty_name } fn append_swift_type(swift: &mut String, ast: &AST, ty: &RustType) { use RustType::*; match ty { Pair { other, .. } => append_swift_type(swift, ast, other), Verbatim(text) => swift.push_str(text), Bool => swift.push_str("Bool"), U8 => swift.push_str("UInt8"), U16 => swift.push_str("UInt16"), U32 => swift.push_str("UInt32"), Usize => swift.push_str("UInt"), U64 => swift.push_str("UInt64"), I8 => swift.push_str("Int8"), I16 => swift.push_str("Int16"), I32 => swift.push_str("Int32"), Isize => swift.push_str("Int"), I64 => swift.push_str("Int64"), F32 => swift.push_str("Float32"), F64 => swift.push_str("Float64"), RefStr | OwnStr => swift.push_str("String"), Struct(index) => swift.push_str(&ast.structs[*index].name), Enum(index) => swift.push_str(&ast.enums[*index].name), DynTrait(index) => swift.push_str(&ast.traits[*index].name), Ptr(_, inner) => append_swift_type(swift, ast, inner), Tuple(types) if types.len() == 1 => append_swift_type(swift, ast, &types[0]), Tuple(types) => { swift.push('('); for (i, ty) in types.iter().enumerate() { if i > 0 { swift.push_str(", "); } append_swift_type(swift, ast, ty); } swift.push(')'); } Vector(inner) => { swift.push('['); append_swift_type(swift, ast, inner); swift.push(']'); } ForeignHandle => swift.push_str("UnsafeRawPointer?"), Optional(inner_ty) => { append_swift_type(swift, ast, &inner_ty); swift.push('?'); } } } fn append_swift_val(swift: &mut String, val: &RustVal) { use RustVal::*; match val { Bool(x) => _ = write!(swift, "{x}"), U8(x) => _ = write!(swift, "{x}"), U16(x) => _ = write!(swift, "{x}"), U32(x) => _ = write!(swift, "{x}"), U64(x) => _ = write!(swift, "{x}"), I8(x) => _ = write!(swift, "{x}"), I16(x) => _ = write!(swift, "{x}"), I32(x) => _ = write!(swift, "{x}"), I64(x) => _ = write!(swift, "{x}"), F32(x) => _ = write!(swift, "{x:?}"), F64(x) => _ = write!(swift, "{x:?}"), Str(x) => append_swift_quoted(swift, x), } } fn append_swift_quoted(swift: &mut String, text: &str) { swift.push('"'); for c in text.chars() { match c { '\t' => swift.push_str("\\t"), '\n' => swift.push_str("\\n"), '\r' => swift.push_str("\\r"), '\\' => swift.push_str("\\\\"), '\"' => swift.push_str("\\\""), c if (c as u32) < 0x20 => _ = write!(swift, "\\u{{{:x}}}", c as u32), _ => swift.push(c), } } swift.push('"'); } fn append_c_signature( c: &mut String, deps: &mut HashSet<(HeaderGroup, String)>, returns: Option<&RustType>, name: &str, receiver: Option<&RustType>, args: &[RustArg], ) { // Emit the return type if let Some(returns) = returns { append_c_type(c, deps, returns); c.push(' '); } else { c.push_str("void "); } // The function name goes in the middle in C c.push_str(name); // Emit the arguments c.push('('); if let Some(receiver) = receiver { append_c_type(c, deps, receiver); } for (i, arg) in args.iter().enumerate() { if receiver.is_some() || i > 0 { c.push_str(", "); } append_c_type(c, deps, &arg.ty); c.push(' '); c.push_str(&arg.name); } c.push(')'); } fn append_c_type(c: &mut String, deps: &mut HashSet<(HeaderGroup, String)>, ty: &RustType) { use RustType::*; let text = match ty { Pair { other, .. } => return append_c_type(c, deps, &other), Verbatim(text) => text, Bool => "_Bool", U8 => "uint8_t", U16 => "uint16_t", U32 => "uint32_t", Usize => "uintptr_t", U64 => "uint64_t", I8 => "int8_t", I16 => "int16_t", I32 => "int32_t", Isize => "intptr_t", I64 => "int64_t", F32 => "float", F64 => "double", ForeignHandle => "const void*", _ => unreachable!(), }; if text.ends_with("_t") { deps.insert((HeaderGroup::Include, "".into())); } c.push_str(text); } // We represent "Box" as "T" in Swift, so a recursive struct that uses Box // to refer to itself in Rust will need to be a class in Swift to avoid having // infinite size. fn swift_type_is_infinite_size(ast: &AST, ty: &RustType) -> bool { fn visit(ast: &AST, ty: &RustType, visited: &mut HashSet) -> bool { use RustType::*; match ty { Ptr(kind, inner_ty) if *kind == RustPtr::Box => visit(ast, &inner_ty, visited), Struct(struct_index) => { if visited.contains(ty) { return true; } visited.insert(ty.clone()); ast.structs[*struct_index] .fields .iter() .any(|f| visit(ast, &f.ty, visited)) } Tuple(types) => types.iter().any(|ty| visit(ast, ty, visited)), Optional(inner) => visit(ast, inner, visited), _ => false, } } visit(ast, ty, &mut HashSet::new()) } // We represent "Box" as "T" in Swift, so a recursive enum that uses Box to // refer to itself in Rust will need to use an "indirect case" in Swift to // avoid having infinite size. fn swift_variant_needs_indirect(ast: &AST, query_index: usize, v: &RustVariant) -> bool { use RustType::*; fn visit( ast: &AST, ty: &RustType, query_index: usize, visited: &mut HashSet, ) -> bool { match ty { Enum(enum_index) if *enum_index == query_index => true, Enum(enum_index) => { if visited.contains(ty) { return true; } visited.insert(ty.clone()); ast.enums[*enum_index].variants.iter().any(|v| { v.fields .iter() .any(|f| visit(ast, &f.ty, query_index, visited)) }) } Ptr(kind, inner_ty) if *kind == RustPtr::Box => { visit(ast, inner_ty, query_index, visited) } Struct(struct_index) => { if visited.contains(ty) { return true; } visited.insert(ty.clone()); ast.structs[*struct_index] .fields .iter() .any(|f| visit(ast, &f.ty, query_index, visited)) } Tuple(types) => types.iter().any(|ty| visit(ast, ty, query_index, visited)), Optional(inner) => visit(ast, inner, query_index, visited), _ => false, } } let mut visited = HashSet::new(); v.fields .iter() .any(|f| visit(ast, &f.ty, query_index, &mut visited)) } impl FnBuilder { fn write_to_swift(&mut self, ast: &AST, out: &mut String, base_indent: &str) { let mut indent = 0; let mut callback = |line: &str| { if line.starts_with(&['}', ']', ')']) { indent -= 1; } _ = write!(out, "{base_indent}{}{line}\n", " ".repeat(indent)); if line.ends_with(&['{', '[', '(']) { indent += 1; } }; for line in self.take_lines() { match line { Line::Plain(text) => { text.split('\n').for_each(&mut callback); } Line::PlainAlt(when_false, when_true, flag) => match flag.get() { false if when_false.is_empty() => continue, false => when_false.split('\n').for_each(&mut callback), true => when_true.split('\n').for_each(&mut callback), }, Line::Decl(name, ty, text) => { let mut decl_ty = String::new(); if let Some(ty) = ty { decl_ty.push_str(": "); append_swift_type(&mut decl_ty, ast, &ty); } let text = format!("let {name}{decl_ty} = {text}"); text.split('\n').for_each(&mut callback); } } } } } ================================================ FILE: src/tests/cases/demo_app.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Platform { fn create_window(&self) -> Rc; } pub trait Window { fn get_title(&self) -> String; fn set_title(&self, title: &str); fn get_size(&self) -> (i32, i32); fn set_size(&self, width: i32, height: i32); fn set_handler(&self, handler: Box); fn child_window(&self) -> Rc; } pub trait Handler { fn on_draw(&self, canvas: Box); } pub trait Canvas { fn draw_text_runs(&self, runs: Vec); } pub struct TextRun { pub text: String, pub rect: TextRect, } pub struct TextRect { pub x: i32, pub y: i32, pub w: i32, pub h: i32, } pub fn create_app(platform: Box) { let window = platform.create_window(); assert_eq!(window.get_title(), ""); assert_eq!(window.get_size(), (0, 0)); window.set_title("Untitled"); window.set_size(800, 600); assert_eq!(window.get_title(), "Untitled"); assert_eq!(window.get_size(), (800, 600)); let app = App { window: Rc::clone(&window), }; window.set_handler(Box::new(app)); } struct App { window: Rc, } impl Handler for App { fn on_draw(&self, canvas: Box) { let (w, _) = self.window.get_size(); canvas.draw_text_runs(vec![ TextRun { text: "ABC".into(), rect: TextRect { x: 10, y: 10, w: w - 20, h: 20 }, }, TextRun { text: "xyz".into(), rect: TextRect { x: 10, y: 30, w: w - 20, h: 20 }, }, ]); } } "#; case } test_all!(); ================================================ FILE: src/tests/cases/demo_const.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub const CONST_FALSE: bool = false; pub const CONST_TRUE: bool = true; pub const CONST_U8_MIN: u8 = 0; pub const CONST_U8_MAX: u8 = 0xff; pub const CONST_U16_MIN: u16 = 0; pub const CONST_U16_MAX: u16 = 0xffff; pub const CONST_U32_MIN: u32 = 0; pub const CONST_U32_MAX: u32 = 0xffff_ffff; pub const CONST_U64_MIN: u64 = 0; pub const CONST_U64_MAX: u64 = 0xffff_ffff_ffff_ffff; pub const CONST_I8_MIN: i8 = -0x80; pub const CONST_I8_MAX: i8 = 0x7f; pub const CONST_I16_MIN: i16 = -0x8000; pub const CONST_I16_MAX: i16 = 0x7fff; pub const CONST_I32_MIN: i32 = -0x8000_0000; pub const CONST_I32_MAX: i32 = 0x7fff_ffff; pub const CONST_I64_MIN: i64 = -0x8000_0000_0000_0000; pub const CONST_I64_MAX: i64 = 0x7fff_ffff_ffff_ffff; pub const CONST_F32_NEG_0: f32 = -0.0; pub const CONST_F64_NEG_0: f64 = -0.0; pub const CONST_F32_PI: f32 = 3.141592653589793; pub const CONST_F64_PI: f64 = -3.141592653589793; pub const CONST_STRING: &str = "\0\r\n\u{1f980}"; "#; case.checks = vec![ AssertEqual(Export("CONST_FALSE").into(), Bool(false).into()), AssertEqual(Export("CONST_TRUE").into(), Bool(true).into()), AssertEqual(Export("CONST_U8_MIN").into(), U8(0).into()), AssertEqual(Export("CONST_U8_MAX").into(), U8(0xff).into()), AssertEqual(Export("CONST_U16_MIN").into(), U16(0).into()), AssertEqual(Export("CONST_U16_MAX").into(), U16(0xffff).into()), AssertEqual(Export("CONST_U32_MIN").into(), U32(0).into()), AssertEqual(Export("CONST_U32_MAX").into(), U32(0xffff_ffff).into()), AssertEqual(Export("CONST_U64_MIN").into(), U64(0).into()), AssertEqual( Export("CONST_U64_MAX").into(), U64(0xffff_ffff_ffff_ffff).into(), ), AssertEqual(Export("CONST_I8_MIN").into(), I8(-0x80).into()), AssertEqual(Export("CONST_I8_MAX").into(), I8(0x7f).into()), AssertEqual(Export("CONST_I16_MIN").into(), I16(-0x8000).into()), AssertEqual(Export("CONST_I16_MAX").into(), I16(0x7fff).into()), AssertEqual(Export("CONST_I32_MIN").into(), I32(-0x8000_0000).into()), AssertEqual(Export("CONST_I32_MAX").into(), I32(0x7fff_ffff).into()), AssertEqual( Export("CONST_I64_MIN").into(), I64(-0x8000_0000_0000_0000).into(), ), AssertEqual( Export("CONST_I64_MAX").into(), I64(0x7fff_ffff_ffff_ffff).into(), ), AssertEqual(Export("CONST_F32_NEG_0").into(), F32(-0.0).into()), AssertEqual(Export("CONST_F64_NEG_0").into(), F64(-0.0).into()), AssertEqual( Export("CONST_F32_PI").into(), F32(std::f32::consts::PI).into(), ), AssertEqual( Export("CONST_F64_PI").into(), F64(-std::f64::consts::PI).into(), ), AssertEqual(Export("CONST_STRING").into(), Str("\0\r\n\u{1f980}").into()), ]; case } test_all!(); ================================================ FILE: src/tests/cases/demo_derive_eq.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(Eq, PartialEq)] pub struct EmptyStruct; pub fn empty_tuple(x: ()) -> () { x } pub fn empty_struct(x: EmptyStruct) -> EmptyStruct { x } //////////////////////////////////////// // Swift has trouble with tuple equality #[derive(Eq, PartialEq)] pub struct BoxTup0(Box<()>); #[derive(Eq, PartialEq)] pub struct BoxTup1(Box<(i32,)>); #[derive(Eq, PartialEq)] pub struct BoxTup2(Box<(i32, i32)>); pub fn box_tup_0(x: BoxTup0) -> BoxTup0 { x } pub fn box_tup_1(x: BoxTup1) -> BoxTup1 { x } pub fn box_tup_2(x: BoxTup2) -> BoxTup2 { x } #[derive(Eq, PartialEq)] pub struct VecTup0(Vec<()>); #[derive(Eq, PartialEq)] pub struct VecTup1(Vec<(i32,)>); #[derive(Eq, PartialEq)] pub struct VecTup2(Vec<(i32, i32)>); pub fn vec_tup_0(x: VecTup0) -> VecTup0 { x } pub fn vec_tup_1(x: VecTup1) -> VecTup1 { x } pub fn vec_tup_2(x: VecTup2) -> VecTup2 { x } #[derive(Eq, PartialEq)] pub struct OptTup0(Option<()>); #[derive(Eq, PartialEq)] pub struct OptTup1(Option<(i32,)>); #[derive(Eq, PartialEq)] pub struct OptTup2(Option<(i32, i32)>); pub fn opt_tup_0(x: OptTup0) -> OptTup0 { x } pub fn opt_tup_1(x: OptTup1) -> OptTup1 { x } pub fn opt_tup_2(x: OptTup2) -> OptTup2 { x } #[derive(Eq, PartialEq)] pub enum EnumBoxTup { Foo(Box<(i32, i32)>), Bar, Baz { x: i32, y: i32 } } #[derive(Eq, PartialEq)] pub enum EnumVecTup { Foo(Vec<(i32, i32)>), Bar, Baz { x: i32, y: i32 } } #[derive(Eq, PartialEq)] pub enum EnumOptTup { Foo(Option<(i32, i32)>), Bar, Baz { x: i32, y: i32 } } pub fn enum_box_tup(x: EnumBoxTup) -> EnumBoxTup { x } pub fn enum_vec_tup(x: EnumVecTup) -> EnumVecTup { x } pub fn enum_opt_tup(x: EnumOptTup) -> EnumOptTup { x } //////////////////////////////////////// // C++ has trouble with box equality #[derive(Eq, PartialEq)] pub struct TupBox((Box, Box)); #[derive(Eq, PartialEq)] pub struct VecBox(Vec>); #[derive(Eq, PartialEq)] pub struct BoxVec(Box>); #[derive(Eq, PartialEq)] pub struct OptBox(Option>); #[derive(Eq, PartialEq)] pub struct BoxOpt(Box>); #[derive(Eq, PartialEq)] pub struct VecBoxVec(Vec>>); #[derive(Eq, PartialEq)] pub struct BoxVecBox(Box>>); #[derive(Eq, PartialEq)] pub struct OptBoxOpt(Option>>); #[derive(Eq, PartialEq)] pub struct BoxOptBox(Box>>); pub fn tup_box(x: TupBox) -> TupBox { x } pub fn vec_box(x: VecBox) -> VecBox { x } pub fn box_vec(x: BoxVec) -> BoxVec { x } pub fn opt_box(x: OptBox) -> OptBox { x } pub fn box_opt(x: BoxOpt) -> BoxOpt { x } pub fn vec_box_vec(x: VecBoxVec) -> VecBoxVec { x } pub fn box_vec_box(x: BoxVecBox) -> BoxVecBox { x } pub fn opt_box_opt(x: OptBoxOpt) -> OptBoxOpt { x } pub fn box_opt_box(x: BoxOptBox) -> BoxOptBox { x } "#; // Empty tuple, EmptyStruct case.checks.extend_from_slice(&[ AssertEqual( Call( Export("empty_tuple").into(), [Tuple([].into()).into()].into(), ) .into(), Tuple([].into()).into(), ), AssertEqual( Call( Export("empty_struct").into(), [Struct("EmptyStruct", [].into()).into()].into(), ) .into(), Struct("EmptyStruct", [].into()).into(), ), ]); // BoxTup0 case.checks.extend_from_slice(&[AssertEqual( Call( Export("box_tup_0").into(), [Struct( "BoxTup0", [("0", Boxed(TyTuple([].into()), Tuple([].into()).into()))].into(), )] .into(), ) .into(), Struct( "BoxTup0", [("0", Boxed(TyTuple([].into()), Tuple([].into()).into()))].into(), ) .into(), )]); // BoxTup1 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("box_tup_1").into(), [Struct( "BoxTup1", [( "0", Boxed(TyTuple([TyI32].into()), Tuple([I32(10)].into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxTup1", [( "0", Boxed(TyTuple([TyI32].into()), Tuple([I32(10)].into()).into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("box_tup_1").into(), [Struct( "BoxTup1", [( "0", Boxed(TyTuple([TyI32].into()), Tuple([I32(10)].into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxTup1", [( "0", Boxed(TyTuple([TyI32].into()), Tuple([I32(20)].into()).into()), )] .into(), ) .into(), ), ]); // BoxTup2 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("box_tup_2").into(), [Struct( "BoxTup2", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(20), I32(30)].into()).into(), ), )] .into(), )] .into(), ) .into(), Struct( "BoxTup2", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(20), I32(30)].into()).into(), ), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("box_tup_2").into(), [Struct( "BoxTup2", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(20), I32(30)].into()).into(), ), )] .into(), )] .into(), ) .into(), Struct( "BoxTup2", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(30), I32(20)].into()).into(), ), )] .into(), ) .into(), ), ]); // VecTup0 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("vec_tup_0").into(), [Struct( "VecTup0", [("0", EmptyVector(TyTuple([].into())))].into(), )] .into(), ) .into(), Struct("VecTup0", [("0", EmptyVector(TyTuple([].into())))].into()).into(), ), AssertEqual( Call( Export("vec_tup_0").into(), [Struct( "VecTup0", [("0", Vector([Tuple([].into()), Tuple([].into())].into()))].into(), )] .into(), ) .into(), Struct( "VecTup0", [("0", Vector([Tuple([].into()), Tuple([].into())].into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_0").into(), [Struct( "VecTup0", [("0", Vector([Tuple([].into()), Tuple([].into())].into()))].into(), )] .into(), ) .into(), Struct("VecTup0", [("0", Vector([Tuple([].into())].into()))].into()).into(), ), AssertNotEqual( Call( Export("vec_tup_0").into(), [Struct( "VecTup0", [("0", Vector([Tuple([].into())].into()))].into(), )] .into(), ) .into(), Struct( "VecTup0", [("0", Vector([Tuple([].into()), Tuple([].into())].into()))].into(), ) .into(), ), ]); // VecTup1 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("vec_tup_1").into(), [Struct( "VecTup1", [("0", EmptyVector(TyTuple([TyI32].into())))].into(), )] .into(), ) .into(), Struct( "VecTup1", [("0", EmptyVector(TyTuple([TyI32].into())))].into(), ) .into(), ), AssertEqual( Call( Export("vec_tup_1").into(), [Struct( "VecTup1", [( "0", Vector([Tuple([I32(10)].into()), Tuple([I32(20)].into())].into()), )] .into(), )] .into(), ) .into(), Struct( "VecTup1", [( "0", Vector([Tuple([I32(10)].into()), Tuple([I32(20)].into())].into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_1").into(), [Struct( "VecTup1", [( "0", Vector([Tuple([I32(10)].into()), Tuple([I32(20)].into())].into()), )] .into(), )] .into(), ) .into(), Struct( "VecTup1", [( "0", Vector([Tuple([I32(20)].into()), Tuple([I32(10)].into())].into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_1").into(), [Struct( "VecTup1", [( "0", Vector([Tuple([I32(1)].into()), Tuple([I32(1)].into())].into()), )] .into(), )] .into(), ) .into(), Struct( "VecTup1", [("0", Vector([Tuple([I32(1)].into())].into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_1").into(), [Struct( "VecTup1", [("0", Vector([Tuple([I32(1)].into())].into()))].into(), )] .into(), ) .into(), Struct( "VecTup1", [( "0", Vector([Tuple([I32(1)].into()), Tuple([I32(1)].into())].into()), )] .into(), ) .into(), ), ]); // VecTup2 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("vec_tup_2").into(), [Struct( "VecTup2", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), )] .into(), ) .into(), Struct( "VecTup2", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), AssertEqual( Call( Export("vec_tup_2").into(), [Struct( "VecTup2", [( "0", Vector( [ Tuple([I32(1), I32(2)].into()), Tuple([I32(3), I32(4)].into()), ] .into(), ), )] .into(), )] .into(), ) .into(), Struct( "VecTup2", [( "0", Vector( [ Tuple([I32(1), I32(2)].into()), Tuple([I32(3), I32(4)].into()), ] .into(), ), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_2").into(), [Struct( "VecTup2", [( "0", Vector( [ Tuple([I32(1), I32(2)].into()), Tuple([I32(3), I32(4)].into()), ] .into(), ), )] .into(), )] .into(), ) .into(), Struct( "VecTup2", [( "0", Vector( [ Tuple([I32(1), I32(4)].into()), Tuple([I32(3), I32(2)].into()), ] .into(), ), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_2").into(), [Struct( "VecTup2", [( "0", Vector( [ Tuple([I32(1), I32(1)].into()), Tuple([I32(1), I32(1)].into()), ] .into(), ), )] .into(), )] .into(), ) .into(), Struct( "VecTup2", [("0", Vector([Tuple([I32(1), I32(1)].into())].into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("vec_tup_2").into(), [Struct( "VecTup2", [("0", Vector([Tuple([I32(1), I32(1)].into())].into()))].into(), )] .into(), ) .into(), Struct( "VecTup2", [( "0", Vector( [ Tuple([I32(1), I32(1)].into()), Tuple([I32(1), I32(1)].into()), ] .into(), ), )] .into(), ) .into(), ), ]); // OptTup0 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("opt_tup_0").into(), [Struct( "OptTup0", [("0", OptNone(TyTuple([].into())))].into(), )] .into(), ) .into(), Struct("OptTup0", [("0", OptNone(TyTuple([].into())))].into()).into(), ), AssertEqual( Call( Export("opt_tup_0").into(), [Struct( "OptTup0", [("0", OptSome(Tuple([].into()).into()))].into(), )] .into(), ) .into(), Struct("OptTup0", [("0", OptSome(Tuple([].into()).into()))].into()).into(), ), AssertNotEqual( Call( Export("opt_tup_0").into(), [Struct( "OptTup0", [("0", OptSome(Tuple([].into()).into()))].into(), )] .into(), ) .into(), Struct("OptTup0", [("0", OptNone(TyTuple([].into())))].into()).into(), ), AssertNotEqual( Call( Export("opt_tup_0").into(), [Struct( "OptTup0", [("0", OptNone(TyTuple([].into())))].into(), )] .into(), ) .into(), Struct("OptTup0", [("0", OptSome(Tuple([].into()).into()))].into()).into(), ), ]); // OptTup1 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("opt_tup_1").into(), [Struct( "OptTup1", [("0", OptNone(TyTuple([TyI32].into())))].into(), )] .into(), ) .into(), Struct("OptTup1", [("0", OptNone(TyTuple([TyI32].into())))].into()).into(), ), AssertEqual( Call( Export("opt_tup_1").into(), [Struct( "OptTup1", [("0", OptSome(Tuple([I32(1)].into()).into()))].into(), )] .into(), ) .into(), Struct( "OptTup1", [("0", OptSome(Tuple([I32(1)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_tup_1").into(), [Struct( "OptTup1", [("0", OptSome(Tuple([I32(1)].into()).into()))].into(), )] .into(), ) .into(), Struct("OptTup1", [("0", OptNone(TyTuple([TyI32].into())))].into()).into(), ), AssertNotEqual( Call( Export("opt_tup_1").into(), [Struct( "OptTup1", [("0", OptNone(TyTuple([TyI32].into())))].into(), )] .into(), ) .into(), Struct( "OptTup1", [("0", OptSome(Tuple([I32(1)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_tup_1").into(), [Struct( "OptTup1", [("0", OptSome(Tuple([I32(1)].into()).into()))].into(), )] .into(), ) .into(), Struct( "OptTup1", [("0", OptSome(Tuple([I32(2)].into()).into()))].into(), ) .into(), ), ]); // OptTup2 case.checks.extend_from_slice(&[ AssertEqual( Call( Export("opt_tup_2").into(), [Struct( "OptTup2", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), )] .into(), ) .into(), Struct( "OptTup2", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), AssertEqual( Call( Export("opt_tup_2").into(), [Struct( "OptTup2", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), )] .into(), ) .into(), Struct( "OptTup2", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_tup_2").into(), [Struct( "OptTup2", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), )] .into(), ) .into(), Struct( "OptTup2", [("0", OptSome(Tuple([I32(2), I32(1)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_tup_2").into(), [Struct( "OptTup2", [("0", OptNone(TyTuple([TyI32, TyI32].into()).into()))].into(), )] .into(), ) .into(), Struct( "OptTup2", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_tup_2").into(), [Struct( "OptTup2", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), )] .into(), ) .into(), Struct( "OptTup2", [("0", OptNone(TyTuple([TyI32, TyI32].into()).into()))].into(), ) .into(), ), ]); // EnumBoxTup case.checks.extend_from_slice(&[ AssertEqual( Call( Export("enum_box_tup").into(), [EnumPayload( "EnumBoxTup", "Foo", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(1), I32(2)].into()).into(), ), )] .into(), )] .into(), ) .into(), EnumPayload( "EnumBoxTup", "Foo", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(1), I32(2)].into()).into(), ), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("enum_box_tup").into(), [EnumPayload( "EnumBoxTup", "Foo", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(1), I32(2)].into()).into(), ), )] .into(), )] .into(), ) .into(), EnumPayload( "EnumBoxTup", "Foo", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(1), I32(3)].into()).into(), ), )] .into(), ) .into(), ), AssertEqual( Call( Export("enum_box_tup").into(), [EnumPayload("EnumBoxTup", "Bar", [].into())].into(), ) .into(), EnumPayload("EnumBoxTup", "Bar", [].into()).into(), ), AssertNotEqual( Call( Export("enum_box_tup").into(), [EnumPayload( "EnumBoxTup", "Foo", [( "0", Boxed( TyTuple([TyI32, TyI32].into()), Tuple([I32(1), I32(2)].into()).into(), ), )] .into(), )] .into(), ) .into(), EnumPayload("EnumBoxTup", "Bar", [].into()).into(), ), ]); // EnumVecTup case.checks.extend_from_slice(&[ AssertEqual( Call( Export("enum_vec_tup").into(), [EnumPayload( "EnumVecTup", "Foo", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), )] .into(), ) .into(), EnumPayload( "EnumVecTup", "Foo", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), AssertEqual( Call( Export("enum_vec_tup").into(), [EnumPayload( "EnumVecTup", "Foo", [("0", Vector([Tuple([I32(1), I32(2)].into())].into()))].into(), )] .into(), ) .into(), EnumPayload( "EnumVecTup", "Foo", [("0", Vector([Tuple([I32(1), I32(2)].into())].into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("enum_vec_tup").into(), [EnumPayload( "EnumVecTup", "Foo", [("0", Vector([Tuple([I32(1), I32(2)].into())].into()))].into(), )] .into(), ) .into(), EnumPayload( "EnumVecTup", "Foo", [("0", Vector([Tuple([I32(1), I32(3)].into())].into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("enum_vec_tup").into(), [EnumPayload( "EnumVecTup", "Foo", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), )] .into(), ) .into(), EnumPayload( "EnumVecTup", "Foo", [("0", Vector([Tuple([I32(1), I32(2)].into())].into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("enum_vec_tup").into(), [EnumPayload( "EnumVecTup", "Foo", [("0", Vector([Tuple([I32(1), I32(2)].into())].into()))].into(), )] .into(), ) .into(), EnumPayload( "EnumVecTup", "Foo", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), AssertEqual( Call( Export("enum_vec_tup").into(), [EnumPayload("EnumVecTup", "Bar", [].into())].into(), ) .into(), EnumPayload("EnumVecTup", "Bar", [].into()).into(), ), AssertNotEqual( Call( Export("enum_vec_tup").into(), [EnumPayload("EnumVecTup", "Bar", [].into())].into(), ) .into(), EnumPayload( "EnumVecTup", "Foo", [("0", EmptyVector(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), ]); // EnumOptTup case.checks.extend_from_slice(&[ AssertEqual( Call( Export("enum_opt_tup").into(), [EnumPayload( "EnumOptTup", "Foo", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), )] .into(), ) .into(), EnumPayload( "EnumOptTup", "Foo", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), AssertEqual( Call( Export("enum_opt_tup").into(), [EnumPayload( "EnumOptTup", "Foo", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), )] .into(), ) .into(), EnumPayload( "EnumOptTup", "Foo", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("enum_opt_tup").into(), [EnumPayload( "EnumOptTup", "Foo", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), )] .into(), ) .into(), EnumPayload( "EnumOptTup", "Foo", [("0", OptSome(Tuple([I32(1), I32(3)].into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("enum_opt_tup").into(), [EnumPayload( "EnumOptTup", "Foo", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), )] .into(), ) .into(), EnumPayload( "EnumOptTup", "Foo", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), AssertNotEqual( Call( Export("enum_opt_tup").into(), [EnumPayload( "EnumOptTup", "Foo", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), )] .into(), ) .into(), EnumPayload( "EnumOptTup", "Foo", [("0", OptSome(Tuple([I32(1), I32(2)].into()).into()))].into(), ) .into(), ), AssertEqual( Call( Export("enum_opt_tup").into(), [EnumPayload("EnumOptTup", "Bar", [].into())].into(), ) .into(), EnumPayload("EnumOptTup", "Bar", [].into()).into(), ), AssertNotEqual( Call( Export("enum_opt_tup").into(), [EnumPayload("EnumOptTup", "Bar", [].into())].into(), ) .into(), EnumPayload( "EnumOptTup", "Foo", [("0", OptNone(TyTuple([TyI32, TyI32].into())))].into(), ) .into(), ), ]); // TupBox case.checks.extend_from_slice(&[ AssertEqual( Call( Export("tup_box").into(), [Struct( "TupBox", [( "0", Tuple( [ Boxed(TyI32, I32(0).into()), Boxed(TyBool, Bool(true).into()), ] .into(), ), )] .into(), )] .into(), ) .into(), Struct( "TupBox", [( "0", Tuple( [ Boxed(TyI32, I32(0).into()), Boxed(TyBool, Bool(true).into()), ] .into(), ), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("tup_box").into(), [Struct( "TupBox", [( "0", Tuple( [ Boxed(TyI32, I32(0).into()), Boxed(TyBool, Bool(true).into()), ] .into(), ), )] .into(), )] .into(), ) .into(), Struct( "TupBox", [( "0", Tuple( [ Boxed(TyI32, I32(0).into()), Boxed(TyBool, Bool(false).into()), ] .into(), ), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("tup_box").into(), [Struct( "TupBox", [( "0", Tuple( [ Boxed(TyI32, I32(0).into()), Boxed(TyBool, Bool(true).into()), ] .into(), ), )] .into(), )] .into(), ) .into(), Struct( "TupBox", [( "0", Tuple( [ Boxed(TyI32, I32(2).into()), Boxed(TyBool, Bool(true).into()), ] .into(), ), )] .into(), ) .into(), ), ]); // VecBox case.checks.extend_from_slice(&[ AssertEqual( Call( Export("vec_box").into(), [Struct( "VecBox", [("0", EmptyVector(TyBox(TyI32.into())))].into(), )] .into(), ) .into(), Struct("VecBox", [("0", EmptyVector(TyBox(TyI32.into())))].into()).into(), ), AssertEqual( Call( Export("vec_box").into(), [Struct( "VecBox", [( "0", Vector([Boxed(TyI32, I32(10).into()), Boxed(TyI32, I32(20).into())].into()), )] .into(), )] .into(), ) .into(), Struct( "VecBox", [( "0", Vector([Boxed(TyI32, I32(10).into()), Boxed(TyI32, I32(20).into())].into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_box").into(), [Struct( "VecBox", [( "0", Vector([Boxed(TyI32, I32(10).into()), Boxed(TyI32, I32(20).into())].into()), )] .into(), )] .into(), ) .into(), Struct( "VecBox", [( "0", Vector([Boxed(TyI32, I32(10).into()), Boxed(TyI32, I32(30).into())].into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_box").into(), [Struct( "VecBox", [("0", EmptyVector(TyBox(TyI32.into())))].into(), )] .into(), ) .into(), Struct( "VecBox", [( "0", Vector([Boxed(TyI32, I32(10).into()), Boxed(TyI32, I32(20).into())].into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("vec_box").into(), [Struct( "VecBox", [( "0", Vector([Boxed(TyI32, I32(10).into()), Boxed(TyI32, I32(20).into())].into()), )] .into(), )] .into(), ) .into(), Struct("VecBox", [("0", EmptyVector(TyBox(TyI32.into())))].into()).into(), ), ]); // BoxVec case.checks.extend_from_slice(&[ AssertEqual( Call( Export("box_vec").into(), [Struct( "BoxVec", [("0", Boxed(TyVec(TyI32.into()), EmptyVector(TyI32).into()))].into(), )] .into(), ) .into(), Struct( "BoxVec", [("0", Boxed(TyVec(TyI32.into()), EmptyVector(TyI32).into()))].into(), ) .into(), ), AssertEqual( Call( Export("box_vec").into(), [Struct( "BoxVec", [( "0", Boxed(TyVec(TyI32.into()), Vector([I32(1), I32(2)].into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxVec", [( "0", Boxed(TyVec(TyI32.into()), Vector([I32(1), I32(2)].into()).into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("box_vec").into(), [Struct( "BoxVec", [( "0", Boxed(TyVec(TyI32.into()), Vector([I32(1)].into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxVec", [( "0", Boxed(TyVec(TyI32.into()), Vector([I32(1), I32(2)].into()).into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("box_vec").into(), [Struct( "BoxVec", [( "0", Boxed(TyVec(TyI32.into()), Vector([I32(1), I32(2)].into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxVec", [( "0", Boxed(TyVec(TyI32.into()), Vector([I32(1)].into()).into()), )] .into(), ) .into(), ), ]); // OptBox case.checks.extend_from_slice(&[ AssertEqual( Call( Export("opt_box").into(), [Struct( "OptBox", [("0", OptNone(TyBox(TyI32.into())))].into(), )] .into(), ) .into(), Struct("OptBox", [("0", OptNone(TyBox(TyI32.into())))].into()).into(), ), AssertEqual( Call( Export("opt_box").into(), [Struct( "OptBox", [("0", OptSome(Boxed(TyI32.into(), I32(10).into()).into()))].into(), )] .into(), ) .into(), Struct( "OptBox", [("0", OptSome(Boxed(TyI32.into(), I32(10).into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_box").into(), [Struct( "OptBox", [("0", OptSome(Boxed(TyI32.into(), I32(10).into()).into()))].into(), )] .into(), ) .into(), Struct( "OptBox", [("0", OptSome(Boxed(TyI32.into(), I32(20).into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_box").into(), [Struct( "OptBox", [("0", OptNone(TyBox(TyI32.into())))].into(), )] .into(), ) .into(), Struct( "OptBox", [("0", OptSome(Boxed(TyI32.into(), I32(10).into()).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("opt_box").into(), [Struct( "OptBox", [("0", OptSome(Boxed(TyI32.into(), I32(10).into()).into()))].into(), )] .into(), ) .into(), Struct("OptBox", [("0", OptNone(TyBox(TyI32.into())))].into()).into(), ), ]); // BoxOpt case.checks.extend_from_slice(&[ AssertEqual( Call( Export("box_opt").into(), [Struct( "BoxOpt", [("0", Boxed(TyOption(TyI32.into()), OptNone(TyI32).into()))].into(), )] .into(), ) .into(), Struct( "BoxOpt", [("0", Boxed(TyOption(TyI32.into()), OptNone(TyI32).into()))].into(), ) .into(), ), AssertEqual( Call( Export("box_opt").into(), [Struct( "BoxOpt", [( "0", Boxed(TyOption(TyI32.into()), OptSome(I32(10).into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxOpt", [( "0", Boxed(TyOption(TyI32.into()), OptSome(I32(10).into()).into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("box_opt").into(), [Struct( "BoxOpt", [( "0", Boxed(TyOption(TyI32.into()), OptSome(I32(10).into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxOpt", [( "0", Boxed(TyOption(TyI32.into()), OptSome(I32(20).into()).into()), )] .into(), ) .into(), ), AssertNotEqual( Call( Export("box_opt").into(), [Struct( "BoxOpt", [( "0", Boxed(TyOption(TyI32.into()), OptSome(I32(10).into()).into()), )] .into(), )] .into(), ) .into(), Struct( "BoxOpt", [("0", Boxed(TyOption(TyI32.into()), OptNone(TyI32).into()))].into(), ) .into(), ), AssertNotEqual( Call( Export("box_opt").into(), [Struct( "BoxOpt", [("0", Boxed(TyOption(TyI32.into()), OptNone(TyI32).into()))].into(), )] .into(), ) .into(), Struct( "BoxOpt", [( "0", Boxed(TyOption(TyI32.into()), OptSome(I32(10).into()).into()), )] .into(), ) .into(), ), ]); case } test_all!(); ================================================ FILE: src/tests/cases/demo_enum.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" // This tests the generation of "indirect case" in Swift pub enum NestedBox { Foo, Bar(Box), } pub enum NestedVec { Foo, Bar(Vec), } pub enum NestedOption { Foo, Bar(Option>), } pub enum NestedTuple { Foo, Bar((i32, Box)), } pub enum NestedStruct { Foo, Bar((i32, Box)), } pub struct InnerStruct { pub x: NestedStruct, } pub enum NestedEnum { Foo, Bar((i32, Box)), } pub enum InnerEnum { Foo(NestedEnum), } "#; case } test_all!(); ================================================ FILE: src/tests/cases/demo_keyword.rs ================================================ use super::*; use std::collections::HashSet; const RUST_KEYWORDS: &[&str] = &[ "abstract", "as", "async", "await", "become", "box", "break", "const", "continue", "crate", "do", "dyn", "else", "enum", "extern", "false", "final", "fn", "for", "gen", "if", "impl", "in", "let", "loop", "macro", "match", "mod", "move", "mut", "override", "priv", "pub", "ref", "return", "self", "Self", "static", "struct", "super", "trait", "true", "try", "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield", ]; fn test_case() -> TestCase { let mut keywords = HashSet::<&str>::new(); keywords.extend(crate::wasm::JS_KEYWORDS); keywords.extend(crate::cpp::CPP_KEYWORDS); keywords.extend(crate::swift::SWIFT_KEYWORDS); let mut keywords = keywords.into_iter().collect::>(); keywords.sort(); let rust_keywords: HashSet<_> = RUST_KEYWORDS.iter().collect(); let test_local = |k: &&&str| is_snake_case(k) && !rust_keywords.contains(k); let rust = keywords .iter() .filter(test_local) .map(|k| format!("pub fn test_{k}({k}: i32) -> i32 {{ {k} }}")) .collect::>() .join("\n"); let mut case = TestCase::default(); case.rust = Box::new(rust).leak(); for (i, k) in keywords.iter().filter(test_local).enumerate() { case.checks.push(AssertEqual( Call( Export(Box::new(format!("test_{k}")).leak()).into(), [I32(i as i32).into()].into(), ) .into(), I32(i as i32).into(), )); } case } test_all!(); ================================================ FILE: src/tests/cases/demo_order.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; // These tests are for C++ where declaration is order-dependent // Traits that refer to each other pub trait FirstTrait { fn second(&self) -> Rc; } pub trait SecondTrait { fn first(&self) -> Rc; } //////////////////// // Early struct inside later struct pub struct EarlyInsideStruct { pub y: bool, } pub struct LaterOutsideStruct { pub x: EarlyInsideStruct, } // Early struct outside later struct pub struct EarlyOutsideStruct { pub x: LaterInsideStruct, } pub struct LaterInsideStruct { pub y: bool, } // Structs that refer to each other pub struct FirstStruct { pub second: Vec, } pub struct SecondStruct { pub first: Vec, } //////////////////// // Early enum inside later enum pub enum EarlyInsideEnum { Value(bool), } pub enum LaterOutsideEnum { Value(EarlyInsideEnum), } // Early enum outside later enum pub enum EarlyOutsideEnum { Value(LaterInsideEnum), } pub enum LaterInsideEnum { Value(bool), } // Enums that refer to each other pub enum FirstEnum { Second(Vec), } pub enum SecondEnum { First(Vec), } "#; case } test_all!(); ================================================ FILE: src/tests/cases/demo_trait.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Trait { fn get(&self) -> i32; } pub struct Example { box_ptr: Box, rc_ptr: Rc, text: String, vec_box: Vec>, vec_rc: Vec>, } pub fn test(vec: Vec) -> Vec { vec } "#; case.js_pre = " class TraitImpl { constructor(x) { this.x = x } get() { return this.x } } "; case.swift_pre = " var counter = 0 class TraitImpl : Trait { let x: Int32 init(_ x: Int32) { self.x = x counter += 1 } deinit { counter -= 1 } func get() -> Int32 { return x } } "; case.cpp_pre = " int counter = 0; struct TraitImpl : rust::Trait { int32_t x; TraitImpl(int32_t x) { this->x = x; counter += 1; } ~TraitImpl() { counter -= 1; } int32_t get() { return x; } }; "; case.checks = vec![ DeclareImmutableLocal( "vec", Call( Export("test").into(), [Vector( [Struct( "Example", [ ( "box_ptr", NewBox(TyName("Trait"), "TraitImpl", [I32(1)].into()).into(), ), ( "rc_ptr", NewRc(TyName("Trait"), "TraitImpl", [I32(4)].into()).into(), ), ("text", Str("abc".into())), ( "vec_box", Vector( [ NewBox(TyName("Trait"), "TraitImpl", [I32(2)].into()) .into(), NewBox(TyName("Trait"), "TraitImpl", [I32(3)].into()) .into(), ] .into(), ), ), ( "vec_rc", Vector( [ NewRc(TyName("Trait"), "TraitImpl", [I32(5)].into()).into(), NewRc(TyName("Trait"), "TraitImpl", [I32(6)].into()).into(), ] .into(), ), ), ] .into(), )] .into(), )] .into(), ) .into(), ), AssertEqual( CallMethod( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "box_ptr").into(), "get", [].into(), ) .into(), I32(1).into(), ), AssertEqual( CallMethod( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "rc_ptr").into(), "get", [].into(), ) .into(), I32(4).into(), ), AssertEqual( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "text").into(), Str("abc".into()).into(), ), AssertEqual( VectorLen( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "vec_box").into(), ) .into(), I32(2).into(), ), AssertEqual( CallMethod( VectorMember( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "vec_box").into(), 0, ) .into(), "get", [].into(), ) .into(), I32(2).into(), ), AssertEqual( CallMethod( VectorMember( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "vec_box").into(), 1, ) .into(), "get", [].into(), ) .into(), I32(3).into(), ), AssertEqual( VectorLen( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "vec_rc").into(), ) .into(), I32(2).into(), ), AssertEqual( CallMethod( VectorMember( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "vec_rc").into(), 0, ) .into(), "get", [].into(), ) .into(), I32(5).into(), ), AssertEqual( CallMethod( VectorMember( StructMember(VectorMember(LoadLocal("vec").into(), 0).into(), "vec_rc").into(), 1, ) .into(), "get", [].into(), ) .into(), I32(6).into(), ), ]; case.swift_post = r#" assert(counter == 0, "\(counter) == \(0)") "#; case.cpp_post = " assert(counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cases/fn_basic.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn add_bool(x: bool, y: bool) -> bool { x || y } pub fn add_u8(x: u8, y: u8) -> u8 { x + y } pub fn add_u16(x: u16, y: u16) -> u16 { x + y } pub fn add_u32(x: u32, y: u32) -> u32 { x + y } pub fn add_usize(x: usize, y: usize) -> usize { x + y } pub fn add_u64(x: u64, y: u64) -> u64 { x + y } pub fn add_i8(x: i8, y: i8) -> i8 { x + y } pub fn add_i16(x: i16, y: i16) -> i16 { x + y } pub fn add_i32(x: i32, y: i32) -> i32 { x + y } pub fn add_isize(x: isize, y: isize) -> isize { x + y } pub fn add_i64(x: i64, y: i64) -> i64 { x + y } pub fn add_f32(x: f32, y: f32) -> f32 { x + y } pub fn add_f64(x: f64, y: f64) -> f64 { x + y } "#; case.checks = vec![ AssertEqual( Call(Export("add_bool").into(), [Bool(false), Bool(false)].into()).into(), Bool(false).into(), ), AssertEqual( Call(Export("add_bool").into(), [Bool(true), Bool(false)].into()).into(), Bool(true).into(), ), AssertEqual( Call(Export("add_bool").into(), [Bool(false), Bool(true)].into()).into(), Bool(true).into(), ), AssertEqual( Call(Export("add_bool").into(), [Bool(true), Bool(true)].into()).into(), Bool(true).into(), ), AssertEqual( Call(Export("add_u8").into(), [U8(1), U8(2)].into()).into(), U8(3).into(), ), AssertEqual( Call(Export("add_u16").into(), [U16(1), U16(2)].into()).into(), U16(3).into(), ), AssertEqual( Call(Export("add_u32").into(), [U32(1), U32(2)].into()).into(), U32(3).into(), ), AssertEqual( Call(Export("add_usize").into(), [Usize(1), Usize(2)].into()).into(), Usize(3).into(), ), AssertEqual( Call(Export("add_u64").into(), [U64(1), U64(2)].into()).into(), U64(3).into(), ), AssertEqual( Call(Export("add_i8").into(), [I8(1), I8(2)].into()).into(), I8(3).into(), ), AssertEqual( Call(Export("add_i16").into(), [I16(1), I16(2)].into()).into(), I16(3).into(), ), AssertEqual( Call(Export("add_i32").into(), [I32(1), I32(2)].into()).into(), I32(3).into(), ), AssertEqual( Call(Export("add_isize").into(), [Isize(1), Isize(2)].into()).into(), Isize(3).into(), ), AssertEqual( Call(Export("add_i64").into(), [I64(1), I64(2)].into()).into(), I64(3).into(), ), AssertEqual( Call(Export("add_f32").into(), [F32(1.5), F32(-0.25)].into()).into(), F32(1.25).into(), ), AssertEqual( Call(Export("add_f64").into(), [F64(-1.5), F64(0.25)].into()).into(), F64(-1.25).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_basic_void.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" static mut RESULT: i32 = 0; pub fn add_void(x: i32, y: i32) { unsafe { RESULT = x + y; } } pub fn add_empty_tuple(x: i32, y: i32) -> () { unsafe { RESULT = x + y; } } pub fn get_result() -> i32 { unsafe { RESULT } } // Make sure the "_" wildcard pattern works as an argument pub fn wild_arg(_: i32, _: (), _: i32) -> () { unsafe { RESULT = 123; } } "#; case.checks = vec![ Call(Export("add_void").into(), [I32(1), I32(2)].into()), AssertEqual( Call(Export("get_result").into(), [].into()).into(), I32(3).into(), ), Call(Export("add_empty_tuple").into(), [I32(3), I32(4)].into()), AssertEqual( Call(Export("get_result").into(), [].into()).into(), I32(7).into(), ), Call( Export("wild_arg").into(), [I32(-1), Tuple([].into()), I32(-2)].into(), ), AssertEqual( Call(Export("get_result").into(), [].into()).into(), I32(123).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_box_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(Eq, PartialEq)] pub struct Tree { value: i32, left: Option>, right: Option>, } pub fn sum_tree(tree: Tree) -> i32 { let mut sum = tree.value; sum += tree.left.map(|x| sum_tree(*x)).unwrap_or(0); sum += tree.right.map(|x| sum_tree(*x)).unwrap_or(0); sum } pub fn check_nested(x: Box>>) -> i32 { ***x } "#; case.checks = vec![ AssertEqual( Call( Export("sum_tree").into(), [Struct( "Tree", [ ("value", I32(2)), ( "left", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(1)), ("left", OptNone(TyBox(TyName("Tree").into()))), ("right", OptNone(TyBox(TyName("Tree").into()))), ] .into(), ) .into(), ) .into(), ), ), ( "right", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(4)), ( "left", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(3)), ( "left", OptNone(TyBox( TyName("Tree").into(), )), ), ( "right", OptNone(TyBox( TyName("Tree").into(), )), ), ] .into(), ) .into(), ) .into(), ), ), ( "right", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(5)), ( "left", OptNone(TyBox( TyName("Tree").into(), )), ), ( "right", OptNone(TyBox( TyName("Tree").into(), )), ), ] .into(), ) .into(), ) .into(), ), ), ] .into(), ) .into(), ) .into(), ), ), ] .into(), ) .into()] .into(), ) .into(), I32(1 + 2 + 3 + 4 + 5).into(), ) .into(), AssertEqual( Call( Export("check_nested").into(), [Boxed( TyBox(TyBox(TyI32.into()).into()), Boxed(TyBox(TyI32.into()), Boxed(TyI32, I32(123).into()).into()).into(), ) .into()] .into(), ) .into(), I32(123).into(), ) .into(), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_box_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(Eq, PartialEq)] pub struct Tree { value: i32, left: Option>, right: Option>, } pub fn get_tree() -> Tree { Tree { value: 2, left: Some( Tree { value: 1, left: None, right: None, } .into(), ), right: Some( Tree { value: 4, left: Some( Tree { value: 3, left: None, right: None, } .into(), ), right: Some( Tree { value: 5, left: None, right: None, } .into(), ), } .into(), ), } } #[derive(Eq, PartialEq)] pub struct Nested(Box>>); pub fn check_nested(x: i32) -> Nested { Nested(Box::new(Box::new(Box::new(x)))) } "#; case.checks = vec![ AssertEqual( Call(Export("get_tree").into(), [].into()).into(), Struct( "Tree", [ ("value", I32(2)), ( "left", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(1)), ("left", OptNone(TyBox(TyName("Tree").into()))), ("right", OptNone(TyBox(TyName("Tree").into()))), ] .into(), ) .into(), ) .into(), ), ), ( "right", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(4)), ( "left", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(3)), ( "left", OptNone(TyBox( TyName("Tree").into(), )), ), ( "right", OptNone(TyBox( TyName("Tree").into(), )), ), ] .into(), ) .into(), ) .into(), ), ), ( "right", OptSome( Boxed( TyName("Tree"), Struct( "Tree", [ ("value", I32(5)), ( "left", OptNone(TyBox( TyName("Tree").into(), )), ), ( "right", OptNone(TyBox( TyName("Tree").into(), )), ), ] .into(), ) .into(), ) .into(), ), ), ] .into(), ) .into(), ) .into(), ), ), ] .into(), ) .into(), ) .into(), AssertEqual( Call(Export("check_nested").into(), [I32(123).into()].into()).into(), Struct( "Nested", [( "0", Boxed( TyBox(TyBox(TyI32.into()).into()), Boxed(TyBox(TyI32.into()), Boxed(TyI32, I32(123).into()).into()).into(), ) .into(), )] .into(), ) .into(), ) .into(), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_combo_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(Debug)] pub struct Foo { pub x: (Bar, Vec), pub y: Vec<((), (i32,), (f32, bool))>, } #[derive(Debug)] pub struct Bar { pub x: i32, pub y: Vec, } pub fn check_combo(foo: Foo) -> String { format!("{foo:?}") } "#; let mut foo = Struct( "Foo", [ ( "x", Tuple( [ Struct( "Bar", [("x", I32(1)), ("y", EmptyVector(TyName("Foo")))].into(), ), Vector( [Struct( "Bar", [("x", I32(2)), ("y", EmptyVector(TyName("Foo")))].into(), )] .into(), ), ] .into(), ), ), ( "y", Vector( [Tuple( [ Tuple([].into()), Tuple([I32(3)].into()), Tuple([F32(4.0), Bool(true)].into()), ] .into(), )] .into(), ), ), ] .into(), ); case.checks.push(AssertEqual( Call(Export("check_combo").into(), [foo.clone()].into()).into(), Str("Foo { x: (Bar { x: 1, y: [] }, [\ Bar { x: 2, y: [] }]), y: [((), (3,), (4.0, true))] }") .into(), )); foo = Struct( "Foo", [ ( "x", Tuple( [ Struct( "Bar", [("x", I32(5)), ("y", Vector([foo.clone(), foo].into()))].into(), ), Vector( [Struct( "Bar", [("x", I32(6)), ("y", EmptyVector(TyName("Foo")))].into(), )] .into(), ), ] .into(), ), ), ( "y", Vector( [Tuple( [ Tuple([].into()), Tuple([I32(7)].into()), Tuple([F32(8.0), Bool(true)].into()), ] .into(), )] .into(), ), ), ] .into(), ); case.checks.push(AssertEqual( Call(Export("check_combo").into(), [foo].into()).into(), Str("Foo { x: (Bar { x: 5, y: [Foo { x: (Bar { x: 1, y: [] }, \ [Bar { x: 2, y: [] }]), y: [((), (3,), (4.0, true))] }, \ Foo { x: (Bar { x: 1, y: [] }, [Bar { x: 2, y: [] }]), y: [((), (3,), (4.0, true))] }] }, \ [Bar { x: 6, y: [] }]), y: [((), (7,), (8.0, true))] }") .into(), )); case } test_all!(); ================================================ FILE: src/tests/cases/fn_combo_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(PartialEq)] pub struct Foo { // Note: One purpose of this test is to cover our manual "Equatable" // implementation in Swift, since tuples aren't equatable in Swift. pub x: (Bar, Vec), pub y: Vec<((), (i32,), (f32, bool))>, } #[derive(PartialEq)] pub struct Bar { pub x: i32, pub y: Vec, } pub fn check_combo1() -> Foo { Foo { x: ( Bar { x: 1, y: vec![] }, vec![Bar { x: 2, y: vec![] }], ), y: vec![((), (3,), (4.0, true))], } } pub fn check_combo2() -> Foo { Foo { x: ( Bar { x: 5, y: vec![check_combo1(), check_combo1()] }, vec![Bar { x: 6, y: vec![] }], ), y: vec![((), (7,), (8.0, true))], } } "#; let mut foo = Struct( "Foo", [ ( "x", Tuple( [ Struct( "Bar", [("x", I32(1)), ("y", EmptyVector(TyName("Foo")))].into(), ), Vector( [Struct( "Bar", [("x", I32(2)), ("y", EmptyVector(TyName("Foo")))].into(), )] .into(), ), ] .into(), ), ), ( "y", Vector( [Tuple( [ Tuple([].into()), Tuple([I32(3)].into()), Tuple([F32(4.0), Bool(true)].into()), ] .into(), )] .into(), ), ), ] .into(), ); case.checks = vec![AssertEqual( Call(Export("check_combo1").into(), [].into()).into(), foo.clone().into(), )]; foo = Struct( "Foo", [ ( "x", Tuple( [ Struct( "Bar", [ ("x", I32(5)), ("y", Vector([foo.clone(), foo.clone()].into())), ] .into(), ), Vector( [Struct( "Bar", [("x", I32(6)), ("y", EmptyVector(TyName("Foo")))].into(), )] .into(), ), ] .into(), ), ), ( "y", Vector( [Tuple( [ Tuple([].into()), Tuple([I32(7)].into()), Tuple([F32(8.0), Bool(true)].into()), ] .into(), )] .into(), ), ), ] .into(), ); case.checks = vec![AssertEqual( Call(Export("check_combo2").into(), [].into()).into(), foo.into(), )]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_enum_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub enum Foo { Zero, One, Hundred = 100, } pub fn foo_to_i32(foo: Foo) -> i32 { foo as i32 } pub enum Big { Min = -0x8000_0000, Max = 0x7fff_ffff, } pub fn big_to_i32(big: Big) -> i32 { big as i32 } // Also test code generation for enums with many members pub enum LongEnum { Empty, ShortTuple(i32), ShortStruct { a: i32, }, LongTuple(i32, i32, i32, i32, i32, i32, i32, i32), LongStruct { a: i32, b: i32, c: i32, d: i32, e: i32, f: i32 }, } pub fn long_in(_: LongEnum) {} "#; case.checks = vec![ AssertEqual( Call(Export("foo_to_i32").into(), [Enum("Foo", "Zero")].into()).into(), I32(0).into(), ), AssertEqual( Call(Export("foo_to_i32").into(), [Enum("Foo", "One")].into()).into(), I32(1).into(), ), AssertEqual( Call(Export("foo_to_i32").into(), [Enum("Foo", "Hundred")].into()).into(), I32(100).into(), ), AssertEqual( Call(Export("big_to_i32").into(), [Enum("Big", "Min")].into()).into(), I32(-0x8000_0000).into(), ), AssertEqual( Call(Export("big_to_i32").into(), [Enum("Big", "Max")].into()).into(), I32(0x7fff_ffff).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_enum_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub enum Foo { Zero, One, Hundred = 100, } pub fn i32_to_foo(foo: i32) -> Foo { match foo { 0 => Foo::Zero, 1 => Foo::One, 2 => Foo::Hundred, _ => panic!(), } } pub enum Big { Min = -0x8000_0000, Max = 0x7fff_ffff, } pub fn i32_to_big(big: i32) -> Big { match big { 0 => Big::Min, 1 => Big::Max, _ => panic!(), } } // Also test code generation for enums with many members pub enum LongEnum { Empty, ShortTuple(i32), ShortStruct { a: i32, }, LongTuple(i32, i32, i32, i32, i32, i32, i32, i32), LongStruct { a: i32, b: i32, c: i32, d: i32, e: i32, f: i32 }, } pub fn long_out() -> LongEnum { LongEnum::Empty } "#; case.checks = vec![ AssertEqual( Call(Export("i32_to_foo").into(), [I32(0)].into()).into(), Enum("Foo", "Zero").into(), ), AssertEqual( Call(Export("i32_to_foo").into(), [I32(1)].into()).into(), Enum("Foo", "One").into(), ), AssertEqual( Call(Export("i32_to_foo").into(), [I32(2)].into()).into(), Enum("Foo", "Hundred").into(), ), AssertEqual( Call(Export("i32_to_big").into(), [I32(0)].into()).into(), Enum("Big", "Min").into(), ), AssertEqual( Call(Export("i32_to_big").into(), [I32(1)].into()).into(), Enum("Big", "Max").into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_nested_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub struct Foo { #[allow(unused)] empty: (), ptr: Rc, } pub trait Bar { fn get(&self) -> i32; } pub fn test(x: (i32, Foo, Vec<(i32, Foo)>)) -> i32 { let mut total = x.0 + x.1.ptr.get(); for y in &x.2 { total += y.0 + y.1.ptr.get(); } total } "#; case.js_pre = " class BarImpl { get() { return 20 } } "; case.swift_pre = " var counter = 0 class BarImpl : Bar { init() { counter += 1 } deinit { counter -= 1 } func get() -> Int32 { return 20 } } "; case.cpp_pre = " int counter = 0; struct BarImpl : rust::Bar { BarImpl() { counter += 1; } ~BarImpl() { counter -= 1; } int32_t get() { return 20; } }; "; case.checks = vec![ AssertEqual( Call( Export("test").into(), [Tuple( [ I32(10), Struct( "Foo", [ ("empty", Tuple([].into())), ("ptr", NewRc(TyName("Bar"), "BarImpl", [].into())), ] .into(), ), EmptyVector(TyTuple([TyI32, TyName("Foo")].into()).into()), ] .into(), )] .into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("test").into(), [Tuple( [ I32(1), Struct( "Foo", [ ("empty", Tuple([].into())), ("ptr", NewRc(TyName("Bar"), "BarImpl", [].into())), ] .into(), ), Vector( [ Tuple( [ I32(5), Struct( "Foo", [ ("empty", Tuple([].into())), ("ptr", NewRc(TyName("Bar"), "BarImpl", [].into())), ] .into(), ), ] .into(), ), Tuple( [ I32(600), Struct( "Foo", [ ("empty", Tuple([].into())), ("ptr", NewRc(TyName("Bar"), "BarImpl", [].into())), ] .into(), ), ] .into(), ), ] .into(), ), ] .into(), )] .into(), ) .into(), I32(666).into(), ), ]; case.swift_post = r#" assert(counter == 0, "\(counter) == \(0)") "#; case.cpp_post = " assert(counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cases/fn_nested_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub struct Foo { ptr: Rc, } pub trait Bar { fn get(&self) -> i32; } struct BarImpl(i32); impl Bar for BarImpl { fn get(&self) -> i32 { self.0 } } pub fn test(x: i32) -> (i32, Foo) { (x, Foo { ptr: Rc::new(BarImpl(-x)) }) } "#; case.checks = vec![ AssertEqual( TupleMember(Call(Export("test").into(), [I32(123)].into()).into(), 0).into(), I32(123).into(), ), AssertEqual( CallMethod( StructMember( TupleMember(Call(Export("test").into(), [I32(123)].into()).into(), 1).into(), "ptr", ) .into(), "get", [].into(), ) .into(), I32(-123).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_option_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn add_option(x: Option, y: Option) -> i32 { x.unwrap_or(0) + y.unwrap_or(0) } pub fn add_nested(x: Option>, y: Option>) -> i32 { x.unwrap_or(None).unwrap_or(0) + y.unwrap_or(None).unwrap_or(0) } pub fn add_all(x: Vec>) -> i32 { x.iter().map(|x| x.unwrap_or(0)).sum() } pub fn join_all(x: Vec>) -> String { x.iter().map(|x| x.as_ref().map(String::as_str).unwrap_or("")).collect::>().join("") } "#; case.checks = vec![ AssertEqual( Call( Export("add_option").into(), [OptNone(TyI32), OptNone(TyI32)].into(), ) .into(), I32(0).into(), ), AssertEqual( Call( Export("add_option").into(), [OptSome(I32(1).into()), OptNone(TyI32)].into(), ) .into(), I32(1).into(), ), AssertEqual( Call( Export("add_option").into(), [OptNone(TyI32), OptSome(I32(2).into())].into(), ) .into(), I32(2).into(), ), AssertEqual( Call( Export("add_option").into(), [OptSome(I32(1).into()), OptSome(I32(2).into())].into(), ) .into(), I32(3).into(), ), AssertEqual( Call( Export("add_all").into(), [Vector( [ OptNone(TyI32), OptSome(I32(100).into()), OptNone(TyI32), OptSome(I32(20).into()), OptNone(TyI32), OptSome(I32(3).into()), OptNone(TyI32), ] .into(), )] .into(), ) .into(), I32(123).into(), ), AssertEqual( Call( Export("add_nested").into(), [ OptNone(TyOption(TyI32.into())), OptNone(TyOption(TyI32.into())), ] .into(), ) .into(), I32(0).into(), ), AssertEqual( Call( Export("add_nested").into(), [ OptSome(OptSome(I32(-1).into()).into()), OptSome(OptNone(TyI32).into()), ] .into(), ) .into(), I32(-1).into(), ), AssertEqual( Call( Export("add_nested").into(), [ OptSome(OptNone(TyI32).into()), OptSome(OptSome(I32(-2).into()).into()), ] .into(), ) .into(), I32(-2).into(), ), AssertEqual( Call( Export("add_nested").into(), [ OptSome(OptSome(I32(-1).into()).into()), OptSome(OptSome(I32(-2).into()).into()), ] .into(), ) .into(), I32(-3).into(), ), AssertEqual( Call( Export("join_all").into(), [Vector( [ OptNone(TyString), OptSome(Str("abc").into()), OptNone(TyString), OptSome(Str("xy").into()), OptNone(TyString), OptSome(Str("z").into()), OptNone(TyString), ] .into(), )] .into(), ) .into(), Str("abcxyz").into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_option_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn opt_int(x: bool, y: i32) -> Option { x.then(|| y) } pub fn opt_opt_int(x: bool, y: bool, z: i32) -> Option> { x.then(|| y.then(|| z)) } pub fn vec_opt_int(n: i32) -> Vec> { (0..n).map(|x| (x % 3 != 0 && x % 5 != 0).then_some(x)).collect() } pub fn opt_vec_opt_string(n: i32) -> Option>> { if n < 1 { None } else { Some((0..n).map(|x| (x % 3 != 0 && x % 5 != 0).then_some(x.to_string())).collect()) } } "#; case.checks = vec![ AssertEqual( Call(Export("opt_int").into(), [Bool(false), I32(10)].into()).into(), OptNone(TyI32.into()).into(), ), AssertEqual( Call(Export("opt_int").into(), [Bool(true), I32(10)].into()).into(), OptSome(I32(10).into()).into(), ), AssertEqual( Call( Export("opt_opt_int").into(), [Bool(false), Bool(false), I32(30)].into(), ) .into(), OptNone(TyOption(TyI32.into())).into(), ), AssertEqual( Call( Export("opt_opt_int").into(), [Bool(true), Bool(false), I32(30)].into(), ) .into(), OptSome(OptNone(TyI32.into()).into()).into(), ), AssertEqual( Call( Export("opt_opt_int").into(), [Bool(true), Bool(true), I32(30)].into(), ) .into(), OptSome(OptSome(I32(30).into()).into()).into(), ), AssertEqual( Call(Export("vec_opt_int").into(), [I32(10)].into()).into(), Vector( [ OptNone(TyI32.into()), OptSome(I32(1).into()), OptSome(I32(2).into()), OptNone(TyI32.into()), OptSome(I32(4).into()), OptNone(TyI32.into()), OptNone(TyI32.into()), OptSome(I32(7).into()), OptSome(I32(8).into()), OptNone(TyI32.into()), ] .into(), ) .into(), ), AssertEqual( Call(Export("opt_vec_opt_string").into(), [I32(10)].into()).into(), OptSome( Vector( [ OptNone(TyString.into()), OptSome(Str("1").into()), OptSome(Str("2").into()), OptNone(TyString.into()), OptSome(Str("4").into()), OptNone(TyString.into()), OptNone(TyString.into()), OptSome(Str("7").into()), OptSome(Str("8").into()), OptNone(TyString.into()), ] .into(), ) .into(), ) .into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_payload_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(Debug, Eq, PartialEq)] pub enum Foo { Empty, Single(i32), Point { x: i32, y: i32 }, Nested(Box), } pub fn set_tests(tests: Vec) -> bool { assert_eq!(tests, vec![ Foo::Empty, Foo::Single(123), Foo::Point { x: 1, y: -2 }, Foo::Nested(Box::new(Foo::Nested(Box::new(Foo::Single(-321))))), ]); true } "#; case.checks = vec![AssertEqual( Call( Export("set_tests").into(), [Vector( [ EnumPayload("Foo", "Empty", [].into()), EnumPayload("Foo", "Single", [("0", I32(123))].into()), EnumPayload("Foo", "Point", [("x", I32(1)), ("y", I32(-2))].into()), EnumPayload( "Foo", "Nested", [( "0", Boxed( TyName("Foo"), EnumPayload( "Foo", "Nested", [( "0", Boxed( TyName("Foo"), EnumPayload("Foo", "Single", [("0", I32(-321))].into()) .into(), ) .into(), )] .into(), ) .into(), ), )] .into(), ), ] .into(), ) .into()] .into(), ) .into(), Bool(true).into(), )]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_payload_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(Eq, PartialEq)] pub enum Foo { Empty, Single(i32), Point { x: i32, y: i32 }, Nested(Box), } pub fn get_tests() -> Vec { vec![ Foo::Empty, Foo::Single(123), Foo::Point { x: 1, y: -2 }, Foo::Nested(Box::new(Foo::Nested(Box::new(Foo::Single(-321))))), ] } "#; case.checks = vec![AssertEqual( Call(Export("get_tests").into(), [].into()).into(), Vector( [ EnumPayload("Foo", "Empty", [].into()), EnumPayload("Foo", "Single", [("0", I32(123))].into()), EnumPayload("Foo", "Point", [("x", I32(1)), ("y", I32(-2))].into()), EnumPayload( "Foo", "Nested", [( "0", Boxed( TyName("Foo"), EnumPayload( "Foo", "Nested", [( "0", Boxed( TyName("Foo"), EnumPayload("Foo", "Single", [("0", I32(-321))].into()) .into(), ) .into(), )] .into(), ) .into(), ), )] .into(), ), ] .into(), ) .into(), )]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_string.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::cell::UnsafeCell; // Can't use "Mutex" because it allocates memory and throws off our memory check struct Wrapper(UnsafeCell>); unsafe impl Sync for Wrapper {} static STRING: Wrapper = Wrapper(UnsafeCell::new(None)); // This prepares for the memory leak check at the end pub fn reset() { unsafe { *STRING.0.get() = None; } } pub fn get_string_len() -> i32 { let x = unsafe { (*STRING.0.get()).as_ref() }; x.map(|x| x.len()).unwrap_or(0) as i32 } pub fn get_string() -> String { let x = unsafe { (*STRING.0.get()).as_ref() }; x.map(|x| x.as_str()).unwrap_or("").to_string() } pub fn set_string(x: String) { unsafe { *STRING.0.get() = Some(x); } } pub fn set_str(x: &str) { unsafe { *STRING.0.get() = Some(x.to_string()); } } "#; case.checks = vec![ AssertEqual( Call(Export("get_string_len").into(), [].into()).into(), I32(0).into(), ), AssertEqual( Call(Export("get_string").into(), [].into()).into(), Str("").into(), ), Call(Export("set_string").into(), [Str("abc")].into()).into(), AssertEqual( Call(Export("get_string_len").into(), [].into()).into(), I32(3).into(), ), AssertEqual( Call(Export("get_string").into(), [].into()).into(), Str("abc").into(), ), Call(Export("set_string").into(), [Str("\0\r\n\u{1f980}")].into()), AssertEqual( Call(Export("get_string_len").into(), [].into()).into(), I32(7).into(), ), AssertEqual( Call(Export("get_string").into(), [].into()).into(), Str("\0\r\n\u{1f980}").into(), ), Call(Export("set_str").into(), [Str("<<<\0>>>")].into()), AssertEqual( Call(Export("get_string_len").into(), [].into()).into(), I32(7).into(), ), AssertEqual( Call(Export("get_string").into(), [].into()).into(), Str("<<<\0>>>").into(), ), Call(Export("reset").into(), [].into()), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_struct_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub struct EmptyStruct; pub struct SingleElementStruct(i32); pub struct PairStruct { x: f32, y: f32 } pub fn empty_tuple(x: i32, #[allow(unused)] foo: EmptyStruct, y: i32) -> i32 { x + y } pub fn single_element_tuple(x: SingleElementStruct, y: SingleElementStruct) -> i32 { x.0 + y.0 } pub fn multiply_pairs(ab: PairStruct, cd: PairStruct) -> f32 { let PairStruct { x: a, y: b } = ab; let PairStruct { x: c, y: d } = cd; a * c - b * d } "#; case.checks = vec![ AssertEqual( Call( Export("empty_tuple").into(), [I32(10), Struct("EmptyStruct", [].into()), I32(20)].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("single_element_tuple").into(), [ Struct("SingleElementStruct", [("0", I32(10))].into()), Struct("SingleElementStruct", [("0", I32(20))].into()), ] .into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("multiply_pairs").into(), [ Struct("PairStruct", [("x", F32(2.0)), ("y", F32(3.0))].into()), Struct("PairStruct", [("x", F32(5.0)), ("y", F32(7.0))].into()), ] .into(), ) .into(), F32(-11.0).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_struct_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" #[derive(PartialEq)] pub struct EmptyStruct; #[derive(PartialEq)] pub struct SingleElementStruct(i32); #[derive(PartialEq)] pub struct PairStruct { x: f32, y: f32 } pub fn empty_struct() -> EmptyStruct { EmptyStruct } pub fn single_element_struct(x: i32) -> SingleElementStruct { SingleElementStruct(x) } pub fn make_pair(x: f32, y: f32) -> PairStruct { PairStruct { x, y } } "#; case.checks = vec![ AssertEqual( Call(Export("empty_struct").into(), [].into()).into(), Struct("EmptyStruct", [].into()).into(), ), AssertEqual( Call(Export("single_element_struct").into(), [I32(10)].into()).into(), Struct("SingleElementStruct", [("0", I32(10))].into()).into(), ), AssertEqual( Call(Export("make_pair").into(), [F32(2.0), F32(3.0)].into()).into(), Struct("PairStruct", [("x", F32(2.0)), ("y", F32(3.0))].into()).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_tuple_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn empty_tuple(x: i32, #[allow(unused)] foo: (), y: i32) -> i32 { x + y } pub fn single_element_tuple(x: (i32,), y: (i32,)) -> i32 { x.0 + y.0 } pub fn multiply_pairs(ab: (f32, f32), cd: (f32, f32)) -> f32 { let (a, b) = ab; let (c, d) = cd; a * c - b * d } pub fn nesting(x: (i32, (), (i32, (i32,)))) -> i32 { x.0 + x.2.0 + x.2.1.0 } "#; case.checks = vec![ AssertEqual( Call( Export("empty_tuple").into(), [I32(10), Tuple([].into()), I32(20)].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("single_element_tuple").into(), [Tuple([I32(10)].into()), Tuple([I32(20)].into())].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("multiply_pairs").into(), [ Tuple([F32(2.0), F32(3.0)].into()), Tuple([F32(5.0), F32(7.0)].into()), ] .into(), ) .into(), F32(-11.0).into(), ), AssertEqual( Call( Export("nesting").into(), [Tuple( [ I32(10), Tuple([].into()), Tuple([I32(20), Tuple([I32(30)].into())].into()), ] .into(), )] .into(), ) .into(), I32(60).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_tuple_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn single_element_tuple(x: i32) -> (i32,) { (-x,) } pub fn return_pair(x: f32, y: bool) -> (f32, bool) { (-x, !y) } "#; case.checks = vec![ AssertEqual( Call(Export("single_element_tuple").into(), [I32(123)].into()).into(), Tuple([I32(-123)].into()).into(), ), AssertEqual( Call(Export("return_pair").into(), [F32(1.23), Bool(true)].into()).into(), Tuple([F32(-1.23), Bool(false)].into()).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_vec_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn sum_u8(values: Vec) -> u8 { values.iter().sum() } pub fn sum_u16(values: Vec) -> u16 { values.iter().sum() } pub fn sum_u32(values: Vec) -> u32 { values.iter().sum() } pub fn sum_usize(values: Vec) -> usize { values.iter().sum() } pub fn sum_u64(values: Vec) -> u64 { values.iter().sum() } pub fn sum_i8(values: Vec) -> i8 { values.iter().sum() } pub fn sum_i16(values: Vec) -> i16 { values.iter().sum() } pub fn sum_i32(values: Vec) -> i32 { values.iter().sum() } pub fn sum_isize(values: Vec) -> isize { values.iter().sum() } pub fn sum_i64(values: Vec) -> i64 { values.iter().sum() } // Note: Rust changed how "sum()" behaves in version 1.82.0. It used // to return +0.0 when empty but now returns -0.0. Detect this case and // deliberately always return -0.0 to make this pass with older Rust. // https://github.com/rust-lang/rust/commit/490818851860fb257e23fe7aa0ee32eaffc4ba40 pub fn sum_f32(values: Vec) -> f32 { if values.is_empty() { -0.0 } else { values.iter().sum() } } pub fn sum_f64(values: Vec) -> f64 { if values.is_empty() { -0.0 } else { values.iter().sum() } } pub fn check_nested(values: Vec>) -> String { format!("{values:?}") } "#; case.checks = vec![ AssertEqual( Call(Export("sum_u8").into(), [EmptyVector(TyU8)].into()).into(), U8(0).into(), ), AssertEqual( Call(Export("sum_u16").into(), [EmptyVector(TyU16)].into()).into(), U16(0).into(), ), AssertEqual( Call(Export("sum_u32").into(), [EmptyVector(TyU32)].into()).into(), U32(0).into(), ), AssertEqual( Call(Export("sum_usize").into(), [EmptyVector(TyUsize)].into()).into(), Usize(0).into(), ), AssertEqual( Call(Export("sum_u64").into(), [EmptyVector(TyU64)].into()).into(), U64(0).into(), ), AssertEqual( Call(Export("sum_i8").into(), [EmptyVector(TyI8)].into()).into(), I8(0).into(), ), AssertEqual( Call(Export("sum_i16").into(), [EmptyVector(TyI16)].into()).into(), I16(0).into(), ), AssertEqual( Call(Export("sum_i32").into(), [EmptyVector(TyI32)].into()).into(), I32(0).into(), ), AssertEqual( Call(Export("sum_isize").into(), [EmptyVector(TyIsize)].into()).into(), Isize(0).into(), ), AssertEqual( Call(Export("sum_i64").into(), [EmptyVector(TyI64)].into()).into(), I64(0).into(), ), AssertEqual( Call(Export("sum_f32").into(), [EmptyVector(TyF32)].into()).into(), F32(-0.0).into(), ), AssertEqual( Call(Export("sum_f64").into(), [EmptyVector(TyF64)].into()).into(), F64(-0.0).into(), ), AssertEqual( Call( Export("sum_u8").into(), [Vector([U8(10), U8(20), U8(30)].into())].into(), ) .into(), U8(60).into(), ), AssertEqual( Call( Export("sum_u16").into(), [Vector([U16(10), U16(20), U16(30)].into())].into(), ) .into(), U16(60).into(), ), AssertEqual( Call( Export("sum_u32").into(), [Vector([U32(10), U32(20), U32(30)].into())].into(), ) .into(), U32(60).into(), ), AssertEqual( Call( Export("sum_isize").into(), [Vector([Isize(10), Isize(20), Isize(30)].into())].into(), ) .into(), Isize(60).into(), ), AssertEqual( Call( Export("sum_u64").into(), [Vector([U64(10), U64(20), U64(30)].into())].into(), ) .into(), U64(60).into(), ), AssertEqual( Call( Export("sum_i8").into(), [Vector([I8(10), I8(20), I8(30)].into())].into(), ) .into(), I8(60).into(), ), AssertEqual( Call( Export("sum_i16").into(), [Vector([I16(10), I16(20), I16(30)].into())].into(), ) .into(), I16(60).into(), ), AssertEqual( Call( Export("sum_i32").into(), [Vector([I32(10), I32(20), I32(30)].into())].into(), ) .into(), I32(60).into(), ), AssertEqual( Call( Export("sum_i64").into(), [Vector([I64(10), I64(20), I64(30)].into())].into(), ) .into(), I64(60).into(), ), AssertEqual( Call( Export("sum_f32").into(), [Vector([F32(1.5), F32(2.5), F32(3.5)].into())].into(), ) .into(), F32(7.5).into(), ), AssertEqual( Call( Export("sum_f64").into(), [Vector([F64(1.5), F64(2.5), F64(3.5)].into())].into(), ) .into(), F64(7.5).into(), ), AssertEqual( Call( Export("sum_i32").into(), [Vector( [ I32(1), I32(2), I32(3), I32(4), I32(5), I32(6), I32(7), I32(8), I32(9), I32(10), ] .into(), )] .into(), ) .into(), I32(55).into(), ), AssertEqual( Call( Export("sum_u64").into(), [Vector( [ U64(1), U64(2), U64(3), U64(4), U64(5), U64(6), U64(7), U64(8), U64(9), U64(10), ] .into(), )] .into(), ) .into(), U64(55).into(), ), AssertEqual( Call( Export("check_nested").into(), [Vector( [ EmptyVector(TyI32), Vector([I32(1)].into()), Vector([I32(2), I32(3)].into()), Vector([I32(4), I32(5), I32(6)].into()), Vector([I32(7), I32(8), I32(9), I32(10)].into()), ] .into(), )] .into(), ) .into(), Str("[[], [1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]").into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/fn_vec_out.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub fn get_vec(n: i32) -> Vec { let mut vec = Vec::new(); for i in 0..n { vec.push(i * 10); } vec } pub fn check_nested() -> Vec> { vec![vec![], vec![1], vec![2, 3], vec![4, 5, 6], vec![7, 8, 9, 10]] } "#; case.checks = vec![ AssertEqual( VectorLen(Call(Export("get_vec").into(), [I32(0)].into()).into()).into(), Usize(0).into(), ), AssertEqual( Call(Export("get_vec").into(), [I32(3)].into()).into(), Vector([I32(0), I32(10), I32(20)].into()).into(), ), AssertEqual( Call(Export("get_vec").into(), [I32(10)].into()).into(), Vector( [ I32(0), I32(10), I32(20), I32(30), I32(40), I32(50), I32(60), I32(70), I32(80), I32(90), ] .into(), ) .into(), ), AssertEqual( Call(Export("check_nested").into(), [].into()).into(), Vector( [ EmptyVector(TyI32), Vector([I32(1)].into()), Vector([I32(2), I32(3)].into()), Vector([I32(4), I32(5), I32(6)].into()), Vector([I32(7), I32(8), I32(9), I32(10)].into()), ] .into(), ) .into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/mod.rs ================================================ use super::*; mod demo_app; mod demo_const; mod demo_derive_eq; mod demo_enum; mod demo_keyword; mod demo_order; mod demo_trait; mod fn_basic; mod fn_basic_void; mod fn_box_in; mod fn_box_out; mod fn_combo_in; mod fn_combo_out; mod fn_enum_in; mod fn_enum_out; mod fn_nested_in; mod fn_nested_out; mod fn_option_in; mod fn_option_out; mod fn_payload_in; mod fn_payload_out; mod fn_string; mod fn_struct_in; mod fn_struct_out; mod fn_tuple_in; mod fn_tuple_out; mod fn_vec_in; mod fn_vec_out; mod trait_enum; mod trait_export; mod trait_export_import; mod trait_export_nested; mod trait_import; mod trait_import_export; mod trait_import_nested; mod trait_import_struct_in; mod trait_import_tuple_in; mod trait_string; ================================================ FILE: src/tests/cases/trait_enum.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" pub trait Foo { fn set_enum(&self, bar: Bar); fn get_enum(&self) -> Bar; } pub fn get_foo() -> Box { struct FooImpl; impl Foo for FooImpl { fn set_enum(&self, bar: Bar) { assert_eq!(bar, Bar::C); } fn get_enum(&self) -> Bar { Bar::B } } Box::new(FooImpl) } #[derive(Debug, Eq, PartialEq)] pub enum Bar { A, B, C, } "#; case.checks = vec![ DeclareImmutableLocal("foo", Call(Export("get_foo").into(), [].into()).into()), CallMethod( LoadLocal("foo").into(), "set_enum", [Enum("Bar", "C")].into(), ), AssertEqual( CallMethod(LoadLocal("foo").into(), "get_enum", [].into()).into(), Enum("Bar", "B").into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/trait_export.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Adder { fn add(&self, x: i32) -> i32; } struct AdderImpl(i32); static mut COUNTER: u32 = 0; pub fn get_counter() -> u32 { unsafe { COUNTER } } impl Adder for AdderImpl { fn add(&self, x: i32) -> i32 { self.0 + x } } impl Drop for AdderImpl { fn drop(&mut self) { unsafe { COUNTER -= 1; } } } pub fn get_adder_rc(x: i32) -> Rc { unsafe { COUNTER += 1; } Rc::new(AdderImpl(x)) } pub fn get_adder_box(x: i32) -> Box { unsafe { COUNTER += 1; } Box::new(AdderImpl(x)) } "#; case.checks = vec![ AssertEqual( CallMethod( Call(Export("get_adder_rc").into(), [I32(20)].into()).into(), "add", [I32(10)].into(), ) .into(), I32(30).into(), ), AfterGC( AssertEqual( Call(Export("get_counter").into(), [].into()).into(), U32(0).into(), ) .into(), ), AssertEqual( CallMethod( Call(Export("get_adder_box").into(), [I32(20)].into()).into(), "add", [I32(10)].into(), ) .into(), I32(30).into(), ), AfterGC( AssertEqual( Call(Export("get_counter").into(), [].into()).into(), U32(0).into(), ) .into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/trait_export_import.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Imported { fn add(&self, x: i32, y: i32) -> i32; } pub trait Exported { fn run(&self, imported: Rc) -> i32; } struct ExportedImpl; impl Exported for ExportedImpl { fn run(&self, imported: Rc) -> i32 { imported.add(1, 2) } } static mut COUNTER: u32 = 0; impl Drop for ExportedImpl { fn drop(&mut self) { unsafe { COUNTER -= 1; } } } pub fn get_exported() -> Rc { unsafe { COUNTER += 1; } Rc::new(ExportedImpl) } pub fn get_counter() -> u32 { unsafe { COUNTER } } "#; case.js_pre = " class ImportedImpl { add(x, y) { return x + y } } "; case.swift_pre = " var counter = 0 class ImportedImpl : Imported { init() { counter += 1 } deinit { counter -= 1 } func add(_ x: Int32, _ y: Int32) -> Int32 { return x + y } } "; case.cpp_pre = " int counter = 0; struct ImportedImpl : rust::Imported { ImportedImpl() { counter += 1; } ~ImportedImpl() { counter -= 1; } int32_t add(int32_t x, int32_t y) { return x + y; } }; "; case.checks = vec![ AssertEqual( CallMethod( Call(Export("get_exported").into(), [].into()).into(), "run", [NewRc(TyName("Imported"), "ImportedImpl", [].into())].into(), ) .into(), I32(3).into(), ), AfterGC( AssertEqual( Call(Export("get_counter").into(), [].into()).into(), U32(0).into(), ) .into(), ), ]; case.swift_post = r#" assert(counter == 0, "\(counter) == \(0)") "#; case.cpp_post = " assert(counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cases/trait_export_nested.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Getter { fn get_adder(&self) -> Rc; } struct GetterImpl; static mut GETTER_COUNTER: u32 = 0; pub fn get_getter_counter() -> u32 { unsafe { GETTER_COUNTER } } impl Getter for GetterImpl { fn get_adder(&self) -> Rc { unsafe { ADDER_COUNTER += 1; } Rc::new(AdderImpl) } } impl Drop for GetterImpl { fn drop(&mut self) { unsafe { GETTER_COUNTER -= 1; } } } pub trait Adder { fn add(&self, x: i32, y: i32) -> i32; } struct AdderImpl; static mut ADDER_COUNTER: u32 = 0; pub fn get_adder_counter() -> u32 { unsafe { ADDER_COUNTER } } impl Adder for AdderImpl { fn add(&self, x: i32, y: i32) -> i32 { x + y } } impl Drop for AdderImpl { fn drop(&mut self) { unsafe { ADDER_COUNTER -= 1; } } } pub fn get_getter() -> Rc { unsafe { GETTER_COUNTER += 1; } Rc::new(GetterImpl) } "#; case.checks = vec![ AssertEqual( CallMethod( CallMethod( Call(Export("get_getter").into(), [].into()).into(), "get_adder", [].into(), ) .into(), "add", [I32(1), I32(2)].into(), ) .into(), I32(3).into(), ), AfterGC( AssertEqual( Call(Export("get_getter_counter").into(), [].into()).into(), U32(0).into(), ) .into(), ), AfterGC( AssertEqual( Call(Export("get_adder_counter").into(), [].into()).into(), U32(0).into(), ) .into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/trait_import.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Adder { fn add(&self, y: i32) -> i32; } pub fn set_adder_rc(adder: Rc) -> i32 { adder.add(10) } pub fn set_adder_box(adder: Box) -> i32 { adder.add(100) } "#; case.js_pre = " class AdderImpl { constructor(x) { this.x = x } add(y) { return this.x + y } } "; case.swift_pre = " var counter = 0 class AdderImpl : Adder { let x: Int32 init(_ x: Int32) { self.x = x counter += 1 } deinit { counter -= 1 } func add(_ y: Int32) -> Int32 { return x + y } } "; case.cpp_pre = " int counter = 0; struct AdderImpl : rust::Adder { int32_t x; AdderImpl(int32_t x) { this->x = x; counter += 1; } ~AdderImpl() { counter -= 1; } int32_t add(int32_t y) { return x + y; } }; "; case.checks = vec![ AssertEqual( Call( Export("set_adder_rc").into(), [NewRc(TyName("Adder"), "AdderImpl", [I32(20)].into())].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("set_adder_box").into(), [NewBox(TyName("Adder"), "AdderImpl", [I32(200)].into())].into(), ) .into(), I32(300).into(), ), ]; case.swift_post = r#" assert(counter == 0, "\(counter) == \(0)") "#; case.cpp_post = " assert(counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cases/trait_import_export.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Imported { fn run(&self, exported: Rc) -> i32; } pub trait Exported { fn add(&self, x: i32, y: i32) -> i32; } struct ExportedImpl; static mut COUNTER: u32 = 0; pub fn get_counter() -> u32 { unsafe { COUNTER } } impl Exported for ExportedImpl { fn add(&self, x: i32, y: i32) -> i32 { x + y } } impl Drop for ExportedImpl { fn drop(&mut self) { unsafe { COUNTER -= 1; } } } pub fn set_imported(imported: Rc) -> i32 { unsafe { COUNTER += 1; } imported.run(Rc::new(ExportedImpl)) } "#; case.js_pre = " class ImportedImpl { run(exported) { return exported.add(1, 2) } } "; case.swift_pre = " var counter = 0 class ImportedImpl : Imported { init() { counter += 1 } deinit { counter -= 1 } func run(_ exported: Exported) -> Int32 { return exported.add(1, 2) } } "; case.cpp_pre = " int counter = 0; struct ImportedImpl : rust::Imported { ImportedImpl() { counter += 1; } ~ImportedImpl() { counter -= 1; } int32_t run(std::shared_ptr exported) { return exported->add(1, 2); } }; "; case.checks = vec![ AssertEqual( Call( Export("set_imported").into(), [NewRc(TyName("Imported"), "ImportedImpl", [].into())].into(), ) .into(), I32(3).into(), ), AfterGC( AssertEqual( Call(Export("get_counter").into(), [].into()).into(), U32(0).into(), ) .into(), ), ]; case.swift_post = r#" assert(counter == 0, "\(counter) == \(0)") "#; case.cpp_post = " assert(counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cases/trait_import_nested.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait Getter { fn get_adder(&self) -> Rc; } pub trait Adder { fn add(&self, x: i32, y: i32) -> i32; } pub fn set_getter(getter: Rc) -> i32 { getter.get_adder().add(1, 2) } "#; case.js_pre = " class GetterImpl { get_adder() { return new AdderImpl } } class AdderImpl { add(x, y) { return x + y } } "; case.swift_pre = " var getter_counter = 0 class GetterImpl : Getter { init() { getter_counter += 1 } deinit { getter_counter -= 1 } func get_adder() -> Adder { return AdderImpl() } } var adder_counter = 0 class AdderImpl : Adder { init() { adder_counter += 1 } deinit { adder_counter -= 1 } func add(_ x: Int32, _ y: Int32) -> Int32 { return x + y } } "; case.cpp_pre = " int adder_counter = 0; struct AdderImpl : rust::Adder { AdderImpl() { adder_counter += 1; } ~AdderImpl() { adder_counter -= 1; } int32_t add(int32_t x, int32_t y) { return x + y; } }; int getter_counter = 0; struct GetterImpl : rust::Getter { GetterImpl() { getter_counter += 1; } ~GetterImpl() { getter_counter -= 1; } std::shared_ptr get_adder() { return std::make_shared(); } }; "; case.checks = vec![AssertEqual( Call( Export("set_getter").into(), [NewRc(TyName("Getter"), "GetterImpl", [].into())].into(), ) .into(), I32(3).into(), )]; case.swift_post = r#" assert(getter_counter == 0, "\(getter_counter) == \(0)") assert(adder_counter == 0, "\(adder_counter) == \(0)") "#; case.cpp_post = " assert(getter_counter == 0); assert(adder_counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cases/trait_import_struct_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub struct EmptyStruct; pub struct SingleElementStruct(i32); pub struct PairStruct { x: f32, y: f32 } pub trait StructIn { fn empty_struct(&self, x: i32, #[allow(unused)] foo: EmptyStruct, y: i32) -> i32; fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32; fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32; } pub fn set_empty_struct(struct_in: Rc) -> i32 { struct_in.empty_struct(10, EmptyStruct, 20) } pub fn set_single_element_struct(struct_in: Rc) -> i32 { struct_in.single_element_struct(SingleElementStruct(10), SingleElementStruct(20)) } pub fn set_multiply_pairs(struct_in: Rc) -> f32 { struct_in.multiply_pairs(PairStruct { x: 2.0, y: 3.0 }, PairStruct { x: 5.0, y: 7.0 }) } "#; case.js_pre = " class StructInImpl { empty_struct(x, foo, y) { assert.deepStrictEqual(foo, {}) return x + y } single_element_struct(x, y) { return x[0] + y[0] } multiply_pairs({ x: a, y: b }, { x: c, y: d }) { return a * c - b * d } } "; case.swift_pre = " class StructInImpl : StructIn { func empty_struct(_ x: Int32, _ foo: EmptyStruct, _ y: Int32) -> Int32 { return x + y } func single_element_struct(_ x: SingleElementStruct, _ y: SingleElementStruct) -> Int32 { return x._0 + y._0 } func multiply_pairs(_ ab: PairStruct, _ cd: PairStruct) -> Float32 { return ab.x * cd.x - ab.y * cd.y } } "; case.cpp_pre = " struct StructInImpl : rust::StructIn { int32_t empty_struct(int32_t x, rust::EmptyStruct, int32_t y) { return x + y; } int32_t single_element_struct(rust::SingleElementStruct x, rust::SingleElementStruct y) { return x._0 + y._0; } float multiply_pairs(rust::PairStruct ab, rust::PairStruct cd) { return ab.x * cd.x - ab.y * cd.y; } }; "; case.checks = vec![ AssertEqual( Call( Export("set_empty_struct").into(), [NewRc(TyName("StructIn"), "StructInImpl", [].into())].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("set_single_element_struct").into(), [NewRc(TyName("StructIn"), "StructInImpl", [].into())].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("set_multiply_pairs").into(), [NewRc(TyName("StructIn"), "StructInImpl", [].into())].into(), ) .into(), F32(-11.0).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/trait_import_tuple_in.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; pub trait TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32; fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32; fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32; } pub fn set_empty_tuple(tuple_in: Rc) -> i32 { tuple_in.empty_tuple(10, (), 20) } pub fn set_single_element_tuple(tuple_in: Rc) -> i32 { tuple_in.single_element_tuple((10,), (20,)) } pub fn set_multiply_pairs(tuple_in: Rc) -> f32 { tuple_in.multiply_pairs((2.0, 3.0), (5.0, 7.0)) } "#; case.js_pre = " class TupleInImpl { empty_tuple(x, foo, y) { assert.deepStrictEqual(foo, undefined) return x + y } single_element_tuple(x, y) { return x[0] + y[0] } multiply_pairs([a, b], [c, d]) { return a * c - b * d } } "; case.swift_pre = " class TupleInImpl : TupleIn { func empty_tuple(_ x: Int32, _ foo: (), _ y: Int32) -> Int32 { return x + y } func single_element_tuple(_ x: Int32, _ y: Int32) -> Int32 { return x + y } func multiply_pairs(_ ab: (Float32, Float32), _ cd: (Float32, Float32)) -> Float32 { let (a, b) = ab let (c, d) = cd return a * c - b * d } } "; case.cpp_pre = " struct TupleInImpl : rust::TupleIn { int32_t empty_tuple(int32_t x, std::tuple<>, int32_t y) { return x + y; } int32_t single_element_tuple(std::tuple x, std::tuple y) { return std::get<0>(x) + std::get<0>(y); } float multiply_pairs(std::tuple ab, std::tuple cd) { float a, b, c, d; std::tie(a, b) = ab; std::tie(c, d) = cd; return a * c - b * d; } }; "; case.checks = vec![ AssertEqual( Call( Export("set_empty_tuple").into(), [NewRc(TyName("TupleIn"), "TupleInImpl", [].into())].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("set_single_element_tuple").into(), [NewRc(TyName("TupleIn"), "TupleInImpl", [].into())].into(), ) .into(), I32(30).into(), ), AssertEqual( Call( Export("set_multiply_pairs").into(), [NewRc(TyName("TupleIn"), "TupleInImpl", [].into())].into(), ) .into(), F32(-11.0).into(), ), ]; case } test_all!(); ================================================ FILE: src/tests/cases/trait_string.rs ================================================ use super::*; fn test_case() -> TestCase { let mut case = TestCase::default(); case.rust = r#" use std::rc::Rc; use std::cell::RefCell; pub trait Test { fn get_string(&self) -> String; fn set_string(&self, x: String); fn set_str(&self, x: &str); } struct TestImpl(RefCell); impl Test for TestImpl { fn get_string(&self) -> String { self.0.borrow().clone() } fn set_string(&self, x: String) { *self.0.borrow_mut() = x; } fn set_str(&self, x: &str) { *self.0.borrow_mut() = x.to_string(); } } pub fn get_test() -> Rc { Rc::new(TestImpl(RefCell::new(String::new()))) } pub fn set_test(test: Rc) -> String { let mut foo = test.get_string(); test.set_string("abc".to_string()); foo.push_str(&test.get_string()); test.set_str("xyz"); foo.push_str(&test.get_string()); foo } "#; case.js_pre = r#" class TestImpl { x = "" get_string() { return this.x } set_string(x) { this.x = x } set_str(x) { this.x = x } } "#; case.swift_pre = r#" var counter = 0 class TestImpl : Test { var x: String = "" init() { counter += 1 } deinit { counter -= 1 } func get_string() -> String { return x } func set_string(_ x: String) { self.x = x } func set_str(_ x: String) { self.x = x } } "#; case.cpp_pre = " int counter = 0; struct TestImpl : rust::Test { std::string x; TestImpl() { counter += 1; } ~TestImpl() { counter -= 1; } std::string get_string() { return x; } void set_string(std::string x) { this->x = std::move(x); } void set_str(std::string x) { this->x = std::move(x); } }; "; case.checks = vec![ AssertEqual( Call( Export("set_test").into(), [NewRc(TyName("Test"), "TestImpl", [].into())].into(), ) .into(), Str("abcxyz").into(), ), DeclareImmutableLocal( "test_from_rust", Call(Export("get_test").into(), [].into()).into(), ), DeclareMutableLocal( "foo", CallMethod(LoadLocal("test_from_rust").into(), "get_string", [].into()).into(), ), CallMethod( LoadLocal("test_from_rust").into(), "set_string", [Str("ABC")].into(), ), StoreLocal( "foo", StrConcat( LoadLocal("foo").into(), CallMethod(LoadLocal("test_from_rust").into(), "get_string", [].into()).into(), ) .into(), ), CallMethod( LoadLocal("test_from_rust").into(), "set_string", [Str("XYZ")].into(), ), StoreLocal( "foo", StrConcat( LoadLocal("foo").into(), CallMethod(LoadLocal("test_from_rust").into(), "get_string", [].into()).into(), ) .into(), ), AssertEqual(LoadLocal("foo").into(), Str("ABCXYZ").into()), ]; case.swift_post = r#" assert(counter == 0, "\(counter) == \(0)") "#; case.cpp_post = " assert(counter == 0); "; case } test_all!(); ================================================ FILE: src/tests/cpp.rs ================================================ use super::*; pub fn run_test(name: &str, case: &TestCase, edition: usize) { let name = Path::new(name).file_stem().unwrap(); let name = &format!("cpp_{}_{edition}", name.to_string_lossy()); let test_dir = &Path::new(".temp").join(name); let src_dir = &test_dir.join("src"); std::fs::create_dir_all(src_dir).expect("failed to create directory `src`"); let TestCase { rust, cpp_pre, cpp_post, checks, .. } = case; let checks = checks .iter() .map(|x| format!("{};", to_str(x))) .collect::>() .join("\n"); std::fs::write( src_dir.join("lib.rs"), format!( r#" #![deny(warnings)] {} {rust} include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); "#, rust_leak_check() ), ) .expect("failed to write file `src/lib.rs`"); std::fs::write( test_dir.join("build.rs"), format!( r#" fn main() {{ use miniffi::*; let mut result = CppTarget::new() .rust_edition({edition}) .write_source_to("ffi.cpp") .write_header_to("ffi.h") .build() .convert_warnings_to_errors(); result.finish(); for output in &result.output_files {{ if output.path.extension().unwrap() == "rs" {{ std::fs::copy(&output.path, "miniffi.rs").unwrap(); }} }} }} "# ), ) .expect("failed to write file `build.rs`"); std::fs::write( test_dir.join("Cargo.toml"), format!( r#" [package] name = "{name}" version = "0.1.0" edition = "{edition}" [lib] crate-type = ["staticlib"] [build-dependencies] miniffi = {{ path = "../.." }} "# ), ) .expect("failed to write file `Cargo.toml`"); std::fs::write( test_dir.join("main.cpp"), format!( r#" #include "ffi.h" #include #include #include #include #include #include // "std::vector" stupidly copies the "std::initializer_list", // which breaks with uncopyable types such as "std::unique_ptr" template std::vector make_vector(T&& arg) {{ std::vector vec; vec.emplace_back(std::forward(arg)); return vec; }} template std::vector make_vector(T&& arg, Args&&... args) {{ auto vec = make_vector(std::forward(args)...); vec.emplace(vec.begin(), std::forward(arg)); return vec; }} size_t cpp_mem_leaked = 0; size_t cpp_mem_total = 0; void* operator new(size_t n) {{ cpp_mem_leaked += n; cpp_mem_total += n; size_t total = n; total = (n + 15) & ~15; // Align to a multiple of 16 total += 16; // Bump up to the next multiple of 16 uint8_t* ptr = (uint8_t*)malloc(total); memcpy(ptr, &n, sizeof(n)); return ptr + 16; }} void operator delete(void* p) throw() {{ uint8_t* ptr = (uint8_t*)p; ptr -= 16; size_t n; memcpy(&n, ptr, sizeof(n)); free(ptr); cpp_mem_leaked -= n; }} {cpp_pre} int main() {{ {{ {{ {checks} }} {cpp_post} }} // Make sure there are no memory leaks assert(cpp_mem_leaked == 0); assert(rust::rust_mem_leaked() == 0); }} "# ), ) .expect("failed to write file `main.cpp`"); cargo_build(test_dir, None); copy_snapshot(name, test_dir.join("miniffi.rs")); copy_snapshot(name, test_dir.join("ffi.cpp")); copy_snapshot(name, test_dir.join("ffi.h")); if cfg!(windows) { check_output( Command::new("cl.exe") .current_dir(test_dir) .arg("main.cpp") .arg("ffi.cpp") .arg("/std:c++17") .arg("/W3") .arg("/WX") .arg(format!("../target/debug/{name}.lib")) .arg("/EHs") .arg("/link") .arg("ntdll.lib") .arg("userenv.lib") .arg("ws2_32.lib") .arg("/out:main.exe") .output() .expect("failed to run command `cl.exe`"), ); check_output( Command::new(test_dir.join("main.exe")) .current_dir(test_dir) .env("RUST_BACKTRACE", "1") .output() .expect("failed to run command `./main.exe`"), ); } else { check_output( Command::new("c++") .current_dir(test_dir) .arg("main.cpp") .arg("ffi.cpp") .arg("-std=c++17") .arg("-Wall") .arg("-Werror") .arg(format!("../target/debug/lib{name}.a")) .args(["-o", "main"]) .output() .expect("failed to run command `c++`"), ); check_output( Command::new("./main") .current_dir(test_dir) .env("RUST_BACKTRACE", "1") .output() .expect("failed to run command `./main`"), ); } _ = std::fs::remove_dir_all(test_dir); } fn ty_to_str(ty: &ExprTy) -> String { match ty { TyBool => "bool".to_string(), TyU8 => "uint8_t".to_string(), TyU16 => "uint16_t".to_string(), TyU32 => "uint32_t".to_string(), TyUsize => "uintptr_t".to_string(), TyU64 => "uint64_t".to_string(), TyI8 => "int8_t".to_string(), TyI16 => "int16_t".to_string(), TyI32 => "int32_t".to_string(), TyIsize => "intptr_t".to_string(), TyI64 => "int64_t".to_string(), TyF32 => "float".to_string(), TyF64 => "double".to_string(), TyString => "std::string".to_string(), TyTuple(x) => format!( "std::tuple<{}>", x.iter().map(ty_to_str).collect::>().join(", ") ), TyOption(x) => format!("std::optional<{}>", ty_to_str(x)), TyVec(x) => format!("std::vector<{}>", ty_to_str(x)), TyBox(x) => format!("std::unique_ptr<{}>", ty_to_str(x)), TyName(x) => format!("rust::{x}"), } } fn many_to_str(x: &[Expr]) -> String { x.iter().map(to_str).collect::>().join(", ") } fn to_str(expr: &Expr) -> String { match expr { Bool(x) => format!("{x}"), U8(x) => format!("uint8_t({x})"), U16(x) => format!("uint16_t({x})"), U32(x) => format!("uint32_t({x})"), Usize(x) => format!("uintptr_t({x})"), U64(x) => format!("uint64_t({x}ull)"), I8(x) => format!("int8_t({x})"), I16(x) => format!("int16_t({x})"), I32(x) => { if *x == std::i32::MIN { // Avoid a Visual C++ warning format!("int32_t({} - 1)", x + 1) } else { format!("int32_t({x})") } } Isize(x) => format!("intptr_t({x})"), I64(x) => { if *x == std::i64::MIN { // Avoid a clang warning format!("int64_t({}ll - 1)", x + 1) } else { format!("int64_t({x}ll)") } } F32(x) => format!("float({x})"), F64(x) => format!("double({x})"), Str(x) => format!("std::string({x:?}, {})", x.len()), Export(x) => format!("rust::{x}"), Enum(x, y) => format!("rust::{x}::{y}"), EnumPayload(x, y, z) => format!( "rust::{x}{{rust::{x}::{y}{{{}}}}}", z.iter() .map(|(_, v)| to_str(v)) .collect::>() .join(", ") ), DeclareMutableLocal(x, y) => format!("auto {x} = {}", to_str(y)), DeclareImmutableLocal(x, y) => format!("const auto {x} = {}", to_str(y)), LoadLocal(x) => format!("{x}"), StoreLocal(x, y) => format!("{x} = {}", to_str(y)), NewBox(ty, x, y) => format!( "std::unique_ptr<{}>(new {x}({}))", ty_to_str(ty), many_to_str(y) ), NewRc(ty, x, y) => format!( "std::shared_ptr<{}>(new {x}({}))", ty_to_str(ty), many_to_str(y) ), Tuple(x) => format!("std::make_tuple({})", many_to_str(x)), Vector(x) => format!("make_vector({})", many_to_str(x)), EmptyVector(x) => format!("std::vector<{}>()", ty_to_str(x)), Struct(x, y) => format!( "rust::{x}{{{}}}", y.iter() .map(|(_, v)| to_str(v)) .collect::>() .join(", ") ), AssertEqual(x, y) => match &**y { F32(y) if *y == 0.0 => { format!( r#"{{ auto left = {}; assert(left == 0.0 && signbit(left) == {}); }}"#, to_str(x), y.is_sign_negative() ) } F64(y) if *y == 0.0 => { format!( r#"{{ auto left = {}; assert(left == 0.0 && signbit(left) == {}); }}"#, to_str(x), y.is_sign_negative() ) } Str(_) => { // "x" might be a "std::string_view" constant format!("assert(std::string({}) == ({}))", to_str(x), to_str(y)) } _ => format!("assert(({}) == ({}))", to_str(x), to_str(y)), }, AssertNotEqual(x, y) => match &**y { F32(y) if *y == 0.0 => { format!( r#"{{ auto left = {}; assert(left != 0.0 || signbit(left) != {}); }}"#, to_str(x), y.is_sign_negative() ) } F64(y) if *y == 0.0 => { format!( r#"{{ auto left = {}; assert(left != 0.0 || signbit(left) != {}); }}"#, to_str(x), y.is_sign_negative() ) } Str(_) => { // "x" might be a "std::string_view" constant format!("assert(std::string({}) != ({}))", to_str(x), to_str(y)) } _ => format!("assert(({}) != ({}))", to_str(x), to_str(y)), }, StrConcat(x, y) => format!("({}) + ({})", to_str(x), to_str(y)), Call(x, y) => format!("{}({})", to_str(x), many_to_str(y)), CallMethod(x, y, z) => format!("({})->{y}({})", to_str(x), many_to_str(z)), TupleMember(x, y) => format!("std::get<{y}>({})", to_str(x)), StructMember(x, y) => format!("({}).{y}", to_str(x)), VectorMember(x, y) => format!("({}).at({y})", to_str(x)), VectorLen(x) => format!("({}).size()", to_str(x)), AfterGC(x) => to_str(x), OptNone(x) => format!("std::optional<{}>()", ty_to_str(x)), OptSome(x) => format!("std::make_optional({})", to_str(x)), Boxed(x, y) => format!("std::make_unique<{}>({})", ty_to_str(x), to_str(y)), } } ================================================ FILE: src/tests/mod.rs ================================================ use super::*; use std::process::{Command, Output}; use std::sync::{Mutex, OnceLock}; mod cases; mod cpp; mod swift; mod warnings; mod wasm; macro_rules! test_all { () => { #[test] fn wasm_2021() { begin_test(); wasm::run_test(file!(), &test_case(), 2021); end_test(); } #[test] fn wasm_2024() { begin_test(); wasm::run_test(file!(), &test_case(), 2024); end_test(); } #[test] fn swift_2021() { begin_test(); swift::run_test(file!(), &test_case(), 2021); end_test(); } #[test] fn swift_2024() { begin_test(); swift::run_test(file!(), &test_case(), 2024); end_test(); } #[test] fn cpp_2021() { begin_test(); cpp::run_test(file!(), &test_case(), 2021); end_test(); } #[test] fn cpp_2024() { begin_test(); cpp::run_test(file!(), &test_case(), 2024); end_test(); } }; } use test_all; #[derive(Default)] struct TestCase { rust: &'static str, checks: Vec, js_pre: &'static str, js_post: &'static str, swift_pre: &'static str, swift_post: &'static str, cpp_pre: &'static str, cpp_post: &'static str, } #[derive(Clone)] enum ExprTy { TyBool, TyU8, TyU16, TyU32, TyUsize, TyU64, TyI8, TyI16, TyI32, TyIsize, TyI64, TyF32, TyF64, TyString, TyTuple(Box<[ExprTy]>), TyOption(Box), TyBox(Box), TyVec(Box), TyName(&'static str), } use ExprTy::*; #[derive(Clone)] enum Expr { Bool(bool), U8(u8), U16(u16), U32(u32), Usize(usize), U64(u64), I8(i8), I16(i16), I32(i32), Isize(isize), I64(i64), F32(f32), F64(f64), Str(&'static str), Export(&'static str), Enum(&'static str, &'static str), EnumPayload(&'static str, &'static str, Box<[(&'static str, Expr)]>), DeclareMutableLocal(&'static str, Box), DeclareImmutableLocal(&'static str, Box), LoadLocal(&'static str), StoreLocal(&'static str, Box), NewBox(ExprTy, &'static str, Box<[Expr]>), NewRc(ExprTy, &'static str, Box<[Expr]>), Tuple(Box<[Expr]>), Vector(Box<[Expr]>), EmptyVector(ExprTy), // This needs a type to help type inference Struct(&'static str, Box<[(&'static str, Expr)]>), AssertEqual(Box, Box), AssertNotEqual(Box, Box), StrConcat(Box, Box), Call(Box, Box<[Expr]>), CallMethod(Box, &'static str, Box<[Expr]>), TupleMember(Box, u32), StructMember(Box, &'static str), VectorMember(Box, usize), VectorLen(Box), AfterGC(Box), OptNone(ExprTy), OptSome(Box), Boxed(ExprTy, Box), } use Expr::*; static COUNTER: OnceLock> = OnceLock::new(); fn counter() -> &'static Mutex { COUNTER.get_or_init(|| Mutex::new(0)) } fn begin_test() { let mut counter = counter().lock().unwrap(); *counter += 1; } fn end_test() { let mut counter = counter().lock().unwrap(); *counter -= 1; // Clean up after the last test (intentionally done while the lock is held) if *counter == 0 { let test_dir = &PathBuf::from(".temp"); if let Ok(entries) = std::fs::read_dir(test_dir) { for entry in entries { let name = entry.unwrap().file_name(); if name != "target" && name != "node_modules" && name != "package.json" && name != "package-lock.json" { // Each test that passes deletes its test directory. So if // we encounter anything here that's not in the allow-list, // then it's likely a test failure. Don't remove the target // directory if there's a test that failed. return; } } // If all tests passed, automatically delete the target directory. // This prevents the target directory from taking up multiple // gigabytes of file system space when it's not needed. _ = std::fs::remove_dir_all(test_dir.join("target")); } } drop(counter); } fn check_output(output: Output) { if !output.status.success() { if output.stdout.is_empty() && output.stderr.is_empty() { panic!("(empty output)"); } panic!( "{}{}", String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr) ); } } fn cargo_build(test_dir: &Path, target: Option<&str>) { // Try offline-only first, otherwise cargo breaks when the internet is down for offline in [true, false] { let mut cmd = Command::new("cargo"); cmd.current_dir(test_dir) .env("RUST_BACKTRACE", "1") .arg("build") .arg("--quiet") .arg("--color=always") .arg("--message-format=short") .arg(format!("--target-dir=../target")); if offline { cmd.arg("--offline"); } if let Some(target) = target { cmd.arg(format!("--target={target}")); } let output = cmd.output().expect("failed to run command `cargo`"); if offline && !output.status.success() { // Fall back to trying online if offline-only failed continue; } check_output(output); return; } } fn copy_snapshot(name: &str, from: PathBuf) { let snapshot_dir = &Path::new("src").join("tests").join("snapshots").join(name); let to = snapshot_dir.join(from.file_name().unwrap()); std::fs::create_dir_all(snapshot_dir) .expect("failed to create directory `src/tests/snapshots`"); std::fs::copy(&from, &to).expect(&format!( "failed to copy snapshot from `{}` to `{}`", from.display(), to.display() )); } fn rust_leak_check() -> &'static str { // Test with "cargo +nightly test" to get memory leak checks if let Ok(toolchain) = std::env::var("RUSTUP_TOOLCHAIN") { if toolchain.contains("nightly") { return r#" #![feature(allocator_api)] struct LeakCheckAlloc; unsafe impl std::alloc::GlobalAlloc for LeakCheckAlloc { unsafe fn alloc(&self, layout: std::alloc::Layout) -> *mut u8 { unsafe { TOTAL_MEMORY += layout.size(); std::alloc::System.alloc(layout) } } unsafe fn dealloc(&self, ptr: *mut u8, layout: std::alloc::Layout) { unsafe { TOTAL_MEMORY -= layout.size(); std::alloc::System.dealloc(ptr, layout); } } } #[global_allocator] static ALLOCATOR: LeakCheckAlloc = LeakCheckAlloc; static mut TOTAL_MEMORY: usize = 0; pub fn rust_mem_leaked() -> usize { unsafe { TOTAL_MEMORY } } "#; } } r#" pub fn rust_mem_leaked() -> usize { 0 } "# } ================================================ FILE: src/tests/snapshots/cpp_demo_app_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_2_i32 { int32_t _0; int32_t _1; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); void _ffi_drop_Box_Handler(const void* ptr); void* _ffi_alloc(uintptr_t len); void _ffi_Box_Handler__on_draw(const void* _self, const void* canvas_ptr); void _ffi_fn_create_app(const void* platform_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } std::vector _ffi_vec_TextRun_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_text_ptr = _ffi_read(end); auto item_text_len = _ffi_read(end); auto item_text_cap = _ffi_read(end); auto item_text = _ffi_string_from_rust(item_text_ptr, item_text_len, item_text_cap); auto item_rect_x = _ffi_read(end); auto item_rect_y = _ffi_read(end); auto item_rect_w = _ffi_read(end); auto item_rect_h = _ffi_read(end); auto item_rect = rust::TextRect{item_rect_x, item_rect_y, item_rect_w, item_rect_h}; auto item = rust::TextRun{std::move(item_text), std::move(item_rect)}; items.emplace_back(std::move(item)); } return items; } struct _ffi_Box_Handler final : rust::Handler { _ffi_Box_Handler(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Handler() { _ffi_drop_Box_Handler(_self); } virtual void on_draw(std::unique_ptr canvas); const void* _self; }; const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } } // namespace extern "C" { void _ffi_cpp_Box_Canvas__draw_text_runs(rust::Canvas* _self, const void* buf_ptr, uintptr_t buf_cap, uintptr_t runs_len) { auto buf_end = (const uint8_t*)buf_ptr; auto runs = _ffi_vec_TextRun_from_rust(runs_len, buf_end); _self->draw_text_runs(std::move(runs)); _ffi_dealloc(buf_ptr, buf_cap); } const void* _ffi_cpp_Box_Platform__create_window(rust::Platform* _self) { return new std::shared_ptr(_self->create_window()); } const void* _ffi_cpp_Rc_Window__child_window(std::shared_ptr* _self) { return new std::shared_ptr(_self->get()->child_window()); } _ffi_ret_2_i32 _ffi_cpp_Rc_Window__get_size(std::shared_ptr* _self) { auto ret = _self->get()->get_size(); auto ret_0 = std::get<0>(ret); auto ret_1 = std::get<1>(ret); return _ffi_ret_2_i32{ret_0, ret_1}; } _ffi_ret_ptr_usize _ffi_cpp_Rc_Window__get_title(std::shared_ptr* _self) { uintptr_t ret_len; const void* ret_ptr = _ffi_string_to_rust(_self->get()->get_title(), ret_len); return _ffi_ret_ptr_usize{ret_ptr, ret_len}; } void _ffi_cpp_Rc_Window__set_handler(std::shared_ptr* _self, const void* handler_ptr) { auto handler = std::unique_ptr(new _ffi_Box_Handler(handler_ptr)); _self->get()->set_handler(std::move(handler)); } void _ffi_cpp_Rc_Window__set_size(std::shared_ptr* _self, int32_t width, int32_t height) { _self->get()->set_size(width, height); } void _ffi_cpp_Rc_Window__set_title(std::shared_ptr* _self, const char* title_ptr, uintptr_t title_len, uintptr_t title_cap) { auto title = _ffi_string_from_rust(title_ptr, title_len, title_cap); _self->get()->set_title(std::move(title)); } void _ffi_cpp_drop_Box_Canvas(rust::Canvas* self) { delete self; } void _ffi_cpp_drop_Box_Platform(rust::Platform* self) { delete self; } void _ffi_cpp_drop_Rc_Window(std::shared_ptr* self) { delete self; } } // extern "C" void _ffi_Box_Handler::on_draw(std::unique_ptr canvas) { auto canvas_ptr = canvas.release(); _ffi_Box_Handler__on_draw(_self, canvas_ptr); } void rust::create_app(std::unique_ptr platform) { auto platform_ptr = platform.release(); _ffi_fn_create_app(platform_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_app_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include #include namespace rust { struct TextRun; struct Canvas; struct Window; struct Handler; struct Canvas { virtual ~Canvas() {} virtual void draw_text_runs(std::vector runs) = 0; }; struct Handler { virtual ~Handler() {} virtual void on_draw(std::unique_ptr canvas) = 0; }; struct Platform { virtual ~Platform() {} virtual std::shared_ptr create_window() = 0; }; struct TextRect { int32_t x = 0; int32_t y = 0; int32_t w = 0; int32_t h = 0; }; struct TextRun { std::string text; TextRect rect; }; struct Window { virtual ~Window() {} virtual std::string get_title() = 0; virtual void set_title(std::string title) = 0; virtual std::tuple get_size() = 0; virtual void set_size(int32_t width, int32_t height) = 0; virtual void set_handler(std::unique_ptr handler) = 0; virtual std::shared_ptr child_window() = 0; }; uintptr_t rust_mem_leaked(); void create_app(std::unique_ptr platform); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_app_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *const u8) { let _self = unsafe { &*(_self as *const Box) }; _self.on_draw(Box::new(_ffi_rs_Box_Canvas(canvas_ptr))); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_drop_Box_Handler(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) { create_app(Box::new(_ffi_rs_Box_Platform(platform_ptr))); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_2_i32(i32, i32); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Box_Canvas(*const u8); impl Drop for _ffi_rs_Box_Canvas { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Box_Canvas(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Canvas(self.0) }; } } impl Canvas for _ffi_rs_Box_Canvas { fn draw_text_runs(&self, runs: Vec) { extern "C" { fn _ffi_cpp_Box_Canvas__draw_text_runs(_: *const u8, buf_ptr: *const u8, buf_cap: usize, runs_len: usize); } let mut buf = Vec::::new(); let runs_len = runs.len(); _ffi_vec_TextRun_to_cpp(runs, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _ffi_cpp_Box_Canvas__draw_text_runs(self.0, buf_ptr, buf_cap, runs_len) }; } } #[allow(non_camel_case_types)] struct _ffi_rs_Box_Platform(*const u8); impl Drop for _ffi_rs_Box_Platform { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Box_Platform(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Platform(self.0) }; } } impl Platform for _ffi_rs_Box_Platform { fn create_window(&self) -> std::rc::Rc { extern "C" { fn _ffi_cpp_Box_Platform__create_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_cpp_Box_Platform__create_window(self.0) }; std::rc::Rc::new(_ffi_rs_Rc_Window(ret_ptr)) } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Window(*const u8); impl Drop for _ffi_rs_Rc_Window { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Window(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Window(self.0) }; } } impl Window for _ffi_rs_Rc_Window { fn get_title(&self) -> String { extern "C" { fn _ffi_cpp_Rc_Window__get_title(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_cpp_Rc_Window__get_title(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_title(&self, title: &str) { extern "C" { fn _ffi_cpp_Rc_Window__set_title(_: *const u8, title_ptr: *const u8, title_len: usize, title_cap: usize); } let (title_ptr, title_len, title_cap) = _ffi_string_to_host(title.into()); unsafe { _ffi_cpp_Rc_Window__set_title(self.0, title_ptr, title_len, title_cap) }; } fn get_size(&self) -> (i32, i32) { extern "C" { fn _ffi_cpp_Rc_Window__get_size(_: *const u8) -> _ffi_ret_2_i32; } let multi_ret = unsafe { _ffi_cpp_Rc_Window__get_size(self.0) }; let ret_0 = multi_ret.0; let ret_1 = multi_ret.1; (ret_0, ret_1) } fn set_size(&self, width: i32, height: i32) { extern "C" { fn _ffi_cpp_Rc_Window__set_size(_: *const u8, width: i32, height: i32); } unsafe { _ffi_cpp_Rc_Window__set_size(self.0, width, height) }; } fn set_handler(&self, handler: Box) { extern "C" { fn _ffi_cpp_Rc_Window__set_handler(_: *const u8, handler_ptr: *const u8); } unsafe { _ffi_cpp_Rc_Window__set_handler(self.0, Box::into_raw(Box::new(handler)) as *const u8) }; } fn child_window(&self) -> std::rc::Rc { extern "C" { fn _ffi_cpp_Rc_Window__child_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_cpp_Rc_Window__child_window(self.0) }; std::rc::Rc::new(_ffi_rs_Rc_Window(ret_ptr)) } } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_TextRun_to_cpp(items: Vec, buf: &mut Vec) { for item in items { let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.rect.x, buf); _ffi_write(item.rect.y, buf); _ffi_write(item.rect.w, buf); _ffi_write(item.rect.h, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_demo_app_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_2_i32 { int32_t _0; int32_t _1; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); void _ffi_drop_Box_Handler(const void* ptr); void* _ffi_alloc(uintptr_t len); void _ffi_Box_Handler__on_draw(const void* _self, const void* canvas_ptr); void _ffi_fn_create_app(const void* platform_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } std::vector _ffi_vec_TextRun_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_text_ptr = _ffi_read(end); auto item_text_len = _ffi_read(end); auto item_text_cap = _ffi_read(end); auto item_text = _ffi_string_from_rust(item_text_ptr, item_text_len, item_text_cap); auto item_rect_x = _ffi_read(end); auto item_rect_y = _ffi_read(end); auto item_rect_w = _ffi_read(end); auto item_rect_h = _ffi_read(end); auto item_rect = rust::TextRect{item_rect_x, item_rect_y, item_rect_w, item_rect_h}; auto item = rust::TextRun{std::move(item_text), std::move(item_rect)}; items.emplace_back(std::move(item)); } return items; } struct _ffi_Box_Handler final : rust::Handler { _ffi_Box_Handler(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Handler() { _ffi_drop_Box_Handler(_self); } virtual void on_draw(std::unique_ptr canvas); const void* _self; }; const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } } // namespace extern "C" { void _ffi_cpp_Box_Canvas__draw_text_runs(rust::Canvas* _self, const void* buf_ptr, uintptr_t buf_cap, uintptr_t runs_len) { auto buf_end = (const uint8_t*)buf_ptr; auto runs = _ffi_vec_TextRun_from_rust(runs_len, buf_end); _self->draw_text_runs(std::move(runs)); _ffi_dealloc(buf_ptr, buf_cap); } const void* _ffi_cpp_Box_Platform__create_window(rust::Platform* _self) { return new std::shared_ptr(_self->create_window()); } const void* _ffi_cpp_Rc_Window__child_window(std::shared_ptr* _self) { return new std::shared_ptr(_self->get()->child_window()); } _ffi_ret_2_i32 _ffi_cpp_Rc_Window__get_size(std::shared_ptr* _self) { auto ret = _self->get()->get_size(); auto ret_0 = std::get<0>(ret); auto ret_1 = std::get<1>(ret); return _ffi_ret_2_i32{ret_0, ret_1}; } _ffi_ret_ptr_usize _ffi_cpp_Rc_Window__get_title(std::shared_ptr* _self) { uintptr_t ret_len; const void* ret_ptr = _ffi_string_to_rust(_self->get()->get_title(), ret_len); return _ffi_ret_ptr_usize{ret_ptr, ret_len}; } void _ffi_cpp_Rc_Window__set_handler(std::shared_ptr* _self, const void* handler_ptr) { auto handler = std::unique_ptr(new _ffi_Box_Handler(handler_ptr)); _self->get()->set_handler(std::move(handler)); } void _ffi_cpp_Rc_Window__set_size(std::shared_ptr* _self, int32_t width, int32_t height) { _self->get()->set_size(width, height); } void _ffi_cpp_Rc_Window__set_title(std::shared_ptr* _self, const char* title_ptr, uintptr_t title_len, uintptr_t title_cap) { auto title = _ffi_string_from_rust(title_ptr, title_len, title_cap); _self->get()->set_title(std::move(title)); } void _ffi_cpp_drop_Box_Canvas(rust::Canvas* self) { delete self; } void _ffi_cpp_drop_Box_Platform(rust::Platform* self) { delete self; } void _ffi_cpp_drop_Rc_Window(std::shared_ptr* self) { delete self; } } // extern "C" void _ffi_Box_Handler::on_draw(std::unique_ptr canvas) { auto canvas_ptr = canvas.release(); _ffi_Box_Handler__on_draw(_self, canvas_ptr); } void rust::create_app(std::unique_ptr platform) { auto platform_ptr = platform.release(); _ffi_fn_create_app(platform_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_app_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include #include namespace rust { struct TextRun; struct Canvas; struct Window; struct Handler; struct Canvas { virtual ~Canvas() {} virtual void draw_text_runs(std::vector runs) = 0; }; struct Handler { virtual ~Handler() {} virtual void on_draw(std::unique_ptr canvas) = 0; }; struct Platform { virtual ~Platform() {} virtual std::shared_ptr create_window() = 0; }; struct TextRect { int32_t x = 0; int32_t y = 0; int32_t w = 0; int32_t h = 0; }; struct TextRun { std::string text; TextRect rect; }; struct Window { virtual ~Window() {} virtual std::string get_title() = 0; virtual void set_title(std::string title) = 0; virtual std::tuple get_size() = 0; virtual void set_size(int32_t width, int32_t height) = 0; virtual void set_handler(std::unique_ptr handler) = 0; virtual std::shared_ptr child_window() = 0; }; uintptr_t rust_mem_leaked(); void create_app(std::unique_ptr platform); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_app_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *const u8) { let _self = unsafe { &*(_self as *const Box) }; _self.on_draw(Box::new(_ffi_rs_Box_Canvas(canvas_ptr))); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Box_Handler(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) { create_app(Box::new(_ffi_rs_Box_Platform(platform_ptr))); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_2_i32(i32, i32); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Box_Canvas(*const u8); impl Drop for _ffi_rs_Box_Canvas { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Box_Canvas(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Canvas(self.0) }; } } impl Canvas for _ffi_rs_Box_Canvas { fn draw_text_runs(&self, runs: Vec) { unsafe extern "C" { fn _ffi_cpp_Box_Canvas__draw_text_runs(_: *const u8, buf_ptr: *const u8, buf_cap: usize, runs_len: usize); } let mut buf = Vec::::new(); let runs_len = runs.len(); _ffi_vec_TextRun_to_cpp(runs, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _ffi_cpp_Box_Canvas__draw_text_runs(self.0, buf_ptr, buf_cap, runs_len) }; } } #[allow(non_camel_case_types)] struct _ffi_rs_Box_Platform(*const u8); impl Drop for _ffi_rs_Box_Platform { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Box_Platform(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Platform(self.0) }; } } impl Platform for _ffi_rs_Box_Platform { fn create_window(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_cpp_Box_Platform__create_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_cpp_Box_Platform__create_window(self.0) }; std::rc::Rc::new(_ffi_rs_Rc_Window(ret_ptr)) } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Window(*const u8); impl Drop for _ffi_rs_Rc_Window { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Window(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Window(self.0) }; } } impl Window for _ffi_rs_Rc_Window { fn get_title(&self) -> String { unsafe extern "C" { fn _ffi_cpp_Rc_Window__get_title(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_cpp_Rc_Window__get_title(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_title(&self, title: &str) { unsafe extern "C" { fn _ffi_cpp_Rc_Window__set_title(_: *const u8, title_ptr: *const u8, title_len: usize, title_cap: usize); } let (title_ptr, title_len, title_cap) = _ffi_string_to_host(title.into()); unsafe { _ffi_cpp_Rc_Window__set_title(self.0, title_ptr, title_len, title_cap) }; } fn get_size(&self) -> (i32, i32) { unsafe extern "C" { fn _ffi_cpp_Rc_Window__get_size(_: *const u8) -> _ffi_ret_2_i32; } let multi_ret = unsafe { _ffi_cpp_Rc_Window__get_size(self.0) }; let ret_0 = multi_ret.0; let ret_1 = multi_ret.1; (ret_0, ret_1) } fn set_size(&self, width: i32, height: i32) { unsafe extern "C" { fn _ffi_cpp_Rc_Window__set_size(_: *const u8, width: i32, height: i32); } unsafe { _ffi_cpp_Rc_Window__set_size(self.0, width, height) }; } fn set_handler(&self, handler: Box) { unsafe extern "C" { fn _ffi_cpp_Rc_Window__set_handler(_: *const u8, handler_ptr: *const u8); } unsafe { _ffi_cpp_Rc_Window__set_handler(self.0, Box::into_raw(Box::new(handler)) as *const u8) }; } fn child_window(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_cpp_Rc_Window__child_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_cpp_Rc_Window__child_window(self.0) }; std::rc::Rc::new(_ffi_rs_Rc_Window(ret_ptr)) } } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_TextRun_to_cpp(items: Vec, buf: &mut Vec) { for item in items { let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.rect.x, buf); _ffi_write(item.rect.y, buf); _ffi_write(item.rect.w, buf); _ffi_write(item.rect.h, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_demo_const_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_const_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { float const CONST_F32_NEG_0 = -0.0f; float const CONST_F32_PI = 3.1415927f; double const CONST_F64_NEG_0 = -0.0; double const CONST_F64_PI = -3.141592653589793; bool const CONST_FALSE = false; int16_t const CONST_I16_MAX = 32767; int16_t const CONST_I16_MIN = -32768; int32_t const CONST_I32_MAX = 2147483647; int32_t const CONST_I32_MIN = -2147483647 - 1; int64_t const CONST_I64_MAX = 9223372036854775807ll; int64_t const CONST_I64_MIN = -9223372036854775807ll - 1; int8_t const CONST_I8_MAX = 127; int8_t const CONST_I8_MIN = -128; std::string_view const CONST_STRING = std::string_view("\000\r\n🦀", 7); bool const CONST_TRUE = true; uint16_t const CONST_U16_MAX = 65535u; uint16_t const CONST_U16_MIN = 0u; uint32_t const CONST_U32_MAX = 4294967295u; uint32_t const CONST_U32_MIN = 0u; uint64_t const CONST_U64_MAX = 18446744073709551615ull; uint64_t const CONST_U64_MIN = 0ull; uint8_t const CONST_U8_MAX = 255u; uint8_t const CONST_U8_MIN = 0u; uintptr_t rust_mem_leaked(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_const_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_demo_const_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_const_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { float const CONST_F32_NEG_0 = -0.0f; float const CONST_F32_PI = 3.1415927f; double const CONST_F64_NEG_0 = -0.0; double const CONST_F64_PI = -3.141592653589793; bool const CONST_FALSE = false; int16_t const CONST_I16_MAX = 32767; int16_t const CONST_I16_MIN = -32768; int32_t const CONST_I32_MAX = 2147483647; int32_t const CONST_I32_MIN = -2147483647 - 1; int64_t const CONST_I64_MAX = 9223372036854775807ll; int64_t const CONST_I64_MIN = -9223372036854775807ll - 1; int8_t const CONST_I8_MAX = 127; int8_t const CONST_I8_MIN = -128; std::string_view const CONST_STRING = std::string_view("\000\r\n🦀", 7); bool const CONST_TRUE = true; uint16_t const CONST_U16_MAX = 65535u; uint16_t const CONST_U16_MIN = 0u; uint32_t const CONST_U32_MAX = 4294967295u; uint32_t const CONST_U32_MIN = 0u; uint64_t const CONST_U64_MAX = 18446744073709551615ull; uint64_t const CONST_U64_MIN = 0ull; uint8_t const CONST_U8_MAX = 255u; uint8_t const CONST_U8_MIN = 0u; uintptr_t rust_mem_leaked(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_const_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_demo_derive_eq_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include #include struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; struct _ffi_ret_ptr_usize_bool { const void* _0; uintptr_t _1; bool _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize _ffi_fn_box_opt(const void* buf_ptr); void* _ffi_alloc(uintptr_t len); _ffi_ret_ptr_usize _ffi_fn_box_opt_box(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_0(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_1(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_2(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec_box(const void* buf_ptr); void _ffi_fn_empty_struct(); void _ffi_fn_empty_tuple(); _ffi_ret_ptr_usize _ffi_fn_enum_box_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_opt_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_vec_tup(const void* buf_ptr); _ffi_ret_ptr_usize_bool _ffi_fn_opt_box(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_box_opt(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_0(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_1(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_2(const void* buf_ptr, bool has_x_0); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_usize _ffi_fn_tup_box(const void* buf_ptr); _ffi_ret_ptr_2_usize _ffi_fn_vec_box(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_box_vec(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_0(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_1(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_2(const void* buf_ptr, uintptr_t x_0_len); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::unique_ptr> _ffi_box_i32_i32_from_rust(const uint8_t*& end) { auto val_0 = _ffi_read(end); auto val_1 = _ffi_read(end); auto val = std::make_tuple(val_0, val_1); return std::make_unique>(std::move(val)); } rust::EnumBoxTup _ffi_enum_EnumBoxTup_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: { auto x = _ffi_box_i32_i32_from_rust(end); return rust::EnumBoxTup{rust::EnumBoxTup::Foo{std::move(x)}}; } case 1: return rust::EnumBoxTup{rust::EnumBoxTup::Bar{}}; case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::EnumBoxTup{rust::EnumBoxTup::Baz{x, y}}; } default: abort(); } } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_box_i32_i32_to_rust(std::tuple val, std::vector& buf) { _ffi_write(std::get<0>(val), buf); _ffi_write(std::get<1>(val), buf); } void _ffi_enum_EnumBoxTup_to_rust(rust::EnumBoxTup val, std::vector& buf) { if (auto it = val.as()) { _ffi_write(int32_t(0), buf); _ffi_box_i32_i32_to_rust(std::move(*it->_0), buf); } else if (val.is()) { _ffi_write(int32_t(1), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else { abort(); } } rust::EnumOptTup _ffi_enum_EnumOptTup_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: { std::optional> x; if (_ffi_read(end)) { auto x_val_0 = _ffi_read(end); auto x_val_1 = _ffi_read(end); x = std::make_optional(std::make_tuple(x_val_0, x_val_1)); } return rust::EnumOptTup{rust::EnumOptTup::Foo{std::move(x)}}; } case 1: return rust::EnumOptTup{rust::EnumOptTup::Bar{}}; case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::EnumOptTup{rust::EnumOptTup::Baz{x, y}}; } default: abort(); } } void _ffi_enum_EnumOptTup_to_rust(rust::EnumOptTup val, std::vector& buf) { if (auto it = val.as()) { _ffi_write(int32_t(0), buf); auto has_x = it->_0.has_value(); _ffi_write(has_x, buf); if (has_x) { _ffi_write(std::get<0>(it->_0.value()), buf); _ffi_write(std::get<1>(it->_0.value()), buf); } } else if (val.is()) { _ffi_write(int32_t(1), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else { abort(); } } std::vector> _ffi_vec_i32_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_0 = _ffi_read(end); auto item_1 = _ffi_read(end); auto item = std::make_tuple(item_0, item_1); items.emplace_back(std::move(item)); } return items; } rust::EnumVecTup _ffi_enum_EnumVecTup_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: { auto x_len = _ffi_read(end); auto x = _ffi_vec_i32_i32_from_rust(x_len, end); return rust::EnumVecTup{rust::EnumVecTup::Foo{std::move(x)}}; } case 1: return rust::EnumVecTup{rust::EnumVecTup::Bar{}}; case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::EnumVecTup{rust::EnumVecTup::Baz{x, y}}; } default: abort(); } } void _ffi_vec_i32_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item), buf); _ffi_write(std::get<1>(item), buf); } } void _ffi_enum_EnumVecTup_to_rust(rust::EnumVecTup val, std::vector& buf) { if (auto it = val.as()) { _ffi_write(int32_t(0), buf); auto x_len = it->_0.size(); _ffi_write(x_len, buf); _ffi_vec_i32_i32_to_rust(std::move(it->_0), buf); } else if (val.is()) { _ffi_write(int32_t(1), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else { abort(); } } std::unique_ptr> _ffi_box_option_i32_from_rust(const uint8_t*& end) { auto val = _ffi_read(end) ? std::make_optional(_ffi_read(end)) : std::nullopt; return std::make_unique>(std::move(val)); } void _ffi_box_option_i32_to_rust(std::optional val, std::vector& buf) { auto has_val = val.has_value(); _ffi_write(has_val, buf); if (has_val) { _ffi_write(val.value(), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } std::unique_ptr _ffi_box_i32_from_rust2(const uint8_t*& end) { auto val = _ffi_read(end); return std::make_unique(val); } std::unique_ptr>> _ffi_box_option_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_read(end) ? std::make_optional(_ffi_box_i32_from_rust2(end)) : std::nullopt; return std::make_unique>>(std::move(val)); } void _ffi_box_i32_to_rust2(int32_t val, std::vector& buf) { _ffi_write(val, buf); } void _ffi_box_option_box_i32_to_rust(std::optional> val, std::vector& buf) { auto has_val = val.has_value(); _ffi_write(has_val, buf); if (has_val) { _ffi_box_i32_to_rust2(std::move(*val.value()), buf); } } std::unique_ptr> _ffi_box__from_rust(const uint8_t*& end) { auto val = std::tuple<>(); return std::make_unique>(std::move(val)); } void _ffi_box__to_rust(std::tuple<> val, std::vector& buf) { (void)val; } std::unique_ptr> _ffi_box_i32_from_rust(const uint8_t*& end) { auto val_0 = _ffi_read(end); auto val = val_0; return std::make_unique>(std::move(val)); } void _ffi_box_i32_to_rust(std::tuple val, std::vector& buf) { _ffi_write(std::get<0>(val), buf); } std::vector _ffi_vec_i32_from_rust2(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item = _ffi_read(end); items.emplace_back(item); } return items; } std::unique_ptr> _ffi_box_vec_i32_from_rust(const uint8_t*& end) { auto val_len = _ffi_read(end); auto val = _ffi_vec_i32_from_rust2(val_len, end); return std::make_unique>(std::move(val)); } void _ffi_vec_i32_to_rust2(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_box_vec_i32_to_rust(std::vector val, std::vector& buf) { auto val_len = val.size(); _ffi_write(val_len, buf); _ffi_vec_i32_to_rust2(std::move(val), buf); } std::vector> _ffi_vec_box_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item = _ffi_box_i32_from_rust2(end); items.emplace_back(std::move(item)); } return items; } std::unique_ptr>> _ffi_box_vec_box_i32_from_rust(const uint8_t*& end) { auto val_len = _ffi_read(end); auto val = _ffi_vec_box_i32_from_rust(val_len, end); return std::make_unique>>(std::move(val)); } void _ffi_vec_box_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_box_i32_to_rust2(std::move(*item), buf); } } void _ffi_box_vec_box_i32_to_rust(std::vector> val, std::vector& buf) { auto val_len = val.size(); _ffi_write(val_len, buf); _ffi_vec_box_i32_to_rust(std::move(val), buf); } std::unique_ptr _ffi_box_bool_from_rust(const uint8_t*& end) { auto val = _ffi_read(end); return std::make_unique(val); } void _ffi_box_bool_to_rust(bool val, std::vector& buf) { _ffi_write(val, buf); } std::vector>> _ffi_vec_box_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector>> items; items.reserve(len); while (items.size() < len) { auto item = _ffi_box_vec_i32_from_rust(end); items.emplace_back(std::move(item)); } return items; } void _ffi_vec_box_vec_i32_to_rust(std::vector>>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_box_vec_i32_to_rust(std::move(*item), buf); } } std::vector> _ffi_vec__from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item = std::tuple<>(); items.emplace_back(std::move(item)); } return items; } void _ffi_vec__to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { (void)item; } } std::vector> _ffi_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_0 = _ffi_read(end); auto item = item_0; items.emplace_back(std::move(item)); } return items; } void _ffi_vec_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item), buf); } } } // namespace bool rust::BoxOpt::operator == (const rust::BoxOpt& b) const { return *_0 == *b._0; } bool rust::BoxOptBox::operator == (const rust::BoxOptBox& b) const { return (*_0 && *b._0 ? ***_0 == ***b._0 : !*_0 && !*b._0); } bool rust::BoxTup0::operator == (const rust::BoxTup0& b) const { return *_0 == *b._0; } bool rust::BoxTup1::operator == (const rust::BoxTup1& b) const { return *_0 == *b._0; } bool rust::BoxTup2::operator == (const rust::BoxTup2& b) const { return *_0 == *b._0; } bool rust::BoxVec::operator == (const rust::BoxVec& b) const { return *_0 == *b._0; } bool rust::BoxVecBox::operator == (const rust::BoxVecBox& b) const { return std::equal((*_0).begin(), (*_0).end(), (*b._0).begin(), (*b._0).end(), [](const auto& a, const auto& b) { return *a == *b; }); } bool rust::detail::EnumBoxTup__Baz::operator == (const rust::detail::EnumBoxTup__Baz& e) const { return x == e.x && y == e.y; } bool rust::detail::EnumBoxTup__Foo::operator == (const rust::detail::EnumBoxTup__Foo& e) const { return *_0 == *e._0; } bool rust::detail::EnumOptTup__Baz::operator == (const rust::detail::EnumOptTup__Baz& e) const { return x == e.x && y == e.y; } bool rust::detail::EnumOptTup__Foo::operator == (const rust::detail::EnumOptTup__Foo& e) const { return _0 == e._0; } bool rust::detail::EnumVecTup__Baz::operator == (const rust::detail::EnumVecTup__Baz& e) const { return x == e.x && y == e.y; } bool rust::detail::EnumVecTup__Foo::operator == (const rust::detail::EnumVecTup__Foo& e) const { return _0 == e._0; } bool rust::OptBox::operator == (const rust::OptBox& o) const { return (_0 && o._0 ? **_0 == **o._0 : !_0 && !o._0); } bool rust::OptBoxOpt::operator == (const rust::OptBoxOpt& o) const { return (_0 && o._0 ? **_0 == **o._0 : !_0 && !o._0); } bool rust::OptTup0::operator == (const rust::OptTup0& o) const { return _0 == o._0; } bool rust::OptTup1::operator == (const rust::OptTup1& o) const { return _0 == o._0; } bool rust::OptTup2::operator == (const rust::OptTup2& o) const { return _0 == o._0; } bool rust::TupBox::operator == (const rust::TupBox& t) const { return *std::get<0>(_0) == *std::get<0>(t._0) && *std::get<1>(_0) == *std::get<1>(t._0); } bool rust::VecBox::operator == (const rust::VecBox& v) const { return std::equal(_0.begin(), _0.end(), v._0.begin(), v._0.end(), [](const auto& a, const auto& b) { return *a == *b; }); } bool rust::VecBoxVec::operator == (const rust::VecBoxVec& v) const { return std::equal(_0.begin(), _0.end(), v._0.begin(), v._0.end(), [](const auto& a, const auto& b) { return *a == *b; }); } bool rust::VecTup0::operator == (const rust::VecTup0& v) const { return _0 == v._0; } bool rust::VecTup1::operator == (const rust::VecTup1& v) const { return _0 == v._0; } bool rust::VecTup2::operator == (const rust::VecTup2& v) const { return _0 == v._0; } rust::BoxOpt rust::box_opt(rust::BoxOpt x) { std::vector buf; _ffi_box_option_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_opt(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_option_i32_from_rust(buf_end2); auto ret = rust::BoxOpt{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxOptBox rust::box_opt_box(rust::BoxOptBox x) { std::vector buf; _ffi_box_option_box_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_opt_box(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_option_box_i32_from_rust(buf_end2); auto ret = rust::BoxOptBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxTup0 rust::box_tup_0(rust::BoxTup0 x) { std::vector buf; _ffi_box__to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_tup_0(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box__from_rust(buf_end2); auto ret = rust::BoxTup0{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxTup1 rust::box_tup_1(rust::BoxTup1 x) { std::vector buf; _ffi_box_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_tup_1(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_i32_from_rust(buf_end2); auto ret = rust::BoxTup1{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxTup2 rust::box_tup_2(rust::BoxTup2 x) { std::vector buf; _ffi_box_i32_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_tup_2(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_i32_i32_from_rust(buf_end2); auto ret = rust::BoxTup2{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxVec rust::box_vec(rust::BoxVec x) { std::vector buf; _ffi_box_vec_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_vec(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_vec_i32_from_rust(buf_end2); auto ret = rust::BoxVec{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxVecBox rust::box_vec_box(rust::BoxVecBox x) { std::vector buf; _ffi_box_vec_box_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_vec_box(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_vec_box_i32_from_rust(buf_end2); auto ret = rust::BoxVecBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::EmptyStruct rust::empty_struct(rust::EmptyStruct x) { (void)x; _ffi_fn_empty_struct(); return rust::EmptyStruct{}; } std::tuple<> rust::empty_tuple(std::tuple<> x) { (void)x; _ffi_fn_empty_tuple(); return std::tuple<>(); } rust::EnumBoxTup rust::enum_box_tup(rust::EnumBoxTup x) { std::vector buf; _ffi_enum_EnumBoxTup_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_enum_box_tup(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_enum_EnumBoxTup_from_rust(buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::EnumOptTup rust::enum_opt_tup(rust::EnumOptTup x) { std::vector buf; _ffi_enum_EnumOptTup_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_enum_opt_tup(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_enum_EnumOptTup_from_rust(buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::EnumVecTup rust::enum_vec_tup(rust::EnumVecTup x) { std::vector buf; _ffi_enum_EnumVecTup_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_enum_vec_tup(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_enum_EnumVecTup_from_rust(buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptBox rust::opt_box(rust::OptBox x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_box_i32_to_rust2(std::move(*x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_box(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = has_ret_0 ? std::make_optional(_ffi_box_i32_from_rust2(buf_end2)) : std::nullopt; auto ret = rust::OptBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptBoxOpt rust::opt_box_opt(rust::OptBoxOpt x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_box_option_i32_to_rust(std::move(*x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_box_opt(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = has_ret_0 ? std::make_optional(_ffi_box_option_i32_from_rust(buf_end2)) : std::nullopt; auto ret = rust::OptBoxOpt{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptTup0 rust::opt_tup_0(rust::OptTup0 x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { (void)x._0.value(); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_tup_0(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto ret_0 = has_ret_0 ? std::make_optional(std::tuple<>()) : std::nullopt; auto ret = rust::OptTup0{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptTup1 rust::opt_tup_1(rust::OptTup1 x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_write(std::get<0>(x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_tup_1(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; std::optional> ret_0; if (has_ret_0) { auto ret_0_val_0 = _ffi_read(buf_end2); ret_0 = std::make_optional(ret_0_val_0); } auto ret = rust::OptTup1{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptTup2 rust::opt_tup_2(rust::OptTup2 x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_write(std::get<0>(x._0.value()), buf); _ffi_write(std::get<1>(x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_tup_2(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; std::optional> ret_0; if (has_ret_0) { auto ret_0_val_0 = _ffi_read(buf_end2); auto ret_0_val_1 = _ffi_read(buf_end2); ret_0 = std::make_optional(std::make_tuple(ret_0_val_0, ret_0_val_1)); } auto ret = rust::OptTup2{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } rust::TupBox rust::tup_box(rust::TupBox x) { std::vector buf; _ffi_box_i32_to_rust2(std::move(*std::get<0>(x._0)), buf); _ffi_box_bool_to_rust(std::move(*std::get<1>(x._0)), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_tup_box(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0_0 = _ffi_box_i32_from_rust2(buf_end2); auto ret_0_1 = _ffi_box_bool_from_rust(buf_end2); auto ret_0 = std::make_tuple(std::move(ret_0_0), std::move(ret_0_1)); auto ret = rust::TupBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecBox rust::vec_box(rust::VecBox x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_box_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_box(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_box_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecBoxVec rust::vec_box_vec(rust::VecBoxVec x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_box_vec_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_box_vec(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_box_vec_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecBoxVec{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecTup0 rust::vec_tup_0(rust::VecTup0 x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec__to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_tup_0(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec__from_rust(ret_0_len, buf_end2); auto ret = rust::VecTup0{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecTup1 rust::vec_tup_1(rust::VecTup1 x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_tup_1(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecTup1{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecTup2 rust::vec_tup_2(rust::VecTup2 x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_i32_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_tup_2(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_i32_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecTup2{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } ================================================ FILE: src/tests/snapshots/cpp_demo_derive_eq_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include #include #include namespace rust { struct BoxOpt { std::unique_ptr> _0; bool operator == (const BoxOpt&) const; bool operator != (const BoxOpt& b) const { return !(*this == b); } }; struct BoxOptBox { std::unique_ptr>> _0; bool operator == (const BoxOptBox&) const; bool operator != (const BoxOptBox& b) const { return !(*this == b); } }; struct BoxTup0 { std::unique_ptr> _0; bool operator == (const BoxTup0&) const; bool operator != (const BoxTup0& b) const { return !(*this == b); } }; struct BoxTup1 { std::unique_ptr> _0; bool operator == (const BoxTup1&) const; bool operator != (const BoxTup1& b) const { return !(*this == b); } }; struct BoxTup2 { std::unique_ptr> _0; bool operator == (const BoxTup2&) const; bool operator != (const BoxTup2& b) const { return !(*this == b); } }; struct BoxVec { std::unique_ptr> _0; bool operator == (const BoxVec&) const; bool operator != (const BoxVec& b) const { return !(*this == b); } }; struct BoxVecBox { std::unique_ptr>> _0; bool operator == (const BoxVecBox&) const; bool operator != (const BoxVecBox& b) const { return !(*this == b); } }; struct EmptyStruct { bool operator == (const EmptyStruct&) const { return true; } bool operator != (const EmptyStruct& e) const { return !(*this == e); } }; namespace detail { struct EnumBoxTup__Foo { std::unique_ptr> _0; bool operator == (const EnumBoxTup__Foo&) const; bool operator != (const EnumBoxTup__Foo& e) const { return !(*this == e); } }; struct EnumBoxTup__Bar { bool operator == (const EnumBoxTup__Bar&) const { return true; } bool operator != (const EnumBoxTup__Bar& e) const { return !(*this == e); } }; struct EnumBoxTup__Baz { int32_t x = 0; int32_t y = 0; bool operator == (const EnumBoxTup__Baz&) const; bool operator != (const EnumBoxTup__Baz& e) const { return !(*this == e); } }; } // namespace detail struct EnumBoxTup : std::variant { using Foo = detail::EnumBoxTup__Foo; using Bar = detail::EnumBoxTup__Bar; using Baz = detail::EnumBoxTup__Baz; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct EnumOptTup__Foo { std::optional> _0; bool operator == (const EnumOptTup__Foo&) const; bool operator != (const EnumOptTup__Foo& e) const { return !(*this == e); } }; struct EnumOptTup__Bar { bool operator == (const EnumOptTup__Bar&) const { return true; } bool operator != (const EnumOptTup__Bar& e) const { return !(*this == e); } }; struct EnumOptTup__Baz { int32_t x = 0; int32_t y = 0; bool operator == (const EnumOptTup__Baz&) const; bool operator != (const EnumOptTup__Baz& e) const { return !(*this == e); } }; } // namespace detail struct EnumOptTup : std::variant { using Foo = detail::EnumOptTup__Foo; using Bar = detail::EnumOptTup__Bar; using Baz = detail::EnumOptTup__Baz; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct EnumVecTup__Foo { std::vector> _0; bool operator == (const EnumVecTup__Foo&) const; bool operator != (const EnumVecTup__Foo& e) const { return !(*this == e); } }; struct EnumVecTup__Bar { bool operator == (const EnumVecTup__Bar&) const { return true; } bool operator != (const EnumVecTup__Bar& e) const { return !(*this == e); } }; struct EnumVecTup__Baz { int32_t x = 0; int32_t y = 0; bool operator == (const EnumVecTup__Baz&) const; bool operator != (const EnumVecTup__Baz& e) const { return !(*this == e); } }; } // namespace detail struct EnumVecTup : std::variant { using Foo = detail::EnumVecTup__Foo; using Bar = detail::EnumVecTup__Bar; using Baz = detail::EnumVecTup__Baz; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct OptBox { std::optional> _0; bool operator == (const OptBox&) const; bool operator != (const OptBox& o) const { return !(*this == o); } }; struct OptBoxOpt { std::optional>> _0; bool operator == (const OptBoxOpt&) const; bool operator != (const OptBoxOpt& o) const { return !(*this == o); } }; struct OptTup0 { std::optional> _0; bool operator == (const OptTup0&) const; bool operator != (const OptTup0& o) const { return !(*this == o); } }; struct OptTup1 { std::optional> _0; bool operator == (const OptTup1&) const; bool operator != (const OptTup1& o) const { return !(*this == o); } }; struct OptTup2 { std::optional> _0; bool operator == (const OptTup2&) const; bool operator != (const OptTup2& o) const { return !(*this == o); } }; struct TupBox { std::tuple, std::unique_ptr> _0; bool operator == (const TupBox&) const; bool operator != (const TupBox& t) const { return !(*this == t); } }; struct VecBox { std::vector> _0; bool operator == (const VecBox&) const; bool operator != (const VecBox& v) const { return !(*this == v); } }; struct VecBoxVec { std::vector>> _0; bool operator == (const VecBoxVec&) const; bool operator != (const VecBoxVec& v) const { return !(*this == v); } }; struct VecTup0 { std::vector> _0; bool operator == (const VecTup0&) const; bool operator != (const VecTup0& v) const { return !(*this == v); } }; struct VecTup1 { std::vector> _0; bool operator == (const VecTup1&) const; bool operator != (const VecTup1& v) const { return !(*this == v); } }; struct VecTup2 { std::vector> _0; bool operator == (const VecTup2&) const; bool operator != (const VecTup2& v) const { return !(*this == v); } }; uintptr_t rust_mem_leaked(); std::tuple<> empty_tuple(std::tuple<> x); EmptyStruct empty_struct(EmptyStruct x); BoxTup0 box_tup_0(BoxTup0 x); BoxTup1 box_tup_1(BoxTup1 x); BoxTup2 box_tup_2(BoxTup2 x); VecTup0 vec_tup_0(VecTup0 x); VecTup1 vec_tup_1(VecTup1 x); VecTup2 vec_tup_2(VecTup2 x); OptTup0 opt_tup_0(OptTup0 x); OptTup1 opt_tup_1(OptTup1 x); OptTup2 opt_tup_2(OptTup2 x); EnumBoxTup enum_box_tup(EnumBoxTup x); EnumVecTup enum_vec_tup(EnumVecTup x); EnumOptTup enum_opt_tup(EnumOptTup x); TupBox tup_box(TupBox x); VecBox vec_box(VecBox x); BoxVec box_vec(BoxVec x); OptBox opt_box(OptBox x); BoxOpt box_opt(BoxOpt x); VecBoxVec vec_box_vec(VecBoxVec x); BoxVecBox box_vec_box(BoxVecBox x); OptBoxOpt opt_box_opt(OptBoxOpt x); BoxOptBox box_opt_box(BoxOptBox x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_derive_eq_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box__from_cpp(_: &mut *const u8) -> Box<()> { Box::new(()) } #[allow(non_snake_case)] fn _ffi_box__to_cpp(val: (), _: &mut Vec) { _ = val; } fn _ffi_box_bool_from_cpp(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_bool_to_cpp(val: bool, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box<(i32,)> { Box::new((_ffi_read::(end),)) } fn _ffi_box_i32_from_cpp2(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_i32_i32_from_cpp(end: &mut *const u8) -> Box<(i32, i32)> { Box::new((_ffi_read::(end), _ffi_read::(end))) } fn _ffi_box_i32_i32_to_cpp(val: (i32, i32), buf: &mut Vec) { _ffi_write(val.0, buf); _ffi_write(val.1, buf); } fn _ffi_box_i32_to_cpp(val: (i32,), buf: &mut Vec) { _ffi_write(val.0, buf); } fn _ffi_box_i32_to_cpp2(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_option_box_i32_from_cpp(end: &mut *const u8) -> Box>> { Box::new(_ffi_read::(end).then(|| _ffi_box_i32_from_cpp2(end))) } fn _ffi_box_option_box_i32_to_cpp(val: Option>, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_box_i32_to_cpp2(*val_val, buf); } } fn _ffi_box_option_i32_from_cpp(end: &mut *const u8) -> Box> { Box::new(_ffi_read::(end).then(|| _ffi_read::(end))) } fn _ffi_box_option_i32_to_cpp(val: Option, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_write(val_val, buf); } } fn _ffi_box_vec_box_i32_from_cpp(end: &mut *const u8) -> Box>> { Box::new(_ffi_vec_box_i32_from_cpp(_ffi_read::(end), end)) } fn _ffi_box_vec_box_i32_to_cpp(val: Vec>, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_box_i32_to_cpp(val, buf); } fn _ffi_box_vec_i32_from_cpp(end: &mut *const u8) -> Box> { Box::new(_ffi_vec_i32_from_cpp2(_ffi_read::(end), end)) } fn _ffi_box_vec_i32_to_cpp(val: Vec, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_i32_to_cpp2(val, buf); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_from_cpp(end: &mut *const u8) -> EnumBoxTup { match _ffi_read::(end) { 0 => EnumBoxTup::Foo(_ffi_box_i32_i32_from_cpp(end)), 1 => EnumBoxTup::Bar, 2 => EnumBoxTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_to_cpp(val: EnumBoxTup, buf: &mut Vec) { match val { EnumBoxTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_box_i32_i32_to_cpp(*x, buf); } EnumBoxTup::Bar => _ffi_write(1 as i32, buf), EnumBoxTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_from_cpp(end: &mut *const u8) -> EnumOptTup { match _ffi_read::(end) { 0 => EnumOptTup::Foo(_ffi_read::(end).then(|| (_ffi_read::(end), _ffi_read::(end)))), 1 => EnumOptTup::Bar, 2 => EnumOptTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_to_cpp(val: EnumOptTup, buf: &mut Vec) { match val { EnumOptTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.is_some(), buf); if let Some(x_val) = x { _ffi_write(x_val.0, buf); _ffi_write(x_val.1, buf); } } EnumOptTup::Bar => _ffi_write(1 as i32, buf), EnumOptTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_from_cpp(end: &mut *const u8) -> EnumVecTup { match _ffi_read::(end) { 0 => EnumVecTup::Foo(_ffi_vec_i32_i32_from_cpp(_ffi_read::(end), end)), 1 => EnumVecTup::Bar, 2 => EnumVecTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_to_cpp(val: EnumVecTup, buf: &mut Vec) { match val { EnumVecTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.len(), buf); _ffi_vec_i32_i32_to_cpp(x, buf); } EnumVecTup::Bar => _ffi_write(1 as i32, buf), EnumVecTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt(BoxOpt(_ffi_box_option_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt_box(BoxOptBox(_ffi_box_option_box_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_box_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_0(BoxTup0(_ffi_box__from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box__to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_1(BoxTup1(_ffi_box_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_2(BoxTup2(_ffi_box_i32_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec(BoxVec(_ffi_box_vec_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec_box(BoxVecBox(_ffi_box_vec_box_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_box_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(EmptyStruct); } #[no_mangle] extern "C" fn _ffi_fn_empty_tuple() { _ = empty_tuple(()); } #[no_mangle] extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumBoxTup_to_cpp(enum_box_tup(_ffi_enum_EnumBoxTup_from_cpp(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumOptTup_to_cpp(enum_opt_tup(_ffi_enum_EnumOptTup_from_cpp(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumVecTup_to_cpp(enum_vec_tup(_ffi_enum_EnumVecTup_from_cpp(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box(OptBox(has_x_0.then(|| _ffi_box_i32_from_cpp2(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_i32_to_cpp2(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box_opt(OptBoxOpt(has_x_0.then(|| _ffi_box_option_i32_from_cpp(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_option_i32_to_cpp(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let buf_end = buf_ptr; let ret = opt_tup_0(OptTup0(has_x_0.then(|| ()))); let ret_0 = ret.0; let buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ = ret_0_val; } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_1(OptTup1(has_x_0.then(|| (_ffi_read::(&mut buf_end),)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_2(OptTup2(has_x_0.then(|| (_ffi_read::(&mut buf_end), _ffi_read::(&mut buf_end))))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); _ffi_write(ret_0_val.1, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = tup_box(TupBox((_ffi_box_i32_from_cpp2(&mut buf_end), _ffi_box_bool_from_cpp(&mut buf_end)))); let ret_0 = ret.0; let ret_0_0 = ret_0.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_cpp2(*ret_0_0, &mut buf2); let ret_0_1 = ret_0.1; _ffi_box_bool_to_cpp(*ret_0_1, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box(VecBox(_ffi_vec_box_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box_vec(VecBoxVec(_ffi_vec_box_vec_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_vec_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_0(VecTup0(_ffi_vec__from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec__to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_1(VecTup1(_ffi_vec_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_2(VecTup2(_ffi_vec_i32_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); #[allow(non_snake_case)] fn _ffi_vec__from_cpp(len: usize, _: &mut *const u8) -> Vec<()> { let mut items = Vec::<()>::with_capacity(len); for _ in 0..len { items.push(()); } items } #[allow(non_snake_case)] fn _ffi_vec__to_cpp(items: Vec<()>, _: &mut Vec) { for item in items { _ = item; } } fn _ffi_vec_box_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_i32_from_cpp2(end)); } items } fn _ffi_vec_box_i32_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_box_i32_to_cpp2(*item, buf); } } fn _ffi_vec_box_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec>> { let mut items = Vec::>>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_vec_i32_from_cpp(end)); } items } fn _ffi_vec_box_vec_i32_to_cpp(items: Vec>>, buf: &mut Vec) { for item in items { _ffi_box_vec_i32_to_cpp(*item, buf); } } fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32,)> { let mut items = Vec::<(i32,)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end),)); } items } fn _ffi_vec_i32_from_cpp2(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32, i32)> { let mut items = Vec::<(i32, i32)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end), _ffi_read::(end))); } items } fn _ffi_vec_i32_i32_to_cpp(items: Vec<(i32, i32)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); _ffi_write(item.1, buf); } } fn _ffi_vec_i32_to_cpp(items: Vec<(i32,)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); } } fn _ffi_vec_i32_to_cpp2(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } ================================================ FILE: src/tests/snapshots/cpp_demo_derive_eq_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include #include struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; struct _ffi_ret_ptr_usize_bool { const void* _0; uintptr_t _1; bool _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize _ffi_fn_box_opt(const void* buf_ptr); void* _ffi_alloc(uintptr_t len); _ffi_ret_ptr_usize _ffi_fn_box_opt_box(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_0(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_1(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_2(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec_box(const void* buf_ptr); void _ffi_fn_empty_struct(); void _ffi_fn_empty_tuple(); _ffi_ret_ptr_usize _ffi_fn_enum_box_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_opt_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_vec_tup(const void* buf_ptr); _ffi_ret_ptr_usize_bool _ffi_fn_opt_box(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_box_opt(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_0(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_1(const void* buf_ptr, bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_2(const void* buf_ptr, bool has_x_0); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_usize _ffi_fn_tup_box(const void* buf_ptr); _ffi_ret_ptr_2_usize _ffi_fn_vec_box(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_box_vec(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_0(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_1(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_2(const void* buf_ptr, uintptr_t x_0_len); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::unique_ptr> _ffi_box_i32_i32_from_rust(const uint8_t*& end) { auto val_0 = _ffi_read(end); auto val_1 = _ffi_read(end); auto val = std::make_tuple(val_0, val_1); return std::make_unique>(std::move(val)); } rust::EnumBoxTup _ffi_enum_EnumBoxTup_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: { auto x = _ffi_box_i32_i32_from_rust(end); return rust::EnumBoxTup{rust::EnumBoxTup::Foo{std::move(x)}}; } case 1: return rust::EnumBoxTup{rust::EnumBoxTup::Bar{}}; case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::EnumBoxTup{rust::EnumBoxTup::Baz{x, y}}; } default: abort(); } } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_box_i32_i32_to_rust(std::tuple val, std::vector& buf) { _ffi_write(std::get<0>(val), buf); _ffi_write(std::get<1>(val), buf); } void _ffi_enum_EnumBoxTup_to_rust(rust::EnumBoxTup val, std::vector& buf) { if (auto it = val.as()) { _ffi_write(int32_t(0), buf); _ffi_box_i32_i32_to_rust(std::move(*it->_0), buf); } else if (val.is()) { _ffi_write(int32_t(1), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else { abort(); } } rust::EnumOptTup _ffi_enum_EnumOptTup_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: { std::optional> x; if (_ffi_read(end)) { auto x_val_0 = _ffi_read(end); auto x_val_1 = _ffi_read(end); x = std::make_optional(std::make_tuple(x_val_0, x_val_1)); } return rust::EnumOptTup{rust::EnumOptTup::Foo{std::move(x)}}; } case 1: return rust::EnumOptTup{rust::EnumOptTup::Bar{}}; case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::EnumOptTup{rust::EnumOptTup::Baz{x, y}}; } default: abort(); } } void _ffi_enum_EnumOptTup_to_rust(rust::EnumOptTup val, std::vector& buf) { if (auto it = val.as()) { _ffi_write(int32_t(0), buf); auto has_x = it->_0.has_value(); _ffi_write(has_x, buf); if (has_x) { _ffi_write(std::get<0>(it->_0.value()), buf); _ffi_write(std::get<1>(it->_0.value()), buf); } } else if (val.is()) { _ffi_write(int32_t(1), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else { abort(); } } std::vector> _ffi_vec_i32_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_0 = _ffi_read(end); auto item_1 = _ffi_read(end); auto item = std::make_tuple(item_0, item_1); items.emplace_back(std::move(item)); } return items; } rust::EnumVecTup _ffi_enum_EnumVecTup_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: { auto x_len = _ffi_read(end); auto x = _ffi_vec_i32_i32_from_rust(x_len, end); return rust::EnumVecTup{rust::EnumVecTup::Foo{std::move(x)}}; } case 1: return rust::EnumVecTup{rust::EnumVecTup::Bar{}}; case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::EnumVecTup{rust::EnumVecTup::Baz{x, y}}; } default: abort(); } } void _ffi_vec_i32_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item), buf); _ffi_write(std::get<1>(item), buf); } } void _ffi_enum_EnumVecTup_to_rust(rust::EnumVecTup val, std::vector& buf) { if (auto it = val.as()) { _ffi_write(int32_t(0), buf); auto x_len = it->_0.size(); _ffi_write(x_len, buf); _ffi_vec_i32_i32_to_rust(std::move(it->_0), buf); } else if (val.is()) { _ffi_write(int32_t(1), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else { abort(); } } std::unique_ptr> _ffi_box_option_i32_from_rust(const uint8_t*& end) { auto val = _ffi_read(end) ? std::make_optional(_ffi_read(end)) : std::nullopt; return std::make_unique>(std::move(val)); } void _ffi_box_option_i32_to_rust(std::optional val, std::vector& buf) { auto has_val = val.has_value(); _ffi_write(has_val, buf); if (has_val) { _ffi_write(val.value(), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } std::unique_ptr _ffi_box_i32_from_rust2(const uint8_t*& end) { auto val = _ffi_read(end); return std::make_unique(val); } std::unique_ptr>> _ffi_box_option_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_read(end) ? std::make_optional(_ffi_box_i32_from_rust2(end)) : std::nullopt; return std::make_unique>>(std::move(val)); } void _ffi_box_i32_to_rust2(int32_t val, std::vector& buf) { _ffi_write(val, buf); } void _ffi_box_option_box_i32_to_rust(std::optional> val, std::vector& buf) { auto has_val = val.has_value(); _ffi_write(has_val, buf); if (has_val) { _ffi_box_i32_to_rust2(std::move(*val.value()), buf); } } std::unique_ptr> _ffi_box__from_rust(const uint8_t*& end) { auto val = std::tuple<>(); return std::make_unique>(std::move(val)); } void _ffi_box__to_rust(std::tuple<> val, std::vector& buf) { (void)val; } std::unique_ptr> _ffi_box_i32_from_rust(const uint8_t*& end) { auto val_0 = _ffi_read(end); auto val = val_0; return std::make_unique>(std::move(val)); } void _ffi_box_i32_to_rust(std::tuple val, std::vector& buf) { _ffi_write(std::get<0>(val), buf); } std::vector _ffi_vec_i32_from_rust2(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item = _ffi_read(end); items.emplace_back(item); } return items; } std::unique_ptr> _ffi_box_vec_i32_from_rust(const uint8_t*& end) { auto val_len = _ffi_read(end); auto val = _ffi_vec_i32_from_rust2(val_len, end); return std::make_unique>(std::move(val)); } void _ffi_vec_i32_to_rust2(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_box_vec_i32_to_rust(std::vector val, std::vector& buf) { auto val_len = val.size(); _ffi_write(val_len, buf); _ffi_vec_i32_to_rust2(std::move(val), buf); } std::vector> _ffi_vec_box_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item = _ffi_box_i32_from_rust2(end); items.emplace_back(std::move(item)); } return items; } std::unique_ptr>> _ffi_box_vec_box_i32_from_rust(const uint8_t*& end) { auto val_len = _ffi_read(end); auto val = _ffi_vec_box_i32_from_rust(val_len, end); return std::make_unique>>(std::move(val)); } void _ffi_vec_box_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_box_i32_to_rust2(std::move(*item), buf); } } void _ffi_box_vec_box_i32_to_rust(std::vector> val, std::vector& buf) { auto val_len = val.size(); _ffi_write(val_len, buf); _ffi_vec_box_i32_to_rust(std::move(val), buf); } std::unique_ptr _ffi_box_bool_from_rust(const uint8_t*& end) { auto val = _ffi_read(end); return std::make_unique(val); } void _ffi_box_bool_to_rust(bool val, std::vector& buf) { _ffi_write(val, buf); } std::vector>> _ffi_vec_box_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector>> items; items.reserve(len); while (items.size() < len) { auto item = _ffi_box_vec_i32_from_rust(end); items.emplace_back(std::move(item)); } return items; } void _ffi_vec_box_vec_i32_to_rust(std::vector>>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_box_vec_i32_to_rust(std::move(*item), buf); } } std::vector> _ffi_vec__from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item = std::tuple<>(); items.emplace_back(std::move(item)); } return items; } void _ffi_vec__to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { (void)item; } } std::vector> _ffi_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_0 = _ffi_read(end); auto item = item_0; items.emplace_back(std::move(item)); } return items; } void _ffi_vec_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item), buf); } } } // namespace bool rust::BoxOpt::operator == (const rust::BoxOpt& b) const { return *_0 == *b._0; } bool rust::BoxOptBox::operator == (const rust::BoxOptBox& b) const { return (*_0 && *b._0 ? ***_0 == ***b._0 : !*_0 && !*b._0); } bool rust::BoxTup0::operator == (const rust::BoxTup0& b) const { return *_0 == *b._0; } bool rust::BoxTup1::operator == (const rust::BoxTup1& b) const { return *_0 == *b._0; } bool rust::BoxTup2::operator == (const rust::BoxTup2& b) const { return *_0 == *b._0; } bool rust::BoxVec::operator == (const rust::BoxVec& b) const { return *_0 == *b._0; } bool rust::BoxVecBox::operator == (const rust::BoxVecBox& b) const { return std::equal((*_0).begin(), (*_0).end(), (*b._0).begin(), (*b._0).end(), [](const auto& a, const auto& b) { return *a == *b; }); } bool rust::detail::EnumBoxTup__Baz::operator == (const rust::detail::EnumBoxTup__Baz& e) const { return x == e.x && y == e.y; } bool rust::detail::EnumBoxTup__Foo::operator == (const rust::detail::EnumBoxTup__Foo& e) const { return *_0 == *e._0; } bool rust::detail::EnumOptTup__Baz::operator == (const rust::detail::EnumOptTup__Baz& e) const { return x == e.x && y == e.y; } bool rust::detail::EnumOptTup__Foo::operator == (const rust::detail::EnumOptTup__Foo& e) const { return _0 == e._0; } bool rust::detail::EnumVecTup__Baz::operator == (const rust::detail::EnumVecTup__Baz& e) const { return x == e.x && y == e.y; } bool rust::detail::EnumVecTup__Foo::operator == (const rust::detail::EnumVecTup__Foo& e) const { return _0 == e._0; } bool rust::OptBox::operator == (const rust::OptBox& o) const { return (_0 && o._0 ? **_0 == **o._0 : !_0 && !o._0); } bool rust::OptBoxOpt::operator == (const rust::OptBoxOpt& o) const { return (_0 && o._0 ? **_0 == **o._0 : !_0 && !o._0); } bool rust::OptTup0::operator == (const rust::OptTup0& o) const { return _0 == o._0; } bool rust::OptTup1::operator == (const rust::OptTup1& o) const { return _0 == o._0; } bool rust::OptTup2::operator == (const rust::OptTup2& o) const { return _0 == o._0; } bool rust::TupBox::operator == (const rust::TupBox& t) const { return *std::get<0>(_0) == *std::get<0>(t._0) && *std::get<1>(_0) == *std::get<1>(t._0); } bool rust::VecBox::operator == (const rust::VecBox& v) const { return std::equal(_0.begin(), _0.end(), v._0.begin(), v._0.end(), [](const auto& a, const auto& b) { return *a == *b; }); } bool rust::VecBoxVec::operator == (const rust::VecBoxVec& v) const { return std::equal(_0.begin(), _0.end(), v._0.begin(), v._0.end(), [](const auto& a, const auto& b) { return *a == *b; }); } bool rust::VecTup0::operator == (const rust::VecTup0& v) const { return _0 == v._0; } bool rust::VecTup1::operator == (const rust::VecTup1& v) const { return _0 == v._0; } bool rust::VecTup2::operator == (const rust::VecTup2& v) const { return _0 == v._0; } rust::BoxOpt rust::box_opt(rust::BoxOpt x) { std::vector buf; _ffi_box_option_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_opt(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_option_i32_from_rust(buf_end2); auto ret = rust::BoxOpt{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxOptBox rust::box_opt_box(rust::BoxOptBox x) { std::vector buf; _ffi_box_option_box_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_opt_box(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_option_box_i32_from_rust(buf_end2); auto ret = rust::BoxOptBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxTup0 rust::box_tup_0(rust::BoxTup0 x) { std::vector buf; _ffi_box__to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_tup_0(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box__from_rust(buf_end2); auto ret = rust::BoxTup0{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxTup1 rust::box_tup_1(rust::BoxTup1 x) { std::vector buf; _ffi_box_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_tup_1(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_i32_from_rust(buf_end2); auto ret = rust::BoxTup1{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxTup2 rust::box_tup_2(rust::BoxTup2 x) { std::vector buf; _ffi_box_i32_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_tup_2(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_i32_i32_from_rust(buf_end2); auto ret = rust::BoxTup2{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxVec rust::box_vec(rust::BoxVec x) { std::vector buf; _ffi_box_vec_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_vec(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_vec_i32_from_rust(buf_end2); auto ret = rust::BoxVec{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::BoxVecBox rust::box_vec_box(rust::BoxVecBox x) { std::vector buf; _ffi_box_vec_box_i32_to_rust(std::move(*x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_box_vec_box(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_box_vec_box_i32_from_rust(buf_end2); auto ret = rust::BoxVecBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::EmptyStruct rust::empty_struct(rust::EmptyStruct x) { (void)x; _ffi_fn_empty_struct(); return rust::EmptyStruct{}; } std::tuple<> rust::empty_tuple(std::tuple<> x) { (void)x; _ffi_fn_empty_tuple(); return std::tuple<>(); } rust::EnumBoxTup rust::enum_box_tup(rust::EnumBoxTup x) { std::vector buf; _ffi_enum_EnumBoxTup_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_enum_box_tup(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_enum_EnumBoxTup_from_rust(buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::EnumOptTup rust::enum_opt_tup(rust::EnumOptTup x) { std::vector buf; _ffi_enum_EnumOptTup_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_enum_opt_tup(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_enum_EnumOptTup_from_rust(buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::EnumVecTup rust::enum_vec_tup(rust::EnumVecTup x) { std::vector buf; _ffi_enum_EnumVecTup_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_enum_vec_tup(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_enum_EnumVecTup_from_rust(buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptBox rust::opt_box(rust::OptBox x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_box_i32_to_rust2(std::move(*x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_box(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = has_ret_0 ? std::make_optional(_ffi_box_i32_from_rust2(buf_end2)) : std::nullopt; auto ret = rust::OptBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptBoxOpt rust::opt_box_opt(rust::OptBoxOpt x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_box_option_i32_to_rust(std::move(*x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_box_opt(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = has_ret_0 ? std::make_optional(_ffi_box_option_i32_from_rust(buf_end2)) : std::nullopt; auto ret = rust::OptBoxOpt{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptTup0 rust::opt_tup_0(rust::OptTup0 x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { (void)x._0.value(); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_tup_0(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto ret_0 = has_ret_0 ? std::make_optional(std::tuple<>()) : std::nullopt; auto ret = rust::OptTup0{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptTup1 rust::opt_tup_1(rust::OptTup1 x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_write(std::get<0>(x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_tup_1(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; std::optional> ret_0; if (has_ret_0) { auto ret_0_val_0 = _ffi_read(buf_end2); ret_0 = std::make_optional(ret_0_val_0); } auto ret = rust::OptTup1{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::OptTup2 rust::opt_tup_2(rust::OptTup2 x) { std::vector buf; auto has_x_0 = x._0.has_value(); if (has_x_0) { _ffi_write(std::get<0>(x._0.value()), buf); _ffi_write(std::get<1>(x._0.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_opt_tup_2(buf_ptr, has_x_0); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret_0 = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; std::optional> ret_0; if (has_ret_0) { auto ret_0_val_0 = _ffi_read(buf_end2); auto ret_0_val_1 = _ffi_read(buf_end2); ret_0 = std::make_optional(std::make_tuple(ret_0_val_0, ret_0_val_1)); } auto ret = rust::OptTup2{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } rust::TupBox rust::tup_box(rust::TupBox x) { std::vector buf; _ffi_box_i32_to_rust2(std::move(*std::get<0>(x._0)), buf); _ffi_box_bool_to_rust(std::move(*std::get<1>(x._0)), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_tup_box(buf_ptr); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0_0 = _ffi_box_i32_from_rust2(buf_end2); auto ret_0_1 = _ffi_box_bool_from_rust(buf_end2); auto ret_0 = std::make_tuple(std::move(ret_0_0), std::move(ret_0_1)); auto ret = rust::TupBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecBox rust::vec_box(rust::VecBox x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_box_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_box(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_box_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecBox{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecBoxVec rust::vec_box_vec(rust::VecBoxVec x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_box_vec_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_box_vec(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_box_vec_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecBoxVec{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecTup0 rust::vec_tup_0(rust::VecTup0 x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec__to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_tup_0(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec__from_rust(ret_0_len, buf_end2); auto ret = rust::VecTup0{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecTup1 rust::vec_tup_1(rust::VecTup1 x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_tup_1(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecTup1{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } rust::VecTup2 rust::vec_tup_2(rust::VecTup2 x) { std::vector buf; auto x_0_len = x._0.size(); _ffi_vec_i32_i32_to_rust(std::move(x._0), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_vec_tup_2(buf_ptr, x_0_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_0_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret_0 = _ffi_vec_i32_i32_from_rust(ret_0_len, buf_end2); auto ret = rust::VecTup2{std::move(ret_0)}; _ffi_dealloc(buf_ptr2, buf_cap); return ret; } ================================================ FILE: src/tests/snapshots/cpp_demo_derive_eq_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include #include #include namespace rust { struct BoxOpt { std::unique_ptr> _0; bool operator == (const BoxOpt&) const; bool operator != (const BoxOpt& b) const { return !(*this == b); } }; struct BoxOptBox { std::unique_ptr>> _0; bool operator == (const BoxOptBox&) const; bool operator != (const BoxOptBox& b) const { return !(*this == b); } }; struct BoxTup0 { std::unique_ptr> _0; bool operator == (const BoxTup0&) const; bool operator != (const BoxTup0& b) const { return !(*this == b); } }; struct BoxTup1 { std::unique_ptr> _0; bool operator == (const BoxTup1&) const; bool operator != (const BoxTup1& b) const { return !(*this == b); } }; struct BoxTup2 { std::unique_ptr> _0; bool operator == (const BoxTup2&) const; bool operator != (const BoxTup2& b) const { return !(*this == b); } }; struct BoxVec { std::unique_ptr> _0; bool operator == (const BoxVec&) const; bool operator != (const BoxVec& b) const { return !(*this == b); } }; struct BoxVecBox { std::unique_ptr>> _0; bool operator == (const BoxVecBox&) const; bool operator != (const BoxVecBox& b) const { return !(*this == b); } }; struct EmptyStruct { bool operator == (const EmptyStruct&) const { return true; } bool operator != (const EmptyStruct& e) const { return !(*this == e); } }; namespace detail { struct EnumBoxTup__Foo { std::unique_ptr> _0; bool operator == (const EnumBoxTup__Foo&) const; bool operator != (const EnumBoxTup__Foo& e) const { return !(*this == e); } }; struct EnumBoxTup__Bar { bool operator == (const EnumBoxTup__Bar&) const { return true; } bool operator != (const EnumBoxTup__Bar& e) const { return !(*this == e); } }; struct EnumBoxTup__Baz { int32_t x = 0; int32_t y = 0; bool operator == (const EnumBoxTup__Baz&) const; bool operator != (const EnumBoxTup__Baz& e) const { return !(*this == e); } }; } // namespace detail struct EnumBoxTup : std::variant { using Foo = detail::EnumBoxTup__Foo; using Bar = detail::EnumBoxTup__Bar; using Baz = detail::EnumBoxTup__Baz; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct EnumOptTup__Foo { std::optional> _0; bool operator == (const EnumOptTup__Foo&) const; bool operator != (const EnumOptTup__Foo& e) const { return !(*this == e); } }; struct EnumOptTup__Bar { bool operator == (const EnumOptTup__Bar&) const { return true; } bool operator != (const EnumOptTup__Bar& e) const { return !(*this == e); } }; struct EnumOptTup__Baz { int32_t x = 0; int32_t y = 0; bool operator == (const EnumOptTup__Baz&) const; bool operator != (const EnumOptTup__Baz& e) const { return !(*this == e); } }; } // namespace detail struct EnumOptTup : std::variant { using Foo = detail::EnumOptTup__Foo; using Bar = detail::EnumOptTup__Bar; using Baz = detail::EnumOptTup__Baz; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct EnumVecTup__Foo { std::vector> _0; bool operator == (const EnumVecTup__Foo&) const; bool operator != (const EnumVecTup__Foo& e) const { return !(*this == e); } }; struct EnumVecTup__Bar { bool operator == (const EnumVecTup__Bar&) const { return true; } bool operator != (const EnumVecTup__Bar& e) const { return !(*this == e); } }; struct EnumVecTup__Baz { int32_t x = 0; int32_t y = 0; bool operator == (const EnumVecTup__Baz&) const; bool operator != (const EnumVecTup__Baz& e) const { return !(*this == e); } }; } // namespace detail struct EnumVecTup : std::variant { using Foo = detail::EnumVecTup__Foo; using Bar = detail::EnumVecTup__Bar; using Baz = detail::EnumVecTup__Baz; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct OptBox { std::optional> _0; bool operator == (const OptBox&) const; bool operator != (const OptBox& o) const { return !(*this == o); } }; struct OptBoxOpt { std::optional>> _0; bool operator == (const OptBoxOpt&) const; bool operator != (const OptBoxOpt& o) const { return !(*this == o); } }; struct OptTup0 { std::optional> _0; bool operator == (const OptTup0&) const; bool operator != (const OptTup0& o) const { return !(*this == o); } }; struct OptTup1 { std::optional> _0; bool operator == (const OptTup1&) const; bool operator != (const OptTup1& o) const { return !(*this == o); } }; struct OptTup2 { std::optional> _0; bool operator == (const OptTup2&) const; bool operator != (const OptTup2& o) const { return !(*this == o); } }; struct TupBox { std::tuple, std::unique_ptr> _0; bool operator == (const TupBox&) const; bool operator != (const TupBox& t) const { return !(*this == t); } }; struct VecBox { std::vector> _0; bool operator == (const VecBox&) const; bool operator != (const VecBox& v) const { return !(*this == v); } }; struct VecBoxVec { std::vector>> _0; bool operator == (const VecBoxVec&) const; bool operator != (const VecBoxVec& v) const { return !(*this == v); } }; struct VecTup0 { std::vector> _0; bool operator == (const VecTup0&) const; bool operator != (const VecTup0& v) const { return !(*this == v); } }; struct VecTup1 { std::vector> _0; bool operator == (const VecTup1&) const; bool operator != (const VecTup1& v) const { return !(*this == v); } }; struct VecTup2 { std::vector> _0; bool operator == (const VecTup2&) const; bool operator != (const VecTup2& v) const { return !(*this == v); } }; uintptr_t rust_mem_leaked(); std::tuple<> empty_tuple(std::tuple<> x); EmptyStruct empty_struct(EmptyStruct x); BoxTup0 box_tup_0(BoxTup0 x); BoxTup1 box_tup_1(BoxTup1 x); BoxTup2 box_tup_2(BoxTup2 x); VecTup0 vec_tup_0(VecTup0 x); VecTup1 vec_tup_1(VecTup1 x); VecTup2 vec_tup_2(VecTup2 x); OptTup0 opt_tup_0(OptTup0 x); OptTup1 opt_tup_1(OptTup1 x); OptTup2 opt_tup_2(OptTup2 x); EnumBoxTup enum_box_tup(EnumBoxTup x); EnumVecTup enum_vec_tup(EnumVecTup x); EnumOptTup enum_opt_tup(EnumOptTup x); TupBox tup_box(TupBox x); VecBox vec_box(VecBox x); BoxVec box_vec(BoxVec x); OptBox opt_box(OptBox x); BoxOpt box_opt(BoxOpt x); VecBoxVec vec_box_vec(VecBoxVec x); BoxVecBox box_vec_box(BoxVecBox x); OptBoxOpt opt_box_opt(OptBoxOpt x); BoxOptBox box_opt_box(BoxOptBox x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_derive_eq_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box__from_cpp(_: &mut *const u8) -> Box<()> { Box::new(()) } #[allow(non_snake_case)] fn _ffi_box__to_cpp(val: (), _: &mut Vec) { _ = val; } fn _ffi_box_bool_from_cpp(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_bool_to_cpp(val: bool, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box<(i32,)> { Box::new((_ffi_read::(end),)) } fn _ffi_box_i32_from_cpp2(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_i32_i32_from_cpp(end: &mut *const u8) -> Box<(i32, i32)> { Box::new((_ffi_read::(end), _ffi_read::(end))) } fn _ffi_box_i32_i32_to_cpp(val: (i32, i32), buf: &mut Vec) { _ffi_write(val.0, buf); _ffi_write(val.1, buf); } fn _ffi_box_i32_to_cpp(val: (i32,), buf: &mut Vec) { _ffi_write(val.0, buf); } fn _ffi_box_i32_to_cpp2(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_option_box_i32_from_cpp(end: &mut *const u8) -> Box>> { Box::new(_ffi_read::(end).then(|| _ffi_box_i32_from_cpp2(end))) } fn _ffi_box_option_box_i32_to_cpp(val: Option>, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_box_i32_to_cpp2(*val_val, buf); } } fn _ffi_box_option_i32_from_cpp(end: &mut *const u8) -> Box> { Box::new(_ffi_read::(end).then(|| _ffi_read::(end))) } fn _ffi_box_option_i32_to_cpp(val: Option, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_write(val_val, buf); } } fn _ffi_box_vec_box_i32_from_cpp(end: &mut *const u8) -> Box>> { Box::new(_ffi_vec_box_i32_from_cpp(_ffi_read::(end), end)) } fn _ffi_box_vec_box_i32_to_cpp(val: Vec>, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_box_i32_to_cpp(val, buf); } fn _ffi_box_vec_i32_from_cpp(end: &mut *const u8) -> Box> { Box::new(_ffi_vec_i32_from_cpp2(_ffi_read::(end), end)) } fn _ffi_box_vec_i32_to_cpp(val: Vec, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_i32_to_cpp2(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_from_cpp(end: &mut *const u8) -> EnumBoxTup { match _ffi_read::(end) { 0 => EnumBoxTup::Foo(_ffi_box_i32_i32_from_cpp(end)), 1 => EnumBoxTup::Bar, 2 => EnumBoxTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_to_cpp(val: EnumBoxTup, buf: &mut Vec) { match val { EnumBoxTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_box_i32_i32_to_cpp(*x, buf); } EnumBoxTup::Bar => _ffi_write(1 as i32, buf), EnumBoxTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_from_cpp(end: &mut *const u8) -> EnumOptTup { match _ffi_read::(end) { 0 => EnumOptTup::Foo(_ffi_read::(end).then(|| (_ffi_read::(end), _ffi_read::(end)))), 1 => EnumOptTup::Bar, 2 => EnumOptTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_to_cpp(val: EnumOptTup, buf: &mut Vec) { match val { EnumOptTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.is_some(), buf); if let Some(x_val) = x { _ffi_write(x_val.0, buf); _ffi_write(x_val.1, buf); } } EnumOptTup::Bar => _ffi_write(1 as i32, buf), EnumOptTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_from_cpp(end: &mut *const u8) -> EnumVecTup { match _ffi_read::(end) { 0 => EnumVecTup::Foo(_ffi_vec_i32_i32_from_cpp(_ffi_read::(end), end)), 1 => EnumVecTup::Bar, 2 => EnumVecTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_to_cpp(val: EnumVecTup, buf: &mut Vec) { match val { EnumVecTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.len(), buf); _ffi_vec_i32_i32_to_cpp(x, buf); } EnumVecTup::Bar => _ffi_write(1 as i32, buf), EnumVecTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt(BoxOpt(_ffi_box_option_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt_box(BoxOptBox(_ffi_box_option_box_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_box_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_0(BoxTup0(_ffi_box__from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box__to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_1(BoxTup1(_ffi_box_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_2(BoxTup2(_ffi_box_i32_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec(BoxVec(_ffi_box_vec_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec_box(BoxVecBox(_ffi_box_vec_box_i32_from_cpp(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_box_i32_to_cpp(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(EmptyStruct); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple() { _ = empty_tuple(()); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumBoxTup_to_cpp(enum_box_tup(_ffi_enum_EnumBoxTup_from_cpp(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumOptTup_to_cpp(enum_opt_tup(_ffi_enum_EnumOptTup_from_cpp(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumVecTup_to_cpp(enum_vec_tup(_ffi_enum_EnumVecTup_from_cpp(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box(OptBox(has_x_0.then(|| _ffi_box_i32_from_cpp2(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_i32_to_cpp2(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box_opt(OptBoxOpt(has_x_0.then(|| _ffi_box_option_i32_from_cpp(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_option_i32_to_cpp(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let buf_end = buf_ptr; let ret = opt_tup_0(OptTup0(has_x_0.then(|| ()))); let ret_0 = ret.0; let buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ = ret_0_val; } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_1(OptTup1(has_x_0.then(|| (_ffi_read::(&mut buf_end),)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_2(OptTup2(has_x_0.then(|| (_ffi_read::(&mut buf_end), _ffi_read::(&mut buf_end))))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); _ffi_write(ret_0_val.1, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = tup_box(TupBox((_ffi_box_i32_from_cpp2(&mut buf_end), _ffi_box_bool_from_cpp(&mut buf_end)))); let ret_0 = ret.0; let ret_0_0 = ret_0.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_cpp2(*ret_0_0, &mut buf2); let ret_0_1 = ret_0.1; _ffi_box_bool_to_cpp(*ret_0_1, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box(VecBox(_ffi_vec_box_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box_vec(VecBoxVec(_ffi_vec_box_vec_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_vec_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_0(VecTup0(_ffi_vec__from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec__to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_1(VecTup1(_ffi_vec_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_2(VecTup2(_ffi_vec_i32_i32_from_cpp(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_i32_to_cpp(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); #[allow(non_snake_case)] fn _ffi_vec__from_cpp(len: usize, _: &mut *const u8) -> Vec<()> { let mut items = Vec::<()>::with_capacity(len); for _ in 0..len { items.push(()); } items } #[allow(non_snake_case)] fn _ffi_vec__to_cpp(items: Vec<()>, _: &mut Vec) { for item in items { _ = item; } } fn _ffi_vec_box_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_i32_from_cpp2(end)); } items } fn _ffi_vec_box_i32_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_box_i32_to_cpp2(*item, buf); } } fn _ffi_vec_box_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec>> { let mut items = Vec::>>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_vec_i32_from_cpp(end)); } items } fn _ffi_vec_box_vec_i32_to_cpp(items: Vec>>, buf: &mut Vec) { for item in items { _ffi_box_vec_i32_to_cpp(*item, buf); } } fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32,)> { let mut items = Vec::<(i32,)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end),)); } items } fn _ffi_vec_i32_from_cpp2(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32, i32)> { let mut items = Vec::<(i32, i32)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end), _ffi_read::(end))); } items } fn _ffi_vec_i32_i32_to_cpp(items: Vec<(i32, i32)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); _ffi_write(item.1, buf); } } fn _ffi_vec_i32_to_cpp(items: Vec<(i32,)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); } } fn _ffi_vec_i32_to_cpp2(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } ================================================ FILE: src/tests/snapshots/cpp_demo_enum_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_enum_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include #include #include namespace rust { struct InnerEnum; struct InnerStruct; struct NestedBox; struct NestedOption; struct NestedTuple; struct NestedVec; namespace detail { struct NestedEnum__Foo { }; struct NestedEnum__Bar { std::tuple> _0; }; } // namespace detail struct NestedEnum : std::variant { using Foo = detail::NestedEnum__Foo; using Bar = detail::NestedEnum__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct InnerEnum__Foo { NestedEnum _0; }; } // namespace detail struct InnerEnum : std::variant { using Foo = detail::InnerEnum__Foo; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedStruct__Foo { }; struct NestedStruct__Bar { std::tuple> _0; }; } // namespace detail struct NestedStruct : std::variant { using Foo = detail::NestedStruct__Foo; using Bar = detail::NestedStruct__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct InnerStruct { NestedStruct x; }; namespace detail { struct NestedBox__Foo { }; struct NestedBox__Bar { std::unique_ptr _0; }; } // namespace detail struct NestedBox : std::variant { using Foo = detail::NestedBox__Foo; using Bar = detail::NestedBox__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedOption__Foo { }; struct NestedOption__Bar { std::optional> _0; }; } // namespace detail struct NestedOption : std::variant { using Foo = detail::NestedOption__Foo; using Bar = detail::NestedOption__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedTuple__Foo { }; struct NestedTuple__Bar { std::tuple> _0; }; } // namespace detail struct NestedTuple : std::variant { using Foo = detail::NestedTuple__Foo; using Bar = detail::NestedTuple__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedVec__Foo { }; struct NestedVec__Bar { std::vector _0; }; } // namespace detail struct NestedVec : std::variant { using Foo = detail::NestedVec__Foo; using Bar = detail::NestedVec__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_enum_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_demo_enum_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_enum_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include #include #include namespace rust { struct InnerEnum; struct InnerStruct; struct NestedBox; struct NestedOption; struct NestedTuple; struct NestedVec; namespace detail { struct NestedEnum__Foo { }; struct NestedEnum__Bar { std::tuple> _0; }; } // namespace detail struct NestedEnum : std::variant { using Foo = detail::NestedEnum__Foo; using Bar = detail::NestedEnum__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct InnerEnum__Foo { NestedEnum _0; }; } // namespace detail struct InnerEnum : std::variant { using Foo = detail::InnerEnum__Foo; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedStruct__Foo { }; struct NestedStruct__Bar { std::tuple> _0; }; } // namespace detail struct NestedStruct : std::variant { using Foo = detail::NestedStruct__Foo; using Bar = detail::NestedStruct__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct InnerStruct { NestedStruct x; }; namespace detail { struct NestedBox__Foo { }; struct NestedBox__Bar { std::unique_ptr _0; }; } // namespace detail struct NestedBox : std::variant { using Foo = detail::NestedBox__Foo; using Bar = detail::NestedBox__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedOption__Foo { }; struct NestedOption__Bar { std::optional> _0; }; } // namespace detail struct NestedOption : std::variant { using Foo = detail::NestedOption__Foo; using Bar = detail::NestedOption__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedTuple__Foo { }; struct NestedTuple__Bar { std::tuple> _0; }; } // namespace detail struct NestedTuple : std::variant { using Foo = detail::NestedTuple__Foo; using Bar = detail::NestedTuple__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct NestedVec__Foo { }; struct NestedVec__Bar { std::vector _0; }; } // namespace detail struct NestedVec : std::variant { using Foo = detail::NestedVec__Foo; using Bar = detail::NestedVec__Bar; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_enum_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_demo_keyword_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test_alignas(int32_t alignas2); int32_t _ffi_fn_test_alignof(int32_t alignof2); int32_t _ffi_fn_test_and(int32_t and2); int32_t _ffi_fn_test_and_eq(int32_t and_eq2); int32_t _ffi_fn_test_asm(int32_t asm2); int32_t _ffi_fn_test_associatedtype(int32_t associatedtype); int32_t _ffi_fn_test_associativity(int32_t associativity); int32_t _ffi_fn_test_atomic_cancel(int32_t atomic_cancel2); int32_t _ffi_fn_test_atomic_commit(int32_t atomic_commit2); int32_t _ffi_fn_test_atomic_noexcept(int32_t atomic_noexcept2); int32_t _ffi_fn_test_auto(int32_t auto2); int32_t _ffi_fn_test_bitand(int32_t bitand2); int32_t _ffi_fn_test_bitor(int32_t bitor2); int32_t _ffi_fn_test_bool(int32_t bool2); int32_t _ffi_fn_test_boolean(int32_t boolean); int32_t _ffi_fn_test_borrowing(int32_t borrowing); int32_t _ffi_fn_test_byte(int32_t byte); int32_t _ffi_fn_test_case(int32_t case2); int32_t _ffi_fn_test_catch(int32_t catch2); int32_t _ffi_fn_test_char(int32_t char2); int32_t _ffi_fn_test_char16_t(int32_t char16_t2); int32_t _ffi_fn_test_char32_t(int32_t char32_t2); int32_t _ffi_fn_test_char8_t(int32_t char8_t2); int32_t _ffi_fn_test_class(int32_t class2); int32_t _ffi_fn_test_co_await(int32_t co_await2); int32_t _ffi_fn_test_co_return(int32_t co_return2); int32_t _ffi_fn_test_co_yield(int32_t co_yield2); int32_t _ffi_fn_test_compl(int32_t compl2); int32_t _ffi_fn_test_concept(int32_t concept2); int32_t _ffi_fn_test_const_cast(int32_t const_cast2); int32_t _ffi_fn_test_consteval(int32_t consteval2); int32_t _ffi_fn_test_constexpr(int32_t constexpr2); int32_t _ffi_fn_test_constinit(int32_t constinit2); int32_t _ffi_fn_test_consuming(int32_t consuming); int32_t _ffi_fn_test_contract_assert(int32_t contract_assert2); int32_t _ffi_fn_test_convenience(int32_t convenience); int32_t _ffi_fn_test_debugger(int32_t debugger); int32_t _ffi_fn_test_decltype(int32_t decltype2); int32_t _ffi_fn_test_default(int32_t default2); int32_t _ffi_fn_test_defer(int32_t defer); int32_t _ffi_fn_test_deinit(int32_t deinit); int32_t _ffi_fn_test_delete(int32_t delete2); int32_t _ffi_fn_test_double(int32_t double2); int32_t _ffi_fn_test_dynamic(int32_t dynamic); int32_t _ffi_fn_test_dynamic_cast(int32_t dynamic_cast2); int32_t _ffi_fn_test_explicit(int32_t explicit2); int32_t _ffi_fn_test_export(int32_t export2); int32_t _ffi_fn_test_extends(int32_t extends); int32_t _ffi_fn_test_extension(int32_t extension); int32_t _ffi_fn_test_fallthrough(int32_t fallthrough); int32_t _ffi_fn_test_fileprivate(int32_t fileprivate); int32_t _ffi_fn_test_finally(int32_t finally); int32_t _ffi_fn_test_float(int32_t float2); int32_t _ffi_fn_test_friend(int32_t friend2); int32_t _ffi_fn_test_func(int32_t func); int32_t _ffi_fn_test_function(int32_t function); int32_t _ffi_fn_test_get(int32_t get); int32_t _ffi_fn_test_goto(int32_t goto2); int32_t _ffi_fn_test_guard(int32_t guard); int32_t _ffi_fn_test_implements(int32_t implements); int32_t _ffi_fn_test_import(int32_t import); int32_t _ffi_fn_test_indirect(int32_t indirect); int32_t _ffi_fn_test_infix(int32_t infix); int32_t _ffi_fn_test_init(int32_t init); int32_t _ffi_fn_test_inline(int32_t inline2); int32_t _ffi_fn_test_inout(int32_t inout); int32_t _ffi_fn_test_instanceof(int32_t instanceof); int32_t _ffi_fn_test_int(int32_t int2); int32_t _ffi_fn_test_interface(int32_t interface); int32_t _ffi_fn_test_internal(int32_t internal); int32_t _ffi_fn_test_is(int32_t is); int32_t _ffi_fn_test_lazy(int32_t lazy); int32_t _ffi_fn_test_left(int32_t left); int32_t _ffi_fn_test_long(int32_t long2); int32_t _ffi_fn_test_mutable(int32_t mutable2); int32_t _ffi_fn_test_mutating(int32_t mutating); int32_t _ffi_fn_test_namespace(int32_t namespace2); int32_t _ffi_fn_test_native(int32_t native); int32_t _ffi_fn_test_new(int32_t new2); int32_t _ffi_fn_test_nil(int32_t nil); int32_t _ffi_fn_test_noexcept(int32_t noexcept2); int32_t _ffi_fn_test_none(int32_t none); int32_t _ffi_fn_test_nonisolated(int32_t nonisolated); int32_t _ffi_fn_test_nonmutating(int32_t nonmutating); int32_t _ffi_fn_test_not(int32_t not2); int32_t _ffi_fn_test_not_eq(int32_t not_eq2); int32_t _ffi_fn_test_null(int32_t null); int32_t _ffi_fn_test_nullptr(int32_t nullptr2); int32_t _ffi_fn_test_open(int32_t open); int32_t _ffi_fn_test_operator(int32_t operator2); int32_t _ffi_fn_test_optional(int32_t optional); int32_t _ffi_fn_test_or(int32_t or2); int32_t _ffi_fn_test_or_eq(int32_t or_eq2); int32_t _ffi_fn_test_package(int32_t package); int32_t _ffi_fn_test_postfix(int32_t postfix); int32_t _ffi_fn_test_precedence(int32_t precedence); int32_t _ffi_fn_test_precedencegroup(int32_t precedencegroup); int32_t _ffi_fn_test_prefix(int32_t prefix); int32_t _ffi_fn_test_private(int32_t private2); int32_t _ffi_fn_test_protected(int32_t protected2); int32_t _ffi_fn_test_protocol(int32_t protocol); int32_t _ffi_fn_test_public(int32_t public2); int32_t _ffi_fn_test_reflexpr(int32_t reflexpr2); int32_t _ffi_fn_test_register(int32_t register2); int32_t _ffi_fn_test_reinterpret_cast(int32_t reinterpret_cast2); int32_t _ffi_fn_test_repeat(int32_t repeat); int32_t _ffi_fn_test_required(int32_t required); int32_t _ffi_fn_test_requires(int32_t requires2); int32_t _ffi_fn_test_rethrows(int32_t rethrows); int32_t _ffi_fn_test_right(int32_t right); int32_t _ffi_fn_test_set(int32_t set); int32_t _ffi_fn_test_short(int32_t short2); int32_t _ffi_fn_test_signed(int32_t signed2); int32_t _ffi_fn_test_sizeof(int32_t sizeof2); int32_t _ffi_fn_test_some(int32_t some); int32_t _ffi_fn_test_static_assert(int32_t static_assert2); int32_t _ffi_fn_test_static_cast(int32_t static_cast2); int32_t _ffi_fn_test_subscript(int32_t subscript); int32_t _ffi_fn_test_switch(int32_t switch2); int32_t _ffi_fn_test_synchronized(int32_t synchronized2); int32_t _ffi_fn_test_template(int32_t template2); int32_t _ffi_fn_test_this(int32_t this2); int32_t _ffi_fn_test_thread_local(int32_t thread_local2); int32_t _ffi_fn_test_throw(int32_t throw2); int32_t _ffi_fn_test_throws(int32_t throws); int32_t _ffi_fn_test_transient(int32_t transient); int32_t _ffi_fn_test_typealias(int32_t typealias); int32_t _ffi_fn_test_typedef(int32_t typedef2); int32_t _ffi_fn_test_typeid(int32_t typeid2); int32_t _ffi_fn_test_typename(int32_t typename2); int32_t _ffi_fn_test_undefined(int32_t undefined); int32_t _ffi_fn_test_union(int32_t union2); int32_t _ffi_fn_test_unowned(int32_t unowned); int32_t _ffi_fn_test_unsigned(int32_t unsigned2); int32_t _ffi_fn_test_using(int32_t using2); int32_t _ffi_fn_test_var(int32_t var); int32_t _ffi_fn_test_void(int32_t void2); int32_t _ffi_fn_test_volatile(int32_t volatile2); int32_t _ffi_fn_test_wchar_t(int32_t wchar_t2); int32_t _ffi_fn_test_weak(int32_t weak); int32_t _ffi_fn_test_with(int32_t with); int32_t _ffi_fn_test_xor(int32_t xor2); int32_t _ffi_fn_test_xor_eq(int32_t xor_eq2); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::test_alignas(int32_t alignas2) { return _ffi_fn_test_alignas(alignas2); } int32_t rust::test_alignof(int32_t alignof2) { return _ffi_fn_test_alignof(alignof2); } int32_t rust::test_and(int32_t and2) { return _ffi_fn_test_and(and2); } int32_t rust::test_and_eq(int32_t and_eq2) { return _ffi_fn_test_and_eq(and_eq2); } int32_t rust::test_asm(int32_t asm2) { return _ffi_fn_test_asm(asm2); } int32_t rust::test_associatedtype(int32_t associatedtype) { return _ffi_fn_test_associatedtype(associatedtype); } int32_t rust::test_associativity(int32_t associativity) { return _ffi_fn_test_associativity(associativity); } int32_t rust::test_atomic_cancel(int32_t atomic_cancel2) { return _ffi_fn_test_atomic_cancel(atomic_cancel2); } int32_t rust::test_atomic_commit(int32_t atomic_commit2) { return _ffi_fn_test_atomic_commit(atomic_commit2); } int32_t rust::test_atomic_noexcept(int32_t atomic_noexcept2) { return _ffi_fn_test_atomic_noexcept(atomic_noexcept2); } int32_t rust::test_auto(int32_t auto2) { return _ffi_fn_test_auto(auto2); } int32_t rust::test_bitand(int32_t bitand2) { return _ffi_fn_test_bitand(bitand2); } int32_t rust::test_bitor(int32_t bitor2) { return _ffi_fn_test_bitor(bitor2); } int32_t rust::test_bool(int32_t bool2) { return _ffi_fn_test_bool(bool2); } int32_t rust::test_boolean(int32_t boolean) { return _ffi_fn_test_boolean(boolean); } int32_t rust::test_borrowing(int32_t borrowing) { return _ffi_fn_test_borrowing(borrowing); } int32_t rust::test_byte(int32_t byte) { return _ffi_fn_test_byte(byte); } int32_t rust::test_case(int32_t case2) { return _ffi_fn_test_case(case2); } int32_t rust::test_catch(int32_t catch2) { return _ffi_fn_test_catch(catch2); } int32_t rust::test_char(int32_t char2) { return _ffi_fn_test_char(char2); } int32_t rust::test_char16_t(int32_t char16_t2) { return _ffi_fn_test_char16_t(char16_t2); } int32_t rust::test_char32_t(int32_t char32_t2) { return _ffi_fn_test_char32_t(char32_t2); } int32_t rust::test_char8_t(int32_t char8_t2) { return _ffi_fn_test_char8_t(char8_t2); } int32_t rust::test_class(int32_t class2) { return _ffi_fn_test_class(class2); } int32_t rust::test_co_await(int32_t co_await2) { return _ffi_fn_test_co_await(co_await2); } int32_t rust::test_co_return(int32_t co_return2) { return _ffi_fn_test_co_return(co_return2); } int32_t rust::test_co_yield(int32_t co_yield2) { return _ffi_fn_test_co_yield(co_yield2); } int32_t rust::test_compl(int32_t compl2) { return _ffi_fn_test_compl(compl2); } int32_t rust::test_concept(int32_t concept2) { return _ffi_fn_test_concept(concept2); } int32_t rust::test_const_cast(int32_t const_cast2) { return _ffi_fn_test_const_cast(const_cast2); } int32_t rust::test_consteval(int32_t consteval2) { return _ffi_fn_test_consteval(consteval2); } int32_t rust::test_constexpr(int32_t constexpr2) { return _ffi_fn_test_constexpr(constexpr2); } int32_t rust::test_constinit(int32_t constinit2) { return _ffi_fn_test_constinit(constinit2); } int32_t rust::test_consuming(int32_t consuming) { return _ffi_fn_test_consuming(consuming); } int32_t rust::test_contract_assert(int32_t contract_assert2) { return _ffi_fn_test_contract_assert(contract_assert2); } int32_t rust::test_convenience(int32_t convenience) { return _ffi_fn_test_convenience(convenience); } int32_t rust::test_debugger(int32_t debugger) { return _ffi_fn_test_debugger(debugger); } int32_t rust::test_decltype(int32_t decltype2) { return _ffi_fn_test_decltype(decltype2); } int32_t rust::test_default(int32_t default2) { return _ffi_fn_test_default(default2); } int32_t rust::test_defer(int32_t defer) { return _ffi_fn_test_defer(defer); } int32_t rust::test_deinit(int32_t deinit) { return _ffi_fn_test_deinit(deinit); } int32_t rust::test_delete(int32_t delete2) { return _ffi_fn_test_delete(delete2); } int32_t rust::test_double(int32_t double2) { return _ffi_fn_test_double(double2); } int32_t rust::test_dynamic(int32_t dynamic) { return _ffi_fn_test_dynamic(dynamic); } int32_t rust::test_dynamic_cast(int32_t dynamic_cast2) { return _ffi_fn_test_dynamic_cast(dynamic_cast2); } int32_t rust::test_explicit(int32_t explicit2) { return _ffi_fn_test_explicit(explicit2); } int32_t rust::test_export(int32_t export2) { return _ffi_fn_test_export(export2); } int32_t rust::test_extends(int32_t extends) { return _ffi_fn_test_extends(extends); } int32_t rust::test_extension(int32_t extension) { return _ffi_fn_test_extension(extension); } int32_t rust::test_fallthrough(int32_t fallthrough) { return _ffi_fn_test_fallthrough(fallthrough); } int32_t rust::test_fileprivate(int32_t fileprivate) { return _ffi_fn_test_fileprivate(fileprivate); } int32_t rust::test_finally(int32_t finally) { return _ffi_fn_test_finally(finally); } int32_t rust::test_float(int32_t float2) { return _ffi_fn_test_float(float2); } int32_t rust::test_friend(int32_t friend2) { return _ffi_fn_test_friend(friend2); } int32_t rust::test_func(int32_t func) { return _ffi_fn_test_func(func); } int32_t rust::test_function(int32_t function) { return _ffi_fn_test_function(function); } int32_t rust::test_get(int32_t get) { return _ffi_fn_test_get(get); } int32_t rust::test_goto(int32_t goto2) { return _ffi_fn_test_goto(goto2); } int32_t rust::test_guard(int32_t guard) { return _ffi_fn_test_guard(guard); } int32_t rust::test_implements(int32_t implements) { return _ffi_fn_test_implements(implements); } int32_t rust::test_import(int32_t import) { return _ffi_fn_test_import(import); } int32_t rust::test_indirect(int32_t indirect) { return _ffi_fn_test_indirect(indirect); } int32_t rust::test_infix(int32_t infix) { return _ffi_fn_test_infix(infix); } int32_t rust::test_init(int32_t init) { return _ffi_fn_test_init(init); } int32_t rust::test_inline(int32_t inline2) { return _ffi_fn_test_inline(inline2); } int32_t rust::test_inout(int32_t inout) { return _ffi_fn_test_inout(inout); } int32_t rust::test_instanceof(int32_t instanceof) { return _ffi_fn_test_instanceof(instanceof); } int32_t rust::test_int(int32_t int2) { return _ffi_fn_test_int(int2); } int32_t rust::test_interface(int32_t interface) { return _ffi_fn_test_interface(interface); } int32_t rust::test_internal(int32_t internal) { return _ffi_fn_test_internal(internal); } int32_t rust::test_is(int32_t is) { return _ffi_fn_test_is(is); } int32_t rust::test_lazy(int32_t lazy) { return _ffi_fn_test_lazy(lazy); } int32_t rust::test_left(int32_t left) { return _ffi_fn_test_left(left); } int32_t rust::test_long(int32_t long2) { return _ffi_fn_test_long(long2); } int32_t rust::test_mutable(int32_t mutable2) { return _ffi_fn_test_mutable(mutable2); } int32_t rust::test_mutating(int32_t mutating) { return _ffi_fn_test_mutating(mutating); } int32_t rust::test_namespace(int32_t namespace2) { return _ffi_fn_test_namespace(namespace2); } int32_t rust::test_native(int32_t native) { return _ffi_fn_test_native(native); } int32_t rust::test_new(int32_t new2) { return _ffi_fn_test_new(new2); } int32_t rust::test_nil(int32_t nil) { return _ffi_fn_test_nil(nil); } int32_t rust::test_noexcept(int32_t noexcept2) { return _ffi_fn_test_noexcept(noexcept2); } int32_t rust::test_none(int32_t none) { return _ffi_fn_test_none(none); } int32_t rust::test_nonisolated(int32_t nonisolated) { return _ffi_fn_test_nonisolated(nonisolated); } int32_t rust::test_nonmutating(int32_t nonmutating) { return _ffi_fn_test_nonmutating(nonmutating); } int32_t rust::test_not(int32_t not2) { return _ffi_fn_test_not(not2); } int32_t rust::test_not_eq(int32_t not_eq2) { return _ffi_fn_test_not_eq(not_eq2); } int32_t rust::test_null(int32_t null) { return _ffi_fn_test_null(null); } int32_t rust::test_nullptr(int32_t nullptr2) { return _ffi_fn_test_nullptr(nullptr2); } int32_t rust::test_open(int32_t open) { return _ffi_fn_test_open(open); } int32_t rust::test_operator(int32_t operator2) { return _ffi_fn_test_operator(operator2); } int32_t rust::test_optional(int32_t optional) { return _ffi_fn_test_optional(optional); } int32_t rust::test_or(int32_t or2) { return _ffi_fn_test_or(or2); } int32_t rust::test_or_eq(int32_t or_eq2) { return _ffi_fn_test_or_eq(or_eq2); } int32_t rust::test_package(int32_t package) { return _ffi_fn_test_package(package); } int32_t rust::test_postfix(int32_t postfix) { return _ffi_fn_test_postfix(postfix); } int32_t rust::test_precedence(int32_t precedence) { return _ffi_fn_test_precedence(precedence); } int32_t rust::test_precedencegroup(int32_t precedencegroup) { return _ffi_fn_test_precedencegroup(precedencegroup); } int32_t rust::test_prefix(int32_t prefix) { return _ffi_fn_test_prefix(prefix); } int32_t rust::test_private(int32_t private2) { return _ffi_fn_test_private(private2); } int32_t rust::test_protected(int32_t protected2) { return _ffi_fn_test_protected(protected2); } int32_t rust::test_protocol(int32_t protocol) { return _ffi_fn_test_protocol(protocol); } int32_t rust::test_public(int32_t public2) { return _ffi_fn_test_public(public2); } int32_t rust::test_reflexpr(int32_t reflexpr2) { return _ffi_fn_test_reflexpr(reflexpr2); } int32_t rust::test_register(int32_t register2) { return _ffi_fn_test_register(register2); } int32_t rust::test_reinterpret_cast(int32_t reinterpret_cast2) { return _ffi_fn_test_reinterpret_cast(reinterpret_cast2); } int32_t rust::test_repeat(int32_t repeat) { return _ffi_fn_test_repeat(repeat); } int32_t rust::test_required(int32_t required) { return _ffi_fn_test_required(required); } int32_t rust::test_requires(int32_t requires2) { return _ffi_fn_test_requires(requires2); } int32_t rust::test_rethrows(int32_t rethrows) { return _ffi_fn_test_rethrows(rethrows); } int32_t rust::test_right(int32_t right) { return _ffi_fn_test_right(right); } int32_t rust::test_set(int32_t set) { return _ffi_fn_test_set(set); } int32_t rust::test_short(int32_t short2) { return _ffi_fn_test_short(short2); } int32_t rust::test_signed(int32_t signed2) { return _ffi_fn_test_signed(signed2); } int32_t rust::test_sizeof(int32_t sizeof2) { return _ffi_fn_test_sizeof(sizeof2); } int32_t rust::test_some(int32_t some) { return _ffi_fn_test_some(some); } int32_t rust::test_static_assert(int32_t static_assert2) { return _ffi_fn_test_static_assert(static_assert2); } int32_t rust::test_static_cast(int32_t static_cast2) { return _ffi_fn_test_static_cast(static_cast2); } int32_t rust::test_subscript(int32_t subscript) { return _ffi_fn_test_subscript(subscript); } int32_t rust::test_switch(int32_t switch2) { return _ffi_fn_test_switch(switch2); } int32_t rust::test_synchronized(int32_t synchronized2) { return _ffi_fn_test_synchronized(synchronized2); } int32_t rust::test_template(int32_t template2) { return _ffi_fn_test_template(template2); } int32_t rust::test_this(int32_t this2) { return _ffi_fn_test_this(this2); } int32_t rust::test_thread_local(int32_t thread_local2) { return _ffi_fn_test_thread_local(thread_local2); } int32_t rust::test_throw(int32_t throw2) { return _ffi_fn_test_throw(throw2); } int32_t rust::test_throws(int32_t throws) { return _ffi_fn_test_throws(throws); } int32_t rust::test_transient(int32_t transient) { return _ffi_fn_test_transient(transient); } int32_t rust::test_typealias(int32_t typealias) { return _ffi_fn_test_typealias(typealias); } int32_t rust::test_typedef(int32_t typedef2) { return _ffi_fn_test_typedef(typedef2); } int32_t rust::test_typeid(int32_t typeid2) { return _ffi_fn_test_typeid(typeid2); } int32_t rust::test_typename(int32_t typename2) { return _ffi_fn_test_typename(typename2); } int32_t rust::test_undefined(int32_t undefined) { return _ffi_fn_test_undefined(undefined); } int32_t rust::test_union(int32_t union2) { return _ffi_fn_test_union(union2); } int32_t rust::test_unowned(int32_t unowned) { return _ffi_fn_test_unowned(unowned); } int32_t rust::test_unsigned(int32_t unsigned2) { return _ffi_fn_test_unsigned(unsigned2); } int32_t rust::test_using(int32_t using2) { return _ffi_fn_test_using(using2); } int32_t rust::test_var(int32_t var) { return _ffi_fn_test_var(var); } int32_t rust::test_void(int32_t void2) { return _ffi_fn_test_void(void2); } int32_t rust::test_volatile(int32_t volatile2) { return _ffi_fn_test_volatile(volatile2); } int32_t rust::test_wchar_t(int32_t wchar_t2) { return _ffi_fn_test_wchar_t(wchar_t2); } int32_t rust::test_weak(int32_t weak) { return _ffi_fn_test_weak(weak); } int32_t rust::test_with(int32_t with) { return _ffi_fn_test_with(with); } int32_t rust::test_xor(int32_t xor2) { return _ffi_fn_test_xor(xor2); } int32_t rust::test_xor_eq(int32_t xor_eq2) { return _ffi_fn_test_xor_eq(xor_eq2); } ================================================ FILE: src/tests/snapshots/cpp_demo_keyword_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { uintptr_t rust_mem_leaked(); int32_t test_alignas(int32_t alignas2); int32_t test_alignof(int32_t alignof2); int32_t test_and(int32_t and2); int32_t test_and_eq(int32_t and_eq2); int32_t test_asm(int32_t asm2); int32_t test_associatedtype(int32_t associatedtype); int32_t test_associativity(int32_t associativity); int32_t test_atomic_cancel(int32_t atomic_cancel2); int32_t test_atomic_commit(int32_t atomic_commit2); int32_t test_atomic_noexcept(int32_t atomic_noexcept2); int32_t test_auto(int32_t auto2); int32_t test_bitand(int32_t bitand2); int32_t test_bitor(int32_t bitor2); int32_t test_bool(int32_t bool2); int32_t test_boolean(int32_t boolean); int32_t test_borrowing(int32_t borrowing); int32_t test_byte(int32_t byte); int32_t test_case(int32_t case2); int32_t test_catch(int32_t catch2); int32_t test_char(int32_t char2); int32_t test_char16_t(int32_t char16_t2); int32_t test_char32_t(int32_t char32_t2); int32_t test_char8_t(int32_t char8_t2); int32_t test_class(int32_t class2); int32_t test_co_await(int32_t co_await2); int32_t test_co_return(int32_t co_return2); int32_t test_co_yield(int32_t co_yield2); int32_t test_compl(int32_t compl2); int32_t test_concept(int32_t concept2); int32_t test_const_cast(int32_t const_cast2); int32_t test_consteval(int32_t consteval2); int32_t test_constexpr(int32_t constexpr2); int32_t test_constinit(int32_t constinit2); int32_t test_consuming(int32_t consuming); int32_t test_contract_assert(int32_t contract_assert2); int32_t test_convenience(int32_t convenience); int32_t test_debugger(int32_t debugger); int32_t test_decltype(int32_t decltype2); int32_t test_default(int32_t default2); int32_t test_defer(int32_t defer); int32_t test_deinit(int32_t deinit); int32_t test_delete(int32_t delete2); int32_t test_double(int32_t double2); int32_t test_dynamic(int32_t dynamic); int32_t test_dynamic_cast(int32_t dynamic_cast2); int32_t test_explicit(int32_t explicit2); int32_t test_export(int32_t export2); int32_t test_extends(int32_t extends); int32_t test_extension(int32_t extension); int32_t test_fallthrough(int32_t fallthrough); int32_t test_fileprivate(int32_t fileprivate); int32_t test_finally(int32_t finally); int32_t test_float(int32_t float2); int32_t test_friend(int32_t friend2); int32_t test_func(int32_t func); int32_t test_function(int32_t function); int32_t test_get(int32_t get); int32_t test_goto(int32_t goto2); int32_t test_guard(int32_t guard); int32_t test_implements(int32_t implements); int32_t test_import(int32_t import); int32_t test_indirect(int32_t indirect); int32_t test_infix(int32_t infix); int32_t test_init(int32_t init); int32_t test_inline(int32_t inline2); int32_t test_inout(int32_t inout); int32_t test_instanceof(int32_t instanceof); int32_t test_int(int32_t int2); int32_t test_interface(int32_t interface); int32_t test_internal(int32_t internal); int32_t test_is(int32_t is); int32_t test_lazy(int32_t lazy); int32_t test_left(int32_t left); int32_t test_long(int32_t long2); int32_t test_mutable(int32_t mutable2); int32_t test_mutating(int32_t mutating); int32_t test_namespace(int32_t namespace2); int32_t test_native(int32_t native); int32_t test_new(int32_t new2); int32_t test_nil(int32_t nil); int32_t test_noexcept(int32_t noexcept2); int32_t test_none(int32_t none); int32_t test_nonisolated(int32_t nonisolated); int32_t test_nonmutating(int32_t nonmutating); int32_t test_not(int32_t not2); int32_t test_not_eq(int32_t not_eq2); int32_t test_null(int32_t null); int32_t test_nullptr(int32_t nullptr2); int32_t test_open(int32_t open); int32_t test_operator(int32_t operator2); int32_t test_optional(int32_t optional); int32_t test_or(int32_t or2); int32_t test_or_eq(int32_t or_eq2); int32_t test_package(int32_t package); int32_t test_postfix(int32_t postfix); int32_t test_precedence(int32_t precedence); int32_t test_precedencegroup(int32_t precedencegroup); int32_t test_prefix(int32_t prefix); int32_t test_private(int32_t private2); int32_t test_protected(int32_t protected2); int32_t test_protocol(int32_t protocol); int32_t test_public(int32_t public2); int32_t test_reflexpr(int32_t reflexpr2); int32_t test_register(int32_t register2); int32_t test_reinterpret_cast(int32_t reinterpret_cast2); int32_t test_repeat(int32_t repeat); int32_t test_required(int32_t required); int32_t test_requires(int32_t requires2); int32_t test_rethrows(int32_t rethrows); int32_t test_right(int32_t right); int32_t test_set(int32_t set); int32_t test_short(int32_t short2); int32_t test_signed(int32_t signed2); int32_t test_sizeof(int32_t sizeof2); int32_t test_some(int32_t some); int32_t test_static_assert(int32_t static_assert2); int32_t test_static_cast(int32_t static_cast2); int32_t test_subscript(int32_t subscript); int32_t test_switch(int32_t switch2); int32_t test_synchronized(int32_t synchronized2); int32_t test_template(int32_t template2); int32_t test_this(int32_t this2); int32_t test_thread_local(int32_t thread_local2); int32_t test_throw(int32_t throw2); int32_t test_throws(int32_t throws); int32_t test_transient(int32_t transient); int32_t test_typealias(int32_t typealias); int32_t test_typedef(int32_t typedef2); int32_t test_typeid(int32_t typeid2); int32_t test_typename(int32_t typename2); int32_t test_undefined(int32_t undefined); int32_t test_union(int32_t union2); int32_t test_unowned(int32_t unowned); int32_t test_unsigned(int32_t unsigned2); int32_t test_using(int32_t using2); int32_t test_var(int32_t var); int32_t test_void(int32_t void2); int32_t test_volatile(int32_t volatile2); int32_t test_wchar_t(int32_t wchar_t2); int32_t test_weak(int32_t weak); int32_t test_with(int32_t with); int32_t test_xor(int32_t xor2); int32_t test_xor_eq(int32_t xor_eq2); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_keyword_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test_alignas(alignas2: i32) -> i32 { test_alignas(alignas2) } #[no_mangle] extern "C" fn _ffi_fn_test_alignof(alignof2: i32) -> i32 { test_alignof(alignof2) } #[no_mangle] extern "C" fn _ffi_fn_test_and(and2: i32) -> i32 { test_and(and2) } #[no_mangle] extern "C" fn _ffi_fn_test_and_eq(and_eq2: i32) -> i32 { test_and_eq(and_eq2) } #[no_mangle] extern "C" fn _ffi_fn_test_asm(asm2: i32) -> i32 { test_asm(asm2) } #[no_mangle] extern "C" fn _ffi_fn_test_associatedtype(associatedtype: i32) -> i32 { test_associatedtype(associatedtype) } #[no_mangle] extern "C" fn _ffi_fn_test_associativity(associativity: i32) -> i32 { test_associativity(associativity) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel2: i32) -> i32 { test_atomic_cancel(atomic_cancel2) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit2: i32) -> i32 { test_atomic_commit(atomic_commit2) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept2: i32) -> i32 { test_atomic_noexcept(atomic_noexcept2) } #[no_mangle] extern "C" fn _ffi_fn_test_auto(auto2: i32) -> i32 { test_auto(auto2) } #[no_mangle] extern "C" fn _ffi_fn_test_bitand(bitand2: i32) -> i32 { test_bitand(bitand2) } #[no_mangle] extern "C" fn _ffi_fn_test_bitor(bitor2: i32) -> i32 { test_bitor(bitor2) } #[no_mangle] extern "C" fn _ffi_fn_test_bool(bool2: i32) -> i32 { test_bool(bool2) } #[no_mangle] extern "C" fn _ffi_fn_test_boolean(boolean: i32) -> i32 { test_boolean(boolean) } #[no_mangle] extern "C" fn _ffi_fn_test_borrowing(borrowing: i32) -> i32 { test_borrowing(borrowing) } #[no_mangle] extern "C" fn _ffi_fn_test_byte(byte: i32) -> i32 { test_byte(byte) } #[no_mangle] extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 { test_case(case2) } #[no_mangle] extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 { test_catch(catch2) } #[no_mangle] extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 { test_char(char2) } #[no_mangle] extern "C" fn _ffi_fn_test_char16_t(char16_t2: i32) -> i32 { test_char16_t(char16_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_char32_t(char32_t2: i32) -> i32 { test_char32_t(char32_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_char8_t(char8_t2: i32) -> i32 { test_char8_t(char8_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 { test_class(class2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_await(co_await2: i32) -> i32 { test_co_await(co_await2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_return(co_return2: i32) -> i32 { test_co_return(co_return2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_yield(co_yield2: i32) -> i32 { test_co_yield(co_yield2) } #[no_mangle] extern "C" fn _ffi_fn_test_compl(compl2: i32) -> i32 { test_compl(compl2) } #[no_mangle] extern "C" fn _ffi_fn_test_concept(concept2: i32) -> i32 { test_concept(concept2) } #[no_mangle] extern "C" fn _ffi_fn_test_const_cast(const_cast2: i32) -> i32 { test_const_cast(const_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_consteval(consteval2: i32) -> i32 { test_consteval(consteval2) } #[no_mangle] extern "C" fn _ffi_fn_test_constexpr(constexpr2: i32) -> i32 { test_constexpr(constexpr2) } #[no_mangle] extern "C" fn _ffi_fn_test_constinit(constinit2: i32) -> i32 { test_constinit(constinit2) } #[no_mangle] extern "C" fn _ffi_fn_test_consuming(consuming: i32) -> i32 { test_consuming(consuming) } #[no_mangle] extern "C" fn _ffi_fn_test_contract_assert(contract_assert2: i32) -> i32 { test_contract_assert(contract_assert2) } #[no_mangle] extern "C" fn _ffi_fn_test_convenience(convenience: i32) -> i32 { test_convenience(convenience) } #[no_mangle] extern "C" fn _ffi_fn_test_debugger(debugger: i32) -> i32 { test_debugger(debugger) } #[no_mangle] extern "C" fn _ffi_fn_test_decltype(decltype2: i32) -> i32 { test_decltype(decltype2) } #[no_mangle] extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 { test_default(default2) } #[no_mangle] extern "C" fn _ffi_fn_test_defer(defer: i32) -> i32 { test_defer(defer) } #[no_mangle] extern "C" fn _ffi_fn_test_deinit(deinit: i32) -> i32 { test_deinit(deinit) } #[no_mangle] extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 { test_delete(delete2) } #[no_mangle] extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 { test_double(double2) } #[no_mangle] extern "C" fn _ffi_fn_test_dynamic(dynamic: i32) -> i32 { test_dynamic(dynamic) } #[no_mangle] extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast2: i32) -> i32 { test_dynamic_cast(dynamic_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_explicit(explicit2: i32) -> i32 { test_explicit(explicit2) } #[no_mangle] extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 { test_export(export2) } #[no_mangle] extern "C" fn _ffi_fn_test_extends(extends: i32) -> i32 { test_extends(extends) } #[no_mangle] extern "C" fn _ffi_fn_test_extension(extension: i32) -> i32 { test_extension(extension) } #[no_mangle] extern "C" fn _ffi_fn_test_fallthrough(fallthrough: i32) -> i32 { test_fallthrough(fallthrough) } #[no_mangle] extern "C" fn _ffi_fn_test_fileprivate(fileprivate: i32) -> i32 { test_fileprivate(fileprivate) } #[no_mangle] extern "C" fn _ffi_fn_test_finally(finally: i32) -> i32 { test_finally(finally) } #[no_mangle] extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 { test_float(float2) } #[no_mangle] extern "C" fn _ffi_fn_test_friend(friend2: i32) -> i32 { test_friend(friend2) } #[no_mangle] extern "C" fn _ffi_fn_test_func(func: i32) -> i32 { test_func(func) } #[no_mangle] extern "C" fn _ffi_fn_test_function(function: i32) -> i32 { test_function(function) } #[no_mangle] extern "C" fn _ffi_fn_test_get(get: i32) -> i32 { test_get(get) } #[no_mangle] extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 { test_goto(goto2) } #[no_mangle] extern "C" fn _ffi_fn_test_guard(guard: i32) -> i32 { test_guard(guard) } #[no_mangle] extern "C" fn _ffi_fn_test_implements(implements: i32) -> i32 { test_implements(implements) } #[no_mangle] extern "C" fn _ffi_fn_test_import(import: i32) -> i32 { test_import(import) } #[no_mangle] extern "C" fn _ffi_fn_test_indirect(indirect: i32) -> i32 { test_indirect(indirect) } #[no_mangle] extern "C" fn _ffi_fn_test_infix(infix: i32) -> i32 { test_infix(infix) } #[no_mangle] extern "C" fn _ffi_fn_test_init(init: i32) -> i32 { test_init(init) } #[no_mangle] extern "C" fn _ffi_fn_test_inline(inline2: i32) -> i32 { test_inline(inline2) } #[no_mangle] extern "C" fn _ffi_fn_test_inout(inout: i32) -> i32 { test_inout(inout) } #[no_mangle] extern "C" fn _ffi_fn_test_instanceof(instanceof: i32) -> i32 { test_instanceof(instanceof) } #[no_mangle] extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 { test_int(int2) } #[no_mangle] extern "C" fn _ffi_fn_test_interface(interface: i32) -> i32 { test_interface(interface) } #[no_mangle] extern "C" fn _ffi_fn_test_internal(internal: i32) -> i32 { test_internal(internal) } #[no_mangle] extern "C" fn _ffi_fn_test_is(is: i32) -> i32 { test_is(is) } #[no_mangle] extern "C" fn _ffi_fn_test_lazy(lazy: i32) -> i32 { test_lazy(lazy) } #[no_mangle] extern "C" fn _ffi_fn_test_left(left: i32) -> i32 { test_left(left) } #[no_mangle] extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 { test_long(long2) } #[no_mangle] extern "C" fn _ffi_fn_test_mutable(mutable2: i32) -> i32 { test_mutable(mutable2) } #[no_mangle] extern "C" fn _ffi_fn_test_mutating(mutating: i32) -> i32 { test_mutating(mutating) } #[no_mangle] extern "C" fn _ffi_fn_test_namespace(namespace2: i32) -> i32 { test_namespace(namespace2) } #[no_mangle] extern "C" fn _ffi_fn_test_native(native: i32) -> i32 { test_native(native) } #[no_mangle] extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 { test_new(new2) } #[no_mangle] extern "C" fn _ffi_fn_test_nil(nil: i32) -> i32 { test_nil(nil) } #[no_mangle] extern "C" fn _ffi_fn_test_noexcept(noexcept2: i32) -> i32 { test_noexcept(noexcept2) } #[no_mangle] extern "C" fn _ffi_fn_test_none(none: i32) -> i32 { test_none(none) } #[no_mangle] extern "C" fn _ffi_fn_test_nonisolated(nonisolated: i32) -> i32 { test_nonisolated(nonisolated) } #[no_mangle] extern "C" fn _ffi_fn_test_nonmutating(nonmutating: i32) -> i32 { test_nonmutating(nonmutating) } #[no_mangle] extern "C" fn _ffi_fn_test_not(not2: i32) -> i32 { test_not(not2) } #[no_mangle] extern "C" fn _ffi_fn_test_not_eq(not_eq2: i32) -> i32 { test_not_eq(not_eq2) } #[no_mangle] extern "C" fn _ffi_fn_test_null(null: i32) -> i32 { test_null(null) } #[no_mangle] extern "C" fn _ffi_fn_test_nullptr(nullptr2: i32) -> i32 { test_nullptr(nullptr2) } #[no_mangle] extern "C" fn _ffi_fn_test_open(open: i32) -> i32 { test_open(open) } #[no_mangle] extern "C" fn _ffi_fn_test_operator(operator2: i32) -> i32 { test_operator(operator2) } #[no_mangle] extern "C" fn _ffi_fn_test_optional(optional: i32) -> i32 { test_optional(optional) } #[no_mangle] extern "C" fn _ffi_fn_test_or(or2: i32) -> i32 { test_or(or2) } #[no_mangle] extern "C" fn _ffi_fn_test_or_eq(or_eq2: i32) -> i32 { test_or_eq(or_eq2) } #[no_mangle] extern "C" fn _ffi_fn_test_package(package: i32) -> i32 { test_package(package) } #[no_mangle] extern "C" fn _ffi_fn_test_postfix(postfix: i32) -> i32 { test_postfix(postfix) } #[no_mangle] extern "C" fn _ffi_fn_test_precedence(precedence: i32) -> i32 { test_precedence(precedence) } #[no_mangle] extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup: i32) -> i32 { test_precedencegroup(precedencegroup) } #[no_mangle] extern "C" fn _ffi_fn_test_prefix(prefix: i32) -> i32 { test_prefix(prefix) } #[no_mangle] extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 { test_private(private2) } #[no_mangle] extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 { test_protected(protected2) } #[no_mangle] extern "C" fn _ffi_fn_test_protocol(protocol: i32) -> i32 { test_protocol(protocol) } #[no_mangle] extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 { test_public(public2) } #[no_mangle] extern "C" fn _ffi_fn_test_reflexpr(reflexpr2: i32) -> i32 { test_reflexpr(reflexpr2) } #[no_mangle] extern "C" fn _ffi_fn_test_register(register2: i32) -> i32 { test_register(register2) } #[no_mangle] extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast2: i32) -> i32 { test_reinterpret_cast(reinterpret_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_repeat(repeat: i32) -> i32 { test_repeat(repeat) } #[no_mangle] extern "C" fn _ffi_fn_test_required(required: i32) -> i32 { test_required(required) } #[no_mangle] extern "C" fn _ffi_fn_test_requires(requires2: i32) -> i32 { test_requires(requires2) } #[no_mangle] extern "C" fn _ffi_fn_test_rethrows(rethrows: i32) -> i32 { test_rethrows(rethrows) } #[no_mangle] extern "C" fn _ffi_fn_test_right(right: i32) -> i32 { test_right(right) } #[no_mangle] extern "C" fn _ffi_fn_test_set(set: i32) -> i32 { test_set(set) } #[no_mangle] extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 { test_short(short2) } #[no_mangle] extern "C" fn _ffi_fn_test_signed(signed2: i32) -> i32 { test_signed(signed2) } #[no_mangle] extern "C" fn _ffi_fn_test_sizeof(sizeof2: i32) -> i32 { test_sizeof(sizeof2) } #[no_mangle] extern "C" fn _ffi_fn_test_some(some: i32) -> i32 { test_some(some) } #[no_mangle] extern "C" fn _ffi_fn_test_static_assert(static_assert2: i32) -> i32 { test_static_assert(static_assert2) } #[no_mangle] extern "C" fn _ffi_fn_test_static_cast(static_cast2: i32) -> i32 { test_static_cast(static_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_subscript(subscript: i32) -> i32 { test_subscript(subscript) } #[no_mangle] extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 { test_switch(switch2) } #[no_mangle] extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 { test_synchronized(synchronized2) } #[no_mangle] extern "C" fn _ffi_fn_test_template(template2: i32) -> i32 { test_template(template2) } #[no_mangle] extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 { test_this(this2) } #[no_mangle] extern "C" fn _ffi_fn_test_thread_local(thread_local2: i32) -> i32 { test_thread_local(thread_local2) } #[no_mangle] extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 { test_throw(throw2) } #[no_mangle] extern "C" fn _ffi_fn_test_throws(throws: i32) -> i32 { test_throws(throws) } #[no_mangle] extern "C" fn _ffi_fn_test_transient(transient: i32) -> i32 { test_transient(transient) } #[no_mangle] extern "C" fn _ffi_fn_test_typealias(typealias: i32) -> i32 { test_typealias(typealias) } #[no_mangle] extern "C" fn _ffi_fn_test_typedef(typedef2: i32) -> i32 { test_typedef(typedef2) } #[no_mangle] extern "C" fn _ffi_fn_test_typeid(typeid2: i32) -> i32 { test_typeid(typeid2) } #[no_mangle] extern "C" fn _ffi_fn_test_typename(typename2: i32) -> i32 { test_typename(typename2) } #[no_mangle] extern "C" fn _ffi_fn_test_undefined(undefined: i32) -> i32 { test_undefined(undefined) } #[no_mangle] extern "C" fn _ffi_fn_test_union(union2: i32) -> i32 { test_union(union2) } #[no_mangle] extern "C" fn _ffi_fn_test_unowned(unowned: i32) -> i32 { test_unowned(unowned) } #[no_mangle] extern "C" fn _ffi_fn_test_unsigned(unsigned2: i32) -> i32 { test_unsigned(unsigned2) } #[no_mangle] extern "C" fn _ffi_fn_test_using(using2: i32) -> i32 { test_using(using2) } #[no_mangle] extern "C" fn _ffi_fn_test_var(var: i32) -> i32 { test_var(var) } #[no_mangle] extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 { test_void(void2) } #[no_mangle] extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 { test_volatile(volatile2) } #[no_mangle] extern "C" fn _ffi_fn_test_wchar_t(wchar_t2: i32) -> i32 { test_wchar_t(wchar_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_weak(weak: i32) -> i32 { test_weak(weak) } #[no_mangle] extern "C" fn _ffi_fn_test_with(with: i32) -> i32 { test_with(with) } #[no_mangle] extern "C" fn _ffi_fn_test_xor(xor2: i32) -> i32 { test_xor(xor2) } #[no_mangle] extern "C" fn _ffi_fn_test_xor_eq(xor_eq2: i32) -> i32 { test_xor_eq(xor_eq2) } ================================================ FILE: src/tests/snapshots/cpp_demo_keyword_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test_alignas(int32_t alignas2); int32_t _ffi_fn_test_alignof(int32_t alignof2); int32_t _ffi_fn_test_and(int32_t and2); int32_t _ffi_fn_test_and_eq(int32_t and_eq2); int32_t _ffi_fn_test_asm(int32_t asm2); int32_t _ffi_fn_test_associatedtype(int32_t associatedtype); int32_t _ffi_fn_test_associativity(int32_t associativity); int32_t _ffi_fn_test_atomic_cancel(int32_t atomic_cancel2); int32_t _ffi_fn_test_atomic_commit(int32_t atomic_commit2); int32_t _ffi_fn_test_atomic_noexcept(int32_t atomic_noexcept2); int32_t _ffi_fn_test_auto(int32_t auto2); int32_t _ffi_fn_test_bitand(int32_t bitand2); int32_t _ffi_fn_test_bitor(int32_t bitor2); int32_t _ffi_fn_test_bool(int32_t bool2); int32_t _ffi_fn_test_boolean(int32_t boolean); int32_t _ffi_fn_test_borrowing(int32_t borrowing); int32_t _ffi_fn_test_byte(int32_t byte); int32_t _ffi_fn_test_case(int32_t case2); int32_t _ffi_fn_test_catch(int32_t catch2); int32_t _ffi_fn_test_char(int32_t char2); int32_t _ffi_fn_test_char16_t(int32_t char16_t2); int32_t _ffi_fn_test_char32_t(int32_t char32_t2); int32_t _ffi_fn_test_char8_t(int32_t char8_t2); int32_t _ffi_fn_test_class(int32_t class2); int32_t _ffi_fn_test_co_await(int32_t co_await2); int32_t _ffi_fn_test_co_return(int32_t co_return2); int32_t _ffi_fn_test_co_yield(int32_t co_yield2); int32_t _ffi_fn_test_compl(int32_t compl2); int32_t _ffi_fn_test_concept(int32_t concept2); int32_t _ffi_fn_test_const_cast(int32_t const_cast2); int32_t _ffi_fn_test_consteval(int32_t consteval2); int32_t _ffi_fn_test_constexpr(int32_t constexpr2); int32_t _ffi_fn_test_constinit(int32_t constinit2); int32_t _ffi_fn_test_consuming(int32_t consuming); int32_t _ffi_fn_test_contract_assert(int32_t contract_assert2); int32_t _ffi_fn_test_convenience(int32_t convenience); int32_t _ffi_fn_test_debugger(int32_t debugger); int32_t _ffi_fn_test_decltype(int32_t decltype2); int32_t _ffi_fn_test_default(int32_t default2); int32_t _ffi_fn_test_defer(int32_t defer); int32_t _ffi_fn_test_deinit(int32_t deinit); int32_t _ffi_fn_test_delete(int32_t delete2); int32_t _ffi_fn_test_double(int32_t double2); int32_t _ffi_fn_test_dynamic(int32_t dynamic); int32_t _ffi_fn_test_dynamic_cast(int32_t dynamic_cast2); int32_t _ffi_fn_test_explicit(int32_t explicit2); int32_t _ffi_fn_test_export(int32_t export2); int32_t _ffi_fn_test_extends(int32_t extends); int32_t _ffi_fn_test_extension(int32_t extension); int32_t _ffi_fn_test_fallthrough(int32_t fallthrough); int32_t _ffi_fn_test_fileprivate(int32_t fileprivate); int32_t _ffi_fn_test_finally(int32_t finally); int32_t _ffi_fn_test_float(int32_t float2); int32_t _ffi_fn_test_friend(int32_t friend2); int32_t _ffi_fn_test_func(int32_t func); int32_t _ffi_fn_test_function(int32_t function); int32_t _ffi_fn_test_get(int32_t get); int32_t _ffi_fn_test_goto(int32_t goto2); int32_t _ffi_fn_test_guard(int32_t guard); int32_t _ffi_fn_test_implements(int32_t implements); int32_t _ffi_fn_test_import(int32_t import); int32_t _ffi_fn_test_indirect(int32_t indirect); int32_t _ffi_fn_test_infix(int32_t infix); int32_t _ffi_fn_test_init(int32_t init); int32_t _ffi_fn_test_inline(int32_t inline2); int32_t _ffi_fn_test_inout(int32_t inout); int32_t _ffi_fn_test_instanceof(int32_t instanceof); int32_t _ffi_fn_test_int(int32_t int2); int32_t _ffi_fn_test_interface(int32_t interface); int32_t _ffi_fn_test_internal(int32_t internal); int32_t _ffi_fn_test_is(int32_t is); int32_t _ffi_fn_test_lazy(int32_t lazy); int32_t _ffi_fn_test_left(int32_t left); int32_t _ffi_fn_test_long(int32_t long2); int32_t _ffi_fn_test_mutable(int32_t mutable2); int32_t _ffi_fn_test_mutating(int32_t mutating); int32_t _ffi_fn_test_namespace(int32_t namespace2); int32_t _ffi_fn_test_native(int32_t native); int32_t _ffi_fn_test_new(int32_t new2); int32_t _ffi_fn_test_nil(int32_t nil); int32_t _ffi_fn_test_noexcept(int32_t noexcept2); int32_t _ffi_fn_test_none(int32_t none); int32_t _ffi_fn_test_nonisolated(int32_t nonisolated); int32_t _ffi_fn_test_nonmutating(int32_t nonmutating); int32_t _ffi_fn_test_not(int32_t not2); int32_t _ffi_fn_test_not_eq(int32_t not_eq2); int32_t _ffi_fn_test_null(int32_t null); int32_t _ffi_fn_test_nullptr(int32_t nullptr2); int32_t _ffi_fn_test_open(int32_t open); int32_t _ffi_fn_test_operator(int32_t operator2); int32_t _ffi_fn_test_optional(int32_t optional); int32_t _ffi_fn_test_or(int32_t or2); int32_t _ffi_fn_test_or_eq(int32_t or_eq2); int32_t _ffi_fn_test_package(int32_t package); int32_t _ffi_fn_test_postfix(int32_t postfix); int32_t _ffi_fn_test_precedence(int32_t precedence); int32_t _ffi_fn_test_precedencegroup(int32_t precedencegroup); int32_t _ffi_fn_test_prefix(int32_t prefix); int32_t _ffi_fn_test_private(int32_t private2); int32_t _ffi_fn_test_protected(int32_t protected2); int32_t _ffi_fn_test_protocol(int32_t protocol); int32_t _ffi_fn_test_public(int32_t public2); int32_t _ffi_fn_test_reflexpr(int32_t reflexpr2); int32_t _ffi_fn_test_register(int32_t register2); int32_t _ffi_fn_test_reinterpret_cast(int32_t reinterpret_cast2); int32_t _ffi_fn_test_repeat(int32_t repeat); int32_t _ffi_fn_test_required(int32_t required); int32_t _ffi_fn_test_requires(int32_t requires2); int32_t _ffi_fn_test_rethrows(int32_t rethrows); int32_t _ffi_fn_test_right(int32_t right); int32_t _ffi_fn_test_set(int32_t set); int32_t _ffi_fn_test_short(int32_t short2); int32_t _ffi_fn_test_signed(int32_t signed2); int32_t _ffi_fn_test_sizeof(int32_t sizeof2); int32_t _ffi_fn_test_some(int32_t some); int32_t _ffi_fn_test_static_assert(int32_t static_assert2); int32_t _ffi_fn_test_static_cast(int32_t static_cast2); int32_t _ffi_fn_test_subscript(int32_t subscript); int32_t _ffi_fn_test_switch(int32_t switch2); int32_t _ffi_fn_test_synchronized(int32_t synchronized2); int32_t _ffi_fn_test_template(int32_t template2); int32_t _ffi_fn_test_this(int32_t this2); int32_t _ffi_fn_test_thread_local(int32_t thread_local2); int32_t _ffi_fn_test_throw(int32_t throw2); int32_t _ffi_fn_test_throws(int32_t throws); int32_t _ffi_fn_test_transient(int32_t transient); int32_t _ffi_fn_test_typealias(int32_t typealias); int32_t _ffi_fn_test_typedef(int32_t typedef2); int32_t _ffi_fn_test_typeid(int32_t typeid2); int32_t _ffi_fn_test_typename(int32_t typename2); int32_t _ffi_fn_test_undefined(int32_t undefined); int32_t _ffi_fn_test_union(int32_t union2); int32_t _ffi_fn_test_unowned(int32_t unowned); int32_t _ffi_fn_test_unsigned(int32_t unsigned2); int32_t _ffi_fn_test_using(int32_t using2); int32_t _ffi_fn_test_var(int32_t var); int32_t _ffi_fn_test_void(int32_t void2); int32_t _ffi_fn_test_volatile(int32_t volatile2); int32_t _ffi_fn_test_wchar_t(int32_t wchar_t2); int32_t _ffi_fn_test_weak(int32_t weak); int32_t _ffi_fn_test_with(int32_t with); int32_t _ffi_fn_test_xor(int32_t xor2); int32_t _ffi_fn_test_xor_eq(int32_t xor_eq2); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::test_alignas(int32_t alignas2) { return _ffi_fn_test_alignas(alignas2); } int32_t rust::test_alignof(int32_t alignof2) { return _ffi_fn_test_alignof(alignof2); } int32_t rust::test_and(int32_t and2) { return _ffi_fn_test_and(and2); } int32_t rust::test_and_eq(int32_t and_eq2) { return _ffi_fn_test_and_eq(and_eq2); } int32_t rust::test_asm(int32_t asm2) { return _ffi_fn_test_asm(asm2); } int32_t rust::test_associatedtype(int32_t associatedtype) { return _ffi_fn_test_associatedtype(associatedtype); } int32_t rust::test_associativity(int32_t associativity) { return _ffi_fn_test_associativity(associativity); } int32_t rust::test_atomic_cancel(int32_t atomic_cancel2) { return _ffi_fn_test_atomic_cancel(atomic_cancel2); } int32_t rust::test_atomic_commit(int32_t atomic_commit2) { return _ffi_fn_test_atomic_commit(atomic_commit2); } int32_t rust::test_atomic_noexcept(int32_t atomic_noexcept2) { return _ffi_fn_test_atomic_noexcept(atomic_noexcept2); } int32_t rust::test_auto(int32_t auto2) { return _ffi_fn_test_auto(auto2); } int32_t rust::test_bitand(int32_t bitand2) { return _ffi_fn_test_bitand(bitand2); } int32_t rust::test_bitor(int32_t bitor2) { return _ffi_fn_test_bitor(bitor2); } int32_t rust::test_bool(int32_t bool2) { return _ffi_fn_test_bool(bool2); } int32_t rust::test_boolean(int32_t boolean) { return _ffi_fn_test_boolean(boolean); } int32_t rust::test_borrowing(int32_t borrowing) { return _ffi_fn_test_borrowing(borrowing); } int32_t rust::test_byte(int32_t byte) { return _ffi_fn_test_byte(byte); } int32_t rust::test_case(int32_t case2) { return _ffi_fn_test_case(case2); } int32_t rust::test_catch(int32_t catch2) { return _ffi_fn_test_catch(catch2); } int32_t rust::test_char(int32_t char2) { return _ffi_fn_test_char(char2); } int32_t rust::test_char16_t(int32_t char16_t2) { return _ffi_fn_test_char16_t(char16_t2); } int32_t rust::test_char32_t(int32_t char32_t2) { return _ffi_fn_test_char32_t(char32_t2); } int32_t rust::test_char8_t(int32_t char8_t2) { return _ffi_fn_test_char8_t(char8_t2); } int32_t rust::test_class(int32_t class2) { return _ffi_fn_test_class(class2); } int32_t rust::test_co_await(int32_t co_await2) { return _ffi_fn_test_co_await(co_await2); } int32_t rust::test_co_return(int32_t co_return2) { return _ffi_fn_test_co_return(co_return2); } int32_t rust::test_co_yield(int32_t co_yield2) { return _ffi_fn_test_co_yield(co_yield2); } int32_t rust::test_compl(int32_t compl2) { return _ffi_fn_test_compl(compl2); } int32_t rust::test_concept(int32_t concept2) { return _ffi_fn_test_concept(concept2); } int32_t rust::test_const_cast(int32_t const_cast2) { return _ffi_fn_test_const_cast(const_cast2); } int32_t rust::test_consteval(int32_t consteval2) { return _ffi_fn_test_consteval(consteval2); } int32_t rust::test_constexpr(int32_t constexpr2) { return _ffi_fn_test_constexpr(constexpr2); } int32_t rust::test_constinit(int32_t constinit2) { return _ffi_fn_test_constinit(constinit2); } int32_t rust::test_consuming(int32_t consuming) { return _ffi_fn_test_consuming(consuming); } int32_t rust::test_contract_assert(int32_t contract_assert2) { return _ffi_fn_test_contract_assert(contract_assert2); } int32_t rust::test_convenience(int32_t convenience) { return _ffi_fn_test_convenience(convenience); } int32_t rust::test_debugger(int32_t debugger) { return _ffi_fn_test_debugger(debugger); } int32_t rust::test_decltype(int32_t decltype2) { return _ffi_fn_test_decltype(decltype2); } int32_t rust::test_default(int32_t default2) { return _ffi_fn_test_default(default2); } int32_t rust::test_defer(int32_t defer) { return _ffi_fn_test_defer(defer); } int32_t rust::test_deinit(int32_t deinit) { return _ffi_fn_test_deinit(deinit); } int32_t rust::test_delete(int32_t delete2) { return _ffi_fn_test_delete(delete2); } int32_t rust::test_double(int32_t double2) { return _ffi_fn_test_double(double2); } int32_t rust::test_dynamic(int32_t dynamic) { return _ffi_fn_test_dynamic(dynamic); } int32_t rust::test_dynamic_cast(int32_t dynamic_cast2) { return _ffi_fn_test_dynamic_cast(dynamic_cast2); } int32_t rust::test_explicit(int32_t explicit2) { return _ffi_fn_test_explicit(explicit2); } int32_t rust::test_export(int32_t export2) { return _ffi_fn_test_export(export2); } int32_t rust::test_extends(int32_t extends) { return _ffi_fn_test_extends(extends); } int32_t rust::test_extension(int32_t extension) { return _ffi_fn_test_extension(extension); } int32_t rust::test_fallthrough(int32_t fallthrough) { return _ffi_fn_test_fallthrough(fallthrough); } int32_t rust::test_fileprivate(int32_t fileprivate) { return _ffi_fn_test_fileprivate(fileprivate); } int32_t rust::test_finally(int32_t finally) { return _ffi_fn_test_finally(finally); } int32_t rust::test_float(int32_t float2) { return _ffi_fn_test_float(float2); } int32_t rust::test_friend(int32_t friend2) { return _ffi_fn_test_friend(friend2); } int32_t rust::test_func(int32_t func) { return _ffi_fn_test_func(func); } int32_t rust::test_function(int32_t function) { return _ffi_fn_test_function(function); } int32_t rust::test_get(int32_t get) { return _ffi_fn_test_get(get); } int32_t rust::test_goto(int32_t goto2) { return _ffi_fn_test_goto(goto2); } int32_t rust::test_guard(int32_t guard) { return _ffi_fn_test_guard(guard); } int32_t rust::test_implements(int32_t implements) { return _ffi_fn_test_implements(implements); } int32_t rust::test_import(int32_t import) { return _ffi_fn_test_import(import); } int32_t rust::test_indirect(int32_t indirect) { return _ffi_fn_test_indirect(indirect); } int32_t rust::test_infix(int32_t infix) { return _ffi_fn_test_infix(infix); } int32_t rust::test_init(int32_t init) { return _ffi_fn_test_init(init); } int32_t rust::test_inline(int32_t inline2) { return _ffi_fn_test_inline(inline2); } int32_t rust::test_inout(int32_t inout) { return _ffi_fn_test_inout(inout); } int32_t rust::test_instanceof(int32_t instanceof) { return _ffi_fn_test_instanceof(instanceof); } int32_t rust::test_int(int32_t int2) { return _ffi_fn_test_int(int2); } int32_t rust::test_interface(int32_t interface) { return _ffi_fn_test_interface(interface); } int32_t rust::test_internal(int32_t internal) { return _ffi_fn_test_internal(internal); } int32_t rust::test_is(int32_t is) { return _ffi_fn_test_is(is); } int32_t rust::test_lazy(int32_t lazy) { return _ffi_fn_test_lazy(lazy); } int32_t rust::test_left(int32_t left) { return _ffi_fn_test_left(left); } int32_t rust::test_long(int32_t long2) { return _ffi_fn_test_long(long2); } int32_t rust::test_mutable(int32_t mutable2) { return _ffi_fn_test_mutable(mutable2); } int32_t rust::test_mutating(int32_t mutating) { return _ffi_fn_test_mutating(mutating); } int32_t rust::test_namespace(int32_t namespace2) { return _ffi_fn_test_namespace(namespace2); } int32_t rust::test_native(int32_t native) { return _ffi_fn_test_native(native); } int32_t rust::test_new(int32_t new2) { return _ffi_fn_test_new(new2); } int32_t rust::test_nil(int32_t nil) { return _ffi_fn_test_nil(nil); } int32_t rust::test_noexcept(int32_t noexcept2) { return _ffi_fn_test_noexcept(noexcept2); } int32_t rust::test_none(int32_t none) { return _ffi_fn_test_none(none); } int32_t rust::test_nonisolated(int32_t nonisolated) { return _ffi_fn_test_nonisolated(nonisolated); } int32_t rust::test_nonmutating(int32_t nonmutating) { return _ffi_fn_test_nonmutating(nonmutating); } int32_t rust::test_not(int32_t not2) { return _ffi_fn_test_not(not2); } int32_t rust::test_not_eq(int32_t not_eq2) { return _ffi_fn_test_not_eq(not_eq2); } int32_t rust::test_null(int32_t null) { return _ffi_fn_test_null(null); } int32_t rust::test_nullptr(int32_t nullptr2) { return _ffi_fn_test_nullptr(nullptr2); } int32_t rust::test_open(int32_t open) { return _ffi_fn_test_open(open); } int32_t rust::test_operator(int32_t operator2) { return _ffi_fn_test_operator(operator2); } int32_t rust::test_optional(int32_t optional) { return _ffi_fn_test_optional(optional); } int32_t rust::test_or(int32_t or2) { return _ffi_fn_test_or(or2); } int32_t rust::test_or_eq(int32_t or_eq2) { return _ffi_fn_test_or_eq(or_eq2); } int32_t rust::test_package(int32_t package) { return _ffi_fn_test_package(package); } int32_t rust::test_postfix(int32_t postfix) { return _ffi_fn_test_postfix(postfix); } int32_t rust::test_precedence(int32_t precedence) { return _ffi_fn_test_precedence(precedence); } int32_t rust::test_precedencegroup(int32_t precedencegroup) { return _ffi_fn_test_precedencegroup(precedencegroup); } int32_t rust::test_prefix(int32_t prefix) { return _ffi_fn_test_prefix(prefix); } int32_t rust::test_private(int32_t private2) { return _ffi_fn_test_private(private2); } int32_t rust::test_protected(int32_t protected2) { return _ffi_fn_test_protected(protected2); } int32_t rust::test_protocol(int32_t protocol) { return _ffi_fn_test_protocol(protocol); } int32_t rust::test_public(int32_t public2) { return _ffi_fn_test_public(public2); } int32_t rust::test_reflexpr(int32_t reflexpr2) { return _ffi_fn_test_reflexpr(reflexpr2); } int32_t rust::test_register(int32_t register2) { return _ffi_fn_test_register(register2); } int32_t rust::test_reinterpret_cast(int32_t reinterpret_cast2) { return _ffi_fn_test_reinterpret_cast(reinterpret_cast2); } int32_t rust::test_repeat(int32_t repeat) { return _ffi_fn_test_repeat(repeat); } int32_t rust::test_required(int32_t required) { return _ffi_fn_test_required(required); } int32_t rust::test_requires(int32_t requires2) { return _ffi_fn_test_requires(requires2); } int32_t rust::test_rethrows(int32_t rethrows) { return _ffi_fn_test_rethrows(rethrows); } int32_t rust::test_right(int32_t right) { return _ffi_fn_test_right(right); } int32_t rust::test_set(int32_t set) { return _ffi_fn_test_set(set); } int32_t rust::test_short(int32_t short2) { return _ffi_fn_test_short(short2); } int32_t rust::test_signed(int32_t signed2) { return _ffi_fn_test_signed(signed2); } int32_t rust::test_sizeof(int32_t sizeof2) { return _ffi_fn_test_sizeof(sizeof2); } int32_t rust::test_some(int32_t some) { return _ffi_fn_test_some(some); } int32_t rust::test_static_assert(int32_t static_assert2) { return _ffi_fn_test_static_assert(static_assert2); } int32_t rust::test_static_cast(int32_t static_cast2) { return _ffi_fn_test_static_cast(static_cast2); } int32_t rust::test_subscript(int32_t subscript) { return _ffi_fn_test_subscript(subscript); } int32_t rust::test_switch(int32_t switch2) { return _ffi_fn_test_switch(switch2); } int32_t rust::test_synchronized(int32_t synchronized2) { return _ffi_fn_test_synchronized(synchronized2); } int32_t rust::test_template(int32_t template2) { return _ffi_fn_test_template(template2); } int32_t rust::test_this(int32_t this2) { return _ffi_fn_test_this(this2); } int32_t rust::test_thread_local(int32_t thread_local2) { return _ffi_fn_test_thread_local(thread_local2); } int32_t rust::test_throw(int32_t throw2) { return _ffi_fn_test_throw(throw2); } int32_t rust::test_throws(int32_t throws) { return _ffi_fn_test_throws(throws); } int32_t rust::test_transient(int32_t transient) { return _ffi_fn_test_transient(transient); } int32_t rust::test_typealias(int32_t typealias) { return _ffi_fn_test_typealias(typealias); } int32_t rust::test_typedef(int32_t typedef2) { return _ffi_fn_test_typedef(typedef2); } int32_t rust::test_typeid(int32_t typeid2) { return _ffi_fn_test_typeid(typeid2); } int32_t rust::test_typename(int32_t typename2) { return _ffi_fn_test_typename(typename2); } int32_t rust::test_undefined(int32_t undefined) { return _ffi_fn_test_undefined(undefined); } int32_t rust::test_union(int32_t union2) { return _ffi_fn_test_union(union2); } int32_t rust::test_unowned(int32_t unowned) { return _ffi_fn_test_unowned(unowned); } int32_t rust::test_unsigned(int32_t unsigned2) { return _ffi_fn_test_unsigned(unsigned2); } int32_t rust::test_using(int32_t using2) { return _ffi_fn_test_using(using2); } int32_t rust::test_var(int32_t var) { return _ffi_fn_test_var(var); } int32_t rust::test_void(int32_t void2) { return _ffi_fn_test_void(void2); } int32_t rust::test_volatile(int32_t volatile2) { return _ffi_fn_test_volatile(volatile2); } int32_t rust::test_wchar_t(int32_t wchar_t2) { return _ffi_fn_test_wchar_t(wchar_t2); } int32_t rust::test_weak(int32_t weak) { return _ffi_fn_test_weak(weak); } int32_t rust::test_with(int32_t with) { return _ffi_fn_test_with(with); } int32_t rust::test_xor(int32_t xor2) { return _ffi_fn_test_xor(xor2); } int32_t rust::test_xor_eq(int32_t xor_eq2) { return _ffi_fn_test_xor_eq(xor_eq2); } ================================================ FILE: src/tests/snapshots/cpp_demo_keyword_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { uintptr_t rust_mem_leaked(); int32_t test_alignas(int32_t alignas2); int32_t test_alignof(int32_t alignof2); int32_t test_and(int32_t and2); int32_t test_and_eq(int32_t and_eq2); int32_t test_asm(int32_t asm2); int32_t test_associatedtype(int32_t associatedtype); int32_t test_associativity(int32_t associativity); int32_t test_atomic_cancel(int32_t atomic_cancel2); int32_t test_atomic_commit(int32_t atomic_commit2); int32_t test_atomic_noexcept(int32_t atomic_noexcept2); int32_t test_auto(int32_t auto2); int32_t test_bitand(int32_t bitand2); int32_t test_bitor(int32_t bitor2); int32_t test_bool(int32_t bool2); int32_t test_boolean(int32_t boolean); int32_t test_borrowing(int32_t borrowing); int32_t test_byte(int32_t byte); int32_t test_case(int32_t case2); int32_t test_catch(int32_t catch2); int32_t test_char(int32_t char2); int32_t test_char16_t(int32_t char16_t2); int32_t test_char32_t(int32_t char32_t2); int32_t test_char8_t(int32_t char8_t2); int32_t test_class(int32_t class2); int32_t test_co_await(int32_t co_await2); int32_t test_co_return(int32_t co_return2); int32_t test_co_yield(int32_t co_yield2); int32_t test_compl(int32_t compl2); int32_t test_concept(int32_t concept2); int32_t test_const_cast(int32_t const_cast2); int32_t test_consteval(int32_t consteval2); int32_t test_constexpr(int32_t constexpr2); int32_t test_constinit(int32_t constinit2); int32_t test_consuming(int32_t consuming); int32_t test_contract_assert(int32_t contract_assert2); int32_t test_convenience(int32_t convenience); int32_t test_debugger(int32_t debugger); int32_t test_decltype(int32_t decltype2); int32_t test_default(int32_t default2); int32_t test_defer(int32_t defer); int32_t test_deinit(int32_t deinit); int32_t test_delete(int32_t delete2); int32_t test_double(int32_t double2); int32_t test_dynamic(int32_t dynamic); int32_t test_dynamic_cast(int32_t dynamic_cast2); int32_t test_explicit(int32_t explicit2); int32_t test_export(int32_t export2); int32_t test_extends(int32_t extends); int32_t test_extension(int32_t extension); int32_t test_fallthrough(int32_t fallthrough); int32_t test_fileprivate(int32_t fileprivate); int32_t test_finally(int32_t finally); int32_t test_float(int32_t float2); int32_t test_friend(int32_t friend2); int32_t test_func(int32_t func); int32_t test_function(int32_t function); int32_t test_get(int32_t get); int32_t test_goto(int32_t goto2); int32_t test_guard(int32_t guard); int32_t test_implements(int32_t implements); int32_t test_import(int32_t import); int32_t test_indirect(int32_t indirect); int32_t test_infix(int32_t infix); int32_t test_init(int32_t init); int32_t test_inline(int32_t inline2); int32_t test_inout(int32_t inout); int32_t test_instanceof(int32_t instanceof); int32_t test_int(int32_t int2); int32_t test_interface(int32_t interface); int32_t test_internal(int32_t internal); int32_t test_is(int32_t is); int32_t test_lazy(int32_t lazy); int32_t test_left(int32_t left); int32_t test_long(int32_t long2); int32_t test_mutable(int32_t mutable2); int32_t test_mutating(int32_t mutating); int32_t test_namespace(int32_t namespace2); int32_t test_native(int32_t native); int32_t test_new(int32_t new2); int32_t test_nil(int32_t nil); int32_t test_noexcept(int32_t noexcept2); int32_t test_none(int32_t none); int32_t test_nonisolated(int32_t nonisolated); int32_t test_nonmutating(int32_t nonmutating); int32_t test_not(int32_t not2); int32_t test_not_eq(int32_t not_eq2); int32_t test_null(int32_t null); int32_t test_nullptr(int32_t nullptr2); int32_t test_open(int32_t open); int32_t test_operator(int32_t operator2); int32_t test_optional(int32_t optional); int32_t test_or(int32_t or2); int32_t test_or_eq(int32_t or_eq2); int32_t test_package(int32_t package); int32_t test_postfix(int32_t postfix); int32_t test_precedence(int32_t precedence); int32_t test_precedencegroup(int32_t precedencegroup); int32_t test_prefix(int32_t prefix); int32_t test_private(int32_t private2); int32_t test_protected(int32_t protected2); int32_t test_protocol(int32_t protocol); int32_t test_public(int32_t public2); int32_t test_reflexpr(int32_t reflexpr2); int32_t test_register(int32_t register2); int32_t test_reinterpret_cast(int32_t reinterpret_cast2); int32_t test_repeat(int32_t repeat); int32_t test_required(int32_t required); int32_t test_requires(int32_t requires2); int32_t test_rethrows(int32_t rethrows); int32_t test_right(int32_t right); int32_t test_set(int32_t set); int32_t test_short(int32_t short2); int32_t test_signed(int32_t signed2); int32_t test_sizeof(int32_t sizeof2); int32_t test_some(int32_t some); int32_t test_static_assert(int32_t static_assert2); int32_t test_static_cast(int32_t static_cast2); int32_t test_subscript(int32_t subscript); int32_t test_switch(int32_t switch2); int32_t test_synchronized(int32_t synchronized2); int32_t test_template(int32_t template2); int32_t test_this(int32_t this2); int32_t test_thread_local(int32_t thread_local2); int32_t test_throw(int32_t throw2); int32_t test_throws(int32_t throws); int32_t test_transient(int32_t transient); int32_t test_typealias(int32_t typealias); int32_t test_typedef(int32_t typedef2); int32_t test_typeid(int32_t typeid2); int32_t test_typename(int32_t typename2); int32_t test_undefined(int32_t undefined); int32_t test_union(int32_t union2); int32_t test_unowned(int32_t unowned); int32_t test_unsigned(int32_t unsigned2); int32_t test_using(int32_t using2); int32_t test_var(int32_t var); int32_t test_void(int32_t void2); int32_t test_volatile(int32_t volatile2); int32_t test_wchar_t(int32_t wchar_t2); int32_t test_weak(int32_t weak); int32_t test_with(int32_t with); int32_t test_xor(int32_t xor2); int32_t test_xor_eq(int32_t xor_eq2); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_keyword_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_alignas(alignas2: i32) -> i32 { test_alignas(alignas2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_alignof(alignof2: i32) -> i32 { test_alignof(alignof2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_and(and2: i32) -> i32 { test_and(and2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_and_eq(and_eq2: i32) -> i32 { test_and_eq(and_eq2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_asm(asm2: i32) -> i32 { test_asm(asm2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_associatedtype(associatedtype: i32) -> i32 { test_associatedtype(associatedtype) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_associativity(associativity: i32) -> i32 { test_associativity(associativity) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel2: i32) -> i32 { test_atomic_cancel(atomic_cancel2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit2: i32) -> i32 { test_atomic_commit(atomic_commit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept2: i32) -> i32 { test_atomic_noexcept(atomic_noexcept2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_auto(auto2: i32) -> i32 { test_auto(auto2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bitand(bitand2: i32) -> i32 { test_bitand(bitand2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bitor(bitor2: i32) -> i32 { test_bitor(bitor2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bool(bool2: i32) -> i32 { test_bool(bool2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_boolean(boolean: i32) -> i32 { test_boolean(boolean) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_borrowing(borrowing: i32) -> i32 { test_borrowing(borrowing) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_byte(byte: i32) -> i32 { test_byte(byte) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 { test_case(case2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 { test_catch(catch2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 { test_char(char2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char16_t(char16_t2: i32) -> i32 { test_char16_t(char16_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char32_t(char32_t2: i32) -> i32 { test_char32_t(char32_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char8_t(char8_t2: i32) -> i32 { test_char8_t(char8_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 { test_class(class2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_await(co_await2: i32) -> i32 { test_co_await(co_await2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_return(co_return2: i32) -> i32 { test_co_return(co_return2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_yield(co_yield2: i32) -> i32 { test_co_yield(co_yield2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_compl(compl2: i32) -> i32 { test_compl(compl2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_concept(concept2: i32) -> i32 { test_concept(concept2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_const_cast(const_cast2: i32) -> i32 { test_const_cast(const_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_consteval(consteval2: i32) -> i32 { test_consteval(consteval2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_constexpr(constexpr2: i32) -> i32 { test_constexpr(constexpr2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_constinit(constinit2: i32) -> i32 { test_constinit(constinit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_consuming(consuming: i32) -> i32 { test_consuming(consuming) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_contract_assert(contract_assert2: i32) -> i32 { test_contract_assert(contract_assert2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_convenience(convenience: i32) -> i32 { test_convenience(convenience) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_debugger(debugger: i32) -> i32 { test_debugger(debugger) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_decltype(decltype2: i32) -> i32 { test_decltype(decltype2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 { test_default(default2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_defer(defer: i32) -> i32 { test_defer(defer) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_deinit(deinit: i32) -> i32 { test_deinit(deinit) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 { test_delete(delete2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 { test_double(double2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_dynamic(dynamic: i32) -> i32 { test_dynamic(dynamic) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast2: i32) -> i32 { test_dynamic_cast(dynamic_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_explicit(explicit2: i32) -> i32 { test_explicit(explicit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 { test_export(export2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_extends(extends: i32) -> i32 { test_extends(extends) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_extension(extension: i32) -> i32 { test_extension(extension) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_fallthrough(fallthrough: i32) -> i32 { test_fallthrough(fallthrough) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_fileprivate(fileprivate: i32) -> i32 { test_fileprivate(fileprivate) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_finally(finally: i32) -> i32 { test_finally(finally) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 { test_float(float2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_friend(friend2: i32) -> i32 { test_friend(friend2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_func(func: i32) -> i32 { test_func(func) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_function(function: i32) -> i32 { test_function(function) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_get(get: i32) -> i32 { test_get(get) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 { test_goto(goto2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_guard(guard: i32) -> i32 { test_guard(guard) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_implements(implements: i32) -> i32 { test_implements(implements) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_import(import: i32) -> i32 { test_import(import) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_indirect(indirect: i32) -> i32 { test_indirect(indirect) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_infix(infix: i32) -> i32 { test_infix(infix) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_init(init: i32) -> i32 { test_init(init) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_inline(inline2: i32) -> i32 { test_inline(inline2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_inout(inout: i32) -> i32 { test_inout(inout) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_instanceof(instanceof: i32) -> i32 { test_instanceof(instanceof) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 { test_int(int2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_interface(interface: i32) -> i32 { test_interface(interface) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_internal(internal: i32) -> i32 { test_internal(internal) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_is(is: i32) -> i32 { test_is(is) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_lazy(lazy: i32) -> i32 { test_lazy(lazy) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_left(left: i32) -> i32 { test_left(left) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 { test_long(long2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_mutable(mutable2: i32) -> i32 { test_mutable(mutable2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_mutating(mutating: i32) -> i32 { test_mutating(mutating) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_namespace(namespace2: i32) -> i32 { test_namespace(namespace2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_native(native: i32) -> i32 { test_native(native) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 { test_new(new2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nil(nil: i32) -> i32 { test_nil(nil) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_noexcept(noexcept2: i32) -> i32 { test_noexcept(noexcept2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_none(none: i32) -> i32 { test_none(none) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nonisolated(nonisolated: i32) -> i32 { test_nonisolated(nonisolated) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nonmutating(nonmutating: i32) -> i32 { test_nonmutating(nonmutating) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_not(not2: i32) -> i32 { test_not(not2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_not_eq(not_eq2: i32) -> i32 { test_not_eq(not_eq2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_null(null: i32) -> i32 { test_null(null) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nullptr(nullptr2: i32) -> i32 { test_nullptr(nullptr2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_open(open: i32) -> i32 { test_open(open) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_operator(operator2: i32) -> i32 { test_operator(operator2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_optional(optional: i32) -> i32 { test_optional(optional) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_or(or2: i32) -> i32 { test_or(or2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_or_eq(or_eq2: i32) -> i32 { test_or_eq(or_eq2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_package(package: i32) -> i32 { test_package(package) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_postfix(postfix: i32) -> i32 { test_postfix(postfix) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_precedence(precedence: i32) -> i32 { test_precedence(precedence) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup: i32) -> i32 { test_precedencegroup(precedencegroup) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_prefix(prefix: i32) -> i32 { test_prefix(prefix) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 { test_private(private2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 { test_protected(protected2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_protocol(protocol: i32) -> i32 { test_protocol(protocol) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 { test_public(public2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_reflexpr(reflexpr2: i32) -> i32 { test_reflexpr(reflexpr2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_register(register2: i32) -> i32 { test_register(register2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast2: i32) -> i32 { test_reinterpret_cast(reinterpret_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_repeat(repeat: i32) -> i32 { test_repeat(repeat) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_required(required: i32) -> i32 { test_required(required) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_requires(requires2: i32) -> i32 { test_requires(requires2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_rethrows(rethrows: i32) -> i32 { test_rethrows(rethrows) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_right(right: i32) -> i32 { test_right(right) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_set(set: i32) -> i32 { test_set(set) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 { test_short(short2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_signed(signed2: i32) -> i32 { test_signed(signed2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_sizeof(sizeof2: i32) -> i32 { test_sizeof(sizeof2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_some(some: i32) -> i32 { test_some(some) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_static_assert(static_assert2: i32) -> i32 { test_static_assert(static_assert2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_static_cast(static_cast2: i32) -> i32 { test_static_cast(static_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_subscript(subscript: i32) -> i32 { test_subscript(subscript) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 { test_switch(switch2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 { test_synchronized(synchronized2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_template(template2: i32) -> i32 { test_template(template2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 { test_this(this2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_thread_local(thread_local2: i32) -> i32 { test_thread_local(thread_local2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 { test_throw(throw2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_throws(throws: i32) -> i32 { test_throws(throws) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_transient(transient: i32) -> i32 { test_transient(transient) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typealias(typealias: i32) -> i32 { test_typealias(typealias) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typedef(typedef2: i32) -> i32 { test_typedef(typedef2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typeid(typeid2: i32) -> i32 { test_typeid(typeid2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typename(typename2: i32) -> i32 { test_typename(typename2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_undefined(undefined: i32) -> i32 { test_undefined(undefined) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_union(union2: i32) -> i32 { test_union(union2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_unowned(unowned: i32) -> i32 { test_unowned(unowned) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_unsigned(unsigned2: i32) -> i32 { test_unsigned(unsigned2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_using(using2: i32) -> i32 { test_using(using2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_var(var: i32) -> i32 { test_var(var) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 { test_void(void2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 { test_volatile(volatile2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_wchar_t(wchar_t2: i32) -> i32 { test_wchar_t(wchar_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_weak(weak: i32) -> i32 { test_weak(weak) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_with(with: i32) -> i32 { test_with(with) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_xor(xor2: i32) -> i32 { test_xor(xor2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_xor_eq(xor_eq2: i32) -> i32 { test_xor_eq(xor_eq2) } ================================================ FILE: src/tests/snapshots/cpp_demo_order_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_order_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct SecondEnum; struct SecondStruct; struct SecondTrait; struct FirstEnum; struct FirstStruct; struct FirstTrait; namespace detail { struct EarlyInsideEnum__Value { bool _0 = false; }; } // namespace detail struct EarlyInsideEnum : std::variant { using Value = detail::EarlyInsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct EarlyInsideStruct { bool y = false; }; namespace detail { struct LaterInsideEnum__Value { bool _0 = false; }; } // namespace detail struct LaterInsideEnum : std::variant { using Value = detail::LaterInsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct EarlyOutsideEnum__Value { LaterInsideEnum _0; }; } // namespace detail struct EarlyOutsideEnum : std::variant { using Value = detail::EarlyOutsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct LaterInsideStruct { bool y = false; }; struct EarlyOutsideStruct { LaterInsideStruct x; }; namespace detail { struct FirstEnum__Second { std::vector _0; }; } // namespace detail struct FirstEnum : std::variant { using Second = detail::FirstEnum__Second; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct FirstStruct { std::vector second; }; struct FirstTrait { virtual ~FirstTrait() {} virtual std::shared_ptr second() = 0; }; namespace detail { struct LaterOutsideEnum__Value { EarlyInsideEnum _0; }; } // namespace detail struct LaterOutsideEnum : std::variant { using Value = detail::LaterOutsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct LaterOutsideStruct { EarlyInsideStruct x; }; namespace detail { struct SecondEnum__First { std::vector _0; }; } // namespace detail struct SecondEnum : std::variant { using First = detail::SecondEnum__First; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct SecondStruct { std::vector first; }; struct SecondTrait { virtual ~SecondTrait() {} virtual std::shared_ptr first() = 0; }; uintptr_t rust_mem_leaked(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_order_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_demo_order_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_demo_order_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct SecondEnum; struct SecondStruct; struct SecondTrait; struct FirstEnum; struct FirstStruct; struct FirstTrait; namespace detail { struct EarlyInsideEnum__Value { bool _0 = false; }; } // namespace detail struct EarlyInsideEnum : std::variant { using Value = detail::EarlyInsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct EarlyInsideStruct { bool y = false; }; namespace detail { struct LaterInsideEnum__Value { bool _0 = false; }; } // namespace detail struct LaterInsideEnum : std::variant { using Value = detail::LaterInsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; namespace detail { struct EarlyOutsideEnum__Value { LaterInsideEnum _0; }; } // namespace detail struct EarlyOutsideEnum : std::variant { using Value = detail::EarlyOutsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct LaterInsideStruct { bool y = false; }; struct EarlyOutsideStruct { LaterInsideStruct x; }; namespace detail { struct FirstEnum__Second { std::vector _0; }; } // namespace detail struct FirstEnum : std::variant { using Second = detail::FirstEnum__Second; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct FirstStruct { std::vector second; }; struct FirstTrait { virtual ~FirstTrait() {} virtual std::shared_ptr second() = 0; }; namespace detail { struct LaterOutsideEnum__Value { EarlyInsideEnum _0; }; } // namespace detail struct LaterOutsideEnum : std::variant { using Value = detail::LaterOutsideEnum__Value; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct LaterOutsideStruct { EarlyInsideStruct x; }; namespace detail { struct SecondEnum__First { std::vector _0; }; } // namespace detail struct SecondEnum : std::variant { using First = detail::SecondEnum__First; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; struct SecondStruct { std::vector first; }; struct SecondTrait { virtual ~SecondTrait() {} virtual std::shared_ptr first() = 0; }; uintptr_t rust_mem_leaked(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_order_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_demo_trait_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void _ffi_drop_Box_Trait(const void* ptr); void _ffi_drop_Rc_Trait(const void* ptr); void* _ffi_alloc(uintptr_t len); int32_t _ffi_Box_Trait__get(const void* _self); int32_t _ffi_Rc_Trait__get(const void* _self); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_2_usize _ffi_fn_test(const void* buf_ptr, uintptr_t vec_len); } // extern "C" namespace { struct _ffi_Box_Trait final : rust::Trait { _ffi_Box_Trait(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Trait() { _ffi_drop_Box_Trait(_self); } virtual int32_t get(); const void* _self; }; struct _ffi_Rc_Trait final : rust::Trait { _ffi_Rc_Trait(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Trait() { _ffi_drop_Rc_Trait(_self); } virtual int32_t get(); const void* _self; }; const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } std::vector> _ffi_vec_box_dyn_Trait_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_ptr = _ffi_read(end); auto item = std::unique_ptr(new _ffi_Box_Trait(item_ptr)); items.emplace_back(std::move(item)); } return items; } std::vector> _ffi_vec_rc_dyn_Trait_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_ptr = _ffi_read(end); auto item = std::make_shared<_ffi_Rc_Trait>(item_ptr); items.emplace_back(std::move(item)); } return items; } std::vector _ffi_vec_Example_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_box_ptr_ptr = _ffi_read(end); auto item_box_ptr = std::unique_ptr(new _ffi_Box_Trait(item_box_ptr_ptr)); auto item_rc_ptr_ptr = _ffi_read(end); auto item_rc_ptr = std::make_shared<_ffi_Rc_Trait>(item_rc_ptr_ptr); auto item_text_ptr = _ffi_read(end); auto item_text_len = _ffi_read(end); auto item_text_cap = _ffi_read(end); auto item_text = _ffi_string_from_rust(item_text_ptr, item_text_len, item_text_cap); auto item_vec_box_len = _ffi_read(end); auto item_vec_box = _ffi_vec_box_dyn_Trait_from_rust(item_vec_box_len, end); auto item_vec_rc_len = _ffi_read(end); auto item_vec_rc = _ffi_vec_rc_dyn_Trait_from_rust(item_vec_rc_len, end); auto item = rust::Example{ std::move(item_box_ptr), std::move(item_rc_ptr), std::move(item_text), std::move(item_vec_box), std::move(item_vec_rc) }; items.emplace_back(std::move(item)); } return items; } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_box_dyn_Trait_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto item_ptr = item.release(); _ffi_write(item_ptr, buf); } } void _ffi_vec_rc_dyn_Trait_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto item_ptr = new std::shared_ptr(item); _ffi_write(item_ptr, buf); } } void _ffi_vec_Example_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { auto item_box_ptr_ptr = item.box_ptr.release(); _ffi_write(item_box_ptr_ptr, buf); auto item_rc_ptr_ptr = new std::shared_ptr(item.rc_ptr); _ffi_write(item_rc_ptr_ptr, buf); uintptr_t item_text_len; const void* item_text_ptr = _ffi_string_to_rust(item.text, item_text_len); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); auto item_vec_box_len = item.vec_box.size(); _ffi_write(item_vec_box_len, buf); _ffi_vec_box_dyn_Trait_to_rust(std::move(item.vec_box), buf); auto item_vec_rc_len = item.vec_rc.size(); _ffi_write(item_vec_rc_len, buf); _ffi_vec_rc_dyn_Trait_to_rust(std::move(item.vec_rc), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace extern "C" { int32_t _ffi_cpp_Box_Trait__get(rust::Trait* _self) { return _self->get(); } int32_t _ffi_cpp_Rc_Trait__get(std::shared_ptr* _self) { return _self->get()->get(); } void _ffi_cpp_drop_Box_Trait(rust::Trait* self) { delete self; } void _ffi_cpp_drop_Rc_Trait(std::shared_ptr* self) { delete self; } } // extern "C" int32_t _ffi_Box_Trait::get() { return _ffi_Box_Trait__get(_self); } int32_t _ffi_Rc_Trait::get() { return _ffi_Rc_Trait__get(_self); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::vector rust::test(std::vector vec) { std::vector buf; auto vec_len = vec.size(); _ffi_vec_Example_to_rust(std::move(vec), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_test(buf_ptr, vec_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_vec_Example_from_rust(ret_len, buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } ================================================ FILE: src/tests/snapshots/cpp_demo_trait_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Trait; struct Example { std::unique_ptr box_ptr; std::shared_ptr rc_ptr; std::string text; std::vector> vec_box; std::vector> vec_rc; }; struct Trait { virtual ~Trait() {} virtual int32_t get() = 0; }; uintptr_t rust_mem_leaked(); std::vector test(std::vector vec); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_trait_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get() } #[no_mangle] extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_drop_Box_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_drop_Rc_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = test(_ffi_vec_Example_from_cpp(vec_len, &mut buf_end)); let mut buf2 = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Example_to_cpp(ret, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_len) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Box_Trait(*const u8); impl Drop for _ffi_rs_Box_Trait { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Box_Trait(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Trait(self.0) }; } } impl Trait for _ffi_rs_Box_Trait { fn get(&self) -> i32 { extern "C" { fn _ffi_cpp_Box_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_cpp_Box_Trait__get(self.0) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Trait(*const u8); impl Drop for _ffi_rs_Rc_Trait { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Trait(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Trait(self.0) }; } } impl Trait for _ffi_rs_Rc_Trait { fn get(&self) -> i32 { extern "C" { fn _ffi_cpp_Rc_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_cpp_Rc_Trait__get(self.0) } } } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Example_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Example { box_ptr: Box::new(_ffi_rs_Box_Trait(_ffi_read::<*const u8>(end))), rc_ptr: std::rc::Rc::new(_ffi_rs_Rc_Trait(_ffi_read::<*const u8>(end))), text: _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)), vec_box: _ffi_vec_box_dyn_Trait_from_cpp(_ffi_read::(end), end), vec_rc: _ffi_vec_rc_dyn_Trait_from_cpp(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Example_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item.box_ptr)) as *const u8, buf); _ffi_write(Box::into_raw(Box::new(item.rc_ptr)) as *const u8, buf); let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.vec_box.len(), buf); _ffi_vec_box_dyn_Trait_to_cpp(item.vec_box, buf); _ffi_write(item.vec_rc.len(), buf); _ffi_vec_rc_dyn_Trait_to_cpp(item.vec_rc, buf); } } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(Box::new(_ffi_rs_Box_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(std::rc::Rc::new(_ffi_rs_Rc_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_demo_trait_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void _ffi_drop_Box_Trait(const void* ptr); void _ffi_drop_Rc_Trait(const void* ptr); void* _ffi_alloc(uintptr_t len); int32_t _ffi_Box_Trait__get(const void* _self); int32_t _ffi_Rc_Trait__get(const void* _self); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_2_usize _ffi_fn_test(const void* buf_ptr, uintptr_t vec_len); } // extern "C" namespace { struct _ffi_Box_Trait final : rust::Trait { _ffi_Box_Trait(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Trait() { _ffi_drop_Box_Trait(_self); } virtual int32_t get(); const void* _self; }; struct _ffi_Rc_Trait final : rust::Trait { _ffi_Rc_Trait(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Trait() { _ffi_drop_Rc_Trait(_self); } virtual int32_t get(); const void* _self; }; const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } std::vector> _ffi_vec_box_dyn_Trait_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_ptr = _ffi_read(end); auto item = std::unique_ptr(new _ffi_Box_Trait(item_ptr)); items.emplace_back(std::move(item)); } return items; } std::vector> _ffi_vec_rc_dyn_Trait_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_ptr = _ffi_read(end); auto item = std::make_shared<_ffi_Rc_Trait>(item_ptr); items.emplace_back(std::move(item)); } return items; } std::vector _ffi_vec_Example_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_box_ptr_ptr = _ffi_read(end); auto item_box_ptr = std::unique_ptr(new _ffi_Box_Trait(item_box_ptr_ptr)); auto item_rc_ptr_ptr = _ffi_read(end); auto item_rc_ptr = std::make_shared<_ffi_Rc_Trait>(item_rc_ptr_ptr); auto item_text_ptr = _ffi_read(end); auto item_text_len = _ffi_read(end); auto item_text_cap = _ffi_read(end); auto item_text = _ffi_string_from_rust(item_text_ptr, item_text_len, item_text_cap); auto item_vec_box_len = _ffi_read(end); auto item_vec_box = _ffi_vec_box_dyn_Trait_from_rust(item_vec_box_len, end); auto item_vec_rc_len = _ffi_read(end); auto item_vec_rc = _ffi_vec_rc_dyn_Trait_from_rust(item_vec_rc_len, end); auto item = rust::Example{ std::move(item_box_ptr), std::move(item_rc_ptr), std::move(item_text), std::move(item_vec_box), std::move(item_vec_rc) }; items.emplace_back(std::move(item)); } return items; } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_box_dyn_Trait_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto item_ptr = item.release(); _ffi_write(item_ptr, buf); } } void _ffi_vec_rc_dyn_Trait_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto item_ptr = new std::shared_ptr(item); _ffi_write(item_ptr, buf); } } void _ffi_vec_Example_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { auto item_box_ptr_ptr = item.box_ptr.release(); _ffi_write(item_box_ptr_ptr, buf); auto item_rc_ptr_ptr = new std::shared_ptr(item.rc_ptr); _ffi_write(item_rc_ptr_ptr, buf); uintptr_t item_text_len; const void* item_text_ptr = _ffi_string_to_rust(item.text, item_text_len); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); auto item_vec_box_len = item.vec_box.size(); _ffi_write(item_vec_box_len, buf); _ffi_vec_box_dyn_Trait_to_rust(std::move(item.vec_box), buf); auto item_vec_rc_len = item.vec_rc.size(); _ffi_write(item_vec_rc_len, buf); _ffi_vec_rc_dyn_Trait_to_rust(std::move(item.vec_rc), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace extern "C" { int32_t _ffi_cpp_Box_Trait__get(rust::Trait* _self) { return _self->get(); } int32_t _ffi_cpp_Rc_Trait__get(std::shared_ptr* _self) { return _self->get()->get(); } void _ffi_cpp_drop_Box_Trait(rust::Trait* self) { delete self; } void _ffi_cpp_drop_Rc_Trait(std::shared_ptr* self) { delete self; } } // extern "C" int32_t _ffi_Box_Trait::get() { return _ffi_Box_Trait__get(_self); } int32_t _ffi_Rc_Trait::get() { return _ffi_Rc_Trait__get(_self); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::vector rust::test(std::vector vec) { std::vector buf; auto vec_len = vec.size(); _ffi_vec_Example_to_rust(std::move(vec), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_test(buf_ptr, vec_len); auto buf_ptr2 = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end2 = (const uint8_t*)buf_ptr2; auto ret = _ffi_vec_Example_from_rust(ret_len, buf_end2); _ffi_dealloc(buf_ptr2, buf_cap); return ret; } ================================================ FILE: src/tests/snapshots/cpp_demo_trait_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Trait; struct Example { std::unique_ptr box_ptr; std::shared_ptr rc_ptr; std::string text; std::vector> vec_box; std::vector> vec_rc; }; struct Trait { virtual ~Trait() {} virtual int32_t get() = 0; }; uintptr_t rust_mem_leaked(); std::vector test(std::vector vec); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_demo_trait_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Box_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = test(_ffi_vec_Example_from_cpp(vec_len, &mut buf_end)); let mut buf2 = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Example_to_cpp(ret, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_len) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Box_Trait(*const u8); impl Drop for _ffi_rs_Box_Trait { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Box_Trait(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Trait(self.0) }; } } impl Trait for _ffi_rs_Box_Trait { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_cpp_Box_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_cpp_Box_Trait__get(self.0) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Trait(*const u8); impl Drop for _ffi_rs_Rc_Trait { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Trait(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Trait(self.0) }; } } impl Trait for _ffi_rs_Rc_Trait { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_cpp_Rc_Trait__get(self.0) } } } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Example_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Example { box_ptr: Box::new(_ffi_rs_Box_Trait(_ffi_read::<*const u8>(end))), rc_ptr: std::rc::Rc::new(_ffi_rs_Rc_Trait(_ffi_read::<*const u8>(end))), text: _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)), vec_box: _ffi_vec_box_dyn_Trait_from_cpp(_ffi_read::(end), end), vec_rc: _ffi_vec_rc_dyn_Trait_from_cpp(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Example_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item.box_ptr)) as *const u8, buf); _ffi_write(Box::into_raw(Box::new(item.rc_ptr)) as *const u8, buf); let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.vec_box.len(), buf); _ffi_vec_box_dyn_Trait_to_cpp(item.vec_box, buf); _ffi_write(item.vec_rc.len(), buf); _ffi_vec_rc_dyn_Trait_to_cpp(item.vec_rc, buf); } } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(Box::new(_ffi_rs_Box_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(std::rc::Rc::new(_ffi_rs_Rc_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { bool _ffi_fn_add_bool(bool x, bool y); float _ffi_fn_add_f32(float x, float y); double _ffi_fn_add_f64(double x, double y); int16_t _ffi_fn_add_i16(int16_t x, int16_t y); int32_t _ffi_fn_add_i32(int32_t x, int32_t y); int64_t _ffi_fn_add_i64(int64_t x, int64_t y); int8_t _ffi_fn_add_i8(int8_t x, int8_t y); intptr_t _ffi_fn_add_isize(intptr_t x, intptr_t y); uint16_t _ffi_fn_add_u16(uint16_t x, uint16_t y); uint32_t _ffi_fn_add_u32(uint32_t x, uint32_t y); uint64_t _ffi_fn_add_u64(uint64_t x, uint64_t y); uint8_t _ffi_fn_add_u8(uint8_t x, uint8_t y); uintptr_t _ffi_fn_add_usize(uintptr_t x, uintptr_t y); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" bool rust::add_bool(bool x, bool y) { return _ffi_fn_add_bool(x, y); } float rust::add_f32(float x, float y) { return _ffi_fn_add_f32(x, y); } double rust::add_f64(double x, double y) { return _ffi_fn_add_f64(x, y); } int16_t rust::add_i16(int16_t x, int16_t y) { return _ffi_fn_add_i16(x, y); } int32_t rust::add_i32(int32_t x, int32_t y) { return _ffi_fn_add_i32(x, y); } int64_t rust::add_i64(int64_t x, int64_t y) { return _ffi_fn_add_i64(x, y); } int8_t rust::add_i8(int8_t x, int8_t y) { return _ffi_fn_add_i8(x, y); } intptr_t rust::add_isize(intptr_t x, intptr_t y) { return _ffi_fn_add_isize(x, y); } uint16_t rust::add_u16(uint16_t x, uint16_t y) { return _ffi_fn_add_u16(x, y); } uint32_t rust::add_u32(uint32_t x, uint32_t y) { return _ffi_fn_add_u32(x, y); } uint64_t rust::add_u64(uint64_t x, uint64_t y) { return _ffi_fn_add_u64(x, y); } uint8_t rust::add_u8(uint8_t x, uint8_t y) { return _ffi_fn_add_u8(x, y); } uintptr_t rust::add_usize(uintptr_t x, uintptr_t y) { return _ffi_fn_add_usize(x, y); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { uintptr_t rust_mem_leaked(); bool add_bool(bool x, bool y); uint8_t add_u8(uint8_t x, uint8_t y); uint16_t add_u16(uint16_t x, uint16_t y); uint32_t add_u32(uint32_t x, uint32_t y); uintptr_t add_usize(uintptr_t x, uintptr_t y); uint64_t add_u64(uint64_t x, uint64_t y); int8_t add_i8(int8_t x, int8_t y); int16_t add_i16(int16_t x, int16_t y); int32_t add_i32(int32_t x, int32_t y); intptr_t add_isize(intptr_t x, intptr_t y); int64_t add_i64(int64_t x, int64_t y); float add_f32(float x, float y); double add_f64(double x, double y); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_basic_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool { add_bool(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 { add_f32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 { add_f64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 { add_i16(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 { add_i32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 { add_i64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 { add_i8(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize { add_isize(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 { add_u16(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 { add_u32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 { add_u64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 { add_u8(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize { add_usize(x, y) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { bool _ffi_fn_add_bool(bool x, bool y); float _ffi_fn_add_f32(float x, float y); double _ffi_fn_add_f64(double x, double y); int16_t _ffi_fn_add_i16(int16_t x, int16_t y); int32_t _ffi_fn_add_i32(int32_t x, int32_t y); int64_t _ffi_fn_add_i64(int64_t x, int64_t y); int8_t _ffi_fn_add_i8(int8_t x, int8_t y); intptr_t _ffi_fn_add_isize(intptr_t x, intptr_t y); uint16_t _ffi_fn_add_u16(uint16_t x, uint16_t y); uint32_t _ffi_fn_add_u32(uint32_t x, uint32_t y); uint64_t _ffi_fn_add_u64(uint64_t x, uint64_t y); uint8_t _ffi_fn_add_u8(uint8_t x, uint8_t y); uintptr_t _ffi_fn_add_usize(uintptr_t x, uintptr_t y); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" bool rust::add_bool(bool x, bool y) { return _ffi_fn_add_bool(x, y); } float rust::add_f32(float x, float y) { return _ffi_fn_add_f32(x, y); } double rust::add_f64(double x, double y) { return _ffi_fn_add_f64(x, y); } int16_t rust::add_i16(int16_t x, int16_t y) { return _ffi_fn_add_i16(x, y); } int32_t rust::add_i32(int32_t x, int32_t y) { return _ffi_fn_add_i32(x, y); } int64_t rust::add_i64(int64_t x, int64_t y) { return _ffi_fn_add_i64(x, y); } int8_t rust::add_i8(int8_t x, int8_t y) { return _ffi_fn_add_i8(x, y); } intptr_t rust::add_isize(intptr_t x, intptr_t y) { return _ffi_fn_add_isize(x, y); } uint16_t rust::add_u16(uint16_t x, uint16_t y) { return _ffi_fn_add_u16(x, y); } uint32_t rust::add_u32(uint32_t x, uint32_t y) { return _ffi_fn_add_u32(x, y); } uint64_t rust::add_u64(uint64_t x, uint64_t y) { return _ffi_fn_add_u64(x, y); } uint8_t rust::add_u8(uint8_t x, uint8_t y) { return _ffi_fn_add_u8(x, y); } uintptr_t rust::add_usize(uintptr_t x, uintptr_t y) { return _ffi_fn_add_usize(x, y); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { uintptr_t rust_mem_leaked(); bool add_bool(bool x, bool y); uint8_t add_u8(uint8_t x, uint8_t y); uint16_t add_u16(uint16_t x, uint16_t y); uint32_t add_u32(uint32_t x, uint32_t y); uintptr_t add_usize(uintptr_t x, uintptr_t y); uint64_t add_u64(uint64_t x, uint64_t y); int8_t add_i8(int8_t x, int8_t y); int16_t add_i16(int16_t x, int16_t y); int32_t add_i32(int32_t x, int32_t y); intptr_t add_isize(intptr_t x, intptr_t y); int64_t add_i64(int64_t x, int64_t y); float add_f32(float x, float y); double add_f64(double x, double y); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_basic_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool { add_bool(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 { add_f32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 { add_f64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 { add_i16(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 { add_i32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 { add_i64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 { add_i8(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize { add_isize(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 { add_u16(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 { add_u32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 { add_u64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 { add_u8(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize { add_usize(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_void_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_fn_add_empty_tuple(int32_t x, int32_t y); void _ffi_fn_add_void(int32_t x, int32_t y); int32_t _ffi_fn_get_result(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_wild_arg(int32_t _1, int32_t _3); } // extern "C" std::tuple<> rust::add_empty_tuple(int32_t x, int32_t y) { _ffi_fn_add_empty_tuple(x, y); return std::tuple<>(); } void rust::add_void(int32_t x, int32_t y) { _ffi_fn_add_void(x, y); } int32_t rust::get_result() { return _ffi_fn_get_result(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::tuple<> rust::wild_arg(int32_t _1, std::tuple<> _2, int32_t _3) { (void)_2; _ffi_fn_wild_arg(_1, _3); return std::tuple<>(); } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_void_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); void add_void(int32_t x, int32_t y); std::tuple<> add_empty_tuple(int32_t x, int32_t y); int32_t get_result(); std::tuple<> wild_arg(int32_t _1, std::tuple<> _2, int32_t _3); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_basic_void_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) { _ = add_empty_tuple(x, y); } #[no_mangle] extern "C" fn _ffi_fn_add_void(x: i32, y: i32) { add_void(x, y); } #[no_mangle] extern "C" fn _ffi_fn_get_result() -> i32 { get_result() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) { _ = wild_arg(_1, (), _3); } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_void_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_fn_add_empty_tuple(int32_t x, int32_t y); void _ffi_fn_add_void(int32_t x, int32_t y); int32_t _ffi_fn_get_result(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_wild_arg(int32_t _1, int32_t _3); } // extern "C" std::tuple<> rust::add_empty_tuple(int32_t x, int32_t y) { _ffi_fn_add_empty_tuple(x, y); return std::tuple<>(); } void rust::add_void(int32_t x, int32_t y) { _ffi_fn_add_void(x, y); } int32_t rust::get_result() { return _ffi_fn_get_result(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::tuple<> rust::wild_arg(int32_t _1, std::tuple<> _2, int32_t _3) { (void)_2; _ffi_fn_wild_arg(_1, _3); return std::tuple<>(); } ================================================ FILE: src/tests/snapshots/cpp_fn_basic_void_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); void add_void(int32_t x, int32_t y); std::tuple<> add_empty_tuple(int32_t x, int32_t y); int32_t get_result(); std::tuple<> wild_arg(int32_t _1, std::tuple<> _2, int32_t _3); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_basic_void_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) { _ = add_empty_tuple(x, y); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_void(x: i32, y: i32) { add_void(x, y); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_result() -> i32 { get_result() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) { _ = wild_arg(_1, (), _3); } ================================================ FILE: src/tests/snapshots/cpp_fn_box_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include extern "C" { int32_t _ffi_fn_check_nested(const void* buf_ptr); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_sum_tree(int32_t tree_value, const void* buf_ptr, bool has_tree_left, bool has_tree_right); } // extern "C" namespace { template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_box_i32_to_rust(int32_t val, std::vector& buf) { _ffi_write(val, buf); } void _ffi_box_box_i32_to_rust(std::unique_ptr val, std::vector& buf) { _ffi_box_i32_to_rust(std::move(*val), buf); } void _ffi_box_box_box_i32_to_rust(std::unique_ptr> val, std::vector& buf) { _ffi_box_box_i32_to_rust(std::move(*val), buf); } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } void _ffi_box_Tree_to_rust(rust::Tree val, std::vector& buf); void _ffi_box_Tree_to_rust(rust::Tree val, std::vector& buf) { _ffi_write(val.value, buf); auto has_val_left = val.left.has_value(); _ffi_write(has_val_left, buf); if (has_val_left) { _ffi_box_Tree_to_rust(std::move(*val.left.value()), buf); } auto has_val_right = val.right.has_value(); _ffi_write(has_val_right, buf); if (has_val_right) { _ffi_box_Tree_to_rust(std::move(*val.right.value()), buf); } } } // namespace bool rust::Tree::operator == (const rust::Tree& t) const { return ( value == t.value && (left && t.left ? **left == **t.left : !left && !t.left) && (right && t.right ? **right == **t.right : !right && !t.right) ); } int32_t rust::check_nested(std::unique_ptr>> x) { std::vector buf; _ffi_box_box_box_i32_to_rust(std::move(*x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_check_nested(buf_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::sum_tree(rust::Tree tree) { std::vector buf; auto has_tree_left = tree.left.has_value(); if (has_tree_left) { _ffi_box_Tree_to_rust(std::move(*tree.left.value()), buf); } auto has_tree_right = tree.right.has_value(); if (has_tree_right) { _ffi_box_Tree_to_rust(std::move(*tree.right.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_tree(tree.value, buf_ptr, has_tree_left, has_tree_right); } ================================================ FILE: src/tests/snapshots/cpp_fn_box_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Tree; struct Tree { int32_t value = 0; std::optional> left; std::optional> right; bool operator == (const Tree&) const; bool operator != (const Tree& t) const { return !(*this == t); } }; uintptr_t rust_mem_leaked(); int32_t sum_tree(Tree tree); int32_t check_nested(std::unique_ptr>> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_box_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_from_cpp(end: &mut *const u8) -> Box { Box::new(Tree { value: _ffi_read::(end), left: _ffi_read::(end).then(|| _ffi_box_Tree_from_cpp(end)), right: _ffi_read::(end).then(|| _ffi_box_Tree_from_cpp(end)) }) } fn _ffi_box_box_box_i32_from_cpp(end: &mut *const u8) -> Box>> { Box::new(_ffi_box_box_i32_from_cpp(end)) } fn _ffi_box_box_i32_from_cpp(end: &mut *const u8) -> Box> { Box::new(_ffi_box_i32_from_cpp(end)) } fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 { let mut buf_end = buf_ptr; let ret = check_nested(_ffi_box_box_box_i32_from_cpp(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_tree_left: bool, has_tree_right: bool) -> i32 { let mut buf_end = buf_ptr; let ret = sum_tree(Tree { value: tree_value, left: has_tree_left.then(|| _ffi_box_Tree_from_cpp(&mut buf_end)), right: has_tree_right.then(|| _ffi_box_Tree_from_cpp(&mut buf_end)) }); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ================================================ FILE: src/tests/snapshots/cpp_fn_box_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include extern "C" { int32_t _ffi_fn_check_nested(const void* buf_ptr); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_sum_tree(int32_t tree_value, const void* buf_ptr, bool has_tree_left, bool has_tree_right); } // extern "C" namespace { template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_box_i32_to_rust(int32_t val, std::vector& buf) { _ffi_write(val, buf); } void _ffi_box_box_i32_to_rust(std::unique_ptr val, std::vector& buf) { _ffi_box_i32_to_rust(std::move(*val), buf); } void _ffi_box_box_box_i32_to_rust(std::unique_ptr> val, std::vector& buf) { _ffi_box_box_i32_to_rust(std::move(*val), buf); } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } void _ffi_box_Tree_to_rust(rust::Tree val, std::vector& buf); void _ffi_box_Tree_to_rust(rust::Tree val, std::vector& buf) { _ffi_write(val.value, buf); auto has_val_left = val.left.has_value(); _ffi_write(has_val_left, buf); if (has_val_left) { _ffi_box_Tree_to_rust(std::move(*val.left.value()), buf); } auto has_val_right = val.right.has_value(); _ffi_write(has_val_right, buf); if (has_val_right) { _ffi_box_Tree_to_rust(std::move(*val.right.value()), buf); } } } // namespace bool rust::Tree::operator == (const rust::Tree& t) const { return ( value == t.value && (left && t.left ? **left == **t.left : !left && !t.left) && (right && t.right ? **right == **t.right : !right && !t.right) ); } int32_t rust::check_nested(std::unique_ptr>> x) { std::vector buf; _ffi_box_box_box_i32_to_rust(std::move(*x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_check_nested(buf_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::sum_tree(rust::Tree tree) { std::vector buf; auto has_tree_left = tree.left.has_value(); if (has_tree_left) { _ffi_box_Tree_to_rust(std::move(*tree.left.value()), buf); } auto has_tree_right = tree.right.has_value(); if (has_tree_right) { _ffi_box_Tree_to_rust(std::move(*tree.right.value()), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_tree(tree.value, buf_ptr, has_tree_left, has_tree_right); } ================================================ FILE: src/tests/snapshots/cpp_fn_box_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Tree; struct Tree { int32_t value = 0; std::optional> left; std::optional> right; bool operator == (const Tree&) const; bool operator != (const Tree& t) const { return !(*this == t); } }; uintptr_t rust_mem_leaked(); int32_t sum_tree(Tree tree); int32_t check_nested(std::unique_ptr>> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_box_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_from_cpp(end: &mut *const u8) -> Box { Box::new(Tree { value: _ffi_read::(end), left: _ffi_read::(end).then(|| _ffi_box_Tree_from_cpp(end)), right: _ffi_read::(end).then(|| _ffi_box_Tree_from_cpp(end)) }) } fn _ffi_box_box_box_i32_from_cpp(end: &mut *const u8) -> Box>> { Box::new(_ffi_box_box_i32_from_cpp(end)) } fn _ffi_box_box_i32_from_cpp(end: &mut *const u8) -> Box> { Box::new(_ffi_box_i32_from_cpp(end)) } fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 { let mut buf_end = buf_ptr; let ret = check_nested(_ffi_box_box_box_i32_from_cpp(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_tree_left: bool, has_tree_right: bool) -> i32 { let mut buf_end = buf_ptr; let ret = sum_tree(Tree { value: tree_value, left: has_tree_left.then(|| _ffi_box_Tree_from_cpp(&mut buf_end)), right: has_tree_right.then(|| _ffi_box_Tree_from_cpp(&mut buf_end)) }); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ================================================ FILE: src/tests/snapshots/cpp_fn_box_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_i32_ptr_usize_2_bool { int32_t _0; const void* _1; uintptr_t _2; bool _3; bool _4; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize _ffi_fn_check_nested(int32_t x); _ffi_ret_i32_ptr_usize_2_bool _ffi_fn_get_tree(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::unique_ptr _ffi_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_read(end); return std::make_unique(val); } std::unique_ptr> _ffi_box_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_box_i32_from_rust(end); return std::make_unique>(std::move(val)); } std::unique_ptr>> _ffi_box_box_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_box_box_i32_from_rust(end); return std::make_unique>>(std::move(val)); } std::unique_ptr _ffi_box_Tree_from_rust(const uint8_t*& end); std::unique_ptr _ffi_box_Tree_from_rust(const uint8_t*& end) { auto val_value = _ffi_read(end); auto val_left = _ffi_read(end) ? std::make_optional(_ffi_box_Tree_from_rust(end)) : std::nullopt; auto val_right = _ffi_read(end) ? std::make_optional(_ffi_box_Tree_from_rust(end)) : std::nullopt; auto val = rust::Tree{val_value, std::move(val_left), std::move(val_right)}; return std::make_unique(std::move(val)); } } // namespace bool rust::Nested::operator == (const rust::Nested& n) const { return ***_0 == ***n._0; } bool rust::Tree::operator == (const rust::Tree& t) const { return ( value == t.value && (left && t.left ? **left == **t.left : !left && !t.left) && (right && t.right ? **right == **t.right : !right && !t.right) ); } rust::Nested rust::check_nested(int32_t x) { auto multi_ret = _ffi_fn_check_nested(x); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end = (const uint8_t*)buf_ptr; auto ret_0 = _ffi_box_box_box_i32_from_rust(buf_end); auto ret = rust::Nested{std::move(ret_0)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } rust::Tree rust::get_tree() { auto multi_ret = _ffi_fn_get_tree(); auto ret_value = multi_ret._0; auto buf_ptr = multi_ret._1; auto buf_cap = multi_ret._2; auto has_ret_left = multi_ret._3; auto has_ret_right = multi_ret._4; auto buf_end = (const uint8_t*)buf_ptr; auto ret_left = has_ret_left ? std::make_optional(_ffi_box_Tree_from_rust(buf_end)) : std::nullopt; auto ret_right = has_ret_right ? std::make_optional(_ffi_box_Tree_from_rust(buf_end)) : std::nullopt; auto ret = rust::Tree{ret_value, std::move(ret_left), std::move(ret_right)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_box_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Tree; struct Nested { std::unique_ptr>> _0; bool operator == (const Nested&) const; bool operator != (const Nested& n) const { return !(*this == n); } }; struct Tree { int32_t value = 0; std::optional> left; std::optional> right; bool operator == (const Tree&) const; bool operator != (const Tree& t) const { return !(*this == t); } }; uintptr_t rust_mem_leaked(); Tree get_tree(); Nested check_nested(int32_t x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_box_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_to_cpp(val: Tree, buf: &mut Vec) { _ffi_write(val.value, buf); _ffi_write(val.left.is_some(), buf); if let Some(val_left_val) = val.left { _ffi_box_Tree_to_cpp(*val_left_val, buf); } _ffi_write(val.right.is_some(), buf); if let Some(val_right_val) = val.right { _ffi_box_Tree_to_cpp(*val_right_val, buf); } } fn _ffi_box_box_box_i32_to_cpp(val: Box>, buf: &mut Vec) { _ffi_box_box_i32_to_cpp(*val, buf); } fn _ffi_box_box_i32_to_cpp(val: Box, buf: &mut Vec) { _ffi_box_i32_to_cpp(*val, buf); } fn _ffi_box_i32_to_cpp(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_nested(x: i32) -> _ffi_ret_ptr_usize { let ret = check_nested(x); let ret_0 = ret.0; let mut buf = Vec::::new(); _ffi_box_box_box_i32_to_cpp(*ret_0, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_get_tree() -> _ffi_ret_i32_ptr_usize_2_bool { let ret = get_tree(); let ret_value = ret.value; let ret_left = ret.left; let mut buf = Vec::::new(); let has_ret_left = ret_left.is_some(); if let Some(ret_left_val) = ret_left { _ffi_box_Tree_to_cpp(*ret_left_val, &mut buf); } let ret_right = ret.right; let has_ret_right = ret_right.is_some(); if let Some(ret_right_val) = ret_right { _ffi_box_Tree_to_cpp(*ret_right_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_usize_2_bool(ret_value, buf_ptr, buf_cap, has_ret_left, has_ret_right) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_box_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_i32_ptr_usize_2_bool { int32_t _0; const void* _1; uintptr_t _2; bool _3; bool _4; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize _ffi_fn_check_nested(int32_t x); _ffi_ret_i32_ptr_usize_2_bool _ffi_fn_get_tree(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::unique_ptr _ffi_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_read(end); return std::make_unique(val); } std::unique_ptr> _ffi_box_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_box_i32_from_rust(end); return std::make_unique>(std::move(val)); } std::unique_ptr>> _ffi_box_box_box_i32_from_rust(const uint8_t*& end) { auto val = _ffi_box_box_i32_from_rust(end); return std::make_unique>>(std::move(val)); } std::unique_ptr _ffi_box_Tree_from_rust(const uint8_t*& end); std::unique_ptr _ffi_box_Tree_from_rust(const uint8_t*& end) { auto val_value = _ffi_read(end); auto val_left = _ffi_read(end) ? std::make_optional(_ffi_box_Tree_from_rust(end)) : std::nullopt; auto val_right = _ffi_read(end) ? std::make_optional(_ffi_box_Tree_from_rust(end)) : std::nullopt; auto val = rust::Tree{val_value, std::move(val_left), std::move(val_right)}; return std::make_unique(std::move(val)); } } // namespace bool rust::Nested::operator == (const rust::Nested& n) const { return ***_0 == ***n._0; } bool rust::Tree::operator == (const rust::Tree& t) const { return ( value == t.value && (left && t.left ? **left == **t.left : !left && !t.left) && (right && t.right ? **right == **t.right : !right && !t.right) ); } rust::Nested rust::check_nested(int32_t x) { auto multi_ret = _ffi_fn_check_nested(x); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end = (const uint8_t*)buf_ptr; auto ret_0 = _ffi_box_box_box_i32_from_rust(buf_end); auto ret = rust::Nested{std::move(ret_0)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } rust::Tree rust::get_tree() { auto multi_ret = _ffi_fn_get_tree(); auto ret_value = multi_ret._0; auto buf_ptr = multi_ret._1; auto buf_cap = multi_ret._2; auto has_ret_left = multi_ret._3; auto has_ret_right = multi_ret._4; auto buf_end = (const uint8_t*)buf_ptr; auto ret_left = has_ret_left ? std::make_optional(_ffi_box_Tree_from_rust(buf_end)) : std::nullopt; auto ret_right = has_ret_right ? std::make_optional(_ffi_box_Tree_from_rust(buf_end)) : std::nullopt; auto ret = rust::Tree{ret_value, std::move(ret_left), std::move(ret_right)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_box_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Tree; struct Nested { std::unique_ptr>> _0; bool operator == (const Nested&) const; bool operator != (const Nested& n) const { return !(*this == n); } }; struct Tree { int32_t value = 0; std::optional> left; std::optional> right; bool operator == (const Tree&) const; bool operator != (const Tree& t) const { return !(*this == t); } }; uintptr_t rust_mem_leaked(); Tree get_tree(); Nested check_nested(int32_t x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_box_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_to_cpp(val: Tree, buf: &mut Vec) { _ffi_write(val.value, buf); _ffi_write(val.left.is_some(), buf); if let Some(val_left_val) = val.left { _ffi_box_Tree_to_cpp(*val_left_val, buf); } _ffi_write(val.right.is_some(), buf); if let Some(val_right_val) = val.right { _ffi_box_Tree_to_cpp(*val_right_val, buf); } } fn _ffi_box_box_box_i32_to_cpp(val: Box>, buf: &mut Vec) { _ffi_box_box_i32_to_cpp(*val, buf); } fn _ffi_box_box_i32_to_cpp(val: Box, buf: &mut Vec) { _ffi_box_i32_to_cpp(*val, buf); } fn _ffi_box_i32_to_cpp(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(x: i32) -> _ffi_ret_ptr_usize { let ret = check_nested(x); let ret_0 = ret.0; let mut buf = Vec::::new(); _ffi_box_box_box_i32_to_cpp(*ret_0, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_tree() -> _ffi_ret_i32_ptr_usize_2_bool { let ret = get_tree(); let ret_value = ret.value; let ret_left = ret.left; let mut buf = Vec::::new(); let has_ret_left = ret_left.is_some(); if let Some(ret_left_val) = ret_left { _ffi_box_Tree_to_cpp(*ret_left_val, &mut buf); } let ret_right = ret.right; let has_ret_right = ret_right.is_some(); if let Some(ret_right_val) = ret_right { _ffi_box_Tree_to_cpp(*ret_right_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_usize_2_bool(ret_value, buf_ptr, buf_cap, has_ret_left, has_ret_right) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { _ffi_ret_ptr_2_usize _ffi_fn_check_combo(int32_t foo_x_0_x, const void* buf_ptr, uintptr_t foo_x_0_y_len, uintptr_t foo_x_1_len, uintptr_t foo_y_len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } void _ffi_vec_Bar_to_rust(std::vector&& items, std::vector& buf); void _ffi_vec_Foo_to_rust(std::vector&& items, std::vector& buf); template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec__i32_f32_bool_to_rust(std::vector, std::tuple, std::tuple>>&& items, std::vector& buf) { for (auto&& item : items) { (void)std::get<0>(item); _ffi_write(std::get<0>(std::get<1>(item)), buf); _ffi_write(std::get<0>(std::get<2>(item)), buf); _ffi_write(std::get<1>(std::get<2>(item)), buf); } } void _ffi_vec_Foo_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item.x).x, buf); auto item_x_0_y_len = std::get<0>(item.x).y.size(); _ffi_write(item_x_0_y_len, buf); _ffi_vec_Foo_to_rust(std::move(std::get<0>(item.x).y), buf); auto item_x_1_len = std::get<1>(item.x).size(); _ffi_write(item_x_1_len, buf); _ffi_vec_Bar_to_rust(std::move(std::get<1>(item.x)), buf); auto item_y_len = item.y.size(); _ffi_write(item_y_len, buf); _ffi_vec__i32_f32_bool_to_rust(std::move(item.y), buf); } } void _ffi_vec_Bar_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item.x, buf); auto item_y_len = item.y.size(); _ffi_write(item_y_len, buf); _ffi_vec_Foo_to_rust(std::move(item.y), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace std::string rust::check_combo(rust::Foo foo) { std::vector buf; auto foo_x_0_y_len = std::get<0>(foo.x).y.size(); _ffi_vec_Foo_to_rust(std::move(std::get<0>(foo.x).y), buf); auto foo_x_1_len = std::get<1>(foo.x).size(); _ffi_vec_Bar_to_rust(std::move(std::get<1>(foo.x)), buf); auto foo_y_len = foo.y.size(); _ffi_vec__i32_f32_bool_to_rust(std::move(foo.y), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_check_combo(std::get<0>(foo.x).x, buf_ptr, foo_x_0_y_len, foo_x_1_len, foo_y_len); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Foo; struct Bar; struct Bar { int32_t x = 0; std::vector y; }; struct Foo { std::tuple> x; std::vector, std::tuple, std::tuple>> y; }; uintptr_t rust_mem_leaked(); std::string check_combo(Foo foo); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_combo_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, foo_x_0_y_len: usize, foo_x_1_len: usize, foo_y_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_combo(Foo { x: ( Bar { x: foo_x_0_x, y: _ffi_vec_Foo_from_cpp(foo_x_0_y_len, &mut buf_end) }, _ffi_vec_Bar_from_cpp(foo_x_1_len, &mut buf_end) ), y: _ffi_vec__i32_f32_bool_from_cpp(foo_y_len, &mut buf_end) })); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Bar_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_cpp(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Foo { x: ( Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_cpp(_ffi_read::(end), end) }, _ffi_vec_Bar_from_cpp(_ffi_read::(end), end) ), y: _ffi_vec__i32_f32_bool_from_cpp(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_from_cpp(len: usize, end: &mut *const u8) -> Vec<((), (i32,), (f32, bool))> { let mut items = Vec::<((), (i32,), (f32, bool))>::with_capacity(len); for _ in 0..len { items.push(((), (_ffi_read::(end),), (_ffi_read::(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { _ffi_ret_ptr_2_usize _ffi_fn_check_combo(int32_t foo_x_0_x, const void* buf_ptr, uintptr_t foo_x_0_y_len, uintptr_t foo_x_1_len, uintptr_t foo_y_len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } void _ffi_vec_Bar_to_rust(std::vector&& items, std::vector& buf); void _ffi_vec_Foo_to_rust(std::vector&& items, std::vector& buf); template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec__i32_f32_bool_to_rust(std::vector, std::tuple, std::tuple>>&& items, std::vector& buf) { for (auto&& item : items) { (void)std::get<0>(item); _ffi_write(std::get<0>(std::get<1>(item)), buf); _ffi_write(std::get<0>(std::get<2>(item)), buf); _ffi_write(std::get<1>(std::get<2>(item)), buf); } } void _ffi_vec_Foo_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item.x).x, buf); auto item_x_0_y_len = std::get<0>(item.x).y.size(); _ffi_write(item_x_0_y_len, buf); _ffi_vec_Foo_to_rust(std::move(std::get<0>(item.x).y), buf); auto item_x_1_len = std::get<1>(item.x).size(); _ffi_write(item_x_1_len, buf); _ffi_vec_Bar_to_rust(std::move(std::get<1>(item.x)), buf); auto item_y_len = item.y.size(); _ffi_write(item_y_len, buf); _ffi_vec__i32_f32_bool_to_rust(std::move(item.y), buf); } } void _ffi_vec_Bar_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item.x, buf); auto item_y_len = item.y.size(); _ffi_write(item_y_len, buf); _ffi_vec_Foo_to_rust(std::move(item.y), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace std::string rust::check_combo(rust::Foo foo) { std::vector buf; auto foo_x_0_y_len = std::get<0>(foo.x).y.size(); _ffi_vec_Foo_to_rust(std::move(std::get<0>(foo.x).y), buf); auto foo_x_1_len = std::get<1>(foo.x).size(); _ffi_vec_Bar_to_rust(std::move(std::get<1>(foo.x)), buf); auto foo_y_len = foo.y.size(); _ffi_vec__i32_f32_bool_to_rust(std::move(foo.y), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_check_combo(std::get<0>(foo.x).x, buf_ptr, foo_x_0_y_len, foo_x_1_len, foo_y_len); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Foo; struct Bar; struct Bar { int32_t x = 0; std::vector y; }; struct Foo { std::tuple> x; std::vector, std::tuple, std::tuple>> y; }; uintptr_t rust_mem_leaked(); std::string check_combo(Foo foo); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_combo_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, foo_x_0_y_len: usize, foo_x_1_len: usize, foo_y_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_combo(Foo { x: ( Bar { x: foo_x_0_x, y: _ffi_vec_Foo_from_cpp(foo_x_0_y_len, &mut buf_end) }, _ffi_vec_Bar_from_cpp(foo_x_1_len, &mut buf_end) ), y: _ffi_vec__i32_f32_bool_from_cpp(foo_y_len, &mut buf_end) })); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Bar_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_cpp(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Foo { x: ( Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_cpp(_ffi_read::(end), end) }, _ffi_vec_Bar_from_cpp(_ffi_read::(end), end) ), y: _ffi_vec__i32_f32_bool_from_cpp(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_from_cpp(len: usize, end: &mut *const u8) -> Vec<((), (i32,), (f32, bool))> { let mut items = Vec::<((), (i32,), (f32, bool))>::with_capacity(len); for _ in 0..len { items.push(((), (_ffi_read::(end),), (_ffi_read::(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_i32_ptr_4_usize { int32_t _0; const void* _1; uintptr_t _2; uintptr_t _3; uintptr_t _4; uintptr_t _5; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo1(); _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo2(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::vector _ffi_vec_Bar_from_rust(uintptr_t len, const uint8_t*& end); std::vector _ffi_vec_Foo_from_rust(uintptr_t len, const uint8_t*& end); std::vector, std::tuple, std::tuple>> _ffi_vec__i32_f32_bool_from_rust(uintptr_t len, const uint8_t*& end) { std::vector, std::tuple, std::tuple>> items; items.reserve(len); while (items.size() < len) { auto item_0 = std::tuple<>(); auto item_1_0 = _ffi_read(end); auto item_1 = item_1_0; auto item_2_0 = _ffi_read(end); auto item_2_1 = _ffi_read(end); auto item_2 = std::make_tuple(item_2_0, item_2_1); auto item = std::make_tuple(std::move(item_0), std::move(item_1), std::move(item_2)); items.emplace_back(std::move(item)); } return items; } std::vector _ffi_vec_Foo_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_x_0_x = _ffi_read(end); auto item_x_0_y_len = _ffi_read(end); auto item_x_0_y = _ffi_vec_Foo_from_rust(item_x_0_y_len, end); auto item_x_0 = rust::Bar{item_x_0_x, std::move(item_x_0_y)}; auto item_x_1_len = _ffi_read(end); auto item_x_1 = _ffi_vec_Bar_from_rust(item_x_1_len, end); auto item_x = std::make_tuple(std::move(item_x_0), std::move(item_x_1)); auto item_y_len = _ffi_read(end); auto item_y = _ffi_vec__i32_f32_bool_from_rust(item_y_len, end); auto item = rust::Foo{std::move(item_x), std::move(item_y)}; items.emplace_back(std::move(item)); } return items; } std::vector _ffi_vec_Bar_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_x = _ffi_read(end); auto item_y_len = _ffi_read(end); auto item_y = _ffi_vec_Foo_from_rust(item_y_len, end); auto item = rust::Bar{item_x, std::move(item_y)}; items.emplace_back(std::move(item)); } return items; } } // namespace bool rust::Bar::operator == (const rust::Bar& b) const { return x == b.x && y == b.y; } bool rust::Foo::operator == (const rust::Foo& f) const { return x == f.x && y == f.y; } rust::Foo rust::check_combo1() { auto multi_ret = _ffi_fn_check_combo1(); auto ret_x_0_x = multi_ret._0; auto buf_ptr = multi_ret._1; auto buf_cap = multi_ret._2; auto ret_x_0_y_len = multi_ret._3; auto ret_x_1_len = multi_ret._4; auto ret_y_len = multi_ret._5; auto buf_end = (const uint8_t*)buf_ptr; auto ret_x_0_y = _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf_end); auto ret_x_0 = rust::Bar{ret_x_0_x, std::move(ret_x_0_y)}; auto ret_x_1 = _ffi_vec_Bar_from_rust(ret_x_1_len, buf_end); auto ret_x = std::make_tuple(std::move(ret_x_0), std::move(ret_x_1)); auto ret_y = _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf_end); auto ret = rust::Foo{std::move(ret_x), std::move(ret_y)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } rust::Foo rust::check_combo2() { auto multi_ret = _ffi_fn_check_combo2(); auto ret_x_0_x = multi_ret._0; auto buf_ptr = multi_ret._1; auto buf_cap = multi_ret._2; auto ret_x_0_y_len = multi_ret._3; auto ret_x_1_len = multi_ret._4; auto ret_y_len = multi_ret._5; auto buf_end = (const uint8_t*)buf_ptr; auto ret_x_0_y = _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf_end); auto ret_x_0 = rust::Bar{ret_x_0_x, std::move(ret_x_0_y)}; auto ret_x_1 = _ffi_vec_Bar_from_rust(ret_x_1_len, buf_end); auto ret_x = std::make_tuple(std::move(ret_x_0), std::move(ret_x_1)); auto ret_y = _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf_end); auto ret = rust::Foo{std::move(ret_x), std::move(ret_y)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Foo; struct Bar; struct Bar { int32_t x = 0; std::vector y; bool operator == (const Bar&) const; bool operator != (const Bar& b) const { return !(*this == b); } }; struct Foo { std::tuple> x; std::vector, std::tuple, std::tuple>> y; bool operator == (const Foo&) const; bool operator != (const Foo& f) const { return !(*this == f); } }; uintptr_t rust_mem_leaked(); Foo check_combo1(); Foo check_combo2(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_combo_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_combo1() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo1(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_cpp(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_cpp(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_cpp(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[no_mangle] extern "C" fn _ffi_fn_check_combo2() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo2(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_cpp(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_cpp(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_cpp(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Bar_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x, buf); _ffi_write(item.y.len(), buf); _ffi_vec_Foo_to_cpp(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec_Foo_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x.0.x, buf); _ffi_write(item.x.0.y.len(), buf); _ffi_vec_Foo_to_cpp(item.x.0.y, buf); _ffi_write(item.x.1.len(), buf); _ffi_vec_Bar_to_cpp(item.x.1, buf); _ffi_write(item.y.len(), buf); _ffi_vec__i32_f32_bool_to_cpp(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_to_cpp(items: Vec<((), (i32,), (f32, bool))>, buf: &mut Vec) { for item in items { _ = item.0; _ffi_write(item.1.0, buf); _ffi_write(item.2.0, buf); _ffi_write(item.2.1, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_i32_ptr_4_usize { int32_t _0; const void* _1; uintptr_t _2; uintptr_t _3; uintptr_t _4; uintptr_t _5; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo1(); _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo2(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::vector _ffi_vec_Bar_from_rust(uintptr_t len, const uint8_t*& end); std::vector _ffi_vec_Foo_from_rust(uintptr_t len, const uint8_t*& end); std::vector, std::tuple, std::tuple>> _ffi_vec__i32_f32_bool_from_rust(uintptr_t len, const uint8_t*& end) { std::vector, std::tuple, std::tuple>> items; items.reserve(len); while (items.size() < len) { auto item_0 = std::tuple<>(); auto item_1_0 = _ffi_read(end); auto item_1 = item_1_0; auto item_2_0 = _ffi_read(end); auto item_2_1 = _ffi_read(end); auto item_2 = std::make_tuple(item_2_0, item_2_1); auto item = std::make_tuple(std::move(item_0), std::move(item_1), std::move(item_2)); items.emplace_back(std::move(item)); } return items; } std::vector _ffi_vec_Foo_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_x_0_x = _ffi_read(end); auto item_x_0_y_len = _ffi_read(end); auto item_x_0_y = _ffi_vec_Foo_from_rust(item_x_0_y_len, end); auto item_x_0 = rust::Bar{item_x_0_x, std::move(item_x_0_y)}; auto item_x_1_len = _ffi_read(end); auto item_x_1 = _ffi_vec_Bar_from_rust(item_x_1_len, end); auto item_x = std::make_tuple(std::move(item_x_0), std::move(item_x_1)); auto item_y_len = _ffi_read(end); auto item_y = _ffi_vec__i32_f32_bool_from_rust(item_y_len, end); auto item = rust::Foo{std::move(item_x), std::move(item_y)}; items.emplace_back(std::move(item)); } return items; } std::vector _ffi_vec_Bar_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item_x = _ffi_read(end); auto item_y_len = _ffi_read(end); auto item_y = _ffi_vec_Foo_from_rust(item_y_len, end); auto item = rust::Bar{item_x, std::move(item_y)}; items.emplace_back(std::move(item)); } return items; } } // namespace bool rust::Bar::operator == (const rust::Bar& b) const { return x == b.x && y == b.y; } bool rust::Foo::operator == (const rust::Foo& f) const { return x == f.x && y == f.y; } rust::Foo rust::check_combo1() { auto multi_ret = _ffi_fn_check_combo1(); auto ret_x_0_x = multi_ret._0; auto buf_ptr = multi_ret._1; auto buf_cap = multi_ret._2; auto ret_x_0_y_len = multi_ret._3; auto ret_x_1_len = multi_ret._4; auto ret_y_len = multi_ret._5; auto buf_end = (const uint8_t*)buf_ptr; auto ret_x_0_y = _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf_end); auto ret_x_0 = rust::Bar{ret_x_0_x, std::move(ret_x_0_y)}; auto ret_x_1 = _ffi_vec_Bar_from_rust(ret_x_1_len, buf_end); auto ret_x = std::make_tuple(std::move(ret_x_0), std::move(ret_x_1)); auto ret_y = _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf_end); auto ret = rust::Foo{std::move(ret_x), std::move(ret_y)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } rust::Foo rust::check_combo2() { auto multi_ret = _ffi_fn_check_combo2(); auto ret_x_0_x = multi_ret._0; auto buf_ptr = multi_ret._1; auto buf_cap = multi_ret._2; auto ret_x_0_y_len = multi_ret._3; auto ret_x_1_len = multi_ret._4; auto ret_y_len = multi_ret._5; auto buf_end = (const uint8_t*)buf_ptr; auto ret_x_0_y = _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf_end); auto ret_x_0 = rust::Bar{ret_x_0_x, std::move(ret_x_0_y)}; auto ret_x_1 = _ffi_vec_Bar_from_rust(ret_x_1_len, buf_end); auto ret_x = std::make_tuple(std::move(ret_x_0), std::move(ret_x_1)); auto ret_y = _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf_end); auto ret = rust::Foo{std::move(ret_x), std::move(ret_y)}; _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_combo_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Foo; struct Bar; struct Bar { int32_t x = 0; std::vector y; bool operator == (const Bar&) const; bool operator != (const Bar& b) const { return !(*this == b); } }; struct Foo { std::tuple> x; std::vector, std::tuple, std::tuple>> y; bool operator == (const Foo&) const; bool operator != (const Foo& f) const { return !(*this == f); } }; uintptr_t rust_mem_leaked(); Foo check_combo1(); Foo check_combo2(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_combo_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo1() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo1(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_cpp(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_cpp(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_cpp(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo2() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo2(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_cpp(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_cpp(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_cpp(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Bar_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x, buf); _ffi_write(item.y.len(), buf); _ffi_vec_Foo_to_cpp(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec_Foo_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x.0.x, buf); _ffi_write(item.x.0.y.len(), buf); _ffi_vec_Foo_to_cpp(item.x.0.y, buf); _ffi_write(item.x.1.len(), buf); _ffi_vec_Bar_to_cpp(item.x.1, buf); _ffi_write(item.y.len(), buf); _ffi_vec__i32_f32_bool_to_cpp(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_to_cpp(items: Vec<((), (i32,), (f32, bool))>, buf: &mut Vec) { for item in items { _ = item.0; _ffi_write(item.1.0, buf); _ffi_write(item.2.0, buf); _ffi_write(item.2.1, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include #include extern "C" { int32_t _ffi_fn_big_to_i32(int32_t big_raw); int32_t _ffi_fn_foo_to_i32(int32_t foo_raw); void _ffi_fn_long_in(const void* buf_ptr); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_enum_LongEnum_to_rust(rust::LongEnum val, std::vector& buf) { if (val.is()) { _ffi_write(int32_t(0), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(1), buf); _ffi_write(it->_0, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->a, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(3), buf); _ffi_write(it->_0, buf); _ffi_write(it->_1, buf); _ffi_write(it->_2, buf); _ffi_write(it->_3, buf); _ffi_write(it->_4, buf); _ffi_write(it->_5, buf); _ffi_write(it->_6, buf); _ffi_write(it->_7, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(4), buf); _ffi_write(it->a, buf); _ffi_write(it->b, buf); _ffi_write(it->c, buf); _ffi_write(it->d, buf); _ffi_write(it->e, buf); _ffi_write(it->f, buf); } else { abort(); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace int32_t rust::big_to_i32(rust::Big big) { return _ffi_fn_big_to_i32(int32_t(big)); } int32_t rust::foo_to_i32(rust::Foo foo) { return _ffi_fn_foo_to_i32(int32_t(foo)); } void rust::long_in(rust::LongEnum _1) { std::vector buf; _ffi_enum_LongEnum_to_rust(std::move(_1), buf); auto buf_ptr = _ffi_vec_to_rust(buf); _ffi_fn_long_in(buf_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { enum struct Big : int32_t { Min = -2147483647 - 1, Max = 2147483647, }; enum struct Foo : int32_t { Zero = 0, One = 1, Hundred = 100, }; namespace detail { struct LongEnum__Empty { }; struct LongEnum__ShortTuple { int32_t _0 = 0; }; struct LongEnum__ShortStruct { int32_t a = 0; }; struct LongEnum__LongTuple { int32_t _0 = 0; int32_t _1 = 0; int32_t _2 = 0; int32_t _3 = 0; int32_t _4 = 0; int32_t _5 = 0; int32_t _6 = 0; int32_t _7 = 0; }; struct LongEnum__LongStruct { int32_t a = 0; int32_t b = 0; int32_t c = 0; int32_t d = 0; int32_t e = 0; int32_t f = 0; }; } // namespace detail struct LongEnum : std::variant { using Empty = detail::LongEnum__Empty; using ShortTuple = detail::LongEnum__ShortTuple; using ShortStruct = detail::LongEnum__ShortStruct; using LongTuple = detail::LongEnum__LongTuple; using LongStruct = detail::LongEnum__LongStruct; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); int32_t foo_to_i32(Foo foo); int32_t big_to_i32(Big big); void long_in(LongEnum _1); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_enum_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Big_from_cpp(val: i32) -> Big { match val { -2147483648 => Big::Min, 2147483647 => Big::Max, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_cpp(val: i32) -> Foo { match val { 0 => Foo::Zero, 1 => Foo::One, 100 => Foo::Hundred, _ => panic!(), } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_from_cpp(end: &mut *const u8) -> LongEnum { match _ffi_read::(end) { 0 => LongEnum::Empty, 1 => LongEnum::ShortTuple(_ffi_read::(end)), 2 => LongEnum::ShortStruct { a: _ffi_read::(end) }, 3 => LongEnum::LongTuple( _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end) ), 4 => LongEnum::LongStruct { a: _ffi_read::(end), b: _ffi_read::(end), c: _ffi_read::(end), d: _ffi_read::(end), e: _ffi_read::(end), f: _ffi_read::(end) }, _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 { big_to_i32(_ffi_enum_Big_from_cpp(big_raw)) } #[no_mangle] extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 { foo_to_i32(_ffi_enum_Foo_from_cpp(foo_raw)) } #[no_mangle] extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) { let mut buf_end = buf_ptr; long_in(_ffi_enum_LongEnum_from_cpp(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include #include extern "C" { int32_t _ffi_fn_big_to_i32(int32_t big_raw); int32_t _ffi_fn_foo_to_i32(int32_t foo_raw); void _ffi_fn_long_in(const void* buf_ptr); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_enum_LongEnum_to_rust(rust::LongEnum val, std::vector& buf) { if (val.is()) { _ffi_write(int32_t(0), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(1), buf); _ffi_write(it->_0, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->a, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(3), buf); _ffi_write(it->_0, buf); _ffi_write(it->_1, buf); _ffi_write(it->_2, buf); _ffi_write(it->_3, buf); _ffi_write(it->_4, buf); _ffi_write(it->_5, buf); _ffi_write(it->_6, buf); _ffi_write(it->_7, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(4), buf); _ffi_write(it->a, buf); _ffi_write(it->b, buf); _ffi_write(it->c, buf); _ffi_write(it->d, buf); _ffi_write(it->e, buf); _ffi_write(it->f, buf); } else { abort(); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace int32_t rust::big_to_i32(rust::Big big) { return _ffi_fn_big_to_i32(int32_t(big)); } int32_t rust::foo_to_i32(rust::Foo foo) { return _ffi_fn_foo_to_i32(int32_t(foo)); } void rust::long_in(rust::LongEnum _1) { std::vector buf; _ffi_enum_LongEnum_to_rust(std::move(_1), buf); auto buf_ptr = _ffi_vec_to_rust(buf); _ffi_fn_long_in(buf_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { enum struct Big : int32_t { Min = -2147483647 - 1, Max = 2147483647, }; enum struct Foo : int32_t { Zero = 0, One = 1, Hundred = 100, }; namespace detail { struct LongEnum__Empty { }; struct LongEnum__ShortTuple { int32_t _0 = 0; }; struct LongEnum__ShortStruct { int32_t a = 0; }; struct LongEnum__LongTuple { int32_t _0 = 0; int32_t _1 = 0; int32_t _2 = 0; int32_t _3 = 0; int32_t _4 = 0; int32_t _5 = 0; int32_t _6 = 0; int32_t _7 = 0; }; struct LongEnum__LongStruct { int32_t a = 0; int32_t b = 0; int32_t c = 0; int32_t d = 0; int32_t e = 0; int32_t f = 0; }; } // namespace detail struct LongEnum : std::variant { using Empty = detail::LongEnum__Empty; using ShortTuple = detail::LongEnum__ShortTuple; using ShortStruct = detail::LongEnum__ShortStruct; using LongTuple = detail::LongEnum__LongTuple; using LongStruct = detail::LongEnum__LongStruct; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); int32_t foo_to_i32(Foo foo); int32_t big_to_i32(Big big); void long_in(LongEnum _1); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_enum_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Big_from_cpp(val: i32) -> Big { match val { -2147483648 => Big::Min, 2147483647 => Big::Max, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_cpp(val: i32) -> Foo { match val { 0 => Foo::Zero, 1 => Foo::One, 100 => Foo::Hundred, _ => panic!(), } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_from_cpp(end: &mut *const u8) -> LongEnum { match _ffi_read::(end) { 0 => LongEnum::Empty, 1 => LongEnum::ShortTuple(_ffi_read::(end)), 2 => LongEnum::ShortStruct { a: _ffi_read::(end) }, 3 => LongEnum::LongTuple( _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end) ), 4 => LongEnum::LongStruct { a: _ffi_read::(end), b: _ffi_read::(end), c: _ffi_read::(end), d: _ffi_read::(end), e: _ffi_read::(end), f: _ffi_read::(end) }, _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 { big_to_i32(_ffi_enum_Big_from_cpp(big_raw)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 { foo_to_i32(_ffi_enum_Foo_from_cpp(foo_raw)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) { let mut buf_end = buf_ptr; long_in(_ffi_enum_LongEnum_from_cpp(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { int32_t _ffi_fn_i32_to_big(int32_t big); int32_t _ffi_fn_i32_to_foo(int32_t foo); void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize _ffi_fn_long_out(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } rust::LongEnum _ffi_enum_LongEnum_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: return rust::LongEnum{rust::LongEnum::Empty{}}; case 1: { auto x = _ffi_read(end); return rust::LongEnum{rust::LongEnum::ShortTuple{x}}; } case 2: { auto a = _ffi_read(end); return rust::LongEnum{rust::LongEnum::ShortStruct{a}}; } case 3: { auto x0 = _ffi_read(end); auto x1 = _ffi_read(end); auto x2 = _ffi_read(end); auto x3 = _ffi_read(end); auto x4 = _ffi_read(end); auto x5 = _ffi_read(end); auto x6 = _ffi_read(end); auto x7 = _ffi_read(end); return rust::LongEnum{rust::LongEnum::LongTuple{x0, x1, x2, x3, x4, x5, x6, x7}}; } case 4: { auto a = _ffi_read(end); auto b = _ffi_read(end); auto c = _ffi_read(end); auto d = _ffi_read(end); auto e = _ffi_read(end); auto f = _ffi_read(end); return rust::LongEnum{rust::LongEnum::LongStruct{a, b, c, d, e, f}}; } default: abort(); } } } // namespace rust::Big rust::i32_to_big(int32_t big) { auto ret_raw = _ffi_fn_i32_to_big(big); return rust::Big(ret_raw); } rust::Foo rust::i32_to_foo(int32_t foo) { auto ret_raw = _ffi_fn_i32_to_foo(foo); return rust::Foo(ret_raw); } rust::LongEnum rust::long_out() { auto multi_ret = _ffi_fn_long_out(); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_enum_LongEnum_from_rust(buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { enum struct Big : int32_t { Min = -2147483647 - 1, Max = 2147483647, }; enum struct Foo : int32_t { Zero = 0, One = 1, Hundred = 100, }; namespace detail { struct LongEnum__Empty { }; struct LongEnum__ShortTuple { int32_t _0 = 0; }; struct LongEnum__ShortStruct { int32_t a = 0; }; struct LongEnum__LongTuple { int32_t _0 = 0; int32_t _1 = 0; int32_t _2 = 0; int32_t _3 = 0; int32_t _4 = 0; int32_t _5 = 0; int32_t _6 = 0; int32_t _7 = 0; }; struct LongEnum__LongStruct { int32_t a = 0; int32_t b = 0; int32_t c = 0; int32_t d = 0; int32_t e = 0; int32_t f = 0; }; } // namespace detail struct LongEnum : std::variant { using Empty = detail::LongEnum__Empty; using ShortTuple = detail::LongEnum__ShortTuple; using ShortStruct = detail::LongEnum__ShortStruct; using LongTuple = detail::LongEnum__LongTuple; using LongStruct = detail::LongEnum__LongStruct; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); Foo i32_to_foo(int32_t foo); Big i32_to_big(int32_t big); LongEnum long_out(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_enum_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_to_cpp(val: LongEnum, buf: &mut Vec) { match val { LongEnum::Empty => _ffi_write(0 as i32, buf), LongEnum::ShortTuple(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } LongEnum::ShortStruct { a } => { _ffi_write(2 as i32, buf); _ffi_write(a, buf); } LongEnum::LongTuple(x0, x1, x2, x3, x4, x5, x6, x7) => { _ffi_write(3 as i32, buf); _ffi_write(x0, buf); _ffi_write(x1, buf); _ffi_write(x2, buf); _ffi_write(x3, buf); _ffi_write(x4, buf); _ffi_write(x5, buf); _ffi_write(x6, buf); _ffi_write(x7, buf); } LongEnum::LongStruct { a, b, c, d, e, f } => { _ffi_write(4 as i32, buf); _ffi_write(a, buf); _ffi_write(b, buf); _ffi_write(c, buf); _ffi_write(d, buf); _ffi_write(e, buf); _ffi_write(f, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 { i32_to_big(big) as i32 } #[no_mangle] extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 { i32_to_foo(foo) as i32 } #[no_mangle] extern "C" fn _ffi_fn_long_out() -> _ffi_ret_ptr_usize { let mut buf = Vec::::new(); _ffi_enum_LongEnum_to_cpp(long_out(), &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); ================================================ FILE: src/tests/snapshots/cpp_fn_enum_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { int32_t _ffi_fn_i32_to_big(int32_t big); int32_t _ffi_fn_i32_to_foo(int32_t foo); void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize _ffi_fn_long_out(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } rust::LongEnum _ffi_enum_LongEnum_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: return rust::LongEnum{rust::LongEnum::Empty{}}; case 1: { auto x = _ffi_read(end); return rust::LongEnum{rust::LongEnum::ShortTuple{x}}; } case 2: { auto a = _ffi_read(end); return rust::LongEnum{rust::LongEnum::ShortStruct{a}}; } case 3: { auto x0 = _ffi_read(end); auto x1 = _ffi_read(end); auto x2 = _ffi_read(end); auto x3 = _ffi_read(end); auto x4 = _ffi_read(end); auto x5 = _ffi_read(end); auto x6 = _ffi_read(end); auto x7 = _ffi_read(end); return rust::LongEnum{rust::LongEnum::LongTuple{x0, x1, x2, x3, x4, x5, x6, x7}}; } case 4: { auto a = _ffi_read(end); auto b = _ffi_read(end); auto c = _ffi_read(end); auto d = _ffi_read(end); auto e = _ffi_read(end); auto f = _ffi_read(end); return rust::LongEnum{rust::LongEnum::LongStruct{a, b, c, d, e, f}}; } default: abort(); } } } // namespace rust::Big rust::i32_to_big(int32_t big) { auto ret_raw = _ffi_fn_i32_to_big(big); return rust::Big(ret_raw); } rust::Foo rust::i32_to_foo(int32_t foo) { auto ret_raw = _ffi_fn_i32_to_foo(foo); return rust::Foo(ret_raw); } rust::LongEnum rust::long_out() { auto multi_ret = _ffi_fn_long_out(); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_enum_LongEnum_from_rust(buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_enum_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { enum struct Big : int32_t { Min = -2147483647 - 1, Max = 2147483647, }; enum struct Foo : int32_t { Zero = 0, One = 1, Hundred = 100, }; namespace detail { struct LongEnum__Empty { }; struct LongEnum__ShortTuple { int32_t _0 = 0; }; struct LongEnum__ShortStruct { int32_t a = 0; }; struct LongEnum__LongTuple { int32_t _0 = 0; int32_t _1 = 0; int32_t _2 = 0; int32_t _3 = 0; int32_t _4 = 0; int32_t _5 = 0; int32_t _6 = 0; int32_t _7 = 0; }; struct LongEnum__LongStruct { int32_t a = 0; int32_t b = 0; int32_t c = 0; int32_t d = 0; int32_t e = 0; int32_t f = 0; }; } // namespace detail struct LongEnum : std::variant { using Empty = detail::LongEnum__Empty; using ShortTuple = detail::LongEnum__ShortTuple; using ShortStruct = detail::LongEnum__ShortStruct; using LongTuple = detail::LongEnum__LongTuple; using LongStruct = detail::LongEnum__LongStruct; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); Foo i32_to_foo(int32_t foo); Big i32_to_big(int32_t big); LongEnum long_out(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_enum_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_to_cpp(val: LongEnum, buf: &mut Vec) { match val { LongEnum::Empty => _ffi_write(0 as i32, buf), LongEnum::ShortTuple(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } LongEnum::ShortStruct { a } => { _ffi_write(2 as i32, buf); _ffi_write(a, buf); } LongEnum::LongTuple(x0, x1, x2, x3, x4, x5, x6, x7) => { _ffi_write(3 as i32, buf); _ffi_write(x0, buf); _ffi_write(x1, buf); _ffi_write(x2, buf); _ffi_write(x3, buf); _ffi_write(x4, buf); _ffi_write(x5, buf); _ffi_write(x6, buf); _ffi_write(x7, buf); } LongEnum::LongStruct { a, b, c, d, e, f } => { _ffi_write(4 as i32, buf); _ffi_write(a, buf); _ffi_write(b, buf); _ffi_write(c, buf); _ffi_write(d, buf); _ffi_write(e, buf); _ffi_write(f, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 { i32_to_big(big) as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 { i32_to_foo(foo) as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_long_out() -> _ffi_ret_ptr_usize { let mut buf = Vec::::new(); _ffi_enum_LongEnum_to_cpp(long_out(), &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); ================================================ FILE: src/tests/snapshots/cpp_fn_nested_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test(int32_t x_0, const void* x_1_ptr_ptr, const void* buf_ptr, uintptr_t x_2_len); void* _ffi_alloc(uintptr_t len); } // extern "C" namespace { template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_i32_Foo_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item), buf); (void)std::get<1>(item).empty; auto item_1_ptr_ptr = new std::shared_ptr(std::get<1>(item).ptr); _ffi_write(item_1_ptr_ptr, buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace extern "C" { int32_t _ffi_cpp_Rc_Bar__get(std::shared_ptr* _self) { return _self->get()->get(); } void _ffi_cpp_drop_Rc_Bar(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::test(std::tuple>> x) { (void)std::get<1>(x).empty; auto x_1_ptr_ptr = new std::shared_ptr(std::get<1>(x).ptr); std::vector buf; auto x_2_len = std::get<2>(x).size(); _ffi_vec_i32_Foo_to_rust(std::move(std::get<2>(x)), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_test(std::get<0>(x), x_1_ptr_ptr, buf_ptr, x_2_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_nested_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Bar; struct Bar { virtual ~Bar() {} virtual int32_t get() = 0; }; struct Foo { std::tuple<> empty; std::shared_ptr ptr; }; uintptr_t rust_mem_leaked(); int32_t test(std::tuple>> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_nested_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *const u8, x_2_len: usize) -> i32 { let x_1 = Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Rc_Bar(x_1_ptr_ptr)) }; let mut buf_end = buf_ptr; let ret = test((x_0, x_1, _ffi_vec_i32_Foo_from_cpp(x_2_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Bar(*const u8); impl Drop for _ffi_rs_Rc_Bar { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Bar(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Bar(self.0) }; } } impl Bar for _ffi_rs_Rc_Bar { fn get(&self) -> i32 { extern "C" { fn _ffi_cpp_Rc_Bar__get(_: *const u8) -> i32; } unsafe { _ffi_cpp_Rc_Bar__get(self.0) } } } #[allow(non_snake_case)] fn _ffi_vec_i32_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32, Foo)> { let mut items = Vec::<(i32, Foo)>::with_capacity(len); for _ in 0..len { items.push(( _ffi_read::(end), Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Rc_Bar(_ffi_read::<*const u8>(end))) } )); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_nested_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test(int32_t x_0, const void* x_1_ptr_ptr, const void* buf_ptr, uintptr_t x_2_len); void* _ffi_alloc(uintptr_t len); } // extern "C" namespace { template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_i32_Foo_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(std::get<0>(item), buf); (void)std::get<1>(item).empty; auto item_1_ptr_ptr = new std::shared_ptr(std::get<1>(item).ptr); _ffi_write(item_1_ptr_ptr, buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace extern "C" { int32_t _ffi_cpp_Rc_Bar__get(std::shared_ptr* _self) { return _self->get()->get(); } void _ffi_cpp_drop_Rc_Bar(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::test(std::tuple>> x) { (void)std::get<1>(x).empty; auto x_1_ptr_ptr = new std::shared_ptr(std::get<1>(x).ptr); std::vector buf; auto x_2_len = std::get<2>(x).size(); _ffi_vec_i32_Foo_to_rust(std::move(std::get<2>(x)), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_test(std::get<0>(x), x_1_ptr_ptr, buf_ptr, x_2_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_nested_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Bar; struct Bar { virtual ~Bar() {} virtual int32_t get() = 0; }; struct Foo { std::tuple<> empty; std::shared_ptr ptr; }; uintptr_t rust_mem_leaked(); int32_t test(std::tuple>> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_nested_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *const u8, x_2_len: usize) -> i32 { let x_1 = Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Rc_Bar(x_1_ptr_ptr)) }; let mut buf_end = buf_ptr; let ret = test((x_0, x_1, _ffi_vec_i32_Foo_from_cpp(x_2_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Bar(*const u8); impl Drop for _ffi_rs_Rc_Bar { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Bar(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Bar(self.0) }; } } impl Bar for _ffi_rs_Rc_Bar { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_Bar__get(_: *const u8) -> i32; } unsafe { _ffi_cpp_Rc_Bar__get(self.0) } } } #[allow(non_snake_case)] fn _ffi_vec_i32_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32, Foo)> { let mut items = Vec::<(i32, Foo)>::with_capacity(len); for _ in 0..len { items.push(( _ffi_read::(end), Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Rc_Bar(_ffi_read::<*const u8>(end))) } )); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_nested_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_i32_ptr { int32_t _0; const void* _1; }; extern "C" { void _ffi_drop_Rc_Bar(const void* ptr); int32_t _ffi_Rc_Bar__get(const void* _self); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_i32_ptr _ffi_fn_test(int32_t x); } // extern "C" namespace { struct _ffi_Rc_Bar final : rust::Bar { _ffi_Rc_Bar(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Bar() { _ffi_drop_Rc_Bar(_self); } virtual int32_t get(); const void* _self; }; } // namespace int32_t _ffi_Rc_Bar::get() { return _ffi_Rc_Bar__get(_self); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::tuple rust::test(int32_t x) { auto multi_ret = _ffi_fn_test(x); auto ret_0 = multi_ret._0; auto ret_1_ptr_ptr = multi_ret._1; auto ret_1_ptr = std::make_shared<_ffi_Rc_Bar>(ret_1_ptr_ptr); auto ret_1 = rust::Foo{std::move(ret_1_ptr)}; return std::make_tuple(ret_0, std::move(ret_1)); } ================================================ FILE: src/tests/snapshots/cpp_fn_nested_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Bar; struct Bar { virtual ~Bar() {} virtual int32_t get() = 0; }; struct Foo { std::shared_ptr ptr; }; uintptr_t rust_mem_leaked(); std::tuple test(int32_t x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_nested_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[no_mangle] extern "C" fn _ffi_drop_Rc_Bar(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(x: i32) -> _ffi_ret_i32_ptr { let ret = test(x); let ret_0 = ret.0; let ret_1 = ret.1; _ffi_ret_i32_ptr(ret_0, Box::into_raw(Box::new(ret_1.ptr)) as *const u8) } #[repr(C)] struct _ffi_ret_i32_ptr(i32, *const u8); ================================================ FILE: src/tests/snapshots/cpp_fn_nested_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_i32_ptr { int32_t _0; const void* _1; }; extern "C" { void _ffi_drop_Rc_Bar(const void* ptr); int32_t _ffi_Rc_Bar__get(const void* _self); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_i32_ptr _ffi_fn_test(int32_t x); } // extern "C" namespace { struct _ffi_Rc_Bar final : rust::Bar { _ffi_Rc_Bar(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Bar() { _ffi_drop_Rc_Bar(_self); } virtual int32_t get(); const void* _self; }; } // namespace int32_t _ffi_Rc_Bar::get() { return _ffi_Rc_Bar__get(_self); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::tuple rust::test(int32_t x) { auto multi_ret = _ffi_fn_test(x); auto ret_0 = multi_ret._0; auto ret_1_ptr_ptr = multi_ret._1; auto ret_1_ptr = std::make_shared<_ffi_Rc_Bar>(ret_1_ptr_ptr); auto ret_1 = rust::Foo{std::move(ret_1_ptr)}; return std::make_tuple(ret_0, std::move(ret_1)); } ================================================ FILE: src/tests/snapshots/cpp_fn_nested_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Bar; struct Bar { virtual ~Bar() {} virtual int32_t get() = 0; }; struct Foo { std::shared_ptr ptr; }; uintptr_t rust_mem_leaked(); std::tuple test(int32_t x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_nested_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Bar(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(x: i32) -> _ffi_ret_i32_ptr { let ret = test(x); let ret_0 = ret.0; let ret_1 = ret.1; _ffi_ret_i32_ptr(ret_0, Box::into_raw(Box::new(ret_1.ptr)) as *const u8) } #[repr(C)] struct _ffi_ret_i32_ptr(i32, *const u8); ================================================ FILE: src/tests/snapshots/cpp_fn_option_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void* _ffi_alloc(uintptr_t len); int32_t _ffi_fn_add_all(const void* buf_ptr, uintptr_t x_len); int32_t _ffi_fn_add_nested(const void* buf_ptr, bool has_x, bool has_y); int32_t _ffi_fn_add_option(const void* buf_ptr, bool has_x, bool has_y); _ffi_ret_ptr_2_usize _ffi_fn_join_all(const void* buf_ptr, uintptr_t x_len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_option_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto has_item = item.has_value(); _ffi_write(has_item, buf); if (has_item) { _ffi_write(item.value(), buf); } } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } void _ffi_vec_option_string_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto has_item = item.has_value(); _ffi_write(has_item, buf); if (has_item) { uintptr_t item_val_len; const void* item_val_ptr = _ffi_string_to_rust(item.value(), item_val_len); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); } } } } // namespace int32_t rust::add_all(std::vector> x) { std::vector buf; auto x_len = x.size(); _ffi_vec_option_i32_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_add_all(buf_ptr, x_len); } int32_t rust::add_nested(std::optional> x, std::optional> y) { std::vector buf; auto has_x = x.has_value(); if (has_x) { auto has_x_val = x.value().has_value(); _ffi_write(has_x_val, buf); if (has_x_val) { _ffi_write(x.value().value(), buf); } } auto has_y = y.has_value(); if (has_y) { auto has_y_val = y.value().has_value(); _ffi_write(has_y_val, buf); if (has_y_val) { _ffi_write(y.value().value(), buf); } } auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_add_nested(buf_ptr, has_x, has_y); } int32_t rust::add_option(std::optional x, std::optional y) { std::vector buf; auto has_x = x.has_value(); if (has_x) { _ffi_write(x.value(), buf); } auto has_y = y.has_value(); if (has_y) { _ffi_write(y.value(), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_add_option(buf_ptr, has_x, has_y); } std::string rust::join_all(std::vector> x) { std::vector buf; auto x_len = x.size(); _ffi_vec_option_string_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_join_all(buf_ptr, x_len); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_option_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { uintptr_t rust_mem_leaked(); int32_t add_option(std::optional x, std::optional y); int32_t add_nested(std::optional> x, std::optional> y); int32_t add_all(std::vector> x); std::string join_all(std::vector> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_option_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = add_all(_ffi_vec_option_i32_from_cpp(x_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_nested( has_x.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))), has_y.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))) ); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_option(has_x.then(|| _ffi_read::(&mut buf_end)), has_y.then(|| _ffi_read::(&mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(join_all(_ffi_vec_option_string_from_cpp(x_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_read::(end))); } items } fn _ffi_vec_option_string_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_option_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void* _ffi_alloc(uintptr_t len); int32_t _ffi_fn_add_all(const void* buf_ptr, uintptr_t x_len); int32_t _ffi_fn_add_nested(const void* buf_ptr, bool has_x, bool has_y); int32_t _ffi_fn_add_option(const void* buf_ptr, bool has_x, bool has_y); _ffi_ret_ptr_2_usize _ffi_fn_join_all(const void* buf_ptr, uintptr_t x_len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_option_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto has_item = item.has_value(); _ffi_write(has_item, buf); if (has_item) { _ffi_write(item.value(), buf); } } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } void _ffi_vec_option_string_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto has_item = item.has_value(); _ffi_write(has_item, buf); if (has_item) { uintptr_t item_val_len; const void* item_val_ptr = _ffi_string_to_rust(item.value(), item_val_len); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); } } } } // namespace int32_t rust::add_all(std::vector> x) { std::vector buf; auto x_len = x.size(); _ffi_vec_option_i32_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_add_all(buf_ptr, x_len); } int32_t rust::add_nested(std::optional> x, std::optional> y) { std::vector buf; auto has_x = x.has_value(); if (has_x) { auto has_x_val = x.value().has_value(); _ffi_write(has_x_val, buf); if (has_x_val) { _ffi_write(x.value().value(), buf); } } auto has_y = y.has_value(); if (has_y) { auto has_y_val = y.value().has_value(); _ffi_write(has_y_val, buf); if (has_y_val) { _ffi_write(y.value().value(), buf); } } auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_add_nested(buf_ptr, has_x, has_y); } int32_t rust::add_option(std::optional x, std::optional y) { std::vector buf; auto has_x = x.has_value(); if (has_x) { _ffi_write(x.value(), buf); } auto has_y = y.has_value(); if (has_y) { _ffi_write(y.value(), buf); } auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_add_option(buf_ptr, has_x, has_y); } std::string rust::join_all(std::vector> x) { std::vector buf; auto x_len = x.size(); _ffi_vec_option_string_to_rust(std::move(x), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_join_all(buf_ptr, x_len); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_option_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { uintptr_t rust_mem_leaked(); int32_t add_option(std::optional x, std::optional y); int32_t add_nested(std::optional> x, std::optional> y); int32_t add_all(std::vector> x); std::string join_all(std::vector> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_option_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = add_all(_ffi_vec_option_i32_from_cpp(x_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_nested( has_x.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))), has_y.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))) ); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_option(has_x.then(|| _ffi_read::(&mut buf_end)), has_y.then(|| _ffi_read::(&mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(join_all(_ffi_vec_option_string_from_cpp(x_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_read::(end))); } items } fn _ffi_vec_option_string_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_option_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; struct _ffi_ret_ptr_usize_bool { const void* _0; uintptr_t _1; bool _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize_bool _ffi_fn_opt_int(bool x, int32_t y); _ffi_ret_ptr_usize_bool _ffi_fn_opt_opt_int(bool x, bool y, int32_t z); _ffi_ret_ptr_usize_bool _ffi_fn_opt_vec_opt_string(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_2_usize _ffi_fn_vec_opt_int(int32_t n); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } std::vector> _ffi_vec_option_string_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { std::optional item; if (_ffi_read(end)) { auto item_val_ptr = _ffi_read(end); auto item_val_len = _ffi_read(end); auto item_val_cap = _ffi_read(end); item = std::make_optional(_ffi_string_from_rust(item_val_ptr, item_val_len, item_val_cap)); } items.emplace_back(std::move(item)); } return items; } std::vector> _ffi_vec_option_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item = _ffi_read(end) ? std::make_optional(_ffi_read(end)) : std::nullopt; items.emplace_back(std::move(item)); } return items; } } // namespace std::optional rust::opt_int(bool x, int32_t y) { auto multi_ret = _ffi_fn_opt_int(x, y); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = has_ret ? std::make_optional(_ffi_read(buf_end)) : std::nullopt; _ffi_dealloc(buf_ptr, buf_cap); return ret; } std::optional> rust::opt_opt_int(bool x, bool y, int32_t z) { auto multi_ret = _ffi_fn_opt_opt_int(x, y, z); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = has_ret ? std::make_optional(_ffi_read(buf_end) ? std::make_optional(_ffi_read(buf_end)) : std::nullopt) : std::nullopt; _ffi_dealloc(buf_ptr, buf_cap); return ret; } std::optional>> rust::opt_vec_opt_string(int32_t n) { auto multi_ret = _ffi_fn_opt_vec_opt_string(n); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; std::optional>> ret; if (has_ret) { auto ret_val_len = _ffi_read(buf_end); ret = std::make_optional(_ffi_vec_option_string_from_rust(ret_val_len, buf_end)); } _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::vector> rust::vec_opt_int(int32_t n) { auto multi_ret = _ffi_fn_vec_opt_int(n); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_option_i32_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } ================================================ FILE: src/tests/snapshots/cpp_fn_option_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { uintptr_t rust_mem_leaked(); std::optional opt_int(bool x, int32_t y); std::optional> opt_opt_int(bool x, bool y, int32_t z); std::vector> vec_opt_int(int32_t n); std::optional>> opt_vec_opt_string(int32_t n); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_option_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_int(x, y); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[no_mangle] extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_opt_int(x, y, z); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.is_some(), &mut buf); if let Some(ret_val_val) = ret_val { _ffi_write(ret_val_val, &mut buf); } } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[no_mangle] extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_vec_opt_string(n); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.len(), &mut buf); _ffi_vec_option_string_to_cpp(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> _ffi_ret_ptr_2_usize { let ret = vec_opt_int(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_option_i32_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { _ffi_write(item_val, buf); } } } fn _ffi_vec_option_string_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { let (item_val_ptr, item_val_len, item_val_cap) = _ffi_string_to_host(item_val); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); _ffi_write(item_val_cap, buf); } } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_option_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; struct _ffi_ret_ptr_usize_bool { const void* _0; uintptr_t _1; bool _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_usize_bool _ffi_fn_opt_int(bool x, int32_t y); _ffi_ret_ptr_usize_bool _ffi_fn_opt_opt_int(bool x, bool y, int32_t z); _ffi_ret_ptr_usize_bool _ffi_fn_opt_vec_opt_string(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_2_usize _ffi_fn_vec_opt_int(int32_t n); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } std::vector> _ffi_vec_option_string_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { std::optional item; if (_ffi_read(end)) { auto item_val_ptr = _ffi_read(end); auto item_val_len = _ffi_read(end); auto item_val_cap = _ffi_read(end); item = std::make_optional(_ffi_string_from_rust(item_val_ptr, item_val_len, item_val_cap)); } items.emplace_back(std::move(item)); } return items; } std::vector> _ffi_vec_option_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item = _ffi_read(end) ? std::make_optional(_ffi_read(end)) : std::nullopt; items.emplace_back(std::move(item)); } return items; } } // namespace std::optional rust::opt_int(bool x, int32_t y) { auto multi_ret = _ffi_fn_opt_int(x, y); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = has_ret ? std::make_optional(_ffi_read(buf_end)) : std::nullopt; _ffi_dealloc(buf_ptr, buf_cap); return ret; } std::optional> rust::opt_opt_int(bool x, bool y, int32_t z) { auto multi_ret = _ffi_fn_opt_opt_int(x, y, z); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = has_ret ? std::make_optional(_ffi_read(buf_end) ? std::make_optional(_ffi_read(buf_end)) : std::nullopt) : std::nullopt; _ffi_dealloc(buf_ptr, buf_cap); return ret; } std::optional>> rust::opt_vec_opt_string(int32_t n) { auto multi_ret = _ffi_fn_opt_vec_opt_string(n); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto has_ret = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; std::optional>> ret; if (has_ret) { auto ret_val_len = _ffi_read(buf_end); ret = std::make_optional(_ffi_vec_option_string_from_rust(ret_val_len, buf_end)); } _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::vector> rust::vec_opt_int(int32_t n) { auto multi_ret = _ffi_fn_vec_opt_int(n); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_option_i32_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } ================================================ FILE: src/tests/snapshots/cpp_fn_option_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { uintptr_t rust_mem_leaked(); std::optional opt_int(bool x, int32_t y); std::optional> opt_opt_int(bool x, bool y, int32_t z); std::vector> vec_opt_int(int32_t n); std::optional>> opt_vec_opt_string(int32_t n); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_option_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_int(x, y); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_opt_int(x, y, z); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.is_some(), &mut buf); if let Some(ret_val_val) = ret_val { _ffi_write(ret_val_val, &mut buf); } } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_vec_opt_string(n); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.len(), &mut buf); _ffi_vec_option_string_to_cpp(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> _ffi_ret_ptr_2_usize { let ret = vec_opt_int(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_option_i32_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { _ffi_write(item_val, buf); } } } fn _ffi_vec_option_string_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { let (item_val_ptr, item_val_len, item_val_cap) = _ffi_string_to_host(item_val); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); _ffi_write(item_val_cap, buf); } } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); bool _ffi_fn_set_tests(const void* buf_ptr, uintptr_t tests_len); void* _ffi_alloc(uintptr_t len); } // extern "C" namespace { void _ffi_enum_Foo_to_rust(rust::Foo val, std::vector& buf); void _ffi_box_Foo_to_rust(rust::Foo val, std::vector& buf) { _ffi_enum_Foo_to_rust(std::move(val), buf); } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_enum_Foo_to_rust(rust::Foo val, std::vector& buf) { if (val.is()) { _ffi_write(int32_t(0), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(1), buf); _ffi_write(it->_0, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(3), buf); _ffi_box_Foo_to_rust(std::move(*it->_0), buf); } else { abort(); } } void _ffi_vec_Foo_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_enum_Foo_to_rust(std::move(item), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace bool rust::detail::Foo__Nested::operator == (const rust::detail::Foo__Nested& f) const { return *_0 == *f._0; } bool rust::detail::Foo__Point::operator == (const rust::detail::Foo__Point& f) const { return x == f.x && y == f.y; } bool rust::detail::Foo__Single::operator == (const rust::detail::Foo__Single& f) const { return _0 == f._0; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } bool rust::set_tests(std::vector tests) { std::vector buf; auto tests_len = tests.size(); _ffi_vec_Foo_to_rust(std::move(tests), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_set_tests(buf_ptr, tests_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Foo; namespace detail { struct Foo__Empty { bool operator == (const Foo__Empty&) const { return true; } bool operator != (const Foo__Empty& f) const { return !(*this == f); } }; struct Foo__Single { int32_t _0 = 0; bool operator == (const Foo__Single&) const; bool operator != (const Foo__Single& f) const { return !(*this == f); } }; struct Foo__Point { int32_t x = 0; int32_t y = 0; bool operator == (const Foo__Point&) const; bool operator != (const Foo__Point& f) const { return !(*this == f); } }; struct Foo__Nested { std::unique_ptr _0; bool operator == (const Foo__Nested&) const; bool operator != (const Foo__Nested& f) const { return !(*this == f); } }; } // namespace detail struct Foo : std::variant { using Empty = detail::Foo__Empty; using Single = detail::Foo__Single; using Point = detail::Foo__Point; using Nested = detail::Foo__Nested; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); bool set_tests(std::vector tests); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_payload_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_from_cpp(end: &mut *const u8) -> Box { Box::new(_ffi_enum_Foo_from_cpp(end)) } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_cpp(end: &mut *const u8) -> Foo { match _ffi_read::(end) { 0 => Foo::Empty, 1 => Foo::Single(_ffi_read::(end)), 2 => Foo::Point { x: _ffi_read::(end), y: _ffi_read::(end) }, 3 => Foo::Nested(_ffi_box_Foo_from_cpp(end)), _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) -> bool { let mut buf_end = buf_ptr; let ret = set_tests(_ffi_vec_Foo_from_cpp(tests_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_enum_Foo_from_cpp(end)); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); bool _ffi_fn_set_tests(const void* buf_ptr, uintptr_t tests_len); void* _ffi_alloc(uintptr_t len); } // extern "C" namespace { void _ffi_enum_Foo_to_rust(rust::Foo val, std::vector& buf); void _ffi_box_Foo_to_rust(rust::Foo val, std::vector& buf) { _ffi_enum_Foo_to_rust(std::move(val), buf); } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_enum_Foo_to_rust(rust::Foo val, std::vector& buf) { if (val.is()) { _ffi_write(int32_t(0), buf); } else if (auto it = val.as()) { _ffi_write(int32_t(1), buf); _ffi_write(it->_0, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(2), buf); _ffi_write(it->x, buf); _ffi_write(it->y, buf); } else if (auto it = val.as()) { _ffi_write(int32_t(3), buf); _ffi_box_Foo_to_rust(std::move(*it->_0), buf); } else { abort(); } } void _ffi_vec_Foo_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_enum_Foo_to_rust(std::move(item), buf); } } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } } // namespace bool rust::detail::Foo__Nested::operator == (const rust::detail::Foo__Nested& f) const { return *_0 == *f._0; } bool rust::detail::Foo__Point::operator == (const rust::detail::Foo__Point& f) const { return x == f.x && y == f.y; } bool rust::detail::Foo__Single::operator == (const rust::detail::Foo__Single& f) const { return _0 == f._0; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } bool rust::set_tests(std::vector tests) { std::vector buf; auto tests_len = tests.size(); _ffi_vec_Foo_to_rust(std::move(tests), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_set_tests(buf_ptr, tests_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Foo; namespace detail { struct Foo__Empty { bool operator == (const Foo__Empty&) const { return true; } bool operator != (const Foo__Empty& f) const { return !(*this == f); } }; struct Foo__Single { int32_t _0 = 0; bool operator == (const Foo__Single&) const; bool operator != (const Foo__Single& f) const { return !(*this == f); } }; struct Foo__Point { int32_t x = 0; int32_t y = 0; bool operator == (const Foo__Point&) const; bool operator != (const Foo__Point& f) const { return !(*this == f); } }; struct Foo__Nested { std::unique_ptr _0; bool operator == (const Foo__Nested&) const; bool operator != (const Foo__Nested& f) const { return !(*this == f); } }; } // namespace detail struct Foo : std::variant { using Empty = detail::Foo__Empty; using Single = detail::Foo__Single; using Point = detail::Foo__Point; using Nested = detail::Foo__Nested; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); bool set_tests(std::vector tests); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_payload_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_from_cpp(end: &mut *const u8) -> Box { Box::new(_ffi_enum_Foo_from_cpp(end)) } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_cpp(end: &mut *const u8) -> Foo { match _ffi_read::(end) { 0 => Foo::Empty, 1 => Foo::Single(_ffi_read::(end)), 2 => Foo::Point { x: _ffi_read::(end), y: _ffi_read::(end) }, 3 => Foo::Nested(_ffi_box_Foo_from_cpp(end)), _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) -> bool { let mut buf_end = buf_ptr; let ret = set_tests(_ffi_vec_Foo_from_cpp(tests_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_enum_Foo_from_cpp(end)); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_2_usize _ffi_fn_get_tests(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { rust::Foo _ffi_enum_Foo_from_rust(const uint8_t*& end); std::unique_ptr _ffi_box_Foo_from_rust(const uint8_t*& end) { auto val = _ffi_enum_Foo_from_rust(end); return std::make_unique(std::move(val)); } template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } rust::Foo _ffi_enum_Foo_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: return rust::Foo{rust::Foo::Empty{}}; case 1: { auto x = _ffi_read(end); return rust::Foo{rust::Foo::Single{x}}; } case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::Foo{rust::Foo::Point{x, y}}; } case 3: { auto x = _ffi_box_Foo_from_rust(end); return rust::Foo{rust::Foo::Nested{std::move(x)}}; } default: abort(); } } std::vector _ffi_vec_Foo_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item = _ffi_enum_Foo_from_rust(end); items.emplace_back(std::move(item)); } return items; } } // namespace bool rust::detail::Foo__Nested::operator == (const rust::detail::Foo__Nested& f) const { return *_0 == *f._0; } bool rust::detail::Foo__Point::operator == (const rust::detail::Foo__Point& f) const { return x == f.x && y == f.y; } bool rust::detail::Foo__Single::operator == (const rust::detail::Foo__Single& f) const { return _0 == f._0; } std::vector rust::get_tests() { auto multi_ret = _ffi_fn_get_tests(); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_Foo_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Foo; namespace detail { struct Foo__Empty { bool operator == (const Foo__Empty&) const { return true; } bool operator != (const Foo__Empty& f) const { return !(*this == f); } }; struct Foo__Single { int32_t _0 = 0; bool operator == (const Foo__Single&) const; bool operator != (const Foo__Single& f) const { return !(*this == f); } }; struct Foo__Point { int32_t x = 0; int32_t y = 0; bool operator == (const Foo__Point&) const; bool operator != (const Foo__Point& f) const { return !(*this == f); } }; struct Foo__Nested { std::unique_ptr _0; bool operator == (const Foo__Nested&) const; bool operator != (const Foo__Nested& f) const { return !(*this == f); } }; } // namespace detail struct Foo : std::variant { using Empty = detail::Foo__Empty; using Single = detail::Foo__Single; using Point = detail::Foo__Point; using Nested = detail::Foo__Nested; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); std::vector get_tests(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_payload_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_to_cpp(val: Foo, buf: &mut Vec) { _ffi_enum_Foo_to_cpp(val, buf); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Foo_to_cpp(val: Foo, buf: &mut Vec) { match val { Foo::Empty => _ffi_write(0 as i32, buf), Foo::Single(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } Foo::Point { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } Foo::Nested(x) => { _ffi_write(3 as i32, buf); _ffi_box_Foo_to_cpp(*x, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_get_tests() -> _ffi_ret_ptr_2_usize { let ret = get_tests(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Foo_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Foo_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_enum_Foo_to_cpp(item, buf); } } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" #include struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_2_usize _ffi_fn_get_tests(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { rust::Foo _ffi_enum_Foo_from_rust(const uint8_t*& end); std::unique_ptr _ffi_box_Foo_from_rust(const uint8_t*& end) { auto val = _ffi_enum_Foo_from_rust(end); return std::make_unique(std::move(val)); } template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } rust::Foo _ffi_enum_Foo_from_rust(const uint8_t*& end) { switch (_ffi_read(end)) { case 0: return rust::Foo{rust::Foo::Empty{}}; case 1: { auto x = _ffi_read(end); return rust::Foo{rust::Foo::Single{x}}; } case 2: { auto x = _ffi_read(end); auto y = _ffi_read(end); return rust::Foo{rust::Foo::Point{x, y}}; } case 3: { auto x = _ffi_box_Foo_from_rust(end); return rust::Foo{rust::Foo::Nested{std::move(x)}}; } default: abort(); } } std::vector _ffi_vec_Foo_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item = _ffi_enum_Foo_from_rust(end); items.emplace_back(std::move(item)); } return items; } } // namespace bool rust::detail::Foo__Nested::operator == (const rust::detail::Foo__Nested& f) const { return *_0 == *f._0; } bool rust::detail::Foo__Point::operator == (const rust::detail::Foo__Point& f) const { return x == f.x && y == f.y; } bool rust::detail::Foo__Single::operator == (const rust::detail::Foo__Single& f) const { return _0 == f._0; } std::vector rust::get_tests() { auto multi_ret = _ffi_fn_get_tests(); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_Foo_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_payload_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include #include namespace rust { struct Foo; namespace detail { struct Foo__Empty { bool operator == (const Foo__Empty&) const { return true; } bool operator != (const Foo__Empty& f) const { return !(*this == f); } }; struct Foo__Single { int32_t _0 = 0; bool operator == (const Foo__Single&) const; bool operator != (const Foo__Single& f) const { return !(*this == f); } }; struct Foo__Point { int32_t x = 0; int32_t y = 0; bool operator == (const Foo__Point&) const; bool operator != (const Foo__Point& f) const { return !(*this == f); } }; struct Foo__Nested { std::unique_ptr _0; bool operator == (const Foo__Nested&) const; bool operator != (const Foo__Nested& f) const { return !(*this == f); } }; } // namespace detail struct Foo : std::variant { using Empty = detail::Foo__Empty; using Single = detail::Foo__Single; using Point = detail::Foo__Point; using Nested = detail::Foo__Nested; using std::variant::operator =; template bool is() const { return std::holds_alternative(*this); } template const T* as() const { return std::get_if(this); } template T* as() { return std::get_if(this); } }; uintptr_t rust_mem_leaked(); std::vector get_tests(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_payload_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_to_cpp(val: Foo, buf: &mut Vec) { _ffi_enum_Foo_to_cpp(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Foo_to_cpp(val: Foo, buf: &mut Vec) { match val { Foo::Empty => _ffi_write(0 as i32, buf), Foo::Single(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } Foo::Point { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } Foo::Nested(x) => { _ffi_write(3 as i32, buf); _ffi_box_Foo_to_cpp(*x, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_tests() -> _ffi_ret_ptr_2_usize { let ret = get_tests(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Foo_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Foo_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_enum_Foo_to_cpp(item, buf); } } ================================================ FILE: src/tests/snapshots/cpp_fn_string_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void* _ffi_alloc(uintptr_t len); _ffi_ret_ptr_2_usize _ffi_fn_get_string(); void _ffi_dealloc(const void* ptr, uintptr_t capacity); int32_t _ffi_fn_get_string_len(); void _ffi_fn_reset(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_set_str(const void* x_ptr, uintptr_t x_len); void _ffi_fn_set_string(const void* x_ptr, uintptr_t x_len); } // extern "C" namespace { const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } } // namespace std::string rust::get_string() { auto multi_ret = _ffi_fn_get_string(); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } int32_t rust::get_string_len() { return _ffi_fn_get_string_len(); } void rust::reset() { _ffi_fn_reset(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } void rust::set_str(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_fn_set_str(x_ptr, x_len); } void rust::set_string(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_fn_set_string(x_ptr, x_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_string_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); void reset(); int32_t get_string_len(); std::string get_string(); void set_string(std::string x); void set_str(std::string x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_string_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_get_string() -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_get_string_len() -> i32 { get_string_len() } #[no_mangle] extern "C" fn _ffi_fn_reset() { reset(); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) { set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) { set_string(_ffi_string_from_host(x_ptr, x_len)); } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/cpp_fn_string_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void* _ffi_alloc(uintptr_t len); _ffi_ret_ptr_2_usize _ffi_fn_get_string(); void _ffi_dealloc(const void* ptr, uintptr_t capacity); int32_t _ffi_fn_get_string_len(); void _ffi_fn_reset(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_set_str(const void* x_ptr, uintptr_t x_len); void _ffi_fn_set_string(const void* x_ptr, uintptr_t x_len); } // extern "C" namespace { const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } } // namespace std::string rust::get_string() { auto multi_ret = _ffi_fn_get_string(); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } int32_t rust::get_string_len() { return _ffi_fn_get_string_len(); } void rust::reset() { _ffi_fn_reset(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } void rust::set_str(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_fn_set_str(x_ptr, x_len); } void rust::set_string(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_fn_set_string(x_ptr, x_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_string_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); void reset(); int32_t get_string_len(); std::string get_string(); void set_string(std::string x); void set_str(std::string x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_string_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_string() -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_string_len() -> i32 { get_string_len() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_reset() { reset(); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) { set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) { set_string(_ffi_string_from_host(x_ptr, x_len)); } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_x, float ab_y, float cd_x, float cd_y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); } // extern "C" int32_t rust::empty_tuple(int32_t x, rust::EmptyStruct foo, int32_t y) { (void)foo; return _ffi_fn_empty_tuple(x, y); } float rust::multiply_pairs(rust::PairStruct ab, rust::PairStruct cd) { return _ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::single_element_tuple(rust::SingleElementStruct x, rust::SingleElementStruct y) { return _ffi_fn_single_element_tuple(x._0, y._0); } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { struct EmptyStruct { }; struct PairStruct { float x = 0.0f; float y = 0.0f; }; struct SingleElementStruct { int32_t _0 = 0; }; uintptr_t rust_mem_leaked(); int32_t empty_tuple(int32_t x, EmptyStruct foo, int32_t y); int32_t single_element_tuple(SingleElementStruct x, SingleElementStruct y); float multiply_pairs(PairStruct ab, PairStruct cd); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_struct_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, EmptyStruct, y) } #[no_mangle] extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32 { multiply_pairs(PairStruct { x: ab_x, y: ab_y }, PairStruct { x: cd_x, y: cd_y }) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple(SingleElementStruct(x_0), SingleElementStruct(y_0)) } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_x, float ab_y, float cd_x, float cd_y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); } // extern "C" int32_t rust::empty_tuple(int32_t x, rust::EmptyStruct foo, int32_t y) { (void)foo; return _ffi_fn_empty_tuple(x, y); } float rust::multiply_pairs(rust::PairStruct ab, rust::PairStruct cd) { return _ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::single_element_tuple(rust::SingleElementStruct x, rust::SingleElementStruct y) { return _ffi_fn_single_element_tuple(x._0, y._0); } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { struct EmptyStruct { }; struct PairStruct { float x = 0.0f; float y = 0.0f; }; struct SingleElementStruct { int32_t _0 = 0; }; uintptr_t rust_mem_leaked(); int32_t empty_tuple(int32_t x, EmptyStruct foo, int32_t y); int32_t single_element_tuple(SingleElementStruct x, SingleElementStruct y); float multiply_pairs(PairStruct ab, PairStruct cd); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_struct_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, EmptyStruct, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32 { multiply_pairs(PairStruct { x: ab_x, y: ab_y }, PairStruct { x: cd_x, y: cd_y }) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple(SingleElementStruct(x_0), SingleElementStruct(y_0)) } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_2_f32 { float _0; float _1; }; extern "C" { void _ffi_fn_empty_struct(); _ffi_ret_2_f32 _ffi_fn_make_pair(float x, float y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_struct(int32_t x); } // extern "C" bool rust::PairStruct::operator == (const rust::PairStruct& p) const { return x == p.x && y == p.y; } bool rust::SingleElementStruct::operator == (const rust::SingleElementStruct& s) const { return _0 == s._0; } rust::EmptyStruct rust::empty_struct() { _ffi_fn_empty_struct(); return rust::EmptyStruct{}; } rust::PairStruct rust::make_pair(float x, float y) { auto multi_ret = _ffi_fn_make_pair(x, y); auto ret_x = multi_ret._0; auto ret_y = multi_ret._1; return rust::PairStruct{ret_x, ret_y}; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } rust::SingleElementStruct rust::single_element_struct(int32_t x) { auto ret_0 = _ffi_fn_single_element_struct(x); return rust::SingleElementStruct{ret_0}; } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { struct EmptyStruct { bool operator == (const EmptyStruct&) const { return true; } bool operator != (const EmptyStruct& e) const { return !(*this == e); } }; struct PairStruct { float x = 0.0f; float y = 0.0f; bool operator == (const PairStruct&) const; bool operator != (const PairStruct& p) const { return !(*this == p); } }; struct SingleElementStruct { int32_t _0 = 0; bool operator == (const SingleElementStruct&) const; bool operator != (const SingleElementStruct& s) const { return !(*this == s); } }; uintptr_t rust_mem_leaked(); EmptyStruct empty_struct(); SingleElementStruct single_element_struct(int32_t x); PairStruct make_pair(float x, float y); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_struct_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(); } #[no_mangle] extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> _ffi_ret_2_f32 { let ret = make_pair(x, y); _ffi_ret_2_f32(ret.x, ret.y) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 { let ret = single_element_struct(x); ret.0 } #[repr(C)] struct _ffi_ret_2_f32(f32, f32); ================================================ FILE: src/tests/snapshots/cpp_fn_struct_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_2_f32 { float _0; float _1; }; extern "C" { void _ffi_fn_empty_struct(); _ffi_ret_2_f32 _ffi_fn_make_pair(float x, float y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_struct(int32_t x); } // extern "C" bool rust::PairStruct::operator == (const rust::PairStruct& p) const { return x == p.x && y == p.y; } bool rust::SingleElementStruct::operator == (const rust::SingleElementStruct& s) const { return _0 == s._0; } rust::EmptyStruct rust::empty_struct() { _ffi_fn_empty_struct(); return rust::EmptyStruct{}; } rust::PairStruct rust::make_pair(float x, float y) { auto multi_ret = _ffi_fn_make_pair(x, y); auto ret_x = multi_ret._0; auto ret_y = multi_ret._1; return rust::PairStruct{ret_x, ret_y}; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } rust::SingleElementStruct rust::single_element_struct(int32_t x) { auto ret_0 = _ffi_fn_single_element_struct(x); return rust::SingleElementStruct{ret_0}; } ================================================ FILE: src/tests/snapshots/cpp_fn_struct_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include namespace rust { struct EmptyStruct { bool operator == (const EmptyStruct&) const { return true; } bool operator != (const EmptyStruct& e) const { return !(*this == e); } }; struct PairStruct { float x = 0.0f; float y = 0.0f; bool operator == (const PairStruct&) const; bool operator != (const PairStruct& p) const { return !(*this == p); } }; struct SingleElementStruct { int32_t _0 = 0; bool operator == (const SingleElementStruct&) const; bool operator != (const SingleElementStruct& s) const { return !(*this == s); } }; uintptr_t rust_mem_leaked(); EmptyStruct empty_struct(); SingleElementStruct single_element_struct(int32_t x); PairStruct make_pair(float x, float y); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_struct_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> _ffi_ret_2_f32 { let ret = make_pair(x, y); _ffi_ret_2_f32(ret.x, ret.y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 { let ret = single_element_struct(x); ret.0 } #[repr(C)] struct _ffi_ret_2_f32(f32, f32); ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_0, float ab_1, float cd_0, float cd_1); int32_t _ffi_fn_nesting(int32_t x_0, int32_t x_2_0, int32_t x_2_1_0); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); } // extern "C" int32_t rust::empty_tuple(int32_t x, std::tuple<> foo, int32_t y) { (void)foo; return _ffi_fn_empty_tuple(x, y); } float rust::multiply_pairs(std::tuple ab, std::tuple cd) { return _ffi_fn_multiply_pairs(std::get<0>(ab), std::get<1>(ab), std::get<0>(cd), std::get<1>(cd)); } int32_t rust::nesting(std::tuple, std::tuple>> x) { (void)std::get<1>(x); return _ffi_fn_nesting(std::get<0>(x), std::get<0>(std::get<2>(x)), std::get<0>(std::get<1>(std::get<2>(x)))); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::single_element_tuple(std::tuple x, std::tuple y) { return _ffi_fn_single_element_tuple(std::get<0>(x), std::get<0>(y)); } ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); int32_t empty_tuple(int32_t x, std::tuple<> foo, int32_t y); int32_t single_element_tuple(std::tuple x, std::tuple y); float multiply_pairs(std::tuple ab, std::tuple cd); int32_t nesting(std::tuple, std::tuple>> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, (), y) } #[no_mangle] extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32 { multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } #[no_mangle] extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 { nesting((x_0, (), (x_2_0, (x_2_1_0,)))) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple((x_0,), (y_0,)) } ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_0, float ab_1, float cd_0, float cd_1); int32_t _ffi_fn_nesting(int32_t x_0, int32_t x_2_0, int32_t x_2_1_0); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); } // extern "C" int32_t rust::empty_tuple(int32_t x, std::tuple<> foo, int32_t y) { (void)foo; return _ffi_fn_empty_tuple(x, y); } float rust::multiply_pairs(std::tuple ab, std::tuple cd) { return _ffi_fn_multiply_pairs(std::get<0>(ab), std::get<1>(ab), std::get<0>(cd), std::get<1>(cd)); } int32_t rust::nesting(std::tuple, std::tuple>> x) { (void)std::get<1>(x); return _ffi_fn_nesting(std::get<0>(x), std::get<0>(std::get<2>(x)), std::get<0>(std::get<1>(std::get<2>(x)))); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::single_element_tuple(std::tuple x, std::tuple y) { return _ffi_fn_single_element_tuple(std::get<0>(x), std::get<0>(y)); } ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); int32_t empty_tuple(int32_t x, std::tuple<> foo, int32_t y); int32_t single_element_tuple(std::tuple x, std::tuple y); float multiply_pairs(std::tuple ab, std::tuple cd); int32_t nesting(std::tuple, std::tuple>> x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, (), y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32 { multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 { nesting((x_0, (), (x_2_0, (x_2_1_0,)))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple((x_0,), (y_0,)) } ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_f32_bool { float _0; bool _1; }; extern "C" { _ffi_ret_f32_bool _ffi_fn_return_pair(float x, bool y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x); } // extern "C" std::tuple rust::return_pair(float x, bool y) { auto multi_ret = _ffi_fn_return_pair(x, y); auto ret_0 = multi_ret._0; auto ret_1 = multi_ret._1; return std::make_tuple(ret_0, ret_1); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::tuple rust::single_element_tuple(int32_t x) { auto ret_0 = _ffi_fn_single_element_tuple(x); return ret_0; } ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); std::tuple single_element_tuple(int32_t x); std::tuple return_pair(float x, bool y); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> _ffi_ret_f32_bool { let ret = return_pair(x, y); _ffi_ret_f32_bool(ret.0, ret.1) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 { let ret = single_element_tuple(x); ret.0 } #[repr(C)] struct _ffi_ret_f32_bool(f32, bool); ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_f32_bool { float _0; bool _1; }; extern "C" { _ffi_ret_f32_bool _ffi_fn_return_pair(float x, bool y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x); } // extern "C" std::tuple rust::return_pair(float x, bool y) { auto multi_ret = _ffi_fn_return_pair(x, y); auto ret_0 = multi_ret._0; auto ret_1 = multi_ret._1; return std::make_tuple(ret_0, ret_1); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::tuple rust::single_element_tuple(int32_t x) { auto ret_0 = _ffi_fn_single_element_tuple(x); return ret_0; } ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); std::tuple single_element_tuple(int32_t x); std::tuple return_pair(float x, bool y); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_tuple_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> _ffi_ret_f32_bool { let ret = return_pair(x, y); _ffi_ret_f32_bool(ret.0, ret.1) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 { let ret = single_element_tuple(x); ret.0 } #[repr(C)] struct _ffi_ret_f32_bool(f32, bool); ================================================ FILE: src/tests/snapshots/cpp_fn_vec_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { _ffi_ret_ptr_2_usize _ffi_fn_check_nested(const void* buf_ptr, uintptr_t values_len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); float _ffi_fn_sum_f32(const void* buf_ptr, uintptr_t values_len); double _ffi_fn_sum_f64(const void* buf_ptr, uintptr_t values_len); int16_t _ffi_fn_sum_i16(const void* buf_ptr, uintptr_t values_len); int32_t _ffi_fn_sum_i32(const void* buf_ptr, uintptr_t values_len); int64_t _ffi_fn_sum_i64(const void* buf_ptr, uintptr_t values_len); int8_t _ffi_fn_sum_i8(const void* buf_ptr, uintptr_t values_len); intptr_t _ffi_fn_sum_isize(const void* buf_ptr, uintptr_t values_len); uint16_t _ffi_fn_sum_u16(const void* buf_ptr, uintptr_t values_len); uint32_t _ffi_fn_sum_u32(const void* buf_ptr, uintptr_t values_len); uint64_t _ffi_fn_sum_u64(const void* buf_ptr, uintptr_t values_len); uint8_t _ffi_fn_sum_u8(const void* buf_ptr, uintptr_t values_len); uintptr_t _ffi_fn_sum_usize(const void* buf_ptr, uintptr_t values_len); } // extern "C" namespace { std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_i32_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_vec_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto item_len = item.size(); _ffi_write(item_len, buf); _ffi_vec_i32_to_rust(std::move(item), buf); } } void _ffi_vec_f32_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_f64_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_i16_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_i64_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_i8_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_isize_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u16_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u32_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u64_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u8_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_usize_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } } // namespace std::string rust::check_nested(std::vector> values) { std::vector buf; auto values_len = values.size(); _ffi_vec_vec_i32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_check_nested(buf_ptr, values_len); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } float rust::sum_f32(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_f32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_f32(buf_ptr, values_len); } double rust::sum_f64(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_f64_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_f64(buf_ptr, values_len); } int16_t rust::sum_i16(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i16_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i16(buf_ptr, values_len); } int32_t rust::sum_i32(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i32(buf_ptr, values_len); } int64_t rust::sum_i64(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i64_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i64(buf_ptr, values_len); } int8_t rust::sum_i8(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i8_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i8(buf_ptr, values_len); } intptr_t rust::sum_isize(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_isize_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_isize(buf_ptr, values_len); } uint16_t rust::sum_u16(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u16_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u16(buf_ptr, values_len); } uint32_t rust::sum_u32(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u32(buf_ptr, values_len); } uint64_t rust::sum_u64(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u64_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u64(buf_ptr, values_len); } uint8_t rust::sum_u8(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u8_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u8(buf_ptr, values_len); } uintptr_t rust::sum_usize(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_usize_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_usize(buf_ptr, values_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { uintptr_t rust_mem_leaked(); uint8_t sum_u8(std::vector values); uint16_t sum_u16(std::vector values); uint32_t sum_u32(std::vector values); uintptr_t sum_usize(std::vector values); uint64_t sum_u64(std::vector values); int8_t sum_i8(std::vector values); int16_t sum_i16(std::vector values); int32_t sum_i32(std::vector values); intptr_t sum_isize(std::vector values); int64_t sum_i64(std::vector values); float sum_f32(std::vector values); double sum_f64(std::vector values); std::string check_nested(std::vector> values); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_vec_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_nested(_ffi_vec_vec_i32_from_cpp(values_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> f32 { let mut buf_end = buf_ptr; let ret = sum_f32(_ffi_vec_f32_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> f64 { let mut buf_end = buf_ptr; let ret = sum_f64(_ffi_vec_f64_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> i16 { let mut buf_end = buf_ptr; let ret = sum_i16(_ffi_vec_i16_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = sum_i32(_ffi_vec_i32_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> i64 { let mut buf_end = buf_ptr; let ret = sum_i64(_ffi_vec_i64_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 { let mut buf_end = buf_ptr; let ret = sum_i8(_ffi_vec_i8_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -> isize { let mut buf_end = buf_ptr; let ret = sum_isize(_ffi_vec_isize_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> u16 { let mut buf_end = buf_ptr; let ret = sum_u16(_ffi_vec_u16_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> u32 { let mut buf_end = buf_ptr; let ret = sum_u32(_ffi_vec_u32_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> u64 { let mut buf_end = buf_ptr; let ret = sum_u64(_ffi_vec_u64_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 { let mut buf_end = buf_ptr; let ret = sum_u8(_ffi_vec_u8_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -> usize { let mut buf_end = buf_ptr; let ret = sum_usize(_ffi_vec_usize_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_f32_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_f64_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i16_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i64_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i8_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_isize_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u16_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u32_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u64_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u8_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_usize_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_vec_i32_from_cpp(_ffi_read::(end), end)); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { _ffi_ret_ptr_2_usize _ffi_fn_check_nested(const void* buf_ptr, uintptr_t values_len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); void* _ffi_alloc(uintptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); float _ffi_fn_sum_f32(const void* buf_ptr, uintptr_t values_len); double _ffi_fn_sum_f64(const void* buf_ptr, uintptr_t values_len); int16_t _ffi_fn_sum_i16(const void* buf_ptr, uintptr_t values_len); int32_t _ffi_fn_sum_i32(const void* buf_ptr, uintptr_t values_len); int64_t _ffi_fn_sum_i64(const void* buf_ptr, uintptr_t values_len); int8_t _ffi_fn_sum_i8(const void* buf_ptr, uintptr_t values_len); intptr_t _ffi_fn_sum_isize(const void* buf_ptr, uintptr_t values_len); uint16_t _ffi_fn_sum_u16(const void* buf_ptr, uintptr_t values_len); uint32_t _ffi_fn_sum_u32(const void* buf_ptr, uintptr_t values_len); uint64_t _ffi_fn_sum_u64(const void* buf_ptr, uintptr_t values_len); uint8_t _ffi_fn_sum_u8(const void* buf_ptr, uintptr_t values_len); uintptr_t _ffi_fn_sum_usize(const void* buf_ptr, uintptr_t values_len); } // extern "C" namespace { std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } const void* _ffi_vec_to_rust(const std::vector& vec) { return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size()); } template void _ffi_write(T val, std::vector &buf) { buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T)); } void _ffi_vec_i32_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_vec_i32_to_rust(std::vector>&& items, std::vector& buf) { for (auto&& item : items) { auto item_len = item.size(); _ffi_write(item_len, buf); _ffi_vec_i32_to_rust(std::move(item), buf); } } void _ffi_vec_f32_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_f64_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_i16_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_i64_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_i8_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_isize_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u16_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u32_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u64_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_u8_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } void _ffi_vec_usize_to_rust(std::vector&& items, std::vector& buf) { for (auto&& item : items) { _ffi_write(item, buf); } } } // namespace std::string rust::check_nested(std::vector> values) { std::vector buf; auto values_len = values.size(); _ffi_vec_vec_i32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); auto multi_ret = _ffi_fn_check_nested(buf_ptr, values_len); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } float rust::sum_f32(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_f32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_f32(buf_ptr, values_len); } double rust::sum_f64(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_f64_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_f64(buf_ptr, values_len); } int16_t rust::sum_i16(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i16_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i16(buf_ptr, values_len); } int32_t rust::sum_i32(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i32(buf_ptr, values_len); } int64_t rust::sum_i64(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i64_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i64(buf_ptr, values_len); } int8_t rust::sum_i8(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_i8_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_i8(buf_ptr, values_len); } intptr_t rust::sum_isize(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_isize_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_isize(buf_ptr, values_len); } uint16_t rust::sum_u16(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u16_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u16(buf_ptr, values_len); } uint32_t rust::sum_u32(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u32_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u32(buf_ptr, values_len); } uint64_t rust::sum_u64(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u64_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u64(buf_ptr, values_len); } uint8_t rust::sum_u8(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_u8_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_u8(buf_ptr, values_len); } uintptr_t rust::sum_usize(std::vector values) { std::vector buf; auto values_len = values.size(); _ffi_vec_usize_to_rust(std::move(values), buf); auto buf_ptr = _ffi_vec_to_rust(buf); return _ffi_fn_sum_usize(buf_ptr, values_len); } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { uintptr_t rust_mem_leaked(); uint8_t sum_u8(std::vector values); uint16_t sum_u16(std::vector values); uint32_t sum_u32(std::vector values); uintptr_t sum_usize(std::vector values); uint64_t sum_u64(std::vector values); int8_t sum_i8(std::vector values); int16_t sum_i16(std::vector values); int32_t sum_i32(std::vector values); intptr_t sum_isize(std::vector values); int64_t sum_i64(std::vector values); float sum_f32(std::vector values); double sum_f64(std::vector values); std::string check_nested(std::vector> values); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_vec_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_nested(_ffi_vec_vec_i32_from_cpp(values_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> f32 { let mut buf_end = buf_ptr; let ret = sum_f32(_ffi_vec_f32_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> f64 { let mut buf_end = buf_ptr; let ret = sum_f64(_ffi_vec_f64_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> i16 { let mut buf_end = buf_ptr; let ret = sum_i16(_ffi_vec_i16_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = sum_i32(_ffi_vec_i32_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> i64 { let mut buf_end = buf_ptr; let ret = sum_i64(_ffi_vec_i64_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 { let mut buf_end = buf_ptr; let ret = sum_i8(_ffi_vec_i8_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -> isize { let mut buf_end = buf_ptr; let ret = sum_isize(_ffi_vec_isize_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> u16 { let mut buf_end = buf_ptr; let ret = sum_u16(_ffi_vec_u16_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> u32 { let mut buf_end = buf_ptr; let ret = sum_u32(_ffi_vec_u32_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> u64 { let mut buf_end = buf_ptr; let ret = sum_u64(_ffi_vec_u64_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 { let mut buf_end = buf_ptr; let ret = sum_u8(_ffi_vec_u8_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -> usize { let mut buf_end = buf_ptr; let ret = sum_usize(_ffi_vec_usize_from_cpp(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_f32_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_f64_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i16_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i64_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i8_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_isize_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u16_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u32_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u64_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u8_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_usize_from_cpp(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_vec_i32_from_cpp(_ffi_read::(end), end)); } items } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_out_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_2_usize _ffi_fn_check_nested(); _ffi_ret_ptr_2_usize _ffi_fn_get_vec(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::vector _ffi_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item = _ffi_read(end); items.emplace_back(item); } return items; } std::vector> _ffi_vec_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_len = _ffi_read(end); auto item = _ffi_vec_i32_from_rust(item_len, end); items.emplace_back(std::move(item)); } return items; } } // namespace std::vector> rust::check_nested() { auto multi_ret = _ffi_fn_check_nested(); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_vec_i32_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } std::vector rust::get_vec(int32_t n) { auto multi_ret = _ffi_fn_get_vec(n); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_i32_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); std::vector get_vec(int32_t n); std::vector> check_nested(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_vec_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_nested() -> _ffi_ret_ptr_2_usize { let ret = check_nested(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_vec_i32_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[no_mangle] extern "C" fn _ffi_fn_get_vec(n: i32) -> _ffi_ret_ptr_2_usize { let ret = get_vec(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_i32_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_vec_i32_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } fn _ffi_vec_vec_i32_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.len(), buf); _ffi_vec_i32_to_cpp(item, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_out_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const void* _0; uintptr_t _1; uintptr_t _2; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); _ffi_ret_ptr_2_usize _ffi_fn_check_nested(); _ffi_ret_ptr_2_usize _ffi_fn_get_vec(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { template T _ffi_read(const uint8_t* &ptr) { T val; memcpy(&val, ptr, sizeof(T)); ptr += sizeof(T); return val; } std::vector _ffi_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector items; items.reserve(len); while (items.size() < len) { auto item = _ffi_read(end); items.emplace_back(item); } return items; } std::vector> _ffi_vec_vec_i32_from_rust(uintptr_t len, const uint8_t*& end) { std::vector> items; items.reserve(len); while (items.size() < len) { auto item_len = _ffi_read(end); auto item = _ffi_vec_i32_from_rust(item_len, end); items.emplace_back(std::move(item)); } return items; } } // namespace std::vector> rust::check_nested() { auto multi_ret = _ffi_fn_check_nested(); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_vec_i32_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } std::vector rust::get_vec(int32_t n) { auto multi_ret = _ffi_fn_get_vec(n); auto buf_ptr = multi_ret._0; auto buf_cap = multi_ret._1; auto ret_len = multi_ret._2; auto buf_end = (const uint8_t*)buf_ptr; auto ret = _ffi_vec_i32_from_rust(ret_len, buf_end); _ffi_dealloc(buf_ptr, buf_cap); return ret; } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_fn_vec_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { uintptr_t rust_mem_leaked(); std::vector get_vec(int32_t n); std::vector> check_nested(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_fn_vec_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested() -> _ffi_ret_ptr_2_usize { let ret = check_nested(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_vec_i32_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_vec(n: i32) -> _ffi_ret_ptr_2_usize { let ret = get_vec(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_i32_to_cpp(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_vec_i32_to_cpp(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } fn _ffi_vec_vec_i32_to_cpp(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.len(), buf); _ffi_vec_i32_to_cpp(item, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/cpp_trait_enum_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Box_Foo(const void* ptr); int32_t _ffi_Box_Foo__get_enum(const void* _self); void _ffi_Box_Foo__set_enum(const void* _self, int32_t bar_raw); const void* _ffi_fn_get_foo(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Box_Foo final : rust::Foo { _ffi_Box_Foo(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Foo() { _ffi_drop_Box_Foo(_self); } virtual void set_enum(rust::Bar bar); virtual rust::Bar get_enum(); const void* _self; }; } // namespace rust::Bar _ffi_Box_Foo::get_enum() { auto ret_raw = _ffi_Box_Foo__get_enum(_self); return rust::Bar(ret_raw); } void _ffi_Box_Foo::set_enum(rust::Bar bar) { _ffi_Box_Foo__set_enum(_self, int32_t(bar)); } std::unique_ptr rust::get_foo() { auto ret_ptr = _ffi_fn_get_foo(); return std::unique_ptr(new _ffi_Box_Foo(ret_ptr)); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_enum_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { enum struct Bar : int32_t { A = 0, B = 1, C = 2, }; struct Foo { virtual ~Foo() {} virtual void set_enum(Bar bar) = 0; virtual Bar get_enum() = 0; }; uintptr_t rust_mem_leaked(); std::unique_ptr get_foo(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_enum_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get_enum() as i32 } #[no_mangle] extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) { let _self = unsafe { &*(_self as *const Box) }; _self.set_enum(_ffi_enum_Bar_from_cpp(bar_raw)); } #[no_mangle] extern "C" fn _ffi_drop_Box_Foo(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[allow(non_snake_case)] fn _ffi_enum_Bar_from_cpp(val: i32) -> Bar { match val { 0 => Bar::A, 1 => Bar::B, 2 => Bar::C, _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_get_foo() -> *const u8 { Box::into_raw(Box::new(get_foo())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_trait_enum_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Box_Foo(const void* ptr); int32_t _ffi_Box_Foo__get_enum(const void* _self); void _ffi_Box_Foo__set_enum(const void* _self, int32_t bar_raw); const void* _ffi_fn_get_foo(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Box_Foo final : rust::Foo { _ffi_Box_Foo(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Foo() { _ffi_drop_Box_Foo(_self); } virtual void set_enum(rust::Bar bar); virtual rust::Bar get_enum(); const void* _self; }; } // namespace rust::Bar _ffi_Box_Foo::get_enum() { auto ret_raw = _ffi_Box_Foo__get_enum(_self); return rust::Bar(ret_raw); } void _ffi_Box_Foo::set_enum(rust::Bar bar) { _ffi_Box_Foo__set_enum(_self, int32_t(bar)); } std::unique_ptr rust::get_foo() { auto ret_ptr = _ffi_fn_get_foo(); return std::unique_ptr(new _ffi_Box_Foo(ret_ptr)); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_enum_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { enum struct Bar : int32_t { A = 0, B = 1, C = 2, }; struct Foo { virtual ~Foo() {} virtual void set_enum(Bar bar) = 0; virtual Bar get_enum() = 0; }; uintptr_t rust_mem_leaked(); std::unique_ptr get_foo(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_enum_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get_enum() as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) { let _self = unsafe { &*(_self as *const Box) }; _self.set_enum(_ffi_enum_Bar_from_cpp(bar_raw)); } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Box_Foo(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[allow(non_snake_case)] fn _ffi_enum_Bar_from_cpp(val: i32) -> Bar { match val { 0 => Bar::A, 1 => Bar::B, 2 => Bar::C, _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_foo() -> *const u8 { Box::into_raw(Box::new(get_foo())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_trait_export_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Box_Adder(const void* ptr); void _ffi_drop_Rc_Adder(const void* ptr); int32_t _ffi_Box_Adder__add(const void* _self, int32_t x); int32_t _ffi_Rc_Adder__add(const void* _self, int32_t x); const void* _ffi_fn_get_adder_box(int32_t x); const void* _ffi_fn_get_adder_rc(int32_t x); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Box_Adder final : rust::Adder { _ffi_Box_Adder(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Adder() { _ffi_drop_Box_Adder(_self); } virtual int32_t add(int32_t x); const void* _self; }; struct _ffi_Rc_Adder final : rust::Adder { _ffi_Rc_Adder(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Adder() { _ffi_drop_Rc_Adder(_self); } virtual int32_t add(int32_t x); const void* _self; }; } // namespace int32_t _ffi_Box_Adder::add(int32_t x) { return _ffi_Box_Adder__add(_self, x); } int32_t _ffi_Rc_Adder::add(int32_t x) { return _ffi_Rc_Adder__add(_self, x); } std::unique_ptr rust::get_adder_box(int32_t x) { auto ret_ptr = _ffi_fn_get_adder_box(x); return std::unique_ptr(new _ffi_Box_Adder(ret_ptr)); } std::shared_ptr rust::get_adder_rc(int32_t x) { auto ret_ptr = _ffi_fn_get_adder_rc(x); return std::make_shared<_ffi_Rc_Adder>(ret_ptr); } uint32_t rust::get_counter() { return _ffi_fn_get_counter(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_export_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t x) = 0; }; uintptr_t rust_mem_leaked(); uint32_t get_counter(); std::shared_ptr get_adder_rc(int32_t x); std::unique_ptr get_adder_box(int32_t x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_export_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.add(x) } #[no_mangle] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x) } #[no_mangle] extern "C" fn _ffi_drop_Box_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_box(x))) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_rc(x))) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_trait_export_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Box_Adder(const void* ptr); void _ffi_drop_Rc_Adder(const void* ptr); int32_t _ffi_Box_Adder__add(const void* _self, int32_t x); int32_t _ffi_Rc_Adder__add(const void* _self, int32_t x); const void* _ffi_fn_get_adder_box(int32_t x); const void* _ffi_fn_get_adder_rc(int32_t x); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Box_Adder final : rust::Adder { _ffi_Box_Adder(const void* ptr) : _self(ptr) {} virtual ~_ffi_Box_Adder() { _ffi_drop_Box_Adder(_self); } virtual int32_t add(int32_t x); const void* _self; }; struct _ffi_Rc_Adder final : rust::Adder { _ffi_Rc_Adder(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Adder() { _ffi_drop_Rc_Adder(_self); } virtual int32_t add(int32_t x); const void* _self; }; } // namespace int32_t _ffi_Box_Adder::add(int32_t x) { return _ffi_Box_Adder__add(_self, x); } int32_t _ffi_Rc_Adder::add(int32_t x) { return _ffi_Rc_Adder__add(_self, x); } std::unique_ptr rust::get_adder_box(int32_t x) { auto ret_ptr = _ffi_fn_get_adder_box(x); return std::unique_ptr(new _ffi_Box_Adder(ret_ptr)); } std::shared_ptr rust::get_adder_rc(int32_t x) { auto ret_ptr = _ffi_fn_get_adder_rc(x); return std::make_shared<_ffi_Rc_Adder>(ret_ptr); } uint32_t rust::get_counter() { return _ffi_fn_get_counter(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_export_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t x) = 0; }; uintptr_t rust_mem_leaked(); uint32_t get_counter(); std::shared_ptr get_adder_rc(int32_t x); std::unique_ptr get_adder_box(int32_t x); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_export_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.add(x) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x) } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Box_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_box(x))) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_rc(x))) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_trait_export_import_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Rc_Exported(const void* ptr); int32_t _ffi_Rc_Exported__run(const void* _self, const void* imported_ptr); uint32_t _ffi_fn_get_counter(); const void* _ffi_fn_get_exported(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Rc_Exported final : rust::Exported { _ffi_Rc_Exported(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Exported() { _ffi_drop_Rc_Exported(_self); } virtual int32_t run(std::shared_ptr imported); const void* _self; }; } // namespace extern "C" { int32_t _ffi_cpp_Rc_Imported__add(std::shared_ptr* _self, int32_t x, int32_t y) { return _self->get()->add(x, y); } void _ffi_cpp_drop_Rc_Imported(std::shared_ptr* self) { delete self; } } // extern "C" int32_t _ffi_Rc_Exported::run(std::shared_ptr imported) { auto imported_ptr = new std::shared_ptr(imported); return _ffi_Rc_Exported__run(_self, imported_ptr); } uint32_t rust::get_counter() { return _ffi_fn_get_counter(); } std::shared_ptr rust::get_exported() { auto ret_ptr = _ffi_fn_get_exported(); return std::make_shared<_ffi_Rc_Exported>(ret_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_export_import_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Imported; struct Exported { virtual ~Exported() {} virtual int32_t run(std::shared_ptr imported) = 0; }; struct Imported { virtual ~Imported() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; uintptr_t rust_mem_leaked(); std::shared_ptr get_exported(); uint32_t get_counter(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_export_import_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.run(std::rc::Rc::new(_ffi_rs_Rc_Imported(imported_ptr))) } #[no_mangle] extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_get_exported() -> *const u8 { Box::into_raw(Box::new(get_exported())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Imported(*const u8); impl Drop for _ffi_rs_Rc_Imported { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Imported(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Imported(self.0) }; } } impl Imported for _ffi_rs_Rc_Imported { fn add(&self, x: i32, y: i32) -> i32 { extern "C" { fn _ffi_cpp_Rc_Imported__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_cpp_Rc_Imported__add(self.0, x, y) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_export_import_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Rc_Exported(const void* ptr); int32_t _ffi_Rc_Exported__run(const void* _self, const void* imported_ptr); uint32_t _ffi_fn_get_counter(); const void* _ffi_fn_get_exported(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Rc_Exported final : rust::Exported { _ffi_Rc_Exported(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Exported() { _ffi_drop_Rc_Exported(_self); } virtual int32_t run(std::shared_ptr imported); const void* _self; }; } // namespace extern "C" { int32_t _ffi_cpp_Rc_Imported__add(std::shared_ptr* _self, int32_t x, int32_t y) { return _self->get()->add(x, y); } void _ffi_cpp_drop_Rc_Imported(std::shared_ptr* self) { delete self; } } // extern "C" int32_t _ffi_Rc_Exported::run(std::shared_ptr imported) { auto imported_ptr = new std::shared_ptr(imported); return _ffi_Rc_Exported__run(_self, imported_ptr); } uint32_t rust::get_counter() { return _ffi_fn_get_counter(); } std::shared_ptr rust::get_exported() { auto ret_ptr = _ffi_fn_get_exported(); return std::make_shared<_ffi_Rc_Exported>(ret_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_export_import_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Imported; struct Exported { virtual ~Exported() {} virtual int32_t run(std::shared_ptr imported) = 0; }; struct Imported { virtual ~Imported() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; uintptr_t rust_mem_leaked(); std::shared_ptr get_exported(); uint32_t get_counter(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_export_import_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.run(std::rc::Rc::new(_ffi_rs_Rc_Imported(imported_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_exported() -> *const u8 { Box::into_raw(Box::new(get_exported())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Imported(*const u8); impl Drop for _ffi_rs_Rc_Imported { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Imported(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Imported(self.0) }; } } impl Imported for _ffi_rs_Rc_Imported { fn add(&self, x: i32, y: i32) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_Imported__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_cpp_Rc_Imported__add(self.0, x, y) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_export_nested_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Rc_Adder(const void* ptr); void _ffi_drop_Rc_Getter(const void* ptr); int32_t _ffi_Rc_Adder__add(const void* _self, int32_t x, int32_t y); const void* _ffi_Rc_Getter__get_adder(const void* _self); uint32_t _ffi_fn_get_adder_counter(); const void* _ffi_fn_get_getter(); uint32_t _ffi_fn_get_getter_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Rc_Adder final : rust::Adder { _ffi_Rc_Adder(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Adder() { _ffi_drop_Rc_Adder(_self); } virtual int32_t add(int32_t x, int32_t y); const void* _self; }; struct _ffi_Rc_Getter final : rust::Getter { _ffi_Rc_Getter(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Getter() { _ffi_drop_Rc_Getter(_self); } virtual std::shared_ptr get_adder(); const void* _self; }; } // namespace int32_t _ffi_Rc_Adder::add(int32_t x, int32_t y) { return _ffi_Rc_Adder__add(_self, x, y); } std::shared_ptr _ffi_Rc_Getter::get_adder() { auto ret_ptr = _ffi_Rc_Getter__get_adder(_self); return std::make_shared<_ffi_Rc_Adder>(ret_ptr); } uint32_t rust::get_adder_counter() { return _ffi_fn_get_adder_counter(); } std::shared_ptr rust::get_getter() { auto ret_ptr = _ffi_fn_get_getter(); return std::make_shared<_ffi_Rc_Getter>(ret_ptr); } uint32_t rust::get_getter_counter() { return _ffi_fn_get_getter_counter(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_export_nested_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder; struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; struct Getter { virtual ~Getter() {} virtual std::shared_ptr get_adder() = 0; }; uintptr_t rust_mem_leaked(); uint32_t get_getter_counter(); uint32_t get_adder_counter(); std::shared_ptr get_getter(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_export_nested_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[no_mangle] extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; Box::into_raw(Box::new(_self.get_adder())) as *const u8 } #[no_mangle] extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_drop_Rc_Getter(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_get_adder_counter() -> u32 { get_adder_counter() } #[no_mangle] extern "C" fn _ffi_fn_get_getter() -> *const u8 { Box::into_raw(Box::new(get_getter())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_getter_counter() -> u32 { get_getter_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_trait_export_nested_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Rc_Adder(const void* ptr); void _ffi_drop_Rc_Getter(const void* ptr); int32_t _ffi_Rc_Adder__add(const void* _self, int32_t x, int32_t y); const void* _ffi_Rc_Getter__get_adder(const void* _self); uint32_t _ffi_fn_get_adder_counter(); const void* _ffi_fn_get_getter(); uint32_t _ffi_fn_get_getter_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); } // extern "C" namespace { struct _ffi_Rc_Adder final : rust::Adder { _ffi_Rc_Adder(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Adder() { _ffi_drop_Rc_Adder(_self); } virtual int32_t add(int32_t x, int32_t y); const void* _self; }; struct _ffi_Rc_Getter final : rust::Getter { _ffi_Rc_Getter(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Getter() { _ffi_drop_Rc_Getter(_self); } virtual std::shared_ptr get_adder(); const void* _self; }; } // namespace int32_t _ffi_Rc_Adder::add(int32_t x, int32_t y) { return _ffi_Rc_Adder__add(_self, x, y); } std::shared_ptr _ffi_Rc_Getter::get_adder() { auto ret_ptr = _ffi_Rc_Getter__get_adder(_self); return std::make_shared<_ffi_Rc_Adder>(ret_ptr); } uint32_t rust::get_adder_counter() { return _ffi_fn_get_adder_counter(); } std::shared_ptr rust::get_getter() { auto ret_ptr = _ffi_fn_get_getter(); return std::make_shared<_ffi_Rc_Getter>(ret_ptr); } uint32_t rust::get_getter_counter() { return _ffi_fn_get_getter_counter(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } ================================================ FILE: src/tests/snapshots/cpp_trait_export_nested_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder; struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; struct Getter { virtual ~Getter() {} virtual std::shared_ptr get_adder() = 0; }; uintptr_t rust_mem_leaked(); uint32_t get_getter_counter(); uint32_t get_adder_counter(); std::shared_ptr get_getter(); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_export_nested_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; Box::into_raw(Box::new(_self.get_adder())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Getter(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_counter() -> u32 { get_adder_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_getter() -> *const u8 { Box::into_raw(Box::new(get_getter())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_getter_counter() -> u32 { get_getter_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/cpp_trait_import_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_adder_box(const void* adder_ptr); int32_t _ffi_fn_set_adder_rc(const void* adder_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Box_Adder__add(rust::Adder* _self, int32_t y) { return _self->add(y); } int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr* _self, int32_t y) { return _self->get()->add(y); } void _ffi_cpp_drop_Box_Adder(rust::Adder* self) { delete self; } void _ffi_cpp_drop_Rc_Adder(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_adder_box(std::unique_ptr adder) { auto adder_ptr = adder.release(); return _ffi_fn_set_adder_box(adder_ptr); } int32_t rust::set_adder_rc(std::shared_ptr adder) { auto adder_ptr = new std::shared_ptr(adder); return _ffi_fn_set_adder_rc(adder_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t y) = 0; }; uintptr_t rust_mem_leaked(); int32_t set_adder_rc(std::shared_ptr adder); int32_t set_adder_box(std::unique_ptr adder); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 { set_adder_box(Box::new(_ffi_rs_Box_Adder(adder_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 { set_adder_rc(std::rc::Rc::new(_ffi_rs_Rc_Adder(adder_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Box_Adder(*const u8); impl Drop for _ffi_rs_Box_Adder { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Box_Adder(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Adder(self.0) }; } } impl Adder for _ffi_rs_Box_Adder { fn add(&self, y: i32) -> i32 { extern "C" { fn _ffi_cpp_Box_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_cpp_Box_Adder__add(self.0, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Adder(*const u8); impl Drop for _ffi_rs_Rc_Adder { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Adder(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Adder(self.0) }; } } impl Adder for _ffi_rs_Rc_Adder { fn add(&self, y: i32) -> i32 { extern "C" { fn _ffi_cpp_Rc_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_cpp_Rc_Adder__add(self.0, y) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_adder_box(const void* adder_ptr); int32_t _ffi_fn_set_adder_rc(const void* adder_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Box_Adder__add(rust::Adder* _self, int32_t y) { return _self->add(y); } int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr* _self, int32_t y) { return _self->get()->add(y); } void _ffi_cpp_drop_Box_Adder(rust::Adder* self) { delete self; } void _ffi_cpp_drop_Rc_Adder(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_adder_box(std::unique_ptr adder) { auto adder_ptr = adder.release(); return _ffi_fn_set_adder_box(adder_ptr); } int32_t rust::set_adder_rc(std::shared_ptr adder) { auto adder_ptr = new std::shared_ptr(adder); return _ffi_fn_set_adder_rc(adder_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t y) = 0; }; uintptr_t rust_mem_leaked(); int32_t set_adder_rc(std::shared_ptr adder); int32_t set_adder_box(std::unique_ptr adder); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 { set_adder_box(Box::new(_ffi_rs_Box_Adder(adder_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 { set_adder_rc(std::rc::Rc::new(_ffi_rs_Rc_Adder(adder_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Box_Adder(*const u8); impl Drop for _ffi_rs_Box_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Box_Adder(_: *const u8); } unsafe { _ffi_cpp_drop_Box_Adder(self.0) }; } } impl Adder for _ffi_rs_Box_Adder { fn add(&self, y: i32) -> i32 { unsafe extern "C" { fn _ffi_cpp_Box_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_cpp_Box_Adder__add(self.0, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Adder(*const u8); impl Drop for _ffi_rs_Rc_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Adder(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Adder(self.0) }; } } impl Adder for _ffi_rs_Rc_Adder { fn add(&self, y: i32) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_cpp_Rc_Adder__add(self.0, y) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_export_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Rc_Exported(const void* ptr); int32_t _ffi_Rc_Exported__add(const void* _self, int32_t x, int32_t y); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_imported(const void* imported_ptr); } // extern "C" namespace { struct _ffi_Rc_Exported final : rust::Exported { _ffi_Rc_Exported(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Exported() { _ffi_drop_Rc_Exported(_self); } virtual int32_t add(int32_t x, int32_t y); const void* _self; }; } // namespace extern "C" { int32_t _ffi_cpp_Rc_Imported__run(std::shared_ptr* _self, const void* exported_ptr) { auto exported = std::make_shared<_ffi_Rc_Exported>(exported_ptr); return _self->get()->run(std::move(exported)); } void _ffi_cpp_drop_Rc_Imported(std::shared_ptr* self) { delete self; } } // extern "C" int32_t _ffi_Rc_Exported::add(int32_t x, int32_t y) { return _ffi_Rc_Exported__add(_self, x, y); } uint32_t rust::get_counter() { return _ffi_fn_get_counter(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_imported(std::shared_ptr imported) { auto imported_ptr = new std::shared_ptr(imported); return _ffi_fn_set_imported(imported_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_export_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Exported; struct Exported { virtual ~Exported() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; struct Imported { virtual ~Imported() {} virtual int32_t run(std::shared_ptr exported) = 0; }; uintptr_t rust_mem_leaked(); uint32_t get_counter(); int32_t set_imported(std::shared_ptr imported); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_export_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[no_mangle] extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 { set_imported(std::rc::Rc::new(_ffi_rs_Rc_Imported(imported_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Imported(*const u8); impl Drop for _ffi_rs_Rc_Imported { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Imported(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Imported(self.0) }; } } impl Imported for _ffi_rs_Rc_Imported { fn run(&self, exported: std::rc::Rc) -> i32 { extern "C" { fn _ffi_cpp_Rc_Imported__run(_: *const u8, exported_ptr: *const u8) -> i32; } unsafe { _ffi_cpp_Rc_Imported__run(self.0, Box::into_raw(Box::new(exported)) as *const u8) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_export_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { void _ffi_drop_Rc_Exported(const void* ptr); int32_t _ffi_Rc_Exported__add(const void* _self, int32_t x, int32_t y); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_imported(const void* imported_ptr); } // extern "C" namespace { struct _ffi_Rc_Exported final : rust::Exported { _ffi_Rc_Exported(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Exported() { _ffi_drop_Rc_Exported(_self); } virtual int32_t add(int32_t x, int32_t y); const void* _self; }; } // namespace extern "C" { int32_t _ffi_cpp_Rc_Imported__run(std::shared_ptr* _self, const void* exported_ptr) { auto exported = std::make_shared<_ffi_Rc_Exported>(exported_ptr); return _self->get()->run(std::move(exported)); } void _ffi_cpp_drop_Rc_Imported(std::shared_ptr* self) { delete self; } } // extern "C" int32_t _ffi_Rc_Exported::add(int32_t x, int32_t y) { return _ffi_Rc_Exported__add(_self, x, y); } uint32_t rust::get_counter() { return _ffi_fn_get_counter(); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_imported(std::shared_ptr imported) { auto imported_ptr = new std::shared_ptr(imported); return _ffi_fn_set_imported(imported_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_export_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Exported; struct Exported { virtual ~Exported() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; struct Imported { virtual ~Imported() {} virtual int32_t run(std::shared_ptr exported) = 0; }; uintptr_t rust_mem_leaked(); uint32_t get_counter(); int32_t set_imported(std::shared_ptr imported); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_export_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 { set_imported(std::rc::Rc::new(_ffi_rs_Rc_Imported(imported_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Imported(*const u8); impl Drop for _ffi_rs_Rc_Imported { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Imported(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Imported(self.0) }; } } impl Imported for _ffi_rs_Rc_Imported { fn run(&self, exported: std::rc::Rc) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_Imported__run(_: *const u8, exported_ptr: *const u8) -> i32; } unsafe { _ffi_cpp_Rc_Imported__run(self.0, Box::into_raw(Box::new(exported)) as *const u8) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_nested_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_getter(const void* getter_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr* _self, int32_t x, int32_t y) { return _self->get()->add(x, y); } const void* _ffi_cpp_Rc_Getter__get_adder(std::shared_ptr* _self) { return new std::shared_ptr(_self->get()->get_adder()); } void _ffi_cpp_drop_Rc_Adder(std::shared_ptr* self) { delete self; } void _ffi_cpp_drop_Rc_Getter(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_getter(std::shared_ptr getter) { auto getter_ptr = new std::shared_ptr(getter); return _ffi_fn_set_getter(getter_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_nested_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder; struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; struct Getter { virtual ~Getter() {} virtual std::shared_ptr get_adder() = 0; }; uintptr_t rust_mem_leaked(); int32_t set_getter(std::shared_ptr getter); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_nested_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 { set_getter(std::rc::Rc::new(_ffi_rs_Rc_Getter(getter_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Adder(*const u8); impl Drop for _ffi_rs_Rc_Adder { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Adder(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Adder(self.0) }; } } impl Adder for _ffi_rs_Rc_Adder { fn add(&self, x: i32, y: i32) -> i32 { extern "C" { fn _ffi_cpp_Rc_Adder__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_cpp_Rc_Adder__add(self.0, x, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Getter(*const u8); impl Drop for _ffi_rs_Rc_Getter { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Getter(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Getter(self.0) }; } } impl Getter for _ffi_rs_Rc_Getter { fn get_adder(&self) -> std::rc::Rc { extern "C" { fn _ffi_cpp_Rc_Getter__get_adder(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_cpp_Rc_Getter__get_adder(self.0) }; std::rc::Rc::new(_ffi_rs_Rc_Adder(ret_ptr)) } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_nested_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_getter(const void* getter_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr* _self, int32_t x, int32_t y) { return _self->get()->add(x, y); } const void* _ffi_cpp_Rc_Getter__get_adder(std::shared_ptr* _self) { return new std::shared_ptr(_self->get()->get_adder()); } void _ffi_cpp_drop_Rc_Adder(std::shared_ptr* self) { delete self; } void _ffi_cpp_drop_Rc_Getter(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_getter(std::shared_ptr getter) { auto getter_ptr = new std::shared_ptr(getter); return _ffi_fn_set_getter(getter_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_nested_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct Adder; struct Adder { virtual ~Adder() {} virtual int32_t add(int32_t x, int32_t y) = 0; }; struct Getter { virtual ~Getter() {} virtual std::shared_ptr get_adder() = 0; }; uintptr_t rust_mem_leaked(); int32_t set_getter(std::shared_ptr getter); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_nested_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 { set_getter(std::rc::Rc::new(_ffi_rs_Rc_Getter(getter_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Adder(*const u8); impl Drop for _ffi_rs_Rc_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Adder(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Adder(self.0) }; } } impl Adder for _ffi_rs_Rc_Adder { fn add(&self, x: i32, y: i32) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_Adder__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_cpp_Rc_Adder__add(self.0, x, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Getter(*const u8); impl Drop for _ffi_rs_Rc_Getter { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Getter(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Getter(self.0) }; } } impl Getter for _ffi_rs_Rc_Getter { fn get_adder(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_cpp_Rc_Getter__get_adder(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_cpp_Rc_Getter__get_adder(self.0) }; std::rc::Rc::new(_ffi_rs_Rc_Adder(ret_ptr)) } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_struct_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_struct(const void* struct_in_ptr); float _ffi_fn_set_multiply_pairs(const void* struct_in_ptr); int32_t _ffi_fn_set_single_element_struct(const void* struct_in_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Rc_StructIn__empty_struct(std::shared_ptr* _self, int32_t x, int32_t y) { auto foo = rust::EmptyStruct{}; return _self->get()->empty_struct(x, std::move(foo), y); } float _ffi_cpp_Rc_StructIn__multiply_pairs(std::shared_ptr* _self, float ab_x, float ab_y, float cd_x, float cd_y) { auto ab = rust::PairStruct{ab_x, ab_y}; auto cd = rust::PairStruct{cd_x, cd_y}; return _self->get()->multiply_pairs(std::move(ab), std::move(cd)); } int32_t _ffi_cpp_Rc_StructIn__single_element_struct(std::shared_ptr* _self, int32_t x_0, int32_t y_0) { auto x = rust::SingleElementStruct{x_0}; auto y = rust::SingleElementStruct{y_0}; return _self->get()->single_element_struct(std::move(x), std::move(y)); } void _ffi_cpp_drop_Rc_StructIn(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_empty_struct(std::shared_ptr struct_in) { auto struct_in_ptr = new std::shared_ptr(struct_in); return _ffi_fn_set_empty_struct(struct_in_ptr); } float rust::set_multiply_pairs(std::shared_ptr struct_in) { auto struct_in_ptr = new std::shared_ptr(struct_in); return _ffi_fn_set_multiply_pairs(struct_in_ptr); } int32_t rust::set_single_element_struct(std::shared_ptr struct_in) { auto struct_in_ptr = new std::shared_ptr(struct_in); return _ffi_fn_set_single_element_struct(struct_in_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_struct_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct EmptyStruct { }; struct PairStruct { float x = 0.0f; float y = 0.0f; }; struct SingleElementStruct { int32_t _0 = 0; }; struct StructIn { virtual ~StructIn() {} virtual int32_t empty_struct(int32_t x, EmptyStruct foo, int32_t y) = 0; virtual int32_t single_element_struct(SingleElementStruct x, SingleElementStruct y) = 0; virtual float multiply_pairs(PairStruct ab, PairStruct cd) = 0; }; uintptr_t rust_mem_leaked(); int32_t set_empty_struct(std::shared_ptr struct_in); int32_t set_single_element_struct(std::shared_ptr struct_in); float set_multiply_pairs(std::shared_ptr struct_in); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_struct_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 { set_empty_struct(std::rc::Rc::new(_ffi_rs_Rc_StructIn(struct_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_Rc_StructIn(struct_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8) -> i32 { set_single_element_struct(std::rc::Rc::new(_ffi_rs_Rc_StructIn(struct_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_StructIn(*const u8); impl Drop for _ffi_rs_Rc_StructIn { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_StructIn(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_StructIn(self.0) }; } } impl StructIn for _ffi_rs_Rc_StructIn { fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 { extern "C" { fn _ffi_cpp_Rc_StructIn__empty_struct(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_cpp_Rc_StructIn__empty_struct(self.0, x, y) } } fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32 { extern "C" { fn _ffi_cpp_Rc_StructIn__single_element_struct(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_cpp_Rc_StructIn__single_element_struct(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 { extern "C" { fn _ffi_cpp_Rc_StructIn__multiply_pairs(_: *const u8, ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32; } unsafe { _ffi_cpp_Rc_StructIn__multiply_pairs(self.0, ab.x, ab.y, cd.x, cd.y) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_struct_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_struct(const void* struct_in_ptr); float _ffi_fn_set_multiply_pairs(const void* struct_in_ptr); int32_t _ffi_fn_set_single_element_struct(const void* struct_in_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Rc_StructIn__empty_struct(std::shared_ptr* _self, int32_t x, int32_t y) { auto foo = rust::EmptyStruct{}; return _self->get()->empty_struct(x, std::move(foo), y); } float _ffi_cpp_Rc_StructIn__multiply_pairs(std::shared_ptr* _self, float ab_x, float ab_y, float cd_x, float cd_y) { auto ab = rust::PairStruct{ab_x, ab_y}; auto cd = rust::PairStruct{cd_x, cd_y}; return _self->get()->multiply_pairs(std::move(ab), std::move(cd)); } int32_t _ffi_cpp_Rc_StructIn__single_element_struct(std::shared_ptr* _self, int32_t x_0, int32_t y_0) { auto x = rust::SingleElementStruct{x_0}; auto y = rust::SingleElementStruct{y_0}; return _self->get()->single_element_struct(std::move(x), std::move(y)); } void _ffi_cpp_drop_Rc_StructIn(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_empty_struct(std::shared_ptr struct_in) { auto struct_in_ptr = new std::shared_ptr(struct_in); return _ffi_fn_set_empty_struct(struct_in_ptr); } float rust::set_multiply_pairs(std::shared_ptr struct_in) { auto struct_in_ptr = new std::shared_ptr(struct_in); return _ffi_fn_set_multiply_pairs(struct_in_ptr); } int32_t rust::set_single_element_struct(std::shared_ptr struct_in) { auto struct_in_ptr = new std::shared_ptr(struct_in); return _ffi_fn_set_single_element_struct(struct_in_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_struct_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include namespace rust { struct EmptyStruct { }; struct PairStruct { float x = 0.0f; float y = 0.0f; }; struct SingleElementStruct { int32_t _0 = 0; }; struct StructIn { virtual ~StructIn() {} virtual int32_t empty_struct(int32_t x, EmptyStruct foo, int32_t y) = 0; virtual int32_t single_element_struct(SingleElementStruct x, SingleElementStruct y) = 0; virtual float multiply_pairs(PairStruct ab, PairStruct cd) = 0; }; uintptr_t rust_mem_leaked(); int32_t set_empty_struct(std::shared_ptr struct_in); int32_t set_single_element_struct(std::shared_ptr struct_in); float set_multiply_pairs(std::shared_ptr struct_in); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_struct_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 { set_empty_struct(std::rc::Rc::new(_ffi_rs_Rc_StructIn(struct_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_Rc_StructIn(struct_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8) -> i32 { set_single_element_struct(std::rc::Rc::new(_ffi_rs_Rc_StructIn(struct_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_StructIn(*const u8); impl Drop for _ffi_rs_Rc_StructIn { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_StructIn(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_StructIn(self.0) }; } } impl StructIn for _ffi_rs_Rc_StructIn { fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_StructIn__empty_struct(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_cpp_Rc_StructIn__empty_struct(self.0, x, y) } } fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_StructIn__single_element_struct(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_cpp_Rc_StructIn__single_element_struct(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 { unsafe extern "C" { fn _ffi_cpp_Rc_StructIn__multiply_pairs(_: *const u8, ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32; } unsafe { _ffi_cpp_Rc_StructIn__multiply_pairs(self.0, ab.x, ab.y, cd.x, cd.y) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_tuple(const void* tuple_in_ptr); float _ffi_fn_set_multiply_pairs(const void* tuple_in_ptr); int32_t _ffi_fn_set_single_element_tuple(const void* tuple_in_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Rc_TupleIn__empty_tuple(std::shared_ptr* _self, int32_t x, int32_t y) { auto foo = std::tuple<>(); return _self->get()->empty_tuple(x, std::move(foo), y); } float _ffi_cpp_Rc_TupleIn__multiply_pairs(std::shared_ptr* _self, float ab_0, float ab_1, float cd_0, float cd_1) { auto ab = std::make_tuple(ab_0, ab_1); auto cd = std::make_tuple(cd_0, cd_1); return _self->get()->multiply_pairs(std::move(ab), std::move(cd)); } int32_t _ffi_cpp_Rc_TupleIn__single_element_tuple(std::shared_ptr* _self, int32_t x_0, int32_t y_0) { auto x = x_0; auto y = y_0; return _self->get()->single_element_tuple(std::move(x), std::move(y)); } void _ffi_cpp_drop_Rc_TupleIn(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_empty_tuple(std::shared_ptr tuple_in) { auto tuple_in_ptr = new std::shared_ptr(tuple_in); return _ffi_fn_set_empty_tuple(tuple_in_ptr); } float rust::set_multiply_pairs(std::shared_ptr tuple_in) { auto tuple_in_ptr = new std::shared_ptr(tuple_in); return _ffi_fn_set_multiply_pairs(tuple_in_ptr); } int32_t rust::set_single_element_tuple(std::shared_ptr tuple_in) { auto tuple_in_ptr = new std::shared_ptr(tuple_in); return _ffi_fn_set_single_element_tuple(tuple_in_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct TupleIn { virtual ~TupleIn() {} virtual int32_t empty_tuple(int32_t x, std::tuple<> foo, int32_t y) = 0; virtual int32_t single_element_tuple(std::tuple x, std::tuple y) = 0; virtual float multiply_pairs(std::tuple ab, std::tuple cd) = 0; }; uintptr_t rust_mem_leaked(); int32_t set_empty_tuple(std::shared_ptr tuple_in); int32_t set_single_element_tuple(std::shared_ptr tuple_in); float set_multiply_pairs(std::shared_ptr tuple_in); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 { set_empty_tuple(std::rc::Rc::new(_ffi_rs_Rc_TupleIn(tuple_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_Rc_TupleIn(tuple_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) -> i32 { set_single_element_tuple(std::rc::Rc::new(_ffi_rs_Rc_TupleIn(tuple_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_TupleIn(*const u8); impl Drop for _ffi_rs_Rc_TupleIn { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_TupleIn(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_TupleIn(self.0) }; } } impl TupleIn for _ffi_rs_Rc_TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 { extern "C" { fn _ffi_cpp_Rc_TupleIn__empty_tuple(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_cpp_Rc_TupleIn__empty_tuple(self.0, x, y) } } fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 { extern "C" { fn _ffi_cpp_Rc_TupleIn__single_element_tuple(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_cpp_Rc_TupleIn__single_element_tuple(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 { extern "C" { fn _ffi_cpp_Rc_TupleIn__multiply_pairs(_: *const u8, ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32; } unsafe { _ffi_cpp_Rc_TupleIn__multiply_pairs(self.0, ab.0, ab.1, cd.0, cd.1) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" extern "C" { uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_tuple(const void* tuple_in_ptr); float _ffi_fn_set_multiply_pairs(const void* tuple_in_ptr); int32_t _ffi_fn_set_single_element_tuple(const void* tuple_in_ptr); } // extern "C" extern "C" { int32_t _ffi_cpp_Rc_TupleIn__empty_tuple(std::shared_ptr* _self, int32_t x, int32_t y) { auto foo = std::tuple<>(); return _self->get()->empty_tuple(x, std::move(foo), y); } float _ffi_cpp_Rc_TupleIn__multiply_pairs(std::shared_ptr* _self, float ab_0, float ab_1, float cd_0, float cd_1) { auto ab = std::make_tuple(ab_0, ab_1); auto cd = std::make_tuple(cd_0, cd_1); return _self->get()->multiply_pairs(std::move(ab), std::move(cd)); } int32_t _ffi_cpp_Rc_TupleIn__single_element_tuple(std::shared_ptr* _self, int32_t x_0, int32_t y_0) { auto x = x_0; auto y = y_0; return _self->get()->single_element_tuple(std::move(x), std::move(y)); } void _ffi_cpp_drop_Rc_TupleIn(std::shared_ptr* self) { delete self; } } // extern "C" uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } int32_t rust::set_empty_tuple(std::shared_ptr tuple_in) { auto tuple_in_ptr = new std::shared_ptr(tuple_in); return _ffi_fn_set_empty_tuple(tuple_in_ptr); } float rust::set_multiply_pairs(std::shared_ptr tuple_in) { auto tuple_in_ptr = new std::shared_ptr(tuple_in); return _ffi_fn_set_multiply_pairs(tuple_in_ptr); } int32_t rust::set_single_element_tuple(std::shared_ptr tuple_in) { auto tuple_in_ptr = new std::shared_ptr(tuple_in); return _ffi_fn_set_single_element_tuple(tuple_in_ptr); } ================================================ FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct TupleIn { virtual ~TupleIn() {} virtual int32_t empty_tuple(int32_t x, std::tuple<> foo, int32_t y) = 0; virtual int32_t single_element_tuple(std::tuple x, std::tuple y) = 0; virtual float multiply_pairs(std::tuple ab, std::tuple cd) = 0; }; uintptr_t rust_mem_leaked(); int32_t set_empty_tuple(std::shared_ptr tuple_in); int32_t set_single_element_tuple(std::shared_ptr tuple_in); float set_multiply_pairs(std::shared_ptr tuple_in); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 { set_empty_tuple(std::rc::Rc::new(_ffi_rs_Rc_TupleIn(tuple_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_Rc_TupleIn(tuple_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) -> i32 { set_single_element_tuple(std::rc::Rc::new(_ffi_rs_Rc_TupleIn(tuple_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Rc_TupleIn(*const u8); impl Drop for _ffi_rs_Rc_TupleIn { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_TupleIn(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_TupleIn(self.0) }; } } impl TupleIn for _ffi_rs_Rc_TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_TupleIn__empty_tuple(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_cpp_Rc_TupleIn__empty_tuple(self.0, x, y) } } fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 { unsafe extern "C" { fn _ffi_cpp_Rc_TupleIn__single_element_tuple(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_cpp_Rc_TupleIn__single_element_tuple(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 { unsafe extern "C" { fn _ffi_cpp_Rc_TupleIn__multiply_pairs(_: *const u8, ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32; } unsafe { _ffi_cpp_Rc_TupleIn__multiply_pairs(self.0, ab.0, ab.1, cd.0, cd.1) } } } ================================================ FILE: src/tests/snapshots/cpp_trait_string_2021/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); void _ffi_drop_Rc_Test(const void* ptr); void* _ffi_alloc(uintptr_t len); _ffi_ret_ptr_2_usize _ffi_Rc_Test__get_string(const void* _self); void _ffi_Rc_Test__set_str(const void* _self, const void* x_ptr, uintptr_t x_len); void _ffi_Rc_Test__set_string(const void* _self, const void* x_ptr, uintptr_t x_len); const void* _ffi_fn_get_test(); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_2_usize _ffi_fn_set_test(const void* test_ptr); } // extern "C" namespace { std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } struct _ffi_Rc_Test final : rust::Test { _ffi_Rc_Test(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Test() { _ffi_drop_Rc_Test(_self); } virtual std::string get_string(); virtual void set_string(std::string x); virtual void set_str(std::string x); const void* _self; }; const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } } // namespace extern "C" { _ffi_ret_ptr_usize _ffi_cpp_Rc_Test__get_string(std::shared_ptr* _self) { uintptr_t ret_len; const void* ret_ptr = _ffi_string_to_rust(_self->get()->get_string(), ret_len); return _ffi_ret_ptr_usize{ret_ptr, ret_len}; } void _ffi_cpp_Rc_Test__set_str(std::shared_ptr* _self, const char* x_ptr, uintptr_t x_len, uintptr_t x_cap) { auto x = _ffi_string_from_rust(x_ptr, x_len, x_cap); _self->get()->set_str(std::move(x)); } void _ffi_cpp_Rc_Test__set_string(std::shared_ptr* _self, const char* x_ptr, uintptr_t x_len, uintptr_t x_cap) { auto x = _ffi_string_from_rust(x_ptr, x_len, x_cap); _self->get()->set_string(std::move(x)); } void _ffi_cpp_drop_Rc_Test(std::shared_ptr* self) { delete self; } } // extern "C" std::string _ffi_Rc_Test::get_string() { auto multi_ret = _ffi_Rc_Test__get_string(_self); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } void _ffi_Rc_Test::set_str(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_Rc_Test__set_str(_self, x_ptr, x_len); } void _ffi_Rc_Test::set_string(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_Rc_Test__set_string(_self, x_ptr, x_len); } std::shared_ptr rust::get_test() { auto ret_ptr = _ffi_fn_get_test(); return std::make_shared<_ffi_Rc_Test>(ret_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::string rust::set_test(std::shared_ptr test) { auto test_ptr = new std::shared_ptr(test); auto multi_ret = _ffi_fn_set_test(test_ptr); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } ================================================ FILE: src/tests/snapshots/cpp_trait_string_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Test { virtual ~Test() {} virtual std::string get_string() = 0; virtual void set_string(std::string x) = 0; virtual void set_str(std::string x) = 0; }; uintptr_t rust_mem_leaked(); std::shared_ptr get_test(); std::string set_test(std::shared_ptr test); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_string_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> _ffi_ret_ptr_2_usize { let _self = unsafe { &*(_self as *const std::rc::Rc) }; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(_self.get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_string(_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_drop_Rc_Test(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_fn_get_test() -> *const u8 { Box::into_raw(Box::new(get_test())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(set_test(std::rc::Rc::new(_ffi_rs_Rc_Test(test_ptr)))); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Test(*const u8); impl Drop for _ffi_rs_Rc_Test { fn drop(&mut self) { extern "C" { fn _ffi_cpp_drop_Rc_Test(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Test(self.0) }; } } impl Test for _ffi_rs_Rc_Test { fn get_string(&self) -> String { extern "C" { fn _ffi_cpp_Rc_Test__get_string(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_cpp_Rc_Test__get_string(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_string(&self, x: String) { extern "C" { fn _ffi_cpp_Rc_Test__set_string(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x); unsafe { _ffi_cpp_Rc_Test__set_string(self.0, x_ptr, x_len, x_cap) }; } fn set_str(&self, x: &str) { extern "C" { fn _ffi_cpp_Rc_Test__set_str(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x.into()); unsafe { _ffi_cpp_Rc_Test__set_str(self.0, x_ptr, x_len, x_cap) }; } } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/cpp_trait_string_2024/ffi.cpp ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #include "ffi.h" struct _ffi_ret_ptr_2_usize { const char* _0; uintptr_t _1; uintptr_t _2; }; struct _ffi_ret_ptr_usize { const void* _0; uintptr_t _1; }; extern "C" { void _ffi_dealloc(const void* ptr, uintptr_t capacity); void _ffi_drop_Rc_Test(const void* ptr); void* _ffi_alloc(uintptr_t len); _ffi_ret_ptr_2_usize _ffi_Rc_Test__get_string(const void* _self); void _ffi_Rc_Test__set_str(const void* _self, const void* x_ptr, uintptr_t x_len); void _ffi_Rc_Test__set_string(const void* _self, const void* x_ptr, uintptr_t x_len); const void* _ffi_fn_get_test(); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_2_usize _ffi_fn_set_test(const void* test_ptr); } // extern "C" namespace { std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) { std::string str(ptr, len); _ffi_dealloc(ptr, cap); return str; } struct _ffi_Rc_Test final : rust::Test { _ffi_Rc_Test(const void* ptr) : _self(ptr) {} virtual ~_ffi_Rc_Test() { _ffi_drop_Rc_Test(_self); } virtual std::string get_string(); virtual void set_string(std::string x); virtual void set_str(std::string x); const void* _self; }; const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) { len = str.size(); return memcpy(_ffi_alloc(len), str.data(), len); } } // namespace extern "C" { _ffi_ret_ptr_usize _ffi_cpp_Rc_Test__get_string(std::shared_ptr* _self) { uintptr_t ret_len; const void* ret_ptr = _ffi_string_to_rust(_self->get()->get_string(), ret_len); return _ffi_ret_ptr_usize{ret_ptr, ret_len}; } void _ffi_cpp_Rc_Test__set_str(std::shared_ptr* _self, const char* x_ptr, uintptr_t x_len, uintptr_t x_cap) { auto x = _ffi_string_from_rust(x_ptr, x_len, x_cap); _self->get()->set_str(std::move(x)); } void _ffi_cpp_Rc_Test__set_string(std::shared_ptr* _self, const char* x_ptr, uintptr_t x_len, uintptr_t x_cap) { auto x = _ffi_string_from_rust(x_ptr, x_len, x_cap); _self->get()->set_string(std::move(x)); } void _ffi_cpp_drop_Rc_Test(std::shared_ptr* self) { delete self; } } // extern "C" std::string _ffi_Rc_Test::get_string() { auto multi_ret = _ffi_Rc_Test__get_string(_self); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } void _ffi_Rc_Test::set_str(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_Rc_Test__set_str(_self, x_ptr, x_len); } void _ffi_Rc_Test::set_string(std::string x) { uintptr_t x_len; const void* x_ptr = _ffi_string_to_rust(x, x_len); _ffi_Rc_Test__set_string(_self, x_ptr, x_len); } std::shared_ptr rust::get_test() { auto ret_ptr = _ffi_fn_get_test(); return std::make_shared<_ffi_Rc_Test>(ret_ptr); } uintptr_t rust::rust_mem_leaked() { return _ffi_fn_rust_mem_leaked(); } std::string rust::set_test(std::shared_ptr test) { auto test_ptr = new std::shared_ptr(test); auto multi_ret = _ffi_fn_set_test(test_ptr); auto ret_ptr = multi_ret._0; auto ret_len = multi_ret._1; auto ret_cap = multi_ret._2; return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } ================================================ FILE: src/tests/snapshots/cpp_trait_string_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #include #include namespace rust { struct Test { virtual ~Test() {} virtual std::string get_string() = 0; virtual void set_string(std::string x) = 0; virtual void set_str(std::string x) = 0; }; uintptr_t rust_mem_leaked(); std::shared_ptr get_test(); std::string set_test(std::shared_ptr test); } // namespace rust ================================================ FILE: src/tests/snapshots/cpp_trait_string_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> _ffi_ret_ptr_2_usize { let _self = unsafe { &*(_self as *const std::rc::Rc) }; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(_self.get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_string(_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_drop_Rc_Test(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_test() -> *const u8 { Box::into_raw(Box::new(get_test())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(set_test(std::rc::Rc::new(_ffi_rs_Rc_Test(test_ptr)))); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Rc_Test(*const u8); impl Drop for _ffi_rs_Rc_Test { fn drop(&mut self) { unsafe extern "C" { fn _ffi_cpp_drop_Rc_Test(_: *const u8); } unsafe { _ffi_cpp_drop_Rc_Test(self.0) }; } } impl Test for _ffi_rs_Rc_Test { fn get_string(&self) -> String { unsafe extern "C" { fn _ffi_cpp_Rc_Test__get_string(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_cpp_Rc_Test__get_string(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_string(&self, x: String) { unsafe extern "C" { fn _ffi_cpp_Rc_Test__set_string(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x); unsafe { _ffi_cpp_Rc_Test__set_string(self.0, x_ptr, x_len, x_cap) }; } fn set_str(&self, x: &str) { unsafe extern "C" { fn _ffi_cpp_Rc_Test__set_str(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x.into()); unsafe { _ffi_cpp_Rc_Test__set_str(self.0, x_ptr, x_len, x_cap) }; } } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/swift_demo_app_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_Box_Handler__on_draw(const void*, const void* canvas_ptr); void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); void _ffi_fn_create_app(const void* platform_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { int32_t _0; int32_t _1; } _ffi_ret_2_i32; typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; void _ffi_rs_drop_Box_Handler(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_app_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Platform: AnyObject { func create_window() -> Window } protocol Window: AnyObject { func get_title() -> String func set_title(_ title: String) func get_size() -> (Int32, Int32) func set_size(_ width: Int32, _ height: Int32) func set_handler(_ handler: Handler) func child_window() -> Window } protocol Handler: AnyObject { func on_draw(_ canvas: Canvas) } protocol Canvas: AnyObject { func draw_text_runs(_ runs: [TextRun]) } struct TextRun { var text: String var rect: TextRect } struct TextRect { var x: Int32 var y: Int32 var w: Int32 var h: Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func create_app(_ platform: Platform) { _ffi_fn_create_app(UnsafeRawPointer(Unmanaged.passRetained(platform as AnyObject).toOpaque())) } private class _ffi_Box_Handler : Handler { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Handler(_ffi) } func on_draw(_ canvas: Canvas) { _ffi_Box_Handler__on_draw(_ffi, UnsafeRawPointer(Unmanaged.passRetained(canvas as AnyObject).toOpaque())) } } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } @_cdecl("_ffi_swift_Canvas__draw_text_runs") func _ffi_swift_Canvas__draw_text_runs(_self: UnsafeRawPointer?, buf_ptr: UnsafeRawPointer?, buf_cap: UInt, runs_len: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Canvas var buf_end = buf_ptr! _self.draw_text_runs(_ffi_vec_TextRun_from_rust(Int(runs_len), &buf_end)) _ffi_dealloc(buf_ptr, buf_cap) } @_cdecl("_ffi_swift_Platform__create_window") func _ffi_swift_Platform__create_window(_self: UnsafeRawPointer?) -> UnsafeRawPointer? { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Platform return UnsafeRawPointer(Unmanaged.passRetained(_self.create_window() as AnyObject).toOpaque()) } @_cdecl("_ffi_swift_Window__child_window") func _ffi_swift_Window__child_window(_self: UnsafeRawPointer?) -> UnsafeRawPointer? { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window return UnsafeRawPointer(Unmanaged.passRetained(_self.child_window() as AnyObject).toOpaque()) } @_cdecl("_ffi_swift_Window__get_size") func _ffi_swift_Window__get_size(_self: UnsafeRawPointer?) -> _ffi_ret_2_i32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window let ret = _self.get_size() return _ffi_ret_2_i32(_0: ret.0, _1: ret.1) } @_cdecl("_ffi_swift_Window__get_title") func _ffi_swift_Window__get_title(_self: UnsafeRawPointer?) -> _ffi_ret_ptr_usize { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window let (ret_ptr, ret_len) = _ffi_string_to_rust(_self.get_title()); return _ffi_ret_ptr_usize(_0: ret_ptr, _1: ret_len) } @_cdecl("_ffi_swift_Window__set_handler") func _ffi_swift_Window__set_handler(_self: UnsafeRawPointer?, handler_ptr: UnsafeRawPointer?) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window _self.set_handler(_ffi_Box_Handler(handler_ptr)) } @_cdecl("_ffi_swift_Window__set_size") func _ffi_swift_Window__set_size(_self: UnsafeRawPointer?, width: Int32, height: Int32) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window _self.set_size(width, height) } @_cdecl("_ffi_swift_Window__set_title") func _ffi_swift_Window__set_title(_self: UnsafeRawPointer?, title_ptr: UnsafeRawPointer?, title_len: UInt, title_cap: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window _self.set_title(_ffi_string_from_rust(title_ptr, Int(title_len), title_cap)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } private func _ffi_vec_TextRun_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [TextRun] { var items: [TextRun] = [] items.reserveCapacity(len) while items.count < len { items.append(TextRun( text: _ffi_string_from_rust(_ffi_read(&end) as UnsafeRawPointer?, Int(_ffi_read(&end) as UInt), _ffi_read(&end) as UInt), rect: TextRect( x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32, w: _ffi_read(&end) as Int32, h: _ffi_read(&end) as Int32 ) )) } return items } ================================================ FILE: src/tests/snapshots/swift_demo_app_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *const u8) { let _self = unsafe { &*(_self as *const Box) }; _self.on_draw(Box::new(_ffi_rs_Canvas(canvas_ptr))); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) { create_app(Box::new(_ffi_rs_Platform(platform_ptr))); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_2_i32(i32, i32); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Canvas(*const u8); impl Drop for _ffi_rs_Canvas { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Canvas for _ffi_rs_Canvas { fn draw_text_runs(&self, runs: Vec) { extern "C" { fn _ffi_swift_Canvas__draw_text_runs(_: *const u8, buf_ptr: *const u8, buf_cap: usize, runs_len: usize); } let mut buf = Vec::::new(); let runs_len = runs.len(); _ffi_vec_TextRun_to_swift(runs, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _ffi_swift_Canvas__draw_text_runs(self.0, buf_ptr, buf_cap, runs_len) }; } } #[allow(non_camel_case_types)] struct _ffi_rs_Platform(*const u8); impl Drop for _ffi_rs_Platform { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Platform for _ffi_rs_Platform { fn create_window(&self) -> std::rc::Rc { extern "C" { fn _ffi_swift_Platform__create_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_swift_Platform__create_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[allow(non_camel_case_types)] struct _ffi_rs_Window(*const u8); impl Drop for _ffi_rs_Window { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Window for _ffi_rs_Window { fn get_title(&self) -> String { extern "C" { fn _ffi_swift_Window__get_title(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_swift_Window__get_title(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_title(&self, title: &str) { extern "C" { fn _ffi_swift_Window__set_title(_: *const u8, title_ptr: *const u8, title_len: usize, title_cap: usize); } let (title_ptr, title_len, title_cap) = _ffi_string_to_host(title.into()); unsafe { _ffi_swift_Window__set_title(self.0, title_ptr, title_len, title_cap) }; } fn get_size(&self) -> (i32, i32) { extern "C" { fn _ffi_swift_Window__get_size(_: *const u8) -> _ffi_ret_2_i32; } let multi_ret = unsafe { _ffi_swift_Window__get_size(self.0) }; let ret_0 = multi_ret.0; let ret_1 = multi_ret.1; (ret_0, ret_1) } fn set_size(&self, width: i32, height: i32) { extern "C" { fn _ffi_swift_Window__set_size(_: *const u8, width: i32, height: i32); } unsafe { _ffi_swift_Window__set_size(self.0, width, height) }; } fn set_handler(&self, handler: Box) { extern "C" { fn _ffi_swift_Window__set_handler(_: *const u8, handler_ptr: *const u8); } unsafe { _ffi_swift_Window__set_handler(self.0, Box::into_raw(Box::new(handler)) as *const u8) }; } fn child_window(&self) -> std::rc::Rc { extern "C" { fn _ffi_swift_Window__child_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_swift_Window__child_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Handler(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_TextRun_to_swift(items: Vec, buf: &mut Vec) { for item in items { let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.rect.x, buf); _ffi_write(item.rect.y, buf); _ffi_write(item.rect.w, buf); _ffi_write(item.rect.h, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_demo_app_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_Box_Handler__on_draw(const void*, const void* canvas_ptr); void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); void _ffi_fn_create_app(const void* platform_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { int32_t _0; int32_t _1; } _ffi_ret_2_i32; typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; void _ffi_rs_drop_Box_Handler(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_app_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Platform: AnyObject { func create_window() -> Window } protocol Window: AnyObject { func get_title() -> String func set_title(_ title: String) func get_size() -> (Int32, Int32) func set_size(_ width: Int32, _ height: Int32) func set_handler(_ handler: Handler) func child_window() -> Window } protocol Handler: AnyObject { func on_draw(_ canvas: Canvas) } protocol Canvas: AnyObject { func draw_text_runs(_ runs: [TextRun]) } struct TextRun { var text: String var rect: TextRect } struct TextRect { var x: Int32 var y: Int32 var w: Int32 var h: Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func create_app(_ platform: Platform) { _ffi_fn_create_app(UnsafeRawPointer(Unmanaged.passRetained(platform as AnyObject).toOpaque())) } private class _ffi_Box_Handler : Handler { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Handler(_ffi) } func on_draw(_ canvas: Canvas) { _ffi_Box_Handler__on_draw(_ffi, UnsafeRawPointer(Unmanaged.passRetained(canvas as AnyObject).toOpaque())) } } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } @_cdecl("_ffi_swift_Canvas__draw_text_runs") func _ffi_swift_Canvas__draw_text_runs(_self: UnsafeRawPointer?, buf_ptr: UnsafeRawPointer?, buf_cap: UInt, runs_len: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Canvas var buf_end = buf_ptr! _self.draw_text_runs(_ffi_vec_TextRun_from_rust(Int(runs_len), &buf_end)) _ffi_dealloc(buf_ptr, buf_cap) } @_cdecl("_ffi_swift_Platform__create_window") func _ffi_swift_Platform__create_window(_self: UnsafeRawPointer?) -> UnsafeRawPointer? { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Platform return UnsafeRawPointer(Unmanaged.passRetained(_self.create_window() as AnyObject).toOpaque()) } @_cdecl("_ffi_swift_Window__child_window") func _ffi_swift_Window__child_window(_self: UnsafeRawPointer?) -> UnsafeRawPointer? { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window return UnsafeRawPointer(Unmanaged.passRetained(_self.child_window() as AnyObject).toOpaque()) } @_cdecl("_ffi_swift_Window__get_size") func _ffi_swift_Window__get_size(_self: UnsafeRawPointer?) -> _ffi_ret_2_i32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window let ret = _self.get_size() return _ffi_ret_2_i32(_0: ret.0, _1: ret.1) } @_cdecl("_ffi_swift_Window__get_title") func _ffi_swift_Window__get_title(_self: UnsafeRawPointer?) -> _ffi_ret_ptr_usize { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window let (ret_ptr, ret_len) = _ffi_string_to_rust(_self.get_title()); return _ffi_ret_ptr_usize(_0: ret_ptr, _1: ret_len) } @_cdecl("_ffi_swift_Window__set_handler") func _ffi_swift_Window__set_handler(_self: UnsafeRawPointer?, handler_ptr: UnsafeRawPointer?) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window _self.set_handler(_ffi_Box_Handler(handler_ptr)) } @_cdecl("_ffi_swift_Window__set_size") func _ffi_swift_Window__set_size(_self: UnsafeRawPointer?, width: Int32, height: Int32) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window _self.set_size(width, height) } @_cdecl("_ffi_swift_Window__set_title") func _ffi_swift_Window__set_title(_self: UnsafeRawPointer?, title_ptr: UnsafeRawPointer?, title_len: UInt, title_cap: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Window _self.set_title(_ffi_string_from_rust(title_ptr, Int(title_len), title_cap)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } private func _ffi_vec_TextRun_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [TextRun] { var items: [TextRun] = [] items.reserveCapacity(len) while items.count < len { items.append(TextRun( text: _ffi_string_from_rust(_ffi_read(&end) as UnsafeRawPointer?, Int(_ffi_read(&end) as UInt), _ffi_read(&end) as UInt), rect: TextRect( x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32, w: _ffi_read(&end) as Int32, h: _ffi_read(&end) as Int32 ) )) } return items } ================================================ FILE: src/tests/snapshots/swift_demo_app_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *const u8) { let _self = unsafe { &*(_self as *const Box) }; _self.on_draw(Box::new(_ffi_rs_Canvas(canvas_ptr))); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) { create_app(Box::new(_ffi_rs_Platform(platform_ptr))); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_2_i32(i32, i32); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Canvas(*const u8); impl Drop for _ffi_rs_Canvas { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Canvas for _ffi_rs_Canvas { fn draw_text_runs(&self, runs: Vec) { unsafe extern "C" { fn _ffi_swift_Canvas__draw_text_runs(_: *const u8, buf_ptr: *const u8, buf_cap: usize, runs_len: usize); } let mut buf = Vec::::new(); let runs_len = runs.len(); _ffi_vec_TextRun_to_swift(runs, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _ffi_swift_Canvas__draw_text_runs(self.0, buf_ptr, buf_cap, runs_len) }; } } #[allow(non_camel_case_types)] struct _ffi_rs_Platform(*const u8); impl Drop for _ffi_rs_Platform { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Platform for _ffi_rs_Platform { fn create_window(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_swift_Platform__create_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_swift_Platform__create_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[allow(non_camel_case_types)] struct _ffi_rs_Window(*const u8); impl Drop for _ffi_rs_Window { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Window for _ffi_rs_Window { fn get_title(&self) -> String { unsafe extern "C" { fn _ffi_swift_Window__get_title(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_swift_Window__get_title(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_title(&self, title: &str) { unsafe extern "C" { fn _ffi_swift_Window__set_title(_: *const u8, title_ptr: *const u8, title_len: usize, title_cap: usize); } let (title_ptr, title_len, title_cap) = _ffi_string_to_host(title.into()); unsafe { _ffi_swift_Window__set_title(self.0, title_ptr, title_len, title_cap) }; } fn get_size(&self) -> (i32, i32) { unsafe extern "C" { fn _ffi_swift_Window__get_size(_: *const u8) -> _ffi_ret_2_i32; } let multi_ret = unsafe { _ffi_swift_Window__get_size(self.0) }; let ret_0 = multi_ret.0; let ret_1 = multi_ret.1; (ret_0, ret_1) } fn set_size(&self, width: i32, height: i32) { unsafe extern "C" { fn _ffi_swift_Window__set_size(_: *const u8, width: i32, height: i32); } unsafe { _ffi_swift_Window__set_size(self.0, width, height) }; } fn set_handler(&self, handler: Box) { unsafe extern "C" { fn _ffi_swift_Window__set_handler(_: *const u8, handler_ptr: *const u8); } unsafe { _ffi_swift_Window__set_handler(self.0, Box::into_raw(Box::new(handler)) as *const u8) }; } fn child_window(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_swift_Window__child_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_swift_Window__child_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Handler(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_TextRun_to_swift(items: Vec, buf: &mut Vec) { for item in items { let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.rect.x, buf); _ffi_write(item.rect.y, buf); _ffi_write(item.rect.w, buf); _ffi_write(item.rect.h, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_demo_const_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_const_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. let CONST_FALSE: Bool = false let CONST_TRUE: Bool = true let CONST_U8_MIN: UInt8 = 0 let CONST_U8_MAX: UInt8 = 255 let CONST_U16_MIN: UInt16 = 0 let CONST_U16_MAX: UInt16 = 65535 let CONST_U32_MIN: UInt32 = 0 let CONST_U32_MAX: UInt32 = 4294967295 let CONST_U64_MIN: UInt64 = 0 let CONST_U64_MAX: UInt64 = 18446744073709551615 let CONST_I8_MIN: Int8 = -128 let CONST_I8_MAX: Int8 = 127 let CONST_I16_MIN: Int16 = -32768 let CONST_I16_MAX: Int16 = 32767 let CONST_I32_MIN: Int32 = -2147483648 let CONST_I32_MAX: Int32 = 2147483647 let CONST_I64_MIN: Int64 = -9223372036854775808 let CONST_I64_MAX: Int64 = 9223372036854775807 let CONST_F32_NEG_0: Float32 = -0.0 let CONST_F64_NEG_0: Float64 = -0.0 let CONST_F32_PI: Float32 = 3.1415927 let CONST_F64_PI: Float64 = -3.141592653589793 let CONST_STRING: String = "\u{0}\r\n🦀" func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_const_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_const_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_const_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. let CONST_FALSE: Bool = false let CONST_TRUE: Bool = true let CONST_U8_MIN: UInt8 = 0 let CONST_U8_MAX: UInt8 = 255 let CONST_U16_MIN: UInt16 = 0 let CONST_U16_MAX: UInt16 = 65535 let CONST_U32_MIN: UInt32 = 0 let CONST_U32_MAX: UInt32 = 4294967295 let CONST_U64_MIN: UInt64 = 0 let CONST_U64_MAX: UInt64 = 18446744073709551615 let CONST_I8_MIN: Int8 = -128 let CONST_I8_MAX: Int8 = 127 let CONST_I16_MIN: Int16 = -32768 let CONST_I16_MAX: Int16 = 32767 let CONST_I32_MIN: Int32 = -2147483648 let CONST_I32_MAX: Int32 = 2147483647 let CONST_I64_MIN: Int64 = -9223372036854775808 let CONST_I64_MAX: Int64 = 9223372036854775807 let CONST_F32_NEG_0: Float32 = -0.0 let CONST_F64_NEG_0: Float64 = -0.0 let CONST_F32_PI: Float32 = 3.1415927 let CONST_F64_PI: Float64 = -3.141592653589793 let CONST_STRING: String = "\u{0}\r\n🦀" func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_const_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_derive_eq_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; _ffi_ret_ptr_usize _ffi_fn_box_opt(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_opt_box(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_0(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_1(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_2(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec_box(const void* buf_ptr); void _ffi_fn_empty_struct(); void _ffi_fn_empty_tuple(); _ffi_ret_ptr_usize _ffi_fn_enum_box_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_opt_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_vec_tup(const void* buf_ptr); typedef struct { const void* _0; uintptr_t _1; _Bool _2; } _ffi_ret_ptr_usize_bool; _ffi_ret_ptr_usize_bool _ffi_fn_opt_box(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_box_opt(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_0(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_1(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_2(const void* buf_ptr, _Bool has_x_0); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_usize _ffi_fn_tup_box(const void* buf_ptr); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_vec_box(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_box_vec(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_0(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_1(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_2(const void* buf_ptr, uintptr_t x_0_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_derive_eq_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum EnumBoxTup : Equatable { case Foo((Int32, Int32)) case Bar case Baz(x: Int32, y: Int32) static func == (a: EnumBoxTup, b: EnumBoxTup) -> Bool { switch (a, b) { case let (.Foo(a0), .Foo(b0)): return a0.0 == b0.0 && a0.1 == b0.1 case (.Bar, .Bar): return true case let (.Baz(x: ax, y: ay), .Baz(x: bx, y: by)): return ax == bx && ay == by default: return false } } } enum EnumVecTup : Equatable { case Foo([(Int32, Int32)]) case Bar case Baz(x: Int32, y: Int32) static func == (a: EnumVecTup, b: EnumVecTup) -> Bool { switch (a, b) { case let (.Foo(a0), .Foo(b0)): return a0.elementsEqual(b0, by: { a, b in a.0 == b.0 && a.1 == b.1 }) case (.Bar, .Bar): return true case let (.Baz(x: ax, y: ay), .Baz(x: bx, y: by)): return ax == bx && ay == by default: return false } } } enum EnumOptTup : Equatable { case Foo((Int32, Int32)?) case Bar case Baz(x: Int32, y: Int32) static func == (a: EnumOptTup, b: EnumOptTup) -> Bool { switch (a, b) { case let (.Foo(a0), .Foo(b0)): return { if let a = a0, let b = b0 { a.0 == b.0 && a.1 == b.1 } else { a0 == nil && b0 == nil } }() case (.Bar, .Bar): return true case let (.Baz(x: ax, y: ay), .Baz(x: bx, y: by)): return ax == bx && ay == by default: return false } } } struct EmptyStruct : Equatable { } struct BoxTup0 : Equatable { var _0: () static func == (a: BoxTup0, b: BoxTup0) -> Bool { return true } } struct BoxTup1 : Equatable { var _0: Int32 } struct BoxTup2 : Equatable { var _0: (Int32, Int32) static func == (a: BoxTup2, b: BoxTup2) -> Bool { return a._0.0 == b._0.0 && a._0.1 == b._0.1 } } struct VecTup0 : Equatable { var _0: [()] static func == (a: VecTup0, b: VecTup0) -> Bool { return a._0.count == b._0.count } } struct VecTup1 : Equatable { var _0: [Int32] } struct VecTup2 : Equatable { var _0: [(Int32, Int32)] static func == (a: VecTup2, b: VecTup2) -> Bool { return a._0.elementsEqual(b._0, by: { a, b in a.0 == b.0 && a.1 == b.1 }) } } struct OptTup0 : Equatable { var _0: ()? static func == (a: OptTup0, b: OptTup0) -> Bool { return (a._0 != nil) == (b._0 != nil) } } struct OptTup1 : Equatable { var _0: Int32? } struct OptTup2 : Equatable { var _0: (Int32, Int32)? static func == (a: OptTup2, b: OptTup2) -> Bool { return { if let a = a._0, let b = b._0 { a.0 == b.0 && a.1 == b.1 } else { a._0 == nil && b._0 == nil } }() } } struct TupBox : Equatable { var _0: (Int32, Bool) static func == (a: TupBox, b: TupBox) -> Bool { return a._0.0 == b._0.0 && a._0.1 == b._0.1 } } struct VecBox : Equatable { var _0: [Int32] } struct BoxVec : Equatable { var _0: [Int32] } struct OptBox : Equatable { var _0: Int32? } struct BoxOpt : Equatable { var _0: Int32? } struct VecBoxVec : Equatable { var _0: [[Int32]] } struct BoxVecBox : Equatable { var _0: [Int32] } struct OptBoxOpt : Equatable { var _0: Int32?? } struct BoxOptBox : Equatable { var _0: Int32? } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_tuple(_ x: ()) -> () { _ffi_fn_empty_tuple() return () } func empty_struct(_ x: EmptyStruct) -> EmptyStruct { _ffi_fn_empty_struct() return EmptyStruct() } func box_tup_0(_ x: BoxTup0) -> BoxTup0 { var buf = ContiguousArray() _ffi_box__to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_tup_0(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxTup0(_0: _ffi_box__from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_tup_1(_ x: BoxTup1) -> BoxTup1 { var buf = ContiguousArray() _ffi_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_tup_1(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxTup1(_0: _ffi_box_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_tup_2(_ x: BoxTup2) -> BoxTup2 { var buf = ContiguousArray() _ffi_box_i32_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_tup_2(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxTup2(_0: _ffi_box_i32_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_tup_0(_ x: VecTup0) -> VecTup0 { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec__to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_tup_0(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecTup0(_0: _ffi_vec__from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_tup_1(_ x: VecTup1) -> VecTup1 { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_tup_1(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecTup1(_0: _ffi_vec_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_tup_2(_ x: VecTup2) -> VecTup2 { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_i32_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_tup_2(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecTup2(_0: _ffi_vec_i32_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_tup_0(_ x: OptTup0) -> OptTup0 { let buf = ContiguousArray() let has_x_0 = x._0 != nil let multi_ret = _ffi_fn_opt_tup_0(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 let ret = OptTup0(_0: has_ret_0 ? () : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_tup_1(_ x: OptTup1) -> OptTup1 { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_write(x_0_val, &buf) } let multi_ret = _ffi_fn_opt_tup_1(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptTup1(_0: has_ret_0 ? _ffi_read(&buf_end2) as Int32 : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_tup_2(_ x: OptTup2) -> OptTup2 { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_write(x_0_val.0, &buf) _ffi_write(x_0_val.1, &buf) } let multi_ret = _ffi_fn_opt_tup_2(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptTup2(_0: has_ret_0 ? (_ffi_read(&buf_end2) as Int32, _ffi_read(&buf_end2) as Int32) : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func enum_box_tup(_ x: EnumBoxTup) -> EnumBoxTup { var buf = ContiguousArray() _ffi_enum_EnumBoxTup_to_rust(x, &buf) let multi_ret = _ffi_fn_enum_box_tup(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = _ffi_enum_EnumBoxTup_from_rust(&buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func enum_vec_tup(_ x: EnumVecTup) -> EnumVecTup { var buf = ContiguousArray() _ffi_enum_EnumVecTup_to_rust(x, &buf) let multi_ret = _ffi_fn_enum_vec_tup(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = _ffi_enum_EnumVecTup_from_rust(&buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func enum_opt_tup(_ x: EnumOptTup) -> EnumOptTup { var buf = ContiguousArray() _ffi_enum_EnumOptTup_to_rust(x, &buf) let multi_ret = _ffi_fn_enum_opt_tup(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = _ffi_enum_EnumOptTup_from_rust(&buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func tup_box(_ x: TupBox) -> TupBox { var buf = ContiguousArray() _ffi_box_i32_to_rust2(x._0.0, &buf) _ffi_box_bool_to_rust(x._0.1, &buf) let multi_ret = _ffi_fn_tup_box(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = TupBox(_0: (_ffi_box_i32_from_rust2(&buf_end2), _ffi_box_bool_from_rust(&buf_end2))) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_box(_ x: VecBox) -> VecBox { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_box(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecBox(_0: _ffi_vec_box_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_vec(_ x: BoxVec) -> BoxVec { var buf = ContiguousArray() _ffi_box_vec_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_vec(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxVec(_0: _ffi_box_vec_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_box(_ x: OptBox) -> OptBox { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_box_i32_to_rust2(x_0_val, &buf) } let multi_ret = _ffi_fn_opt_box(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptBox(_0: has_ret_0 ? _ffi_box_i32_from_rust2(&buf_end2) : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_opt(_ x: BoxOpt) -> BoxOpt { var buf = ContiguousArray() _ffi_box_option_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_opt(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxOpt(_0: _ffi_box_option_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_box_vec(_ x: VecBoxVec) -> VecBoxVec { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_box_vec_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_box_vec(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecBoxVec(_0: _ffi_vec_box_vec_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_vec_box(_ x: BoxVecBox) -> BoxVecBox { var buf = ContiguousArray() _ffi_box_vec_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_vec_box(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxVecBox(_0: _ffi_box_vec_box_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_box_opt(_ x: OptBoxOpt) -> OptBoxOpt { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_box_option_i32_to_rust(x_0_val, &buf) } let multi_ret = _ffi_fn_opt_box_opt(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptBoxOpt(_0: has_ret_0 ? _ffi_box_option_i32_from_rust(&buf_end2) : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_opt_box(_ x: BoxOptBox) -> BoxOptBox { var buf = ContiguousArray() _ffi_box_option_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_opt_box(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxOptBox(_0: _ffi_box_option_box_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } private func _ffi_box__from_rust(_ end: inout UnsafeRawPointer) -> () { return () } private func _ffi_box__to_rust(_ val: (), _ buf: inout ContiguousArray) { } private func _ffi_box_bool_from_rust(_ end: inout UnsafeRawPointer) -> Bool { return _ffi_read(&end) as Bool } private func _ffi_box_bool_to_rust(_ val: Bool, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_read(&end) as Int32 } private func _ffi_box_i32_from_rust2(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_read(&end) as Int32 } private func _ffi_box_i32_i32_from_rust(_ end: inout UnsafeRawPointer) -> (Int32, Int32) { return (_ffi_read(&end) as Int32, _ffi_read(&end) as Int32) } private func _ffi_box_i32_i32_to_rust(_ val: (Int32, Int32), _ buf: inout ContiguousArray) { _ffi_write(val.0, &buf) _ffi_write(val.1, &buf) } private func _ffi_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_box_i32_to_rust2(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_box_option_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32? { return _ffi_read(&end) as Bool ? _ffi_box_i32_from_rust2(&end) : nil } private func _ffi_box_option_box_i32_to_rust(_ val: Int32?, _ buf: inout ContiguousArray) { _ffi_write(val != nil, &buf) if let val_val = val { _ffi_box_i32_to_rust2(val_val, &buf) } } private func _ffi_box_option_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32? { return _ffi_read(&end) as Bool ? _ffi_read(&end) as Int32 : nil } private func _ffi_box_option_i32_to_rust(_ val: Int32?, _ buf: inout ContiguousArray) { _ffi_write(val != nil, &buf) if let val_val = val { _ffi_write(val_val, &buf) } } private func _ffi_box_vec_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> [Int32] { return _ffi_vec_box_i32_from_rust(Int(_ffi_read(&end) as UInt), &end) } private func _ffi_box_vec_box_i32_to_rust(_ val: [Int32], _ buf: inout ContiguousArray) { _ffi_write(UInt(val.count), &buf) _ffi_vec_box_i32_to_rust(val, &buf) } private func _ffi_box_vec_i32_from_rust(_ end: inout UnsafeRawPointer) -> [Int32] { return _ffi_vec_i32_from_rust2(Int(_ffi_read(&end) as UInt), &end) } private func _ffi_box_vec_i32_to_rust(_ val: [Int32], _ buf: inout ContiguousArray) { _ffi_write(UInt(val.count), &buf) _ffi_vec_i32_to_rust2(val, &buf) } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_enum_EnumBoxTup_from_rust(_ end: inout UnsafeRawPointer) -> EnumBoxTup { switch _ffi_read(&end) as Int32 { case 0: return .Foo(_ffi_box_i32_i32_from_rust(&end)) case 1: return .Bar case 2: return .Baz(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) default: fatalError() } } private func _ffi_enum_EnumBoxTup_to_rust(_ val: EnumBoxTup, _ buf: inout ContiguousArray) { switch val { case let .Foo(x): _ffi_write(0 as Int32, &buf) _ffi_box_i32_i32_to_rust(x, &buf) case .Bar: _ffi_write(1 as Int32, &buf) case let .Baz(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) } } private func _ffi_enum_EnumOptTup_from_rust(_ end: inout UnsafeRawPointer) -> EnumOptTup { switch _ffi_read(&end) as Int32 { case 0: return .Foo(_ffi_read(&end) as Bool ? (_ffi_read(&end) as Int32, _ffi_read(&end) as Int32) : nil) case 1: return .Bar case 2: return .Baz(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) default: fatalError() } } private func _ffi_enum_EnumOptTup_to_rust(_ val: EnumOptTup, _ buf: inout ContiguousArray) { switch val { case let .Foo(x): _ffi_write(0 as Int32, &buf) _ffi_write(x != nil, &buf) if let x_val = x { _ffi_write(x_val.0, &buf) _ffi_write(x_val.1, &buf) } case .Bar: _ffi_write(1 as Int32, &buf) case let .Baz(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) } } private func _ffi_enum_EnumVecTup_from_rust(_ end: inout UnsafeRawPointer) -> EnumVecTup { switch _ffi_read(&end) as Int32 { case 0: return .Foo(_ffi_vec_i32_i32_from_rust(Int(_ffi_read(&end) as UInt), &end)) case 1: return .Bar case 2: return .Baz(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) default: fatalError() } } private func _ffi_enum_EnumVecTup_to_rust(_ val: EnumVecTup, _ buf: inout ContiguousArray) { switch val { case let .Foo(x): _ffi_write(0 as Int32, &buf) _ffi_write(UInt(x.count), &buf) _ffi_vec_i32_i32_to_rust(x, &buf) case .Bar: _ffi_write(1 as Int32, &buf) case let .Baz(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) } } private func _ffi_vec__from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [()] { var items: [()] = [] items.reserveCapacity(len) while items.count < len { items.append(()) } return items } private func _ffi_vec__to_rust(_ items: [()], _ buf: inout ContiguousArray) { } private func _ffi_vec_box_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_box_i32_from_rust2(&end)) } return items } private func _ffi_vec_box_i32_to_rust(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_box_i32_to_rust2(item, &buf) } } private func _ffi_vec_box_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [[Int32]] { var items: [[Int32]] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_box_vec_i32_from_rust(&end)) } return items } private func _ffi_vec_box_vec_i32_to_rust(_ items: [[Int32]], _ buf: inout ContiguousArray) { for item in items { _ffi_box_vec_i32_to_rust(item, &buf) } } private func _ffi_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Int32) } return items } private func _ffi_vec_i32_from_rust2(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Int32) } return items } private func _ffi_vec_i32_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [(Int32, Int32)] { var items: [(Int32, Int32)] = [] items.reserveCapacity(len) while items.count < len { items.append((_ffi_read(&end) as Int32, _ffi_read(&end) as Int32)) } return items } private func _ffi_vec_i32_i32_to_rust(_ items: [(Int32, Int32)], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.0, &buf) _ffi_write(item.1, &buf) } } private func _ffi_vec_i32_to_rust(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i32_to_rust2(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_demo_derive_eq_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box__from_swift(_: &mut *const u8) -> Box<()> { Box::new(()) } #[allow(non_snake_case)] fn _ffi_box__to_swift(val: (), _: &mut Vec) { _ = val; } fn _ffi_box_bool_from_swift(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_bool_to_swift(val: bool, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_i32_from_swift(end: &mut *const u8) -> Box<(i32,)> { Box::new((_ffi_read::(end),)) } fn _ffi_box_i32_from_swift2(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_i32_i32_from_swift(end: &mut *const u8) -> Box<(i32, i32)> { Box::new((_ffi_read::(end), _ffi_read::(end))) } fn _ffi_box_i32_i32_to_swift(val: (i32, i32), buf: &mut Vec) { _ffi_write(val.0, buf); _ffi_write(val.1, buf); } fn _ffi_box_i32_to_swift(val: (i32,), buf: &mut Vec) { _ffi_write(val.0, buf); } fn _ffi_box_i32_to_swift2(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_option_box_i32_from_swift(end: &mut *const u8) -> Box>> { Box::new(_ffi_read::(end).then(|| _ffi_box_i32_from_swift2(end))) } fn _ffi_box_option_box_i32_to_swift(val: Option>, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_box_i32_to_swift2(*val_val, buf); } } fn _ffi_box_option_i32_from_swift(end: &mut *const u8) -> Box> { Box::new(_ffi_read::(end).then(|| _ffi_read::(end))) } fn _ffi_box_option_i32_to_swift(val: Option, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_write(val_val, buf); } } fn _ffi_box_vec_box_i32_from_swift(end: &mut *const u8) -> Box>> { Box::new(_ffi_vec_box_i32_from_swift(_ffi_read::(end), end)) } fn _ffi_box_vec_box_i32_to_swift(val: Vec>, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_box_i32_to_swift(val, buf); } fn _ffi_box_vec_i32_from_swift(end: &mut *const u8) -> Box> { Box::new(_ffi_vec_i32_from_swift2(_ffi_read::(end), end)) } fn _ffi_box_vec_i32_to_swift(val: Vec, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_i32_to_swift2(val, buf); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_from_swift(end: &mut *const u8) -> EnumBoxTup { match _ffi_read::(end) { 0 => EnumBoxTup::Foo(_ffi_box_i32_i32_from_swift(end)), 1 => EnumBoxTup::Bar, 2 => EnumBoxTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_to_swift(val: EnumBoxTup, buf: &mut Vec) { match val { EnumBoxTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_box_i32_i32_to_swift(*x, buf); } EnumBoxTup::Bar => _ffi_write(1 as i32, buf), EnumBoxTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_from_swift(end: &mut *const u8) -> EnumOptTup { match _ffi_read::(end) { 0 => EnumOptTup::Foo(_ffi_read::(end).then(|| (_ffi_read::(end), _ffi_read::(end)))), 1 => EnumOptTup::Bar, 2 => EnumOptTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_to_swift(val: EnumOptTup, buf: &mut Vec) { match val { EnumOptTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.is_some(), buf); if let Some(x_val) = x { _ffi_write(x_val.0, buf); _ffi_write(x_val.1, buf); } } EnumOptTup::Bar => _ffi_write(1 as i32, buf), EnumOptTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_from_swift(end: &mut *const u8) -> EnumVecTup { match _ffi_read::(end) { 0 => EnumVecTup::Foo(_ffi_vec_i32_i32_from_swift(_ffi_read::(end), end)), 1 => EnumVecTup::Bar, 2 => EnumVecTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_to_swift(val: EnumVecTup, buf: &mut Vec) { match val { EnumVecTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.len(), buf); _ffi_vec_i32_i32_to_swift(x, buf); } EnumVecTup::Bar => _ffi_write(1 as i32, buf), EnumVecTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt(BoxOpt(_ffi_box_option_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt_box(BoxOptBox(_ffi_box_option_box_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_box_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_0(BoxTup0(_ffi_box__from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box__to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_1(BoxTup1(_ffi_box_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_2(BoxTup2(_ffi_box_i32_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec(BoxVec(_ffi_box_vec_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec_box(BoxVecBox(_ffi_box_vec_box_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_box_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(EmptyStruct); } #[no_mangle] extern "C" fn _ffi_fn_empty_tuple() { _ = empty_tuple(()); } #[no_mangle] extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumBoxTup_to_swift(enum_box_tup(_ffi_enum_EnumBoxTup_from_swift(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumOptTup_to_swift(enum_opt_tup(_ffi_enum_EnumOptTup_from_swift(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumVecTup_to_swift(enum_vec_tup(_ffi_enum_EnumVecTup_from_swift(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box(OptBox(has_x_0.then(|| _ffi_box_i32_from_swift2(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_i32_to_swift2(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box_opt(OptBoxOpt(has_x_0.then(|| _ffi_box_option_i32_from_swift(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_option_i32_to_swift(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let buf_end = buf_ptr; let ret = opt_tup_0(OptTup0(has_x_0.then(|| ()))); let ret_0 = ret.0; let buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ = ret_0_val; } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_1(OptTup1(has_x_0.then(|| (_ffi_read::(&mut buf_end),)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_2(OptTup2(has_x_0.then(|| (_ffi_read::(&mut buf_end), _ffi_read::(&mut buf_end))))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); _ffi_write(ret_0_val.1, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = tup_box(TupBox((_ffi_box_i32_from_swift2(&mut buf_end), _ffi_box_bool_from_swift(&mut buf_end)))); let ret_0 = ret.0; let ret_0_0 = ret_0.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_swift2(*ret_0_0, &mut buf2); let ret_0_1 = ret_0.1; _ffi_box_bool_to_swift(*ret_0_1, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box(VecBox(_ffi_vec_box_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box_vec(VecBoxVec(_ffi_vec_box_vec_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_vec_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_0(VecTup0(_ffi_vec__from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec__to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_1(VecTup1(_ffi_vec_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_2(VecTup2(_ffi_vec_i32_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); #[allow(non_snake_case)] fn _ffi_vec__from_swift(len: usize, _: &mut *const u8) -> Vec<()> { let mut items = Vec::<()>::with_capacity(len); for _ in 0..len { items.push(()); } items } #[allow(non_snake_case)] fn _ffi_vec__to_swift(items: Vec<()>, _: &mut Vec) { for item in items { _ = item; } } fn _ffi_vec_box_i32_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_i32_from_swift2(end)); } items } fn _ffi_vec_box_i32_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_box_i32_to_swift2(*item, buf); } } fn _ffi_vec_box_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec>> { let mut items = Vec::>>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_vec_i32_from_swift(end)); } items } fn _ffi_vec_box_vec_i32_to_swift(items: Vec>>, buf: &mut Vec) { for item in items { _ffi_box_vec_i32_to_swift(*item, buf); } } fn _ffi_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec<(i32,)> { let mut items = Vec::<(i32,)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end),)); } items } fn _ffi_vec_i32_from_swift2(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_i32_from_swift(len: usize, end: &mut *const u8) -> Vec<(i32, i32)> { let mut items = Vec::<(i32, i32)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end), _ffi_read::(end))); } items } fn _ffi_vec_i32_i32_to_swift(items: Vec<(i32, i32)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); _ffi_write(item.1, buf); } } fn _ffi_vec_i32_to_swift(items: Vec<(i32,)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); } } fn _ffi_vec_i32_to_swift2(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } ================================================ FILE: src/tests/snapshots/swift_demo_derive_eq_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; _ffi_ret_ptr_usize _ffi_fn_box_opt(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_opt_box(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_0(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_1(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_tup_2(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_box_vec_box(const void* buf_ptr); void _ffi_fn_empty_struct(); void _ffi_fn_empty_tuple(); _ffi_ret_ptr_usize _ffi_fn_enum_box_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_opt_tup(const void* buf_ptr); _ffi_ret_ptr_usize _ffi_fn_enum_vec_tup(const void* buf_ptr); typedef struct { const void* _0; uintptr_t _1; _Bool _2; } _ffi_ret_ptr_usize_bool; _ffi_ret_ptr_usize_bool _ffi_fn_opt_box(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_box_opt(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_0(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_1(const void* buf_ptr, _Bool has_x_0); _ffi_ret_ptr_usize_bool _ffi_fn_opt_tup_2(const void* buf_ptr, _Bool has_x_0); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_usize _ffi_fn_tup_box(const void* buf_ptr); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_vec_box(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_box_vec(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_0(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_1(const void* buf_ptr, uintptr_t x_0_len); _ffi_ret_ptr_2_usize _ffi_fn_vec_tup_2(const void* buf_ptr, uintptr_t x_0_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_derive_eq_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum EnumBoxTup : Equatable { case Foo((Int32, Int32)) case Bar case Baz(x: Int32, y: Int32) static func == (a: EnumBoxTup, b: EnumBoxTup) -> Bool { switch (a, b) { case let (.Foo(a0), .Foo(b0)): return a0.0 == b0.0 && a0.1 == b0.1 case (.Bar, .Bar): return true case let (.Baz(x: ax, y: ay), .Baz(x: bx, y: by)): return ax == bx && ay == by default: return false } } } enum EnumVecTup : Equatable { case Foo([(Int32, Int32)]) case Bar case Baz(x: Int32, y: Int32) static func == (a: EnumVecTup, b: EnumVecTup) -> Bool { switch (a, b) { case let (.Foo(a0), .Foo(b0)): return a0.elementsEqual(b0, by: { a, b in a.0 == b.0 && a.1 == b.1 }) case (.Bar, .Bar): return true case let (.Baz(x: ax, y: ay), .Baz(x: bx, y: by)): return ax == bx && ay == by default: return false } } } enum EnumOptTup : Equatable { case Foo((Int32, Int32)?) case Bar case Baz(x: Int32, y: Int32) static func == (a: EnumOptTup, b: EnumOptTup) -> Bool { switch (a, b) { case let (.Foo(a0), .Foo(b0)): return { if let a = a0, let b = b0 { a.0 == b.0 && a.1 == b.1 } else { a0 == nil && b0 == nil } }() case (.Bar, .Bar): return true case let (.Baz(x: ax, y: ay), .Baz(x: bx, y: by)): return ax == bx && ay == by default: return false } } } struct EmptyStruct : Equatable { } struct BoxTup0 : Equatable { var _0: () static func == (a: BoxTup0, b: BoxTup0) -> Bool { return true } } struct BoxTup1 : Equatable { var _0: Int32 } struct BoxTup2 : Equatable { var _0: (Int32, Int32) static func == (a: BoxTup2, b: BoxTup2) -> Bool { return a._0.0 == b._0.0 && a._0.1 == b._0.1 } } struct VecTup0 : Equatable { var _0: [()] static func == (a: VecTup0, b: VecTup0) -> Bool { return a._0.count == b._0.count } } struct VecTup1 : Equatable { var _0: [Int32] } struct VecTup2 : Equatable { var _0: [(Int32, Int32)] static func == (a: VecTup2, b: VecTup2) -> Bool { return a._0.elementsEqual(b._0, by: { a, b in a.0 == b.0 && a.1 == b.1 }) } } struct OptTup0 : Equatable { var _0: ()? static func == (a: OptTup0, b: OptTup0) -> Bool { return (a._0 != nil) == (b._0 != nil) } } struct OptTup1 : Equatable { var _0: Int32? } struct OptTup2 : Equatable { var _0: (Int32, Int32)? static func == (a: OptTup2, b: OptTup2) -> Bool { return { if let a = a._0, let b = b._0 { a.0 == b.0 && a.1 == b.1 } else { a._0 == nil && b._0 == nil } }() } } struct TupBox : Equatable { var _0: (Int32, Bool) static func == (a: TupBox, b: TupBox) -> Bool { return a._0.0 == b._0.0 && a._0.1 == b._0.1 } } struct VecBox : Equatable { var _0: [Int32] } struct BoxVec : Equatable { var _0: [Int32] } struct OptBox : Equatable { var _0: Int32? } struct BoxOpt : Equatable { var _0: Int32? } struct VecBoxVec : Equatable { var _0: [[Int32]] } struct BoxVecBox : Equatable { var _0: [Int32] } struct OptBoxOpt : Equatable { var _0: Int32?? } struct BoxOptBox : Equatable { var _0: Int32? } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_tuple(_ x: ()) -> () { _ffi_fn_empty_tuple() return () } func empty_struct(_ x: EmptyStruct) -> EmptyStruct { _ffi_fn_empty_struct() return EmptyStruct() } func box_tup_0(_ x: BoxTup0) -> BoxTup0 { var buf = ContiguousArray() _ffi_box__to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_tup_0(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxTup0(_0: _ffi_box__from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_tup_1(_ x: BoxTup1) -> BoxTup1 { var buf = ContiguousArray() _ffi_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_tup_1(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxTup1(_0: _ffi_box_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_tup_2(_ x: BoxTup2) -> BoxTup2 { var buf = ContiguousArray() _ffi_box_i32_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_tup_2(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxTup2(_0: _ffi_box_i32_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_tup_0(_ x: VecTup0) -> VecTup0 { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec__to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_tup_0(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecTup0(_0: _ffi_vec__from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_tup_1(_ x: VecTup1) -> VecTup1 { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_tup_1(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecTup1(_0: _ffi_vec_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_tup_2(_ x: VecTup2) -> VecTup2 { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_i32_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_tup_2(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecTup2(_0: _ffi_vec_i32_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_tup_0(_ x: OptTup0) -> OptTup0 { let buf = ContiguousArray() let has_x_0 = x._0 != nil let multi_ret = _ffi_fn_opt_tup_0(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 let ret = OptTup0(_0: has_ret_0 ? () : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_tup_1(_ x: OptTup1) -> OptTup1 { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_write(x_0_val, &buf) } let multi_ret = _ffi_fn_opt_tup_1(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptTup1(_0: has_ret_0 ? _ffi_read(&buf_end2) as Int32 : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_tup_2(_ x: OptTup2) -> OptTup2 { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_write(x_0_val.0, &buf) _ffi_write(x_0_val.1, &buf) } let multi_ret = _ffi_fn_opt_tup_2(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptTup2(_0: has_ret_0 ? (_ffi_read(&buf_end2) as Int32, _ffi_read(&buf_end2) as Int32) : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func enum_box_tup(_ x: EnumBoxTup) -> EnumBoxTup { var buf = ContiguousArray() _ffi_enum_EnumBoxTup_to_rust(x, &buf) let multi_ret = _ffi_fn_enum_box_tup(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = _ffi_enum_EnumBoxTup_from_rust(&buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func enum_vec_tup(_ x: EnumVecTup) -> EnumVecTup { var buf = ContiguousArray() _ffi_enum_EnumVecTup_to_rust(x, &buf) let multi_ret = _ffi_fn_enum_vec_tup(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = _ffi_enum_EnumVecTup_from_rust(&buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func enum_opt_tup(_ x: EnumOptTup) -> EnumOptTup { var buf = ContiguousArray() _ffi_enum_EnumOptTup_to_rust(x, &buf) let multi_ret = _ffi_fn_enum_opt_tup(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = _ffi_enum_EnumOptTup_from_rust(&buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func tup_box(_ x: TupBox) -> TupBox { var buf = ContiguousArray() _ffi_box_i32_to_rust2(x._0.0, &buf) _ffi_box_bool_to_rust(x._0.1, &buf) let multi_ret = _ffi_fn_tup_box(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = TupBox(_0: (_ffi_box_i32_from_rust2(&buf_end2), _ffi_box_bool_from_rust(&buf_end2))) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_box(_ x: VecBox) -> VecBox { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_box(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecBox(_0: _ffi_vec_box_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_vec(_ x: BoxVec) -> BoxVec { var buf = ContiguousArray() _ffi_box_vec_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_vec(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxVec(_0: _ffi_box_vec_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_box(_ x: OptBox) -> OptBox { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_box_i32_to_rust2(x_0_val, &buf) } let multi_ret = _ffi_fn_opt_box(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptBox(_0: has_ret_0 ? _ffi_box_i32_from_rust2(&buf_end2) : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_opt(_ x: BoxOpt) -> BoxOpt { var buf = ContiguousArray() _ffi_box_option_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_opt(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxOpt(_0: _ffi_box_option_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func vec_box_vec(_ x: VecBoxVec) -> VecBoxVec { var buf = ContiguousArray() let x_0_len = UInt(x._0.count) _ffi_vec_box_vec_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_vec_box_vec(_ffi_vec_to_rust(buf), x_0_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_0_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = VecBoxVec(_0: _ffi_vec_box_vec_i32_from_rust(Int(ret_0_len), &buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_vec_box(_ x: BoxVecBox) -> BoxVecBox { var buf = ContiguousArray() _ffi_box_vec_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_vec_box(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxVecBox(_0: _ffi_box_vec_box_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func opt_box_opt(_ x: OptBoxOpt) -> OptBoxOpt { var buf = ContiguousArray() let has_x_0 = x._0 != nil if let x_0_val = x._0 { _ffi_box_option_i32_to_rust(x_0_val, &buf) } let multi_ret = _ffi_fn_opt_box_opt(_ffi_vec_to_rust(buf), has_x_0) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let has_ret_0 = multi_ret._2 var buf_end2 = buf_ptr2! let ret = OptBoxOpt(_0: has_ret_0 ? _ffi_box_option_i32_from_rust(&buf_end2) : nil) _ffi_dealloc(buf_ptr2, buf_cap) return ret } func box_opt_box(_ x: BoxOptBox) -> BoxOptBox { var buf = ContiguousArray() _ffi_box_option_box_i32_to_rust(x._0, &buf) let multi_ret = _ffi_fn_box_opt_box(_ffi_vec_to_rust(buf)) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 var buf_end2 = buf_ptr2! let ret = BoxOptBox(_0: _ffi_box_option_box_i32_from_rust(&buf_end2)) _ffi_dealloc(buf_ptr2, buf_cap) return ret } private func _ffi_box__from_rust(_ end: inout UnsafeRawPointer) -> () { return () } private func _ffi_box__to_rust(_ val: (), _ buf: inout ContiguousArray) { } private func _ffi_box_bool_from_rust(_ end: inout UnsafeRawPointer) -> Bool { return _ffi_read(&end) as Bool } private func _ffi_box_bool_to_rust(_ val: Bool, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_read(&end) as Int32 } private func _ffi_box_i32_from_rust2(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_read(&end) as Int32 } private func _ffi_box_i32_i32_from_rust(_ end: inout UnsafeRawPointer) -> (Int32, Int32) { return (_ffi_read(&end) as Int32, _ffi_read(&end) as Int32) } private func _ffi_box_i32_i32_to_rust(_ val: (Int32, Int32), _ buf: inout ContiguousArray) { _ffi_write(val.0, &buf) _ffi_write(val.1, &buf) } private func _ffi_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_box_i32_to_rust2(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_box_option_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32? { return _ffi_read(&end) as Bool ? _ffi_box_i32_from_rust2(&end) : nil } private func _ffi_box_option_box_i32_to_rust(_ val: Int32?, _ buf: inout ContiguousArray) { _ffi_write(val != nil, &buf) if let val_val = val { _ffi_box_i32_to_rust2(val_val, &buf) } } private func _ffi_box_option_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32? { return _ffi_read(&end) as Bool ? _ffi_read(&end) as Int32 : nil } private func _ffi_box_option_i32_to_rust(_ val: Int32?, _ buf: inout ContiguousArray) { _ffi_write(val != nil, &buf) if let val_val = val { _ffi_write(val_val, &buf) } } private func _ffi_box_vec_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> [Int32] { return _ffi_vec_box_i32_from_rust(Int(_ffi_read(&end) as UInt), &end) } private func _ffi_box_vec_box_i32_to_rust(_ val: [Int32], _ buf: inout ContiguousArray) { _ffi_write(UInt(val.count), &buf) _ffi_vec_box_i32_to_rust(val, &buf) } private func _ffi_box_vec_i32_from_rust(_ end: inout UnsafeRawPointer) -> [Int32] { return _ffi_vec_i32_from_rust2(Int(_ffi_read(&end) as UInt), &end) } private func _ffi_box_vec_i32_to_rust(_ val: [Int32], _ buf: inout ContiguousArray) { _ffi_write(UInt(val.count), &buf) _ffi_vec_i32_to_rust2(val, &buf) } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_enum_EnumBoxTup_from_rust(_ end: inout UnsafeRawPointer) -> EnumBoxTup { switch _ffi_read(&end) as Int32 { case 0: return .Foo(_ffi_box_i32_i32_from_rust(&end)) case 1: return .Bar case 2: return .Baz(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) default: fatalError() } } private func _ffi_enum_EnumBoxTup_to_rust(_ val: EnumBoxTup, _ buf: inout ContiguousArray) { switch val { case let .Foo(x): _ffi_write(0 as Int32, &buf) _ffi_box_i32_i32_to_rust(x, &buf) case .Bar: _ffi_write(1 as Int32, &buf) case let .Baz(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) } } private func _ffi_enum_EnumOptTup_from_rust(_ end: inout UnsafeRawPointer) -> EnumOptTup { switch _ffi_read(&end) as Int32 { case 0: return .Foo(_ffi_read(&end) as Bool ? (_ffi_read(&end) as Int32, _ffi_read(&end) as Int32) : nil) case 1: return .Bar case 2: return .Baz(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) default: fatalError() } } private func _ffi_enum_EnumOptTup_to_rust(_ val: EnumOptTup, _ buf: inout ContiguousArray) { switch val { case let .Foo(x): _ffi_write(0 as Int32, &buf) _ffi_write(x != nil, &buf) if let x_val = x { _ffi_write(x_val.0, &buf) _ffi_write(x_val.1, &buf) } case .Bar: _ffi_write(1 as Int32, &buf) case let .Baz(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) } } private func _ffi_enum_EnumVecTup_from_rust(_ end: inout UnsafeRawPointer) -> EnumVecTup { switch _ffi_read(&end) as Int32 { case 0: return .Foo(_ffi_vec_i32_i32_from_rust(Int(_ffi_read(&end) as UInt), &end)) case 1: return .Bar case 2: return .Baz(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) default: fatalError() } } private func _ffi_enum_EnumVecTup_to_rust(_ val: EnumVecTup, _ buf: inout ContiguousArray) { switch val { case let .Foo(x): _ffi_write(0 as Int32, &buf) _ffi_write(UInt(x.count), &buf) _ffi_vec_i32_i32_to_rust(x, &buf) case .Bar: _ffi_write(1 as Int32, &buf) case let .Baz(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) } } private func _ffi_vec__from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [()] { var items: [()] = [] items.reserveCapacity(len) while items.count < len { items.append(()) } return items } private func _ffi_vec__to_rust(_ items: [()], _ buf: inout ContiguousArray) { } private func _ffi_vec_box_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_box_i32_from_rust2(&end)) } return items } private func _ffi_vec_box_i32_to_rust(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_box_i32_to_rust2(item, &buf) } } private func _ffi_vec_box_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [[Int32]] { var items: [[Int32]] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_box_vec_i32_from_rust(&end)) } return items } private func _ffi_vec_box_vec_i32_to_rust(_ items: [[Int32]], _ buf: inout ContiguousArray) { for item in items { _ffi_box_vec_i32_to_rust(item, &buf) } } private func _ffi_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Int32) } return items } private func _ffi_vec_i32_from_rust2(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Int32) } return items } private func _ffi_vec_i32_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [(Int32, Int32)] { var items: [(Int32, Int32)] = [] items.reserveCapacity(len) while items.count < len { items.append((_ffi_read(&end) as Int32, _ffi_read(&end) as Int32)) } return items } private func _ffi_vec_i32_i32_to_rust(_ items: [(Int32, Int32)], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.0, &buf) _ffi_write(item.1, &buf) } } private func _ffi_vec_i32_to_rust(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i32_to_rust2(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_demo_derive_eq_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box__from_swift(_: &mut *const u8) -> Box<()> { Box::new(()) } #[allow(non_snake_case)] fn _ffi_box__to_swift(val: (), _: &mut Vec) { _ = val; } fn _ffi_box_bool_from_swift(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_bool_to_swift(val: bool, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_i32_from_swift(end: &mut *const u8) -> Box<(i32,)> { Box::new((_ffi_read::(end),)) } fn _ffi_box_i32_from_swift2(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_i32_i32_from_swift(end: &mut *const u8) -> Box<(i32, i32)> { Box::new((_ffi_read::(end), _ffi_read::(end))) } fn _ffi_box_i32_i32_to_swift(val: (i32, i32), buf: &mut Vec) { _ffi_write(val.0, buf); _ffi_write(val.1, buf); } fn _ffi_box_i32_to_swift(val: (i32,), buf: &mut Vec) { _ffi_write(val.0, buf); } fn _ffi_box_i32_to_swift2(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_option_box_i32_from_swift(end: &mut *const u8) -> Box>> { Box::new(_ffi_read::(end).then(|| _ffi_box_i32_from_swift2(end))) } fn _ffi_box_option_box_i32_to_swift(val: Option>, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_box_i32_to_swift2(*val_val, buf); } } fn _ffi_box_option_i32_from_swift(end: &mut *const u8) -> Box> { Box::new(_ffi_read::(end).then(|| _ffi_read::(end))) } fn _ffi_box_option_i32_to_swift(val: Option, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_write(val_val, buf); } } fn _ffi_box_vec_box_i32_from_swift(end: &mut *const u8) -> Box>> { Box::new(_ffi_vec_box_i32_from_swift(_ffi_read::(end), end)) } fn _ffi_box_vec_box_i32_to_swift(val: Vec>, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_box_i32_to_swift(val, buf); } fn _ffi_box_vec_i32_from_swift(end: &mut *const u8) -> Box> { Box::new(_ffi_vec_i32_from_swift2(_ffi_read::(end), end)) } fn _ffi_box_vec_i32_to_swift(val: Vec, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_i32_to_swift2(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_from_swift(end: &mut *const u8) -> EnumBoxTup { match _ffi_read::(end) { 0 => EnumBoxTup::Foo(_ffi_box_i32_i32_from_swift(end)), 1 => EnumBoxTup::Bar, 2 => EnumBoxTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_to_swift(val: EnumBoxTup, buf: &mut Vec) { match val { EnumBoxTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_box_i32_i32_to_swift(*x, buf); } EnumBoxTup::Bar => _ffi_write(1 as i32, buf), EnumBoxTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_from_swift(end: &mut *const u8) -> EnumOptTup { match _ffi_read::(end) { 0 => EnumOptTup::Foo(_ffi_read::(end).then(|| (_ffi_read::(end), _ffi_read::(end)))), 1 => EnumOptTup::Bar, 2 => EnumOptTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_to_swift(val: EnumOptTup, buf: &mut Vec) { match val { EnumOptTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.is_some(), buf); if let Some(x_val) = x { _ffi_write(x_val.0, buf); _ffi_write(x_val.1, buf); } } EnumOptTup::Bar => _ffi_write(1 as i32, buf), EnumOptTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_from_swift(end: &mut *const u8) -> EnumVecTup { match _ffi_read::(end) { 0 => EnumVecTup::Foo(_ffi_vec_i32_i32_from_swift(_ffi_read::(end), end)), 1 => EnumVecTup::Bar, 2 => EnumVecTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_to_swift(val: EnumVecTup, buf: &mut Vec) { match val { EnumVecTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.len(), buf); _ffi_vec_i32_i32_to_swift(x, buf); } EnumVecTup::Bar => _ffi_write(1 as i32, buf), EnumVecTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt(BoxOpt(_ffi_box_option_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt_box(BoxOptBox(_ffi_box_option_box_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_option_box_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_0(BoxTup0(_ffi_box__from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box__to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_1(BoxTup1(_ffi_box_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_2(BoxTup2(_ffi_box_i32_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec(BoxVec(_ffi_box_vec_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec_box(BoxVecBox(_ffi_box_vec_box_i32_from_swift(&mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_vec_box_i32_to_swift(*ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(EmptyStruct); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple() { _ = empty_tuple(()); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumBoxTup_to_swift(enum_box_tup(_ffi_enum_EnumBoxTup_from_swift(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumOptTup_to_swift(enum_opt_tup(_ffi_enum_EnumOptTup_from_swift(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumVecTup_to_swift(enum_vec_tup(_ffi_enum_EnumVecTup_from_swift(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box(OptBox(has_x_0.then(|| _ffi_box_i32_from_swift2(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_i32_to_swift2(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box_opt(OptBoxOpt(has_x_0.then(|| _ffi_box_option_i32_from_swift(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_option_i32_to_swift(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let buf_end = buf_ptr; let ret = opt_tup_0(OptTup0(has_x_0.then(|| ()))); let ret_0 = ret.0; let buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ = ret_0_val; } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_1(OptTup1(has_x_0.then(|| (_ffi_read::(&mut buf_end),)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_2(OptTup2(has_x_0.then(|| (_ffi_read::(&mut buf_end), _ffi_read::(&mut buf_end))))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); _ffi_write(ret_0_val.1, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = tup_box(TupBox((_ffi_box_i32_from_swift2(&mut buf_end), _ffi_box_bool_from_swift(&mut buf_end)))); let ret_0 = ret.0; let ret_0_0 = ret_0.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_swift2(*ret_0_0, &mut buf2); let ret_0_1 = ret_0.1; _ffi_box_bool_to_swift(*ret_0_1, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_usize(buf_ptr2, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box(VecBox(_ffi_vec_box_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box_vec(VecBoxVec(_ffi_vec_box_vec_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_vec_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_0(VecTup0(_ffi_vec__from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec__to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_1(VecTup1(_ffi_vec_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_2(VecTup2(_ffi_vec_i32_i32_from_swift(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_i32_to_swift(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); #[allow(non_snake_case)] fn _ffi_vec__from_swift(len: usize, _: &mut *const u8) -> Vec<()> { let mut items = Vec::<()>::with_capacity(len); for _ in 0..len { items.push(()); } items } #[allow(non_snake_case)] fn _ffi_vec__to_swift(items: Vec<()>, _: &mut Vec) { for item in items { _ = item; } } fn _ffi_vec_box_i32_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_i32_from_swift2(end)); } items } fn _ffi_vec_box_i32_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_box_i32_to_swift2(*item, buf); } } fn _ffi_vec_box_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec>> { let mut items = Vec::>>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_vec_i32_from_swift(end)); } items } fn _ffi_vec_box_vec_i32_to_swift(items: Vec>>, buf: &mut Vec) { for item in items { _ffi_box_vec_i32_to_swift(*item, buf); } } fn _ffi_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec<(i32,)> { let mut items = Vec::<(i32,)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end),)); } items } fn _ffi_vec_i32_from_swift2(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_i32_from_swift(len: usize, end: &mut *const u8) -> Vec<(i32, i32)> { let mut items = Vec::<(i32, i32)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end), _ffi_read::(end))); } items } fn _ffi_vec_i32_i32_to_swift(items: Vec<(i32, i32)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); _ffi_write(item.1, buf); } } fn _ffi_vec_i32_to_swift(items: Vec<(i32,)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); } } fn _ffi_vec_i32_to_swift2(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } ================================================ FILE: src/tests/snapshots/swift_demo_enum_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_enum_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum NestedBox { case Foo indirect case Bar(NestedBox) } enum NestedVec { case Foo case Bar([NestedVec]) } enum NestedOption { case Foo indirect case Bar(NestedOption?) } enum NestedTuple { case Foo indirect case Bar((Int32, NestedTuple)) } enum NestedStruct { case Foo indirect case Bar((Int32, InnerStruct)) } enum NestedEnum { case Foo indirect case Bar((Int32, InnerEnum)) } enum InnerEnum { indirect case Foo(NestedEnum) } struct InnerStruct { var x: NestedStruct } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_enum_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_enum_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_enum_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum NestedBox { case Foo indirect case Bar(NestedBox) } enum NestedVec { case Foo case Bar([NestedVec]) } enum NestedOption { case Foo indirect case Bar(NestedOption?) } enum NestedTuple { case Foo indirect case Bar((Int32, NestedTuple)) } enum NestedStruct { case Foo indirect case Bar((Int32, InnerStruct)) } enum NestedEnum { case Foo indirect case Bar((Int32, InnerEnum)) } enum InnerEnum { indirect case Foo(NestedEnum) } struct InnerStruct { var x: NestedStruct } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_enum_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_keyword_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test_alignas(int32_t alignas2); int32_t _ffi_fn_test_alignof(int32_t alignof2); int32_t _ffi_fn_test_and(int32_t and2); int32_t _ffi_fn_test_and_eq(int32_t and_eq2); int32_t _ffi_fn_test_asm(int32_t asm2); int32_t _ffi_fn_test_associatedtype(int32_t associatedtype2); int32_t _ffi_fn_test_associativity(int32_t associativity2); int32_t _ffi_fn_test_atomic_cancel(int32_t atomic_cancel2); int32_t _ffi_fn_test_atomic_commit(int32_t atomic_commit2); int32_t _ffi_fn_test_atomic_noexcept(int32_t atomic_noexcept2); int32_t _ffi_fn_test_auto(int32_t auto2); int32_t _ffi_fn_test_bitand(int32_t bitand2); int32_t _ffi_fn_test_bitor(int32_t bitor2); int32_t _ffi_fn_test_bool(int32_t bool2); int32_t _ffi_fn_test_boolean(int32_t boolean); int32_t _ffi_fn_test_borrowing(int32_t borrowing2); int32_t _ffi_fn_test_byte(int32_t byte); int32_t _ffi_fn_test_case(int32_t case2); int32_t _ffi_fn_test_catch(int32_t catch2); int32_t _ffi_fn_test_char(int32_t char2); int32_t _ffi_fn_test_char16_t(int32_t char16_t2); int32_t _ffi_fn_test_char32_t(int32_t char32_t2); int32_t _ffi_fn_test_char8_t(int32_t char8_t2); int32_t _ffi_fn_test_class(int32_t class2); int32_t _ffi_fn_test_co_await(int32_t co_await2); int32_t _ffi_fn_test_co_return(int32_t co_return2); int32_t _ffi_fn_test_co_yield(int32_t co_yield2); int32_t _ffi_fn_test_compl(int32_t compl2); int32_t _ffi_fn_test_concept(int32_t concept2); int32_t _ffi_fn_test_const_cast(int32_t const_cast2); int32_t _ffi_fn_test_consteval(int32_t consteval2); int32_t _ffi_fn_test_constexpr(int32_t constexpr2); int32_t _ffi_fn_test_constinit(int32_t constinit2); int32_t _ffi_fn_test_consuming(int32_t consuming2); int32_t _ffi_fn_test_contract_assert(int32_t contract_assert2); int32_t _ffi_fn_test_convenience(int32_t convenience2); int32_t _ffi_fn_test_debugger(int32_t debugger); int32_t _ffi_fn_test_decltype(int32_t decltype2); int32_t _ffi_fn_test_default(int32_t default2); int32_t _ffi_fn_test_defer(int32_t defer2); int32_t _ffi_fn_test_deinit(int32_t deinit2); int32_t _ffi_fn_test_delete(int32_t delete2); int32_t _ffi_fn_test_double(int32_t double2); int32_t _ffi_fn_test_dynamic(int32_t dynamic2); int32_t _ffi_fn_test_dynamic_cast(int32_t dynamic_cast2); int32_t _ffi_fn_test_explicit(int32_t explicit2); int32_t _ffi_fn_test_export(int32_t export2); int32_t _ffi_fn_test_extends(int32_t extends); int32_t _ffi_fn_test_extension(int32_t extension2); int32_t _ffi_fn_test_fallthrough(int32_t fallthrough2); int32_t _ffi_fn_test_fileprivate(int32_t fileprivate2); int32_t _ffi_fn_test_finally(int32_t finally); int32_t _ffi_fn_test_float(int32_t float2); int32_t _ffi_fn_test_friend(int32_t friend2); int32_t _ffi_fn_test_func(int32_t func2); int32_t _ffi_fn_test_function(int32_t function); int32_t _ffi_fn_test_get(int32_t get2); int32_t _ffi_fn_test_goto(int32_t goto2); int32_t _ffi_fn_test_guard(int32_t guard2); int32_t _ffi_fn_test_implements(int32_t implements); int32_t _ffi_fn_test_import(int32_t import2); int32_t _ffi_fn_test_indirect(int32_t indirect2); int32_t _ffi_fn_test_infix(int32_t infix2); int32_t _ffi_fn_test_init(int32_t init2); int32_t _ffi_fn_test_inline(int32_t inline2); int32_t _ffi_fn_test_inout(int32_t inout2); int32_t _ffi_fn_test_instanceof(int32_t instanceof); int32_t _ffi_fn_test_int(int32_t int2); int32_t _ffi_fn_test_interface(int32_t interface); int32_t _ffi_fn_test_internal(int32_t internal2); int32_t _ffi_fn_test_is(int32_t is2); int32_t _ffi_fn_test_lazy(int32_t lazy2); int32_t _ffi_fn_test_left(int32_t left2); int32_t _ffi_fn_test_long(int32_t long2); int32_t _ffi_fn_test_mutable(int32_t mutable2); int32_t _ffi_fn_test_mutating(int32_t mutating2); int32_t _ffi_fn_test_namespace(int32_t namespace2); int32_t _ffi_fn_test_native(int32_t native); int32_t _ffi_fn_test_new(int32_t new2); int32_t _ffi_fn_test_nil(int32_t nil2); int32_t _ffi_fn_test_noexcept(int32_t noexcept2); int32_t _ffi_fn_test_none(int32_t none2); int32_t _ffi_fn_test_nonisolated(int32_t nonisolated2); int32_t _ffi_fn_test_nonmutating(int32_t nonmutating2); int32_t _ffi_fn_test_not(int32_t not2); int32_t _ffi_fn_test_not_eq(int32_t not_eq2); int32_t _ffi_fn_test_null(int32_t null); int32_t _ffi_fn_test_nullptr(int32_t nullptr2); int32_t _ffi_fn_test_open(int32_t open2); int32_t _ffi_fn_test_operator(int32_t operator2); int32_t _ffi_fn_test_optional(int32_t optional2); int32_t _ffi_fn_test_or(int32_t or2); int32_t _ffi_fn_test_or_eq(int32_t or_eq2); int32_t _ffi_fn_test_package(int32_t package2); int32_t _ffi_fn_test_postfix(int32_t postfix2); int32_t _ffi_fn_test_precedence(int32_t precedence2); int32_t _ffi_fn_test_precedencegroup(int32_t precedencegroup2); int32_t _ffi_fn_test_prefix(int32_t prefix2); int32_t _ffi_fn_test_private(int32_t private2); int32_t _ffi_fn_test_protected(int32_t protected2); int32_t _ffi_fn_test_protocol(int32_t protocol2); int32_t _ffi_fn_test_public(int32_t public2); int32_t _ffi_fn_test_reflexpr(int32_t reflexpr2); int32_t _ffi_fn_test_register(int32_t register2); int32_t _ffi_fn_test_reinterpret_cast(int32_t reinterpret_cast2); int32_t _ffi_fn_test_repeat(int32_t repeat2); int32_t _ffi_fn_test_required(int32_t required2); int32_t _ffi_fn_test_requires(int32_t requires2); int32_t _ffi_fn_test_rethrows(int32_t rethrows2); int32_t _ffi_fn_test_right(int32_t right2); int32_t _ffi_fn_test_set(int32_t set2); int32_t _ffi_fn_test_short(int32_t short2); int32_t _ffi_fn_test_signed(int32_t signed2); int32_t _ffi_fn_test_sizeof(int32_t sizeof2); int32_t _ffi_fn_test_some(int32_t some2); int32_t _ffi_fn_test_static_assert(int32_t static_assert2); int32_t _ffi_fn_test_static_cast(int32_t static_cast2); int32_t _ffi_fn_test_subscript(int32_t subscript2); int32_t _ffi_fn_test_switch(int32_t switch2); int32_t _ffi_fn_test_synchronized(int32_t synchronized2); int32_t _ffi_fn_test_template(int32_t template2); int32_t _ffi_fn_test_this(int32_t this2); int32_t _ffi_fn_test_thread_local(int32_t thread_local2); int32_t _ffi_fn_test_throw(int32_t throw2); int32_t _ffi_fn_test_throws(int32_t throws2); int32_t _ffi_fn_test_transient(int32_t transient); int32_t _ffi_fn_test_typealias(int32_t typealias2); int32_t _ffi_fn_test_typedef(int32_t typedef2); int32_t _ffi_fn_test_typeid(int32_t typeid2); int32_t _ffi_fn_test_typename(int32_t typename2); int32_t _ffi_fn_test_undefined(int32_t undefined); int32_t _ffi_fn_test_union(int32_t union2); int32_t _ffi_fn_test_unowned(int32_t unowned2); int32_t _ffi_fn_test_unsigned(int32_t unsigned2); int32_t _ffi_fn_test_using(int32_t using2); int32_t _ffi_fn_test_var(int32_t var2); int32_t _ffi_fn_test_void(int32_t void2); int32_t _ffi_fn_test_volatile(int32_t volatile2); int32_t _ffi_fn_test_wchar_t(int32_t wchar_t2); int32_t _ffi_fn_test_weak(int32_t weak2); int32_t _ffi_fn_test_with(int32_t with); int32_t _ffi_fn_test_xor(int32_t xor2); int32_t _ffi_fn_test_xor_eq(int32_t xor_eq2); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_keyword_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test_alignas(_ alignas2: Int32) -> Int32 { return _ffi_fn_test_alignas(alignas2) } func test_alignof(_ alignof2: Int32) -> Int32 { return _ffi_fn_test_alignof(alignof2) } func test_and(_ and2: Int32) -> Int32 { return _ffi_fn_test_and(and2) } func test_and_eq(_ and_eq2: Int32) -> Int32 { return _ffi_fn_test_and_eq(and_eq2) } func test_asm(_ asm2: Int32) -> Int32 { return _ffi_fn_test_asm(asm2) } func test_associatedtype(_ associatedtype2: Int32) -> Int32 { return _ffi_fn_test_associatedtype(associatedtype2) } func test_associativity(_ associativity2: Int32) -> Int32 { return _ffi_fn_test_associativity(associativity2) } func test_atomic_cancel(_ atomic_cancel2: Int32) -> Int32 { return _ffi_fn_test_atomic_cancel(atomic_cancel2) } func test_atomic_commit(_ atomic_commit2: Int32) -> Int32 { return _ffi_fn_test_atomic_commit(atomic_commit2) } func test_atomic_noexcept(_ atomic_noexcept2: Int32) -> Int32 { return _ffi_fn_test_atomic_noexcept(atomic_noexcept2) } func test_auto(_ auto2: Int32) -> Int32 { return _ffi_fn_test_auto(auto2) } func test_bitand(_ bitand2: Int32) -> Int32 { return _ffi_fn_test_bitand(bitand2) } func test_bitor(_ bitor2: Int32) -> Int32 { return _ffi_fn_test_bitor(bitor2) } func test_bool(_ bool2: Int32) -> Int32 { return _ffi_fn_test_bool(bool2) } func test_boolean(_ boolean: Int32) -> Int32 { return _ffi_fn_test_boolean(boolean) } func test_borrowing(_ borrowing2: Int32) -> Int32 { return _ffi_fn_test_borrowing(borrowing2) } func test_byte(_ byte: Int32) -> Int32 { return _ffi_fn_test_byte(byte) } func test_case(_ case2: Int32) -> Int32 { return _ffi_fn_test_case(case2) } func test_catch(_ catch2: Int32) -> Int32 { return _ffi_fn_test_catch(catch2) } func test_char(_ char2: Int32) -> Int32 { return _ffi_fn_test_char(char2) } func test_char16_t(_ char16_t2: Int32) -> Int32 { return _ffi_fn_test_char16_t(char16_t2) } func test_char32_t(_ char32_t2: Int32) -> Int32 { return _ffi_fn_test_char32_t(char32_t2) } func test_char8_t(_ char8_t2: Int32) -> Int32 { return _ffi_fn_test_char8_t(char8_t2) } func test_class(_ class2: Int32) -> Int32 { return _ffi_fn_test_class(class2) } func test_co_await(_ co_await2: Int32) -> Int32 { return _ffi_fn_test_co_await(co_await2) } func test_co_return(_ co_return2: Int32) -> Int32 { return _ffi_fn_test_co_return(co_return2) } func test_co_yield(_ co_yield2: Int32) -> Int32 { return _ffi_fn_test_co_yield(co_yield2) } func test_compl(_ compl2: Int32) -> Int32 { return _ffi_fn_test_compl(compl2) } func test_concept(_ concept2: Int32) -> Int32 { return _ffi_fn_test_concept(concept2) } func test_const_cast(_ const_cast2: Int32) -> Int32 { return _ffi_fn_test_const_cast(const_cast2) } func test_consteval(_ consteval2: Int32) -> Int32 { return _ffi_fn_test_consteval(consteval2) } func test_constexpr(_ constexpr2: Int32) -> Int32 { return _ffi_fn_test_constexpr(constexpr2) } func test_constinit(_ constinit2: Int32) -> Int32 { return _ffi_fn_test_constinit(constinit2) } func test_consuming(_ consuming2: Int32) -> Int32 { return _ffi_fn_test_consuming(consuming2) } func test_contract_assert(_ contract_assert2: Int32) -> Int32 { return _ffi_fn_test_contract_assert(contract_assert2) } func test_convenience(_ convenience2: Int32) -> Int32 { return _ffi_fn_test_convenience(convenience2) } func test_debugger(_ debugger: Int32) -> Int32 { return _ffi_fn_test_debugger(debugger) } func test_decltype(_ decltype2: Int32) -> Int32 { return _ffi_fn_test_decltype(decltype2) } func test_default(_ default2: Int32) -> Int32 { return _ffi_fn_test_default(default2) } func test_defer(_ defer2: Int32) -> Int32 { return _ffi_fn_test_defer(defer2) } func test_deinit(_ deinit2: Int32) -> Int32 { return _ffi_fn_test_deinit(deinit2) } func test_delete(_ delete2: Int32) -> Int32 { return _ffi_fn_test_delete(delete2) } func test_double(_ double2: Int32) -> Int32 { return _ffi_fn_test_double(double2) } func test_dynamic(_ dynamic2: Int32) -> Int32 { return _ffi_fn_test_dynamic(dynamic2) } func test_dynamic_cast(_ dynamic_cast2: Int32) -> Int32 { return _ffi_fn_test_dynamic_cast(dynamic_cast2) } func test_explicit(_ explicit2: Int32) -> Int32 { return _ffi_fn_test_explicit(explicit2) } func test_export(_ export2: Int32) -> Int32 { return _ffi_fn_test_export(export2) } func test_extends(_ extends: Int32) -> Int32 { return _ffi_fn_test_extends(extends) } func test_extension(_ extension2: Int32) -> Int32 { return _ffi_fn_test_extension(extension2) } func test_fallthrough(_ fallthrough2: Int32) -> Int32 { return _ffi_fn_test_fallthrough(fallthrough2) } func test_fileprivate(_ fileprivate2: Int32) -> Int32 { return _ffi_fn_test_fileprivate(fileprivate2) } func test_finally(_ finally: Int32) -> Int32 { return _ffi_fn_test_finally(finally) } func test_float(_ float2: Int32) -> Int32 { return _ffi_fn_test_float(float2) } func test_friend(_ friend2: Int32) -> Int32 { return _ffi_fn_test_friend(friend2) } func test_func(_ func2: Int32) -> Int32 { return _ffi_fn_test_func(func2) } func test_function(_ function: Int32) -> Int32 { return _ffi_fn_test_function(function) } func test_get(_ get2: Int32) -> Int32 { return _ffi_fn_test_get(get2) } func test_goto(_ goto2: Int32) -> Int32 { return _ffi_fn_test_goto(goto2) } func test_guard(_ guard2: Int32) -> Int32 { return _ffi_fn_test_guard(guard2) } func test_implements(_ implements: Int32) -> Int32 { return _ffi_fn_test_implements(implements) } func test_import(_ import2: Int32) -> Int32 { return _ffi_fn_test_import(import2) } func test_indirect(_ indirect2: Int32) -> Int32 { return _ffi_fn_test_indirect(indirect2) } func test_infix(_ infix2: Int32) -> Int32 { return _ffi_fn_test_infix(infix2) } func test_init(_ init2: Int32) -> Int32 { return _ffi_fn_test_init(init2) } func test_inline(_ inline2: Int32) -> Int32 { return _ffi_fn_test_inline(inline2) } func test_inout(_ inout2: Int32) -> Int32 { return _ffi_fn_test_inout(inout2) } func test_instanceof(_ instanceof: Int32) -> Int32 { return _ffi_fn_test_instanceof(instanceof) } func test_int(_ int2: Int32) -> Int32 { return _ffi_fn_test_int(int2) } func test_interface(_ interface: Int32) -> Int32 { return _ffi_fn_test_interface(interface) } func test_internal(_ internal2: Int32) -> Int32 { return _ffi_fn_test_internal(internal2) } func test_is(_ is2: Int32) -> Int32 { return _ffi_fn_test_is(is2) } func test_lazy(_ lazy2: Int32) -> Int32 { return _ffi_fn_test_lazy(lazy2) } func test_left(_ left2: Int32) -> Int32 { return _ffi_fn_test_left(left2) } func test_long(_ long2: Int32) -> Int32 { return _ffi_fn_test_long(long2) } func test_mutable(_ mutable2: Int32) -> Int32 { return _ffi_fn_test_mutable(mutable2) } func test_mutating(_ mutating2: Int32) -> Int32 { return _ffi_fn_test_mutating(mutating2) } func test_namespace(_ namespace2: Int32) -> Int32 { return _ffi_fn_test_namespace(namespace2) } func test_native(_ native: Int32) -> Int32 { return _ffi_fn_test_native(native) } func test_new(_ new2: Int32) -> Int32 { return _ffi_fn_test_new(new2) } func test_nil(_ nil2: Int32) -> Int32 { return _ffi_fn_test_nil(nil2) } func test_noexcept(_ noexcept2: Int32) -> Int32 { return _ffi_fn_test_noexcept(noexcept2) } func test_none(_ none2: Int32) -> Int32 { return _ffi_fn_test_none(none2) } func test_nonisolated(_ nonisolated2: Int32) -> Int32 { return _ffi_fn_test_nonisolated(nonisolated2) } func test_nonmutating(_ nonmutating2: Int32) -> Int32 { return _ffi_fn_test_nonmutating(nonmutating2) } func test_not(_ not2: Int32) -> Int32 { return _ffi_fn_test_not(not2) } func test_not_eq(_ not_eq2: Int32) -> Int32 { return _ffi_fn_test_not_eq(not_eq2) } func test_null(_ null: Int32) -> Int32 { return _ffi_fn_test_null(null) } func test_nullptr(_ nullptr2: Int32) -> Int32 { return _ffi_fn_test_nullptr(nullptr2) } func test_open(_ open2: Int32) -> Int32 { return _ffi_fn_test_open(open2) } func test_operator(_ operator2: Int32) -> Int32 { return _ffi_fn_test_operator(operator2) } func test_optional(_ optional2: Int32) -> Int32 { return _ffi_fn_test_optional(optional2) } func test_or(_ or2: Int32) -> Int32 { return _ffi_fn_test_or(or2) } func test_or_eq(_ or_eq2: Int32) -> Int32 { return _ffi_fn_test_or_eq(or_eq2) } func test_package(_ package2: Int32) -> Int32 { return _ffi_fn_test_package(package2) } func test_postfix(_ postfix2: Int32) -> Int32 { return _ffi_fn_test_postfix(postfix2) } func test_precedence(_ precedence2: Int32) -> Int32 { return _ffi_fn_test_precedence(precedence2) } func test_precedencegroup(_ precedencegroup2: Int32) -> Int32 { return _ffi_fn_test_precedencegroup(precedencegroup2) } func test_prefix(_ prefix2: Int32) -> Int32 { return _ffi_fn_test_prefix(prefix2) } func test_private(_ private2: Int32) -> Int32 { return _ffi_fn_test_private(private2) } func test_protected(_ protected2: Int32) -> Int32 { return _ffi_fn_test_protected(protected2) } func test_protocol(_ protocol2: Int32) -> Int32 { return _ffi_fn_test_protocol(protocol2) } func test_public(_ public2: Int32) -> Int32 { return _ffi_fn_test_public(public2) } func test_reflexpr(_ reflexpr2: Int32) -> Int32 { return _ffi_fn_test_reflexpr(reflexpr2) } func test_register(_ register2: Int32) -> Int32 { return _ffi_fn_test_register(register2) } func test_reinterpret_cast(_ reinterpret_cast2: Int32) -> Int32 { return _ffi_fn_test_reinterpret_cast(reinterpret_cast2) } func test_repeat(_ repeat2: Int32) -> Int32 { return _ffi_fn_test_repeat(repeat2) } func test_required(_ required2: Int32) -> Int32 { return _ffi_fn_test_required(required2) } func test_requires(_ requires2: Int32) -> Int32 { return _ffi_fn_test_requires(requires2) } func test_rethrows(_ rethrows2: Int32) -> Int32 { return _ffi_fn_test_rethrows(rethrows2) } func test_right(_ right2: Int32) -> Int32 { return _ffi_fn_test_right(right2) } func test_set(_ set2: Int32) -> Int32 { return _ffi_fn_test_set(set2) } func test_short(_ short2: Int32) -> Int32 { return _ffi_fn_test_short(short2) } func test_signed(_ signed2: Int32) -> Int32 { return _ffi_fn_test_signed(signed2) } func test_sizeof(_ sizeof2: Int32) -> Int32 { return _ffi_fn_test_sizeof(sizeof2) } func test_some(_ some2: Int32) -> Int32 { return _ffi_fn_test_some(some2) } func test_static_assert(_ static_assert2: Int32) -> Int32 { return _ffi_fn_test_static_assert(static_assert2) } func test_static_cast(_ static_cast2: Int32) -> Int32 { return _ffi_fn_test_static_cast(static_cast2) } func test_subscript(_ subscript2: Int32) -> Int32 { return _ffi_fn_test_subscript(subscript2) } func test_switch(_ switch2: Int32) -> Int32 { return _ffi_fn_test_switch(switch2) } func test_synchronized(_ synchronized2: Int32) -> Int32 { return _ffi_fn_test_synchronized(synchronized2) } func test_template(_ template2: Int32) -> Int32 { return _ffi_fn_test_template(template2) } func test_this(_ this2: Int32) -> Int32 { return _ffi_fn_test_this(this2) } func test_thread_local(_ thread_local2: Int32) -> Int32 { return _ffi_fn_test_thread_local(thread_local2) } func test_throw(_ throw2: Int32) -> Int32 { return _ffi_fn_test_throw(throw2) } func test_throws(_ throws2: Int32) -> Int32 { return _ffi_fn_test_throws(throws2) } func test_transient(_ transient: Int32) -> Int32 { return _ffi_fn_test_transient(transient) } func test_typealias(_ typealias2: Int32) -> Int32 { return _ffi_fn_test_typealias(typealias2) } func test_typedef(_ typedef2: Int32) -> Int32 { return _ffi_fn_test_typedef(typedef2) } func test_typeid(_ typeid2: Int32) -> Int32 { return _ffi_fn_test_typeid(typeid2) } func test_typename(_ typename2: Int32) -> Int32 { return _ffi_fn_test_typename(typename2) } func test_undefined(_ undefined: Int32) -> Int32 { return _ffi_fn_test_undefined(undefined) } func test_union(_ union2: Int32) -> Int32 { return _ffi_fn_test_union(union2) } func test_unowned(_ unowned2: Int32) -> Int32 { return _ffi_fn_test_unowned(unowned2) } func test_unsigned(_ unsigned2: Int32) -> Int32 { return _ffi_fn_test_unsigned(unsigned2) } func test_using(_ using2: Int32) -> Int32 { return _ffi_fn_test_using(using2) } func test_var(_ var2: Int32) -> Int32 { return _ffi_fn_test_var(var2) } func test_void(_ void2: Int32) -> Int32 { return _ffi_fn_test_void(void2) } func test_volatile(_ volatile2: Int32) -> Int32 { return _ffi_fn_test_volatile(volatile2) } func test_wchar_t(_ wchar_t2: Int32) -> Int32 { return _ffi_fn_test_wchar_t(wchar_t2) } func test_weak(_ weak2: Int32) -> Int32 { return _ffi_fn_test_weak(weak2) } func test_with(_ with: Int32) -> Int32 { return _ffi_fn_test_with(with) } func test_xor(_ xor2: Int32) -> Int32 { return _ffi_fn_test_xor(xor2) } func test_xor_eq(_ xor_eq2: Int32) -> Int32 { return _ffi_fn_test_xor_eq(xor_eq2) } ================================================ FILE: src/tests/snapshots/swift_demo_keyword_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test_alignas(alignas2: i32) -> i32 { test_alignas(alignas2) } #[no_mangle] extern "C" fn _ffi_fn_test_alignof(alignof2: i32) -> i32 { test_alignof(alignof2) } #[no_mangle] extern "C" fn _ffi_fn_test_and(and2: i32) -> i32 { test_and(and2) } #[no_mangle] extern "C" fn _ffi_fn_test_and_eq(and_eq2: i32) -> i32 { test_and_eq(and_eq2) } #[no_mangle] extern "C" fn _ffi_fn_test_asm(asm2: i32) -> i32 { test_asm(asm2) } #[no_mangle] extern "C" fn _ffi_fn_test_associatedtype(associatedtype2: i32) -> i32 { test_associatedtype(associatedtype2) } #[no_mangle] extern "C" fn _ffi_fn_test_associativity(associativity2: i32) -> i32 { test_associativity(associativity2) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel2: i32) -> i32 { test_atomic_cancel(atomic_cancel2) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit2: i32) -> i32 { test_atomic_commit(atomic_commit2) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept2: i32) -> i32 { test_atomic_noexcept(atomic_noexcept2) } #[no_mangle] extern "C" fn _ffi_fn_test_auto(auto2: i32) -> i32 { test_auto(auto2) } #[no_mangle] extern "C" fn _ffi_fn_test_bitand(bitand2: i32) -> i32 { test_bitand(bitand2) } #[no_mangle] extern "C" fn _ffi_fn_test_bitor(bitor2: i32) -> i32 { test_bitor(bitor2) } #[no_mangle] extern "C" fn _ffi_fn_test_bool(bool2: i32) -> i32 { test_bool(bool2) } #[no_mangle] extern "C" fn _ffi_fn_test_boolean(boolean: i32) -> i32 { test_boolean(boolean) } #[no_mangle] extern "C" fn _ffi_fn_test_borrowing(borrowing2: i32) -> i32 { test_borrowing(borrowing2) } #[no_mangle] extern "C" fn _ffi_fn_test_byte(byte: i32) -> i32 { test_byte(byte) } #[no_mangle] extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 { test_case(case2) } #[no_mangle] extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 { test_catch(catch2) } #[no_mangle] extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 { test_char(char2) } #[no_mangle] extern "C" fn _ffi_fn_test_char16_t(char16_t2: i32) -> i32 { test_char16_t(char16_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_char32_t(char32_t2: i32) -> i32 { test_char32_t(char32_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_char8_t(char8_t2: i32) -> i32 { test_char8_t(char8_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 { test_class(class2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_await(co_await2: i32) -> i32 { test_co_await(co_await2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_return(co_return2: i32) -> i32 { test_co_return(co_return2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_yield(co_yield2: i32) -> i32 { test_co_yield(co_yield2) } #[no_mangle] extern "C" fn _ffi_fn_test_compl(compl2: i32) -> i32 { test_compl(compl2) } #[no_mangle] extern "C" fn _ffi_fn_test_concept(concept2: i32) -> i32 { test_concept(concept2) } #[no_mangle] extern "C" fn _ffi_fn_test_const_cast(const_cast2: i32) -> i32 { test_const_cast(const_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_consteval(consteval2: i32) -> i32 { test_consteval(consteval2) } #[no_mangle] extern "C" fn _ffi_fn_test_constexpr(constexpr2: i32) -> i32 { test_constexpr(constexpr2) } #[no_mangle] extern "C" fn _ffi_fn_test_constinit(constinit2: i32) -> i32 { test_constinit(constinit2) } #[no_mangle] extern "C" fn _ffi_fn_test_consuming(consuming2: i32) -> i32 { test_consuming(consuming2) } #[no_mangle] extern "C" fn _ffi_fn_test_contract_assert(contract_assert2: i32) -> i32 { test_contract_assert(contract_assert2) } #[no_mangle] extern "C" fn _ffi_fn_test_convenience(convenience2: i32) -> i32 { test_convenience(convenience2) } #[no_mangle] extern "C" fn _ffi_fn_test_debugger(debugger: i32) -> i32 { test_debugger(debugger) } #[no_mangle] extern "C" fn _ffi_fn_test_decltype(decltype2: i32) -> i32 { test_decltype(decltype2) } #[no_mangle] extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 { test_default(default2) } #[no_mangle] extern "C" fn _ffi_fn_test_defer(defer2: i32) -> i32 { test_defer(defer2) } #[no_mangle] extern "C" fn _ffi_fn_test_deinit(deinit2: i32) -> i32 { test_deinit(deinit2) } #[no_mangle] extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 { test_delete(delete2) } #[no_mangle] extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 { test_double(double2) } #[no_mangle] extern "C" fn _ffi_fn_test_dynamic(dynamic2: i32) -> i32 { test_dynamic(dynamic2) } #[no_mangle] extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast2: i32) -> i32 { test_dynamic_cast(dynamic_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_explicit(explicit2: i32) -> i32 { test_explicit(explicit2) } #[no_mangle] extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 { test_export(export2) } #[no_mangle] extern "C" fn _ffi_fn_test_extends(extends: i32) -> i32 { test_extends(extends) } #[no_mangle] extern "C" fn _ffi_fn_test_extension(extension2: i32) -> i32 { test_extension(extension2) } #[no_mangle] extern "C" fn _ffi_fn_test_fallthrough(fallthrough2: i32) -> i32 { test_fallthrough(fallthrough2) } #[no_mangle] extern "C" fn _ffi_fn_test_fileprivate(fileprivate2: i32) -> i32 { test_fileprivate(fileprivate2) } #[no_mangle] extern "C" fn _ffi_fn_test_finally(finally: i32) -> i32 { test_finally(finally) } #[no_mangle] extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 { test_float(float2) } #[no_mangle] extern "C" fn _ffi_fn_test_friend(friend2: i32) -> i32 { test_friend(friend2) } #[no_mangle] extern "C" fn _ffi_fn_test_func(func2: i32) -> i32 { test_func(func2) } #[no_mangle] extern "C" fn _ffi_fn_test_function(function: i32) -> i32 { test_function(function) } #[no_mangle] extern "C" fn _ffi_fn_test_get(get2: i32) -> i32 { test_get(get2) } #[no_mangle] extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 { test_goto(goto2) } #[no_mangle] extern "C" fn _ffi_fn_test_guard(guard2: i32) -> i32 { test_guard(guard2) } #[no_mangle] extern "C" fn _ffi_fn_test_implements(implements: i32) -> i32 { test_implements(implements) } #[no_mangle] extern "C" fn _ffi_fn_test_import(import2: i32) -> i32 { test_import(import2) } #[no_mangle] extern "C" fn _ffi_fn_test_indirect(indirect2: i32) -> i32 { test_indirect(indirect2) } #[no_mangle] extern "C" fn _ffi_fn_test_infix(infix2: i32) -> i32 { test_infix(infix2) } #[no_mangle] extern "C" fn _ffi_fn_test_init(init2: i32) -> i32 { test_init(init2) } #[no_mangle] extern "C" fn _ffi_fn_test_inline(inline2: i32) -> i32 { test_inline(inline2) } #[no_mangle] extern "C" fn _ffi_fn_test_inout(inout2: i32) -> i32 { test_inout(inout2) } #[no_mangle] extern "C" fn _ffi_fn_test_instanceof(instanceof: i32) -> i32 { test_instanceof(instanceof) } #[no_mangle] extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 { test_int(int2) } #[no_mangle] extern "C" fn _ffi_fn_test_interface(interface: i32) -> i32 { test_interface(interface) } #[no_mangle] extern "C" fn _ffi_fn_test_internal(internal2: i32) -> i32 { test_internal(internal2) } #[no_mangle] extern "C" fn _ffi_fn_test_is(is2: i32) -> i32 { test_is(is2) } #[no_mangle] extern "C" fn _ffi_fn_test_lazy(lazy2: i32) -> i32 { test_lazy(lazy2) } #[no_mangle] extern "C" fn _ffi_fn_test_left(left2: i32) -> i32 { test_left(left2) } #[no_mangle] extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 { test_long(long2) } #[no_mangle] extern "C" fn _ffi_fn_test_mutable(mutable2: i32) -> i32 { test_mutable(mutable2) } #[no_mangle] extern "C" fn _ffi_fn_test_mutating(mutating2: i32) -> i32 { test_mutating(mutating2) } #[no_mangle] extern "C" fn _ffi_fn_test_namespace(namespace2: i32) -> i32 { test_namespace(namespace2) } #[no_mangle] extern "C" fn _ffi_fn_test_native(native: i32) -> i32 { test_native(native) } #[no_mangle] extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 { test_new(new2) } #[no_mangle] extern "C" fn _ffi_fn_test_nil(nil2: i32) -> i32 { test_nil(nil2) } #[no_mangle] extern "C" fn _ffi_fn_test_noexcept(noexcept2: i32) -> i32 { test_noexcept(noexcept2) } #[no_mangle] extern "C" fn _ffi_fn_test_none(none2: i32) -> i32 { test_none(none2) } #[no_mangle] extern "C" fn _ffi_fn_test_nonisolated(nonisolated2: i32) -> i32 { test_nonisolated(nonisolated2) } #[no_mangle] extern "C" fn _ffi_fn_test_nonmutating(nonmutating2: i32) -> i32 { test_nonmutating(nonmutating2) } #[no_mangle] extern "C" fn _ffi_fn_test_not(not2: i32) -> i32 { test_not(not2) } #[no_mangle] extern "C" fn _ffi_fn_test_not_eq(not_eq2: i32) -> i32 { test_not_eq(not_eq2) } #[no_mangle] extern "C" fn _ffi_fn_test_null(null: i32) -> i32 { test_null(null) } #[no_mangle] extern "C" fn _ffi_fn_test_nullptr(nullptr2: i32) -> i32 { test_nullptr(nullptr2) } #[no_mangle] extern "C" fn _ffi_fn_test_open(open2: i32) -> i32 { test_open(open2) } #[no_mangle] extern "C" fn _ffi_fn_test_operator(operator2: i32) -> i32 { test_operator(operator2) } #[no_mangle] extern "C" fn _ffi_fn_test_optional(optional2: i32) -> i32 { test_optional(optional2) } #[no_mangle] extern "C" fn _ffi_fn_test_or(or2: i32) -> i32 { test_or(or2) } #[no_mangle] extern "C" fn _ffi_fn_test_or_eq(or_eq2: i32) -> i32 { test_or_eq(or_eq2) } #[no_mangle] extern "C" fn _ffi_fn_test_package(package2: i32) -> i32 { test_package(package2) } #[no_mangle] extern "C" fn _ffi_fn_test_postfix(postfix2: i32) -> i32 { test_postfix(postfix2) } #[no_mangle] extern "C" fn _ffi_fn_test_precedence(precedence2: i32) -> i32 { test_precedence(precedence2) } #[no_mangle] extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup2: i32) -> i32 { test_precedencegroup(precedencegroup2) } #[no_mangle] extern "C" fn _ffi_fn_test_prefix(prefix2: i32) -> i32 { test_prefix(prefix2) } #[no_mangle] extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 { test_private(private2) } #[no_mangle] extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 { test_protected(protected2) } #[no_mangle] extern "C" fn _ffi_fn_test_protocol(protocol2: i32) -> i32 { test_protocol(protocol2) } #[no_mangle] extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 { test_public(public2) } #[no_mangle] extern "C" fn _ffi_fn_test_reflexpr(reflexpr2: i32) -> i32 { test_reflexpr(reflexpr2) } #[no_mangle] extern "C" fn _ffi_fn_test_register(register2: i32) -> i32 { test_register(register2) } #[no_mangle] extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast2: i32) -> i32 { test_reinterpret_cast(reinterpret_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_repeat(repeat2: i32) -> i32 { test_repeat(repeat2) } #[no_mangle] extern "C" fn _ffi_fn_test_required(required2: i32) -> i32 { test_required(required2) } #[no_mangle] extern "C" fn _ffi_fn_test_requires(requires2: i32) -> i32 { test_requires(requires2) } #[no_mangle] extern "C" fn _ffi_fn_test_rethrows(rethrows2: i32) -> i32 { test_rethrows(rethrows2) } #[no_mangle] extern "C" fn _ffi_fn_test_right(right2: i32) -> i32 { test_right(right2) } #[no_mangle] extern "C" fn _ffi_fn_test_set(set2: i32) -> i32 { test_set(set2) } #[no_mangle] extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 { test_short(short2) } #[no_mangle] extern "C" fn _ffi_fn_test_signed(signed2: i32) -> i32 { test_signed(signed2) } #[no_mangle] extern "C" fn _ffi_fn_test_sizeof(sizeof2: i32) -> i32 { test_sizeof(sizeof2) } #[no_mangle] extern "C" fn _ffi_fn_test_some(some2: i32) -> i32 { test_some(some2) } #[no_mangle] extern "C" fn _ffi_fn_test_static_assert(static_assert2: i32) -> i32 { test_static_assert(static_assert2) } #[no_mangle] extern "C" fn _ffi_fn_test_static_cast(static_cast2: i32) -> i32 { test_static_cast(static_cast2) } #[no_mangle] extern "C" fn _ffi_fn_test_subscript(subscript2: i32) -> i32 { test_subscript(subscript2) } #[no_mangle] extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 { test_switch(switch2) } #[no_mangle] extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 { test_synchronized(synchronized2) } #[no_mangle] extern "C" fn _ffi_fn_test_template(template2: i32) -> i32 { test_template(template2) } #[no_mangle] extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 { test_this(this2) } #[no_mangle] extern "C" fn _ffi_fn_test_thread_local(thread_local2: i32) -> i32 { test_thread_local(thread_local2) } #[no_mangle] extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 { test_throw(throw2) } #[no_mangle] extern "C" fn _ffi_fn_test_throws(throws2: i32) -> i32 { test_throws(throws2) } #[no_mangle] extern "C" fn _ffi_fn_test_transient(transient: i32) -> i32 { test_transient(transient) } #[no_mangle] extern "C" fn _ffi_fn_test_typealias(typealias2: i32) -> i32 { test_typealias(typealias2) } #[no_mangle] extern "C" fn _ffi_fn_test_typedef(typedef2: i32) -> i32 { test_typedef(typedef2) } #[no_mangle] extern "C" fn _ffi_fn_test_typeid(typeid2: i32) -> i32 { test_typeid(typeid2) } #[no_mangle] extern "C" fn _ffi_fn_test_typename(typename2: i32) -> i32 { test_typename(typename2) } #[no_mangle] extern "C" fn _ffi_fn_test_undefined(undefined: i32) -> i32 { test_undefined(undefined) } #[no_mangle] extern "C" fn _ffi_fn_test_union(union2: i32) -> i32 { test_union(union2) } #[no_mangle] extern "C" fn _ffi_fn_test_unowned(unowned2: i32) -> i32 { test_unowned(unowned2) } #[no_mangle] extern "C" fn _ffi_fn_test_unsigned(unsigned2: i32) -> i32 { test_unsigned(unsigned2) } #[no_mangle] extern "C" fn _ffi_fn_test_using(using2: i32) -> i32 { test_using(using2) } #[no_mangle] extern "C" fn _ffi_fn_test_var(var2: i32) -> i32 { test_var(var2) } #[no_mangle] extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 { test_void(void2) } #[no_mangle] extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 { test_volatile(volatile2) } #[no_mangle] extern "C" fn _ffi_fn_test_wchar_t(wchar_t2: i32) -> i32 { test_wchar_t(wchar_t2) } #[no_mangle] extern "C" fn _ffi_fn_test_weak(weak2: i32) -> i32 { test_weak(weak2) } #[no_mangle] extern "C" fn _ffi_fn_test_with(with: i32) -> i32 { test_with(with) } #[no_mangle] extern "C" fn _ffi_fn_test_xor(xor2: i32) -> i32 { test_xor(xor2) } #[no_mangle] extern "C" fn _ffi_fn_test_xor_eq(xor_eq2: i32) -> i32 { test_xor_eq(xor_eq2) } ================================================ FILE: src/tests/snapshots/swift_demo_keyword_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test_alignas(int32_t alignas2); int32_t _ffi_fn_test_alignof(int32_t alignof2); int32_t _ffi_fn_test_and(int32_t and2); int32_t _ffi_fn_test_and_eq(int32_t and_eq2); int32_t _ffi_fn_test_asm(int32_t asm2); int32_t _ffi_fn_test_associatedtype(int32_t associatedtype2); int32_t _ffi_fn_test_associativity(int32_t associativity2); int32_t _ffi_fn_test_atomic_cancel(int32_t atomic_cancel2); int32_t _ffi_fn_test_atomic_commit(int32_t atomic_commit2); int32_t _ffi_fn_test_atomic_noexcept(int32_t atomic_noexcept2); int32_t _ffi_fn_test_auto(int32_t auto2); int32_t _ffi_fn_test_bitand(int32_t bitand2); int32_t _ffi_fn_test_bitor(int32_t bitor2); int32_t _ffi_fn_test_bool(int32_t bool2); int32_t _ffi_fn_test_boolean(int32_t boolean); int32_t _ffi_fn_test_borrowing(int32_t borrowing2); int32_t _ffi_fn_test_byte(int32_t byte); int32_t _ffi_fn_test_case(int32_t case2); int32_t _ffi_fn_test_catch(int32_t catch2); int32_t _ffi_fn_test_char(int32_t char2); int32_t _ffi_fn_test_char16_t(int32_t char16_t2); int32_t _ffi_fn_test_char32_t(int32_t char32_t2); int32_t _ffi_fn_test_char8_t(int32_t char8_t2); int32_t _ffi_fn_test_class(int32_t class2); int32_t _ffi_fn_test_co_await(int32_t co_await2); int32_t _ffi_fn_test_co_return(int32_t co_return2); int32_t _ffi_fn_test_co_yield(int32_t co_yield2); int32_t _ffi_fn_test_compl(int32_t compl2); int32_t _ffi_fn_test_concept(int32_t concept2); int32_t _ffi_fn_test_const_cast(int32_t const_cast2); int32_t _ffi_fn_test_consteval(int32_t consteval2); int32_t _ffi_fn_test_constexpr(int32_t constexpr2); int32_t _ffi_fn_test_constinit(int32_t constinit2); int32_t _ffi_fn_test_consuming(int32_t consuming2); int32_t _ffi_fn_test_contract_assert(int32_t contract_assert2); int32_t _ffi_fn_test_convenience(int32_t convenience2); int32_t _ffi_fn_test_debugger(int32_t debugger); int32_t _ffi_fn_test_decltype(int32_t decltype2); int32_t _ffi_fn_test_default(int32_t default2); int32_t _ffi_fn_test_defer(int32_t defer2); int32_t _ffi_fn_test_deinit(int32_t deinit2); int32_t _ffi_fn_test_delete(int32_t delete2); int32_t _ffi_fn_test_double(int32_t double2); int32_t _ffi_fn_test_dynamic(int32_t dynamic2); int32_t _ffi_fn_test_dynamic_cast(int32_t dynamic_cast2); int32_t _ffi_fn_test_explicit(int32_t explicit2); int32_t _ffi_fn_test_export(int32_t export2); int32_t _ffi_fn_test_extends(int32_t extends); int32_t _ffi_fn_test_extension(int32_t extension2); int32_t _ffi_fn_test_fallthrough(int32_t fallthrough2); int32_t _ffi_fn_test_fileprivate(int32_t fileprivate2); int32_t _ffi_fn_test_finally(int32_t finally); int32_t _ffi_fn_test_float(int32_t float2); int32_t _ffi_fn_test_friend(int32_t friend2); int32_t _ffi_fn_test_func(int32_t func2); int32_t _ffi_fn_test_function(int32_t function); int32_t _ffi_fn_test_get(int32_t get2); int32_t _ffi_fn_test_goto(int32_t goto2); int32_t _ffi_fn_test_guard(int32_t guard2); int32_t _ffi_fn_test_implements(int32_t implements); int32_t _ffi_fn_test_import(int32_t import2); int32_t _ffi_fn_test_indirect(int32_t indirect2); int32_t _ffi_fn_test_infix(int32_t infix2); int32_t _ffi_fn_test_init(int32_t init2); int32_t _ffi_fn_test_inline(int32_t inline2); int32_t _ffi_fn_test_inout(int32_t inout2); int32_t _ffi_fn_test_instanceof(int32_t instanceof); int32_t _ffi_fn_test_int(int32_t int2); int32_t _ffi_fn_test_interface(int32_t interface); int32_t _ffi_fn_test_internal(int32_t internal2); int32_t _ffi_fn_test_is(int32_t is2); int32_t _ffi_fn_test_lazy(int32_t lazy2); int32_t _ffi_fn_test_left(int32_t left2); int32_t _ffi_fn_test_long(int32_t long2); int32_t _ffi_fn_test_mutable(int32_t mutable2); int32_t _ffi_fn_test_mutating(int32_t mutating2); int32_t _ffi_fn_test_namespace(int32_t namespace2); int32_t _ffi_fn_test_native(int32_t native); int32_t _ffi_fn_test_new(int32_t new2); int32_t _ffi_fn_test_nil(int32_t nil2); int32_t _ffi_fn_test_noexcept(int32_t noexcept2); int32_t _ffi_fn_test_none(int32_t none2); int32_t _ffi_fn_test_nonisolated(int32_t nonisolated2); int32_t _ffi_fn_test_nonmutating(int32_t nonmutating2); int32_t _ffi_fn_test_not(int32_t not2); int32_t _ffi_fn_test_not_eq(int32_t not_eq2); int32_t _ffi_fn_test_null(int32_t null); int32_t _ffi_fn_test_nullptr(int32_t nullptr2); int32_t _ffi_fn_test_open(int32_t open2); int32_t _ffi_fn_test_operator(int32_t operator2); int32_t _ffi_fn_test_optional(int32_t optional2); int32_t _ffi_fn_test_or(int32_t or2); int32_t _ffi_fn_test_or_eq(int32_t or_eq2); int32_t _ffi_fn_test_package(int32_t package2); int32_t _ffi_fn_test_postfix(int32_t postfix2); int32_t _ffi_fn_test_precedence(int32_t precedence2); int32_t _ffi_fn_test_precedencegroup(int32_t precedencegroup2); int32_t _ffi_fn_test_prefix(int32_t prefix2); int32_t _ffi_fn_test_private(int32_t private2); int32_t _ffi_fn_test_protected(int32_t protected2); int32_t _ffi_fn_test_protocol(int32_t protocol2); int32_t _ffi_fn_test_public(int32_t public2); int32_t _ffi_fn_test_reflexpr(int32_t reflexpr2); int32_t _ffi_fn_test_register(int32_t register2); int32_t _ffi_fn_test_reinterpret_cast(int32_t reinterpret_cast2); int32_t _ffi_fn_test_repeat(int32_t repeat2); int32_t _ffi_fn_test_required(int32_t required2); int32_t _ffi_fn_test_requires(int32_t requires2); int32_t _ffi_fn_test_rethrows(int32_t rethrows2); int32_t _ffi_fn_test_right(int32_t right2); int32_t _ffi_fn_test_set(int32_t set2); int32_t _ffi_fn_test_short(int32_t short2); int32_t _ffi_fn_test_signed(int32_t signed2); int32_t _ffi_fn_test_sizeof(int32_t sizeof2); int32_t _ffi_fn_test_some(int32_t some2); int32_t _ffi_fn_test_static_assert(int32_t static_assert2); int32_t _ffi_fn_test_static_cast(int32_t static_cast2); int32_t _ffi_fn_test_subscript(int32_t subscript2); int32_t _ffi_fn_test_switch(int32_t switch2); int32_t _ffi_fn_test_synchronized(int32_t synchronized2); int32_t _ffi_fn_test_template(int32_t template2); int32_t _ffi_fn_test_this(int32_t this2); int32_t _ffi_fn_test_thread_local(int32_t thread_local2); int32_t _ffi_fn_test_throw(int32_t throw2); int32_t _ffi_fn_test_throws(int32_t throws2); int32_t _ffi_fn_test_transient(int32_t transient); int32_t _ffi_fn_test_typealias(int32_t typealias2); int32_t _ffi_fn_test_typedef(int32_t typedef2); int32_t _ffi_fn_test_typeid(int32_t typeid2); int32_t _ffi_fn_test_typename(int32_t typename2); int32_t _ffi_fn_test_undefined(int32_t undefined); int32_t _ffi_fn_test_union(int32_t union2); int32_t _ffi_fn_test_unowned(int32_t unowned2); int32_t _ffi_fn_test_unsigned(int32_t unsigned2); int32_t _ffi_fn_test_using(int32_t using2); int32_t _ffi_fn_test_var(int32_t var2); int32_t _ffi_fn_test_void(int32_t void2); int32_t _ffi_fn_test_volatile(int32_t volatile2); int32_t _ffi_fn_test_wchar_t(int32_t wchar_t2); int32_t _ffi_fn_test_weak(int32_t weak2); int32_t _ffi_fn_test_with(int32_t with); int32_t _ffi_fn_test_xor(int32_t xor2); int32_t _ffi_fn_test_xor_eq(int32_t xor_eq2); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_keyword_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test_alignas(_ alignas2: Int32) -> Int32 { return _ffi_fn_test_alignas(alignas2) } func test_alignof(_ alignof2: Int32) -> Int32 { return _ffi_fn_test_alignof(alignof2) } func test_and(_ and2: Int32) -> Int32 { return _ffi_fn_test_and(and2) } func test_and_eq(_ and_eq2: Int32) -> Int32 { return _ffi_fn_test_and_eq(and_eq2) } func test_asm(_ asm2: Int32) -> Int32 { return _ffi_fn_test_asm(asm2) } func test_associatedtype(_ associatedtype2: Int32) -> Int32 { return _ffi_fn_test_associatedtype(associatedtype2) } func test_associativity(_ associativity2: Int32) -> Int32 { return _ffi_fn_test_associativity(associativity2) } func test_atomic_cancel(_ atomic_cancel2: Int32) -> Int32 { return _ffi_fn_test_atomic_cancel(atomic_cancel2) } func test_atomic_commit(_ atomic_commit2: Int32) -> Int32 { return _ffi_fn_test_atomic_commit(atomic_commit2) } func test_atomic_noexcept(_ atomic_noexcept2: Int32) -> Int32 { return _ffi_fn_test_atomic_noexcept(atomic_noexcept2) } func test_auto(_ auto2: Int32) -> Int32 { return _ffi_fn_test_auto(auto2) } func test_bitand(_ bitand2: Int32) -> Int32 { return _ffi_fn_test_bitand(bitand2) } func test_bitor(_ bitor2: Int32) -> Int32 { return _ffi_fn_test_bitor(bitor2) } func test_bool(_ bool2: Int32) -> Int32 { return _ffi_fn_test_bool(bool2) } func test_boolean(_ boolean: Int32) -> Int32 { return _ffi_fn_test_boolean(boolean) } func test_borrowing(_ borrowing2: Int32) -> Int32 { return _ffi_fn_test_borrowing(borrowing2) } func test_byte(_ byte: Int32) -> Int32 { return _ffi_fn_test_byte(byte) } func test_case(_ case2: Int32) -> Int32 { return _ffi_fn_test_case(case2) } func test_catch(_ catch2: Int32) -> Int32 { return _ffi_fn_test_catch(catch2) } func test_char(_ char2: Int32) -> Int32 { return _ffi_fn_test_char(char2) } func test_char16_t(_ char16_t2: Int32) -> Int32 { return _ffi_fn_test_char16_t(char16_t2) } func test_char32_t(_ char32_t2: Int32) -> Int32 { return _ffi_fn_test_char32_t(char32_t2) } func test_char8_t(_ char8_t2: Int32) -> Int32 { return _ffi_fn_test_char8_t(char8_t2) } func test_class(_ class2: Int32) -> Int32 { return _ffi_fn_test_class(class2) } func test_co_await(_ co_await2: Int32) -> Int32 { return _ffi_fn_test_co_await(co_await2) } func test_co_return(_ co_return2: Int32) -> Int32 { return _ffi_fn_test_co_return(co_return2) } func test_co_yield(_ co_yield2: Int32) -> Int32 { return _ffi_fn_test_co_yield(co_yield2) } func test_compl(_ compl2: Int32) -> Int32 { return _ffi_fn_test_compl(compl2) } func test_concept(_ concept2: Int32) -> Int32 { return _ffi_fn_test_concept(concept2) } func test_const_cast(_ const_cast2: Int32) -> Int32 { return _ffi_fn_test_const_cast(const_cast2) } func test_consteval(_ consteval2: Int32) -> Int32 { return _ffi_fn_test_consteval(consteval2) } func test_constexpr(_ constexpr2: Int32) -> Int32 { return _ffi_fn_test_constexpr(constexpr2) } func test_constinit(_ constinit2: Int32) -> Int32 { return _ffi_fn_test_constinit(constinit2) } func test_consuming(_ consuming2: Int32) -> Int32 { return _ffi_fn_test_consuming(consuming2) } func test_contract_assert(_ contract_assert2: Int32) -> Int32 { return _ffi_fn_test_contract_assert(contract_assert2) } func test_convenience(_ convenience2: Int32) -> Int32 { return _ffi_fn_test_convenience(convenience2) } func test_debugger(_ debugger: Int32) -> Int32 { return _ffi_fn_test_debugger(debugger) } func test_decltype(_ decltype2: Int32) -> Int32 { return _ffi_fn_test_decltype(decltype2) } func test_default(_ default2: Int32) -> Int32 { return _ffi_fn_test_default(default2) } func test_defer(_ defer2: Int32) -> Int32 { return _ffi_fn_test_defer(defer2) } func test_deinit(_ deinit2: Int32) -> Int32 { return _ffi_fn_test_deinit(deinit2) } func test_delete(_ delete2: Int32) -> Int32 { return _ffi_fn_test_delete(delete2) } func test_double(_ double2: Int32) -> Int32 { return _ffi_fn_test_double(double2) } func test_dynamic(_ dynamic2: Int32) -> Int32 { return _ffi_fn_test_dynamic(dynamic2) } func test_dynamic_cast(_ dynamic_cast2: Int32) -> Int32 { return _ffi_fn_test_dynamic_cast(dynamic_cast2) } func test_explicit(_ explicit2: Int32) -> Int32 { return _ffi_fn_test_explicit(explicit2) } func test_export(_ export2: Int32) -> Int32 { return _ffi_fn_test_export(export2) } func test_extends(_ extends: Int32) -> Int32 { return _ffi_fn_test_extends(extends) } func test_extension(_ extension2: Int32) -> Int32 { return _ffi_fn_test_extension(extension2) } func test_fallthrough(_ fallthrough2: Int32) -> Int32 { return _ffi_fn_test_fallthrough(fallthrough2) } func test_fileprivate(_ fileprivate2: Int32) -> Int32 { return _ffi_fn_test_fileprivate(fileprivate2) } func test_finally(_ finally: Int32) -> Int32 { return _ffi_fn_test_finally(finally) } func test_float(_ float2: Int32) -> Int32 { return _ffi_fn_test_float(float2) } func test_friend(_ friend2: Int32) -> Int32 { return _ffi_fn_test_friend(friend2) } func test_func(_ func2: Int32) -> Int32 { return _ffi_fn_test_func(func2) } func test_function(_ function: Int32) -> Int32 { return _ffi_fn_test_function(function) } func test_get(_ get2: Int32) -> Int32 { return _ffi_fn_test_get(get2) } func test_goto(_ goto2: Int32) -> Int32 { return _ffi_fn_test_goto(goto2) } func test_guard(_ guard2: Int32) -> Int32 { return _ffi_fn_test_guard(guard2) } func test_implements(_ implements: Int32) -> Int32 { return _ffi_fn_test_implements(implements) } func test_import(_ import2: Int32) -> Int32 { return _ffi_fn_test_import(import2) } func test_indirect(_ indirect2: Int32) -> Int32 { return _ffi_fn_test_indirect(indirect2) } func test_infix(_ infix2: Int32) -> Int32 { return _ffi_fn_test_infix(infix2) } func test_init(_ init2: Int32) -> Int32 { return _ffi_fn_test_init(init2) } func test_inline(_ inline2: Int32) -> Int32 { return _ffi_fn_test_inline(inline2) } func test_inout(_ inout2: Int32) -> Int32 { return _ffi_fn_test_inout(inout2) } func test_instanceof(_ instanceof: Int32) -> Int32 { return _ffi_fn_test_instanceof(instanceof) } func test_int(_ int2: Int32) -> Int32 { return _ffi_fn_test_int(int2) } func test_interface(_ interface: Int32) -> Int32 { return _ffi_fn_test_interface(interface) } func test_internal(_ internal2: Int32) -> Int32 { return _ffi_fn_test_internal(internal2) } func test_is(_ is2: Int32) -> Int32 { return _ffi_fn_test_is(is2) } func test_lazy(_ lazy2: Int32) -> Int32 { return _ffi_fn_test_lazy(lazy2) } func test_left(_ left2: Int32) -> Int32 { return _ffi_fn_test_left(left2) } func test_long(_ long2: Int32) -> Int32 { return _ffi_fn_test_long(long2) } func test_mutable(_ mutable2: Int32) -> Int32 { return _ffi_fn_test_mutable(mutable2) } func test_mutating(_ mutating2: Int32) -> Int32 { return _ffi_fn_test_mutating(mutating2) } func test_namespace(_ namespace2: Int32) -> Int32 { return _ffi_fn_test_namespace(namespace2) } func test_native(_ native: Int32) -> Int32 { return _ffi_fn_test_native(native) } func test_new(_ new2: Int32) -> Int32 { return _ffi_fn_test_new(new2) } func test_nil(_ nil2: Int32) -> Int32 { return _ffi_fn_test_nil(nil2) } func test_noexcept(_ noexcept2: Int32) -> Int32 { return _ffi_fn_test_noexcept(noexcept2) } func test_none(_ none2: Int32) -> Int32 { return _ffi_fn_test_none(none2) } func test_nonisolated(_ nonisolated2: Int32) -> Int32 { return _ffi_fn_test_nonisolated(nonisolated2) } func test_nonmutating(_ nonmutating2: Int32) -> Int32 { return _ffi_fn_test_nonmutating(nonmutating2) } func test_not(_ not2: Int32) -> Int32 { return _ffi_fn_test_not(not2) } func test_not_eq(_ not_eq2: Int32) -> Int32 { return _ffi_fn_test_not_eq(not_eq2) } func test_null(_ null: Int32) -> Int32 { return _ffi_fn_test_null(null) } func test_nullptr(_ nullptr2: Int32) -> Int32 { return _ffi_fn_test_nullptr(nullptr2) } func test_open(_ open2: Int32) -> Int32 { return _ffi_fn_test_open(open2) } func test_operator(_ operator2: Int32) -> Int32 { return _ffi_fn_test_operator(operator2) } func test_optional(_ optional2: Int32) -> Int32 { return _ffi_fn_test_optional(optional2) } func test_or(_ or2: Int32) -> Int32 { return _ffi_fn_test_or(or2) } func test_or_eq(_ or_eq2: Int32) -> Int32 { return _ffi_fn_test_or_eq(or_eq2) } func test_package(_ package2: Int32) -> Int32 { return _ffi_fn_test_package(package2) } func test_postfix(_ postfix2: Int32) -> Int32 { return _ffi_fn_test_postfix(postfix2) } func test_precedence(_ precedence2: Int32) -> Int32 { return _ffi_fn_test_precedence(precedence2) } func test_precedencegroup(_ precedencegroup2: Int32) -> Int32 { return _ffi_fn_test_precedencegroup(precedencegroup2) } func test_prefix(_ prefix2: Int32) -> Int32 { return _ffi_fn_test_prefix(prefix2) } func test_private(_ private2: Int32) -> Int32 { return _ffi_fn_test_private(private2) } func test_protected(_ protected2: Int32) -> Int32 { return _ffi_fn_test_protected(protected2) } func test_protocol(_ protocol2: Int32) -> Int32 { return _ffi_fn_test_protocol(protocol2) } func test_public(_ public2: Int32) -> Int32 { return _ffi_fn_test_public(public2) } func test_reflexpr(_ reflexpr2: Int32) -> Int32 { return _ffi_fn_test_reflexpr(reflexpr2) } func test_register(_ register2: Int32) -> Int32 { return _ffi_fn_test_register(register2) } func test_reinterpret_cast(_ reinterpret_cast2: Int32) -> Int32 { return _ffi_fn_test_reinterpret_cast(reinterpret_cast2) } func test_repeat(_ repeat2: Int32) -> Int32 { return _ffi_fn_test_repeat(repeat2) } func test_required(_ required2: Int32) -> Int32 { return _ffi_fn_test_required(required2) } func test_requires(_ requires2: Int32) -> Int32 { return _ffi_fn_test_requires(requires2) } func test_rethrows(_ rethrows2: Int32) -> Int32 { return _ffi_fn_test_rethrows(rethrows2) } func test_right(_ right2: Int32) -> Int32 { return _ffi_fn_test_right(right2) } func test_set(_ set2: Int32) -> Int32 { return _ffi_fn_test_set(set2) } func test_short(_ short2: Int32) -> Int32 { return _ffi_fn_test_short(short2) } func test_signed(_ signed2: Int32) -> Int32 { return _ffi_fn_test_signed(signed2) } func test_sizeof(_ sizeof2: Int32) -> Int32 { return _ffi_fn_test_sizeof(sizeof2) } func test_some(_ some2: Int32) -> Int32 { return _ffi_fn_test_some(some2) } func test_static_assert(_ static_assert2: Int32) -> Int32 { return _ffi_fn_test_static_assert(static_assert2) } func test_static_cast(_ static_cast2: Int32) -> Int32 { return _ffi_fn_test_static_cast(static_cast2) } func test_subscript(_ subscript2: Int32) -> Int32 { return _ffi_fn_test_subscript(subscript2) } func test_switch(_ switch2: Int32) -> Int32 { return _ffi_fn_test_switch(switch2) } func test_synchronized(_ synchronized2: Int32) -> Int32 { return _ffi_fn_test_synchronized(synchronized2) } func test_template(_ template2: Int32) -> Int32 { return _ffi_fn_test_template(template2) } func test_this(_ this2: Int32) -> Int32 { return _ffi_fn_test_this(this2) } func test_thread_local(_ thread_local2: Int32) -> Int32 { return _ffi_fn_test_thread_local(thread_local2) } func test_throw(_ throw2: Int32) -> Int32 { return _ffi_fn_test_throw(throw2) } func test_throws(_ throws2: Int32) -> Int32 { return _ffi_fn_test_throws(throws2) } func test_transient(_ transient: Int32) -> Int32 { return _ffi_fn_test_transient(transient) } func test_typealias(_ typealias2: Int32) -> Int32 { return _ffi_fn_test_typealias(typealias2) } func test_typedef(_ typedef2: Int32) -> Int32 { return _ffi_fn_test_typedef(typedef2) } func test_typeid(_ typeid2: Int32) -> Int32 { return _ffi_fn_test_typeid(typeid2) } func test_typename(_ typename2: Int32) -> Int32 { return _ffi_fn_test_typename(typename2) } func test_undefined(_ undefined: Int32) -> Int32 { return _ffi_fn_test_undefined(undefined) } func test_union(_ union2: Int32) -> Int32 { return _ffi_fn_test_union(union2) } func test_unowned(_ unowned2: Int32) -> Int32 { return _ffi_fn_test_unowned(unowned2) } func test_unsigned(_ unsigned2: Int32) -> Int32 { return _ffi_fn_test_unsigned(unsigned2) } func test_using(_ using2: Int32) -> Int32 { return _ffi_fn_test_using(using2) } func test_var(_ var2: Int32) -> Int32 { return _ffi_fn_test_var(var2) } func test_void(_ void2: Int32) -> Int32 { return _ffi_fn_test_void(void2) } func test_volatile(_ volatile2: Int32) -> Int32 { return _ffi_fn_test_volatile(volatile2) } func test_wchar_t(_ wchar_t2: Int32) -> Int32 { return _ffi_fn_test_wchar_t(wchar_t2) } func test_weak(_ weak2: Int32) -> Int32 { return _ffi_fn_test_weak(weak2) } func test_with(_ with: Int32) -> Int32 { return _ffi_fn_test_with(with) } func test_xor(_ xor2: Int32) -> Int32 { return _ffi_fn_test_xor(xor2) } func test_xor_eq(_ xor_eq2: Int32) -> Int32 { return _ffi_fn_test_xor_eq(xor_eq2) } ================================================ FILE: src/tests/snapshots/swift_demo_keyword_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_alignas(alignas2: i32) -> i32 { test_alignas(alignas2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_alignof(alignof2: i32) -> i32 { test_alignof(alignof2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_and(and2: i32) -> i32 { test_and(and2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_and_eq(and_eq2: i32) -> i32 { test_and_eq(and_eq2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_asm(asm2: i32) -> i32 { test_asm(asm2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_associatedtype(associatedtype2: i32) -> i32 { test_associatedtype(associatedtype2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_associativity(associativity2: i32) -> i32 { test_associativity(associativity2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel2: i32) -> i32 { test_atomic_cancel(atomic_cancel2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit2: i32) -> i32 { test_atomic_commit(atomic_commit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept2: i32) -> i32 { test_atomic_noexcept(atomic_noexcept2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_auto(auto2: i32) -> i32 { test_auto(auto2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bitand(bitand2: i32) -> i32 { test_bitand(bitand2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bitor(bitor2: i32) -> i32 { test_bitor(bitor2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bool(bool2: i32) -> i32 { test_bool(bool2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_boolean(boolean: i32) -> i32 { test_boolean(boolean) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_borrowing(borrowing2: i32) -> i32 { test_borrowing(borrowing2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_byte(byte: i32) -> i32 { test_byte(byte) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 { test_case(case2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 { test_catch(catch2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 { test_char(char2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char16_t(char16_t2: i32) -> i32 { test_char16_t(char16_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char32_t(char32_t2: i32) -> i32 { test_char32_t(char32_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char8_t(char8_t2: i32) -> i32 { test_char8_t(char8_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 { test_class(class2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_await(co_await2: i32) -> i32 { test_co_await(co_await2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_return(co_return2: i32) -> i32 { test_co_return(co_return2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_yield(co_yield2: i32) -> i32 { test_co_yield(co_yield2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_compl(compl2: i32) -> i32 { test_compl(compl2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_concept(concept2: i32) -> i32 { test_concept(concept2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_const_cast(const_cast2: i32) -> i32 { test_const_cast(const_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_consteval(consteval2: i32) -> i32 { test_consteval(consteval2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_constexpr(constexpr2: i32) -> i32 { test_constexpr(constexpr2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_constinit(constinit2: i32) -> i32 { test_constinit(constinit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_consuming(consuming2: i32) -> i32 { test_consuming(consuming2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_contract_assert(contract_assert2: i32) -> i32 { test_contract_assert(contract_assert2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_convenience(convenience2: i32) -> i32 { test_convenience(convenience2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_debugger(debugger: i32) -> i32 { test_debugger(debugger) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_decltype(decltype2: i32) -> i32 { test_decltype(decltype2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 { test_default(default2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_defer(defer2: i32) -> i32 { test_defer(defer2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_deinit(deinit2: i32) -> i32 { test_deinit(deinit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 { test_delete(delete2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 { test_double(double2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_dynamic(dynamic2: i32) -> i32 { test_dynamic(dynamic2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast2: i32) -> i32 { test_dynamic_cast(dynamic_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_explicit(explicit2: i32) -> i32 { test_explicit(explicit2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 { test_export(export2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_extends(extends: i32) -> i32 { test_extends(extends) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_extension(extension2: i32) -> i32 { test_extension(extension2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_fallthrough(fallthrough2: i32) -> i32 { test_fallthrough(fallthrough2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_fileprivate(fileprivate2: i32) -> i32 { test_fileprivate(fileprivate2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_finally(finally: i32) -> i32 { test_finally(finally) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 { test_float(float2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_friend(friend2: i32) -> i32 { test_friend(friend2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_func(func2: i32) -> i32 { test_func(func2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_function(function: i32) -> i32 { test_function(function) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_get(get2: i32) -> i32 { test_get(get2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 { test_goto(goto2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_guard(guard2: i32) -> i32 { test_guard(guard2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_implements(implements: i32) -> i32 { test_implements(implements) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_import(import2: i32) -> i32 { test_import(import2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_indirect(indirect2: i32) -> i32 { test_indirect(indirect2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_infix(infix2: i32) -> i32 { test_infix(infix2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_init(init2: i32) -> i32 { test_init(init2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_inline(inline2: i32) -> i32 { test_inline(inline2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_inout(inout2: i32) -> i32 { test_inout(inout2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_instanceof(instanceof: i32) -> i32 { test_instanceof(instanceof) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 { test_int(int2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_interface(interface: i32) -> i32 { test_interface(interface) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_internal(internal2: i32) -> i32 { test_internal(internal2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_is(is2: i32) -> i32 { test_is(is2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_lazy(lazy2: i32) -> i32 { test_lazy(lazy2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_left(left2: i32) -> i32 { test_left(left2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 { test_long(long2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_mutable(mutable2: i32) -> i32 { test_mutable(mutable2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_mutating(mutating2: i32) -> i32 { test_mutating(mutating2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_namespace(namespace2: i32) -> i32 { test_namespace(namespace2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_native(native: i32) -> i32 { test_native(native) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 { test_new(new2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nil(nil2: i32) -> i32 { test_nil(nil2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_noexcept(noexcept2: i32) -> i32 { test_noexcept(noexcept2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_none(none2: i32) -> i32 { test_none(none2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nonisolated(nonisolated2: i32) -> i32 { test_nonisolated(nonisolated2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nonmutating(nonmutating2: i32) -> i32 { test_nonmutating(nonmutating2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_not(not2: i32) -> i32 { test_not(not2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_not_eq(not_eq2: i32) -> i32 { test_not_eq(not_eq2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_null(null: i32) -> i32 { test_null(null) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nullptr(nullptr2: i32) -> i32 { test_nullptr(nullptr2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_open(open2: i32) -> i32 { test_open(open2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_operator(operator2: i32) -> i32 { test_operator(operator2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_optional(optional2: i32) -> i32 { test_optional(optional2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_or(or2: i32) -> i32 { test_or(or2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_or_eq(or_eq2: i32) -> i32 { test_or_eq(or_eq2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_package(package2: i32) -> i32 { test_package(package2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_postfix(postfix2: i32) -> i32 { test_postfix(postfix2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_precedence(precedence2: i32) -> i32 { test_precedence(precedence2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup2: i32) -> i32 { test_precedencegroup(precedencegroup2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_prefix(prefix2: i32) -> i32 { test_prefix(prefix2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 { test_private(private2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 { test_protected(protected2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_protocol(protocol2: i32) -> i32 { test_protocol(protocol2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 { test_public(public2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_reflexpr(reflexpr2: i32) -> i32 { test_reflexpr(reflexpr2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_register(register2: i32) -> i32 { test_register(register2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast2: i32) -> i32 { test_reinterpret_cast(reinterpret_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_repeat(repeat2: i32) -> i32 { test_repeat(repeat2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_required(required2: i32) -> i32 { test_required(required2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_requires(requires2: i32) -> i32 { test_requires(requires2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_rethrows(rethrows2: i32) -> i32 { test_rethrows(rethrows2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_right(right2: i32) -> i32 { test_right(right2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_set(set2: i32) -> i32 { test_set(set2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 { test_short(short2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_signed(signed2: i32) -> i32 { test_signed(signed2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_sizeof(sizeof2: i32) -> i32 { test_sizeof(sizeof2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_some(some2: i32) -> i32 { test_some(some2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_static_assert(static_assert2: i32) -> i32 { test_static_assert(static_assert2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_static_cast(static_cast2: i32) -> i32 { test_static_cast(static_cast2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_subscript(subscript2: i32) -> i32 { test_subscript(subscript2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 { test_switch(switch2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 { test_synchronized(synchronized2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_template(template2: i32) -> i32 { test_template(template2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 { test_this(this2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_thread_local(thread_local2: i32) -> i32 { test_thread_local(thread_local2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 { test_throw(throw2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_throws(throws2: i32) -> i32 { test_throws(throws2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_transient(transient: i32) -> i32 { test_transient(transient) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typealias(typealias2: i32) -> i32 { test_typealias(typealias2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typedef(typedef2: i32) -> i32 { test_typedef(typedef2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typeid(typeid2: i32) -> i32 { test_typeid(typeid2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typename(typename2: i32) -> i32 { test_typename(typename2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_undefined(undefined: i32) -> i32 { test_undefined(undefined) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_union(union2: i32) -> i32 { test_union(union2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_unowned(unowned2: i32) -> i32 { test_unowned(unowned2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_unsigned(unsigned2: i32) -> i32 { test_unsigned(unsigned2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_using(using2: i32) -> i32 { test_using(using2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_var(var2: i32) -> i32 { test_var(var2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 { test_void(void2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 { test_volatile(volatile2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_wchar_t(wchar_t2: i32) -> i32 { test_wchar_t(wchar_t2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_weak(weak2: i32) -> i32 { test_weak(weak2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_with(with: i32) -> i32 { test_with(with) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_xor(xor2: i32) -> i32 { test_xor(xor2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_xor_eq(xor_eq2: i32) -> i32 { test_xor_eq(xor_eq2) } ================================================ FILE: src/tests/snapshots/swift_demo_order_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_order_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol FirstTrait: AnyObject { func second() -> SecondTrait } protocol SecondTrait: AnyObject { func first() -> FirstTrait } enum EarlyInsideEnum { case Value(Bool) } enum LaterOutsideEnum { case Value(EarlyInsideEnum) } enum EarlyOutsideEnum { case Value(LaterInsideEnum) } enum LaterInsideEnum { case Value(Bool) } enum FirstEnum { case Second([SecondEnum]) } enum SecondEnum { case First([FirstEnum]) } struct EarlyInsideStruct { var y: Bool } struct LaterOutsideStruct { var x: EarlyInsideStruct } struct EarlyOutsideStruct { var x: LaterInsideStruct } struct LaterInsideStruct { var y: Bool } struct FirstStruct { var second: [SecondStruct] } struct SecondStruct { var first: [FirstStruct] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_order_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_order_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_order_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol FirstTrait: AnyObject { func second() -> SecondTrait } protocol SecondTrait: AnyObject { func first() -> FirstTrait } enum EarlyInsideEnum { case Value(Bool) } enum LaterOutsideEnum { case Value(EarlyInsideEnum) } enum EarlyOutsideEnum { case Value(LaterInsideEnum) } enum LaterInsideEnum { case Value(Bool) } enum FirstEnum { case Second([SecondEnum]) } enum SecondEnum { case First([FirstEnum]) } struct EarlyInsideStruct { var y: Bool } struct LaterOutsideStruct { var x: EarlyInsideStruct } struct EarlyOutsideStruct { var x: LaterInsideStruct } struct LaterInsideStruct { var y: Bool } struct FirstStruct { var second: [SecondStruct] } struct SecondStruct { var first: [FirstStruct] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_order_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_demo_trait_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Box_Trait__get(const void*); int32_t _ffi_Rc_Trait__get(const void*); void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_test(const void* buf_ptr, uintptr_t vec_len); void _ffi_rs_drop_Box_Trait(const void* ptr); void _ffi_rs_drop_Rc_Trait(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_trait_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Trait: AnyObject { func get() -> Int32 } struct Example { var box_ptr: Trait var rc_ptr: Trait var text: String var vec_box: [Trait] var vec_rc: [Trait] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test(_ vec: [Example]) -> [Example] { var buf = ContiguousArray() let vec_len = UInt(vec.count) _ffi_vec_Example_to_rust(vec, &buf) let multi_ret = _ffi_fn_test(_ffi_vec_to_rust(buf), vec_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = _ffi_vec_Example_from_rust(Int(ret_len), &buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } private class _ffi_Box_Trait : Trait { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Trait(_ffi) } func get() -> Int32 { return _ffi_Box_Trait__get(_ffi) } } private class _ffi_Rc_Trait : Trait { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Trait(_ffi) } func get() -> Int32 { return _ffi_Rc_Trait__get(_ffi) } } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } @_cdecl("_ffi_swift_Trait__get") func _ffi_swift_Trait__get(_self: UnsafeRawPointer?) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Trait return _self.get() } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } private func _ffi_vec_Example_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Example] { var items: [Example] = [] items.reserveCapacity(len) while items.count < len { items.append(Example( box_ptr: _ffi_Box_Trait(_ffi_read(&end) as UnsafeRawPointer?), rc_ptr: _ffi_Rc_Trait(_ffi_read(&end) as UnsafeRawPointer?), text: _ffi_string_from_rust(_ffi_read(&end) as UnsafeRawPointer?, Int(_ffi_read(&end) as UInt), _ffi_read(&end) as UInt), vec_box: _ffi_vec_box_dyn_Trait_from_rust(Int(_ffi_read(&end) as UInt), &end), vec_rc: _ffi_vec_rc_dyn_Trait_from_rust(Int(_ffi_read(&end) as UInt), &end) )) } return items } private func _ffi_vec_Example_to_rust(_ items: [Example], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item.box_ptr as AnyObject).toOpaque()), &buf) _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item.rc_ptr as AnyObject).toOpaque()), &buf) let (item_text_ptr, item_text_len) = _ffi_string_to_rust(item.text); _ffi_write(item_text_ptr, &buf) _ffi_write(item_text_len, &buf) _ffi_write(UInt(item.vec_box.count), &buf) _ffi_vec_box_dyn_Trait_to_rust(item.vec_box, &buf) _ffi_write(UInt(item.vec_rc.count), &buf) _ffi_vec_rc_dyn_Trait_to_rust(item.vec_rc, &buf) } } private func _ffi_vec_box_dyn_Trait_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Trait] { var items: [Trait] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_Box_Trait(_ffi_read(&end) as UnsafeRawPointer?)) } return items } private func _ffi_vec_box_dyn_Trait_to_rust(_ items: [Trait], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item as AnyObject).toOpaque()), &buf) } } private func _ffi_vec_rc_dyn_Trait_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Trait] { var items: [Trait] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_Rc_Trait(_ffi_read(&end) as UnsafeRawPointer?)) } return items } private func _ffi_vec_rc_dyn_Trait_to_rust(_ items: [Trait], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item as AnyObject).toOpaque()), &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_demo_trait_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get() } #[no_mangle] extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = test(_ffi_vec_Example_from_swift(vec_len, &mut buf_end)); let mut buf2 = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Example_to_swift(ret, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_len) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Trait(*const u8); impl Drop for _ffi_rs_Trait { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Trait for _ffi_rs_Trait { fn get(&self) -> i32 { extern "C" { fn _ffi_swift_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_swift_Trait__get(self.0) } } } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Example_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Example { box_ptr: Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), rc_ptr: std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), text: _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)), vec_box: _ffi_vec_box_dyn_Trait_from_swift(_ffi_read::(end), end), vec_rc: _ffi_vec_rc_dyn_Trait_from_swift(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Example_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item.box_ptr)) as *const u8, buf); _ffi_write(Box::into_raw(Box::new(item.rc_ptr)) as *const u8, buf); let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.vec_box.len(), buf); _ffi_vec_box_dyn_Trait_to_swift(item.vec_box, buf); _ffi_write(item.vec_rc.len(), buf); _ffi_vec_rc_dyn_Trait_to_swift(item.vec_rc, buf); } } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_demo_trait_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Box_Trait__get(const void*); int32_t _ffi_Rc_Trait__get(const void*); void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_test(const void* buf_ptr, uintptr_t vec_len); void _ffi_rs_drop_Box_Trait(const void* ptr); void _ffi_rs_drop_Rc_Trait(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_demo_trait_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Trait: AnyObject { func get() -> Int32 } struct Example { var box_ptr: Trait var rc_ptr: Trait var text: String var vec_box: [Trait] var vec_rc: [Trait] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test(_ vec: [Example]) -> [Example] { var buf = ContiguousArray() let vec_len = UInt(vec.count) _ffi_vec_Example_to_rust(vec, &buf) let multi_ret = _ffi_fn_test(_ffi_vec_to_rust(buf), vec_len) let buf_ptr2 = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end2 = buf_ptr2! let ret = _ffi_vec_Example_from_rust(Int(ret_len), &buf_end2) _ffi_dealloc(buf_ptr2, buf_cap) return ret } private class _ffi_Box_Trait : Trait { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Trait(_ffi) } func get() -> Int32 { return _ffi_Box_Trait__get(_ffi) } } private class _ffi_Rc_Trait : Trait { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Trait(_ffi) } func get() -> Int32 { return _ffi_Rc_Trait__get(_ffi) } } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } @_cdecl("_ffi_swift_Trait__get") func _ffi_swift_Trait__get(_self: UnsafeRawPointer?) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Trait return _self.get() } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } private func _ffi_vec_Example_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Example] { var items: [Example] = [] items.reserveCapacity(len) while items.count < len { items.append(Example( box_ptr: _ffi_Box_Trait(_ffi_read(&end) as UnsafeRawPointer?), rc_ptr: _ffi_Rc_Trait(_ffi_read(&end) as UnsafeRawPointer?), text: _ffi_string_from_rust(_ffi_read(&end) as UnsafeRawPointer?, Int(_ffi_read(&end) as UInt), _ffi_read(&end) as UInt), vec_box: _ffi_vec_box_dyn_Trait_from_rust(Int(_ffi_read(&end) as UInt), &end), vec_rc: _ffi_vec_rc_dyn_Trait_from_rust(Int(_ffi_read(&end) as UInt), &end) )) } return items } private func _ffi_vec_Example_to_rust(_ items: [Example], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item.box_ptr as AnyObject).toOpaque()), &buf) _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item.rc_ptr as AnyObject).toOpaque()), &buf) let (item_text_ptr, item_text_len) = _ffi_string_to_rust(item.text); _ffi_write(item_text_ptr, &buf) _ffi_write(item_text_len, &buf) _ffi_write(UInt(item.vec_box.count), &buf) _ffi_vec_box_dyn_Trait_to_rust(item.vec_box, &buf) _ffi_write(UInt(item.vec_rc.count), &buf) _ffi_vec_rc_dyn_Trait_to_rust(item.vec_rc, &buf) } } private func _ffi_vec_box_dyn_Trait_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Trait] { var items: [Trait] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_Box_Trait(_ffi_read(&end) as UnsafeRawPointer?)) } return items } private func _ffi_vec_box_dyn_Trait_to_rust(_ items: [Trait], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item as AnyObject).toOpaque()), &buf) } } private func _ffi_vec_rc_dyn_Trait_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Trait] { var items: [Trait] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_Rc_Trait(_ffi_read(&end) as UnsafeRawPointer?)) } return items } private func _ffi_vec_rc_dyn_Trait_to_rust(_ items: [Trait], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item as AnyObject).toOpaque()), &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_demo_trait_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = test(_ffi_vec_Example_from_swift(vec_len, &mut buf_end)); let mut buf2 = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Example_to_swift(ret, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_len) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Trait(*const u8); impl Drop for _ffi_rs_Trait { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Trait for _ffi_rs_Trait { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_swift_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_swift_Trait__get(self.0) } } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Example_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Example { box_ptr: Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), rc_ptr: std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), text: _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)), vec_box: _ffi_vec_box_dyn_Trait_from_swift(_ffi_read::(end), end), vec_rc: _ffi_vec_rc_dyn_Trait_from_swift(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Example_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item.box_ptr)) as *const u8, buf); _ffi_write(Box::into_raw(Box::new(item.rc_ptr)) as *const u8, buf); let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.vec_box.len(), buf); _ffi_vec_box_dyn_Trait_to_swift(item.vec_box, buf); _ffi_write(item.vec_rc.len(), buf); _ffi_vec_rc_dyn_Trait_to_swift(item.vec_rc, buf); } } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_basic_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif _Bool _ffi_fn_add_bool(_Bool x, _Bool y); float _ffi_fn_add_f32(float x, float y); double _ffi_fn_add_f64(double x, double y); int16_t _ffi_fn_add_i16(int16_t x, int16_t y); int32_t _ffi_fn_add_i32(int32_t x, int32_t y); int64_t _ffi_fn_add_i64(int64_t x, int64_t y); int8_t _ffi_fn_add_i8(int8_t x, int8_t y); intptr_t _ffi_fn_add_isize(intptr_t x, intptr_t y); uint16_t _ffi_fn_add_u16(uint16_t x, uint16_t y); uint32_t _ffi_fn_add_u32(uint32_t x, uint32_t y); uint64_t _ffi_fn_add_u64(uint64_t x, uint64_t y); uint8_t _ffi_fn_add_u8(uint8_t x, uint8_t y); uintptr_t _ffi_fn_add_usize(uintptr_t x, uintptr_t y); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_basic_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func add_bool(_ x: Bool, _ y: Bool) -> Bool { return _ffi_fn_add_bool(x, y) } func add_u8(_ x: UInt8, _ y: UInt8) -> UInt8 { return _ffi_fn_add_u8(x, y) } func add_u16(_ x: UInt16, _ y: UInt16) -> UInt16 { return _ffi_fn_add_u16(x, y) } func add_u32(_ x: UInt32, _ y: UInt32) -> UInt32 { return _ffi_fn_add_u32(x, y) } func add_usize(_ x: UInt, _ y: UInt) -> UInt { return _ffi_fn_add_usize(x, y) } func add_u64(_ x: UInt64, _ y: UInt64) -> UInt64 { return _ffi_fn_add_u64(x, y) } func add_i8(_ x: Int8, _ y: Int8) -> Int8 { return _ffi_fn_add_i8(x, y) } func add_i16(_ x: Int16, _ y: Int16) -> Int16 { return _ffi_fn_add_i16(x, y) } func add_i32(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_fn_add_i32(x, y) } func add_isize(_ x: Int, _ y: Int) -> Int { return _ffi_fn_add_isize(x, y) } func add_i64(_ x: Int64, _ y: Int64) -> Int64 { return _ffi_fn_add_i64(x, y) } func add_f32(_ x: Float32, _ y: Float32) -> Float32 { return _ffi_fn_add_f32(x, y) } func add_f64(_ x: Float64, _ y: Float64) -> Float64 { return _ffi_fn_add_f64(x, y) } ================================================ FILE: src/tests/snapshots/swift_fn_basic_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool { add_bool(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 { add_f32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 { add_f64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 { add_i16(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 { add_i32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 { add_i64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 { add_i8(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize { add_isize(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 { add_u16(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 { add_u32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 { add_u64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 { add_u8(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize { add_usize(x, y) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_fn_basic_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif _Bool _ffi_fn_add_bool(_Bool x, _Bool y); float _ffi_fn_add_f32(float x, float y); double _ffi_fn_add_f64(double x, double y); int16_t _ffi_fn_add_i16(int16_t x, int16_t y); int32_t _ffi_fn_add_i32(int32_t x, int32_t y); int64_t _ffi_fn_add_i64(int64_t x, int64_t y); int8_t _ffi_fn_add_i8(int8_t x, int8_t y); intptr_t _ffi_fn_add_isize(intptr_t x, intptr_t y); uint16_t _ffi_fn_add_u16(uint16_t x, uint16_t y); uint32_t _ffi_fn_add_u32(uint32_t x, uint32_t y); uint64_t _ffi_fn_add_u64(uint64_t x, uint64_t y); uint8_t _ffi_fn_add_u8(uint8_t x, uint8_t y); uintptr_t _ffi_fn_add_usize(uintptr_t x, uintptr_t y); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_basic_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func add_bool(_ x: Bool, _ y: Bool) -> Bool { return _ffi_fn_add_bool(x, y) } func add_u8(_ x: UInt8, _ y: UInt8) -> UInt8 { return _ffi_fn_add_u8(x, y) } func add_u16(_ x: UInt16, _ y: UInt16) -> UInt16 { return _ffi_fn_add_u16(x, y) } func add_u32(_ x: UInt32, _ y: UInt32) -> UInt32 { return _ffi_fn_add_u32(x, y) } func add_usize(_ x: UInt, _ y: UInt) -> UInt { return _ffi_fn_add_usize(x, y) } func add_u64(_ x: UInt64, _ y: UInt64) -> UInt64 { return _ffi_fn_add_u64(x, y) } func add_i8(_ x: Int8, _ y: Int8) -> Int8 { return _ffi_fn_add_i8(x, y) } func add_i16(_ x: Int16, _ y: Int16) -> Int16 { return _ffi_fn_add_i16(x, y) } func add_i32(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_fn_add_i32(x, y) } func add_isize(_ x: Int, _ y: Int) -> Int { return _ffi_fn_add_isize(x, y) } func add_i64(_ x: Int64, _ y: Int64) -> Int64 { return _ffi_fn_add_i64(x, y) } func add_f32(_ x: Float32, _ y: Float32) -> Float32 { return _ffi_fn_add_f32(x, y) } func add_f64(_ x: Float64, _ y: Float64) -> Float64 { return _ffi_fn_add_f64(x, y) } ================================================ FILE: src/tests/snapshots/swift_fn_basic_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool { add_bool(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 { add_f32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 { add_f64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 { add_i16(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 { add_i32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 { add_i64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 { add_i8(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize { add_isize(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 { add_u16(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 { add_u32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 { add_u64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 { add_u8(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize { add_usize(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_fn_basic_void_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_fn_add_empty_tuple(int32_t x, int32_t y); void _ffi_fn_add_void(int32_t x, int32_t y); int32_t _ffi_fn_get_result(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_wild_arg(int32_t _1, int32_t _3); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_basic_void_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func add_void(_ x: Int32, _ y: Int32) { _ffi_fn_add_void(x, y) } func add_empty_tuple(_ x: Int32, _ y: Int32) -> () { _ffi_fn_add_empty_tuple(x, y) return () } func get_result() -> Int32 { return _ffi_fn_get_result() } func wild_arg(_ _1: Int32, _ _2: (), _ _3: Int32) -> () { _ffi_fn_wild_arg(_1, _3) return () } ================================================ FILE: src/tests/snapshots/swift_fn_basic_void_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) { _ = add_empty_tuple(x, y); } #[no_mangle] extern "C" fn _ffi_fn_add_void(x: i32, y: i32) { add_void(x, y); } #[no_mangle] extern "C" fn _ffi_fn_get_result() -> i32 { get_result() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) { _ = wild_arg(_1, (), _3); } ================================================ FILE: src/tests/snapshots/swift_fn_basic_void_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_fn_add_empty_tuple(int32_t x, int32_t y); void _ffi_fn_add_void(int32_t x, int32_t y); int32_t _ffi_fn_get_result(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_wild_arg(int32_t _1, int32_t _3); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_basic_void_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func add_void(_ x: Int32, _ y: Int32) { _ffi_fn_add_void(x, y) } func add_empty_tuple(_ x: Int32, _ y: Int32) -> () { _ffi_fn_add_empty_tuple(x, y) return () } func get_result() -> Int32 { return _ffi_fn_get_result() } func wild_arg(_ _1: Int32, _ _2: (), _ _3: Int32) -> () { _ffi_fn_wild_arg(_1, _3) return () } ================================================ FILE: src/tests/snapshots/swift_fn_basic_void_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) { _ = add_empty_tuple(x, y); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_void(x: i32, y: i32) { add_void(x, y); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_result() -> i32 { get_result() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) { _ = wild_arg(_1, (), _3); } ================================================ FILE: src/tests/snapshots/swift_fn_box_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); int32_t _ffi_fn_check_nested(const void* buf_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_sum_tree(int32_t tree_value, const void* buf_ptr, _Bool has_tree_left, _Bool has_tree_right); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_box_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. class Tree : Equatable { var value: Int32 var left: Tree? var right: Tree? init(value: Int32, left: Tree?, right: Tree?) { self.value = value self.left = left self.right = right } static func == (a: Tree, b: Tree) -> Bool { return a.value == b.value && a.left == b.left && a.right == b.right } } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func sum_tree(_ tree: Tree) -> Int32 { var buf = ContiguousArray() let has_tree_left = tree.left != nil if let tree_left_val = tree.left { _ffi_box_Tree_to_rust(tree_left_val, &buf) } let has_tree_right = tree.right != nil if let tree_right_val = tree.right { _ffi_box_Tree_to_rust(tree_right_val, &buf) } return _ffi_fn_sum_tree(tree.value, _ffi_vec_to_rust(buf), has_tree_left, has_tree_right) } func check_nested(_ x: Int32) -> Int32 { var buf = ContiguousArray() _ffi_box_box_box_i32_to_rust(x, &buf) return _ffi_fn_check_nested(_ffi_vec_to_rust(buf)) } private func _ffi_box_Tree_to_rust(_ val: Tree, _ buf: inout ContiguousArray) { _ffi_write(val.value, &buf) _ffi_write(val.left != nil, &buf) if let val_left_val = val.left { _ffi_box_Tree_to_rust(val_left_val, &buf) } _ffi_write(val.right != nil, &buf) if let val_right_val = val.right { _ffi_box_Tree_to_rust(val_right_val, &buf) } } private func _ffi_box_box_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_box_box_i32_to_rust(val, &buf) } private func _ffi_box_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_box_i32_to_rust(val, &buf) } private func _ffi_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_box_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_from_swift(end: &mut *const u8) -> Box { Box::new(Tree { value: _ffi_read::(end), left: _ffi_read::(end).then(|| _ffi_box_Tree_from_swift(end)), right: _ffi_read::(end).then(|| _ffi_box_Tree_from_swift(end)) }) } fn _ffi_box_box_box_i32_from_swift(end: &mut *const u8) -> Box>> { Box::new(_ffi_box_box_i32_from_swift(end)) } fn _ffi_box_box_i32_from_swift(end: &mut *const u8) -> Box> { Box::new(_ffi_box_i32_from_swift(end)) } fn _ffi_box_i32_from_swift(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 { let mut buf_end = buf_ptr; let ret = check_nested(_ffi_box_box_box_i32_from_swift(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_tree_left: bool, has_tree_right: bool) -> i32 { let mut buf_end = buf_ptr; let ret = sum_tree(Tree { value: tree_value, left: has_tree_left.then(|| _ffi_box_Tree_from_swift(&mut buf_end)), right: has_tree_right.then(|| _ffi_box_Tree_from_swift(&mut buf_end)) }); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ================================================ FILE: src/tests/snapshots/swift_fn_box_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); int32_t _ffi_fn_check_nested(const void* buf_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_sum_tree(int32_t tree_value, const void* buf_ptr, _Bool has_tree_left, _Bool has_tree_right); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_box_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. class Tree : Equatable { var value: Int32 var left: Tree? var right: Tree? init(value: Int32, left: Tree?, right: Tree?) { self.value = value self.left = left self.right = right } static func == (a: Tree, b: Tree) -> Bool { return a.value == b.value && a.left == b.left && a.right == b.right } } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func sum_tree(_ tree: Tree) -> Int32 { var buf = ContiguousArray() let has_tree_left = tree.left != nil if let tree_left_val = tree.left { _ffi_box_Tree_to_rust(tree_left_val, &buf) } let has_tree_right = tree.right != nil if let tree_right_val = tree.right { _ffi_box_Tree_to_rust(tree_right_val, &buf) } return _ffi_fn_sum_tree(tree.value, _ffi_vec_to_rust(buf), has_tree_left, has_tree_right) } func check_nested(_ x: Int32) -> Int32 { var buf = ContiguousArray() _ffi_box_box_box_i32_to_rust(x, &buf) return _ffi_fn_check_nested(_ffi_vec_to_rust(buf)) } private func _ffi_box_Tree_to_rust(_ val: Tree, _ buf: inout ContiguousArray) { _ffi_write(val.value, &buf) _ffi_write(val.left != nil, &buf) if let val_left_val = val.left { _ffi_box_Tree_to_rust(val_left_val, &buf) } _ffi_write(val.right != nil, &buf) if let val_right_val = val.right { _ffi_box_Tree_to_rust(val_right_val, &buf) } } private func _ffi_box_box_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_box_box_i32_to_rust(val, &buf) } private func _ffi_box_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_box_i32_to_rust(val, &buf) } private func _ffi_box_i32_to_rust(_ val: Int32, _ buf: inout ContiguousArray) { _ffi_write(val, &buf) } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_box_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_from_swift(end: &mut *const u8) -> Box { Box::new(Tree { value: _ffi_read::(end), left: _ffi_read::(end).then(|| _ffi_box_Tree_from_swift(end)), right: _ffi_read::(end).then(|| _ffi_box_Tree_from_swift(end)) }) } fn _ffi_box_box_box_i32_from_swift(end: &mut *const u8) -> Box>> { Box::new(_ffi_box_box_i32_from_swift(end)) } fn _ffi_box_box_i32_from_swift(end: &mut *const u8) -> Box> { Box::new(_ffi_box_i32_from_swift(end)) } fn _ffi_box_i32_from_swift(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 { let mut buf_end = buf_ptr; let ret = check_nested(_ffi_box_box_box_i32_from_swift(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_tree_left: bool, has_tree_right: bool) -> i32 { let mut buf_end = buf_ptr; let ret = sum_tree(Tree { value: tree_value, left: has_tree_left.then(|| _ffi_box_Tree_from_swift(&mut buf_end)), right: has_tree_right.then(|| _ffi_box_Tree_from_swift(&mut buf_end)) }); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ================================================ FILE: src/tests/snapshots/swift_fn_box_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; _ffi_ret_ptr_usize _ffi_fn_check_nested(int32_t x); typedef struct { int32_t _0; const void* _1; uintptr_t _2; _Bool _3; _Bool _4; } _ffi_ret_i32_ptr_usize_2_bool; _ffi_ret_i32_ptr_usize_2_bool _ffi_fn_get_tree(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_box_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. class Tree : Equatable { var value: Int32 var left: Tree? var right: Tree? init(value: Int32, left: Tree?, right: Tree?) { self.value = value self.left = left self.right = right } static func == (a: Tree, b: Tree) -> Bool { return a.value == b.value && a.left == b.left && a.right == b.right } } struct Nested : Equatable { var _0: Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_tree() -> Tree { let multi_ret = _ffi_fn_get_tree() let ret_value = multi_ret._0 let buf_ptr = multi_ret._1 let buf_cap = multi_ret._2 let has_ret_left = multi_ret._3 let has_ret_right = multi_ret._4 var buf_end = buf_ptr! let ret = Tree( value: ret_value, left: has_ret_left ? _ffi_box_Tree_from_rust(&buf_end) : nil, right: has_ret_right ? _ffi_box_Tree_from_rust(&buf_end) : nil ) _ffi_dealloc(buf_ptr, buf_cap) return ret } func check_nested(_ x: Int32) -> Nested { let multi_ret = _ffi_fn_check_nested(x) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 var buf_end = buf_ptr! let ret = Nested(_0: _ffi_box_box_box_i32_from_rust(&buf_end)) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_box_Tree_from_rust(_ end: inout UnsafeRawPointer) -> Tree { return Tree( value: _ffi_read(&end) as Int32, left: _ffi_read(&end) as Bool ? _ffi_box_Tree_from_rust(&end) : nil, right: _ffi_read(&end) as Bool ? _ffi_box_Tree_from_rust(&end) : nil ) } private func _ffi_box_box_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_box_box_i32_from_rust(&end) } private func _ffi_box_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_box_i32_from_rust(&end) } private func _ffi_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_read(&end) as Int32 } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } ================================================ FILE: src/tests/snapshots/swift_fn_box_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_to_swift(val: Tree, buf: &mut Vec) { _ffi_write(val.value, buf); _ffi_write(val.left.is_some(), buf); if let Some(val_left_val) = val.left { _ffi_box_Tree_to_swift(*val_left_val, buf); } _ffi_write(val.right.is_some(), buf); if let Some(val_right_val) = val.right { _ffi_box_Tree_to_swift(*val_right_val, buf); } } fn _ffi_box_box_box_i32_to_swift(val: Box>, buf: &mut Vec) { _ffi_box_box_i32_to_swift(*val, buf); } fn _ffi_box_box_i32_to_swift(val: Box, buf: &mut Vec) { _ffi_box_i32_to_swift(*val, buf); } fn _ffi_box_i32_to_swift(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_nested(x: i32) -> _ffi_ret_ptr_usize { let ret = check_nested(x); let ret_0 = ret.0; let mut buf = Vec::::new(); _ffi_box_box_box_i32_to_swift(*ret_0, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_get_tree() -> _ffi_ret_i32_ptr_usize_2_bool { let ret = get_tree(); let ret_value = ret.value; let ret_left = ret.left; let mut buf = Vec::::new(); let has_ret_left = ret_left.is_some(); if let Some(ret_left_val) = ret_left { _ffi_box_Tree_to_swift(*ret_left_val, &mut buf); } let ret_right = ret.right; let has_ret_right = ret_right.is_some(); if let Some(ret_right_val) = ret_right { _ffi_box_Tree_to_swift(*ret_right_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_usize_2_bool(ret_value, buf_ptr, buf_cap, has_ret_left, has_ret_right) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_box_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; _ffi_ret_ptr_usize _ffi_fn_check_nested(int32_t x); typedef struct { int32_t _0; const void* _1; uintptr_t _2; _Bool _3; _Bool _4; } _ffi_ret_i32_ptr_usize_2_bool; _ffi_ret_i32_ptr_usize_2_bool _ffi_fn_get_tree(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_box_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. class Tree : Equatable { var value: Int32 var left: Tree? var right: Tree? init(value: Int32, left: Tree?, right: Tree?) { self.value = value self.left = left self.right = right } static func == (a: Tree, b: Tree) -> Bool { return a.value == b.value && a.left == b.left && a.right == b.right } } struct Nested : Equatable { var _0: Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_tree() -> Tree { let multi_ret = _ffi_fn_get_tree() let ret_value = multi_ret._0 let buf_ptr = multi_ret._1 let buf_cap = multi_ret._2 let has_ret_left = multi_ret._3 let has_ret_right = multi_ret._4 var buf_end = buf_ptr! let ret = Tree( value: ret_value, left: has_ret_left ? _ffi_box_Tree_from_rust(&buf_end) : nil, right: has_ret_right ? _ffi_box_Tree_from_rust(&buf_end) : nil ) _ffi_dealloc(buf_ptr, buf_cap) return ret } func check_nested(_ x: Int32) -> Nested { let multi_ret = _ffi_fn_check_nested(x) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 var buf_end = buf_ptr! let ret = Nested(_0: _ffi_box_box_box_i32_from_rust(&buf_end)) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_box_Tree_from_rust(_ end: inout UnsafeRawPointer) -> Tree { return Tree( value: _ffi_read(&end) as Int32, left: _ffi_read(&end) as Bool ? _ffi_box_Tree_from_rust(&end) : nil, right: _ffi_read(&end) as Bool ? _ffi_box_Tree_from_rust(&end) : nil ) } private func _ffi_box_box_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_box_box_i32_from_rust(&end) } private func _ffi_box_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_box_i32_from_rust(&end) } private func _ffi_box_i32_from_rust(_ end: inout UnsafeRawPointer) -> Int32 { return _ffi_read(&end) as Int32 } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } ================================================ FILE: src/tests/snapshots/swift_fn_box_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_to_swift(val: Tree, buf: &mut Vec) { _ffi_write(val.value, buf); _ffi_write(val.left.is_some(), buf); if let Some(val_left_val) = val.left { _ffi_box_Tree_to_swift(*val_left_val, buf); } _ffi_write(val.right.is_some(), buf); if let Some(val_right_val) = val.right { _ffi_box_Tree_to_swift(*val_right_val, buf); } } fn _ffi_box_box_box_i32_to_swift(val: Box>, buf: &mut Vec) { _ffi_box_box_i32_to_swift(*val, buf); } fn _ffi_box_box_i32_to_swift(val: Box, buf: &mut Vec) { _ffi_box_i32_to_swift(*val, buf); } fn _ffi_box_i32_to_swift(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(x: i32) -> _ffi_ret_ptr_usize { let ret = check_nested(x); let ret_0 = ret.0; let mut buf = Vec::::new(); _ffi_box_box_box_i32_to_swift(*ret_0, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_tree() -> _ffi_ret_i32_ptr_usize_2_bool { let ret = get_tree(); let ret_value = ret.value; let ret_left = ret.left; let mut buf = Vec::::new(); let has_ret_left = ret_left.is_some(); if let Some(ret_left_val) = ret_left { _ffi_box_Tree_to_swift(*ret_left_val, &mut buf); } let ret_right = ret.right; let has_ret_right = ret_right.is_some(); if let Some(ret_right_val) = ret_right { _ffi_box_Tree_to_swift(*ret_right_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_usize_2_bool(ret_value, buf_ptr, buf_cap, has_ret_left, has_ret_right) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_combo_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_check_combo(int32_t foo_x_0_x, const void* buf_ptr, uintptr_t foo_x_0_y_len, uintptr_t foo_x_1_len, uintptr_t foo_y_len); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_combo_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct Foo { var x: (Bar, [Bar]) var y: [((), Int32, (Float32, Bool))] } struct Bar { var x: Int32 var y: [Foo] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func check_combo(_ foo: Foo) -> String { var buf = ContiguousArray() let foo_x_0_y_len = UInt(foo.x.0.y.count) _ffi_vec_Foo_to_rust(foo.x.0.y, &buf) let foo_x_1_len = UInt(foo.x.1.count) _ffi_vec_Bar_to_rust(foo.x.1, &buf) let foo_y_len = UInt(foo.y.count) _ffi_vec__i32_f32_bool_to_rust(foo.y, &buf) let multi_ret = _ffi_fn_check_combo(foo.x.0.x, _ffi_vec_to_rust(buf), foo_x_0_y_len, foo_x_1_len, foo_y_len) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_vec_Bar_to_rust(_ items: [Bar], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.x, &buf) _ffi_write(UInt(item.y.count), &buf) _ffi_vec_Foo_to_rust(item.y, &buf) } } private func _ffi_vec_Foo_to_rust(_ items: [Foo], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.x.0.x, &buf) _ffi_write(UInt(item.x.0.y.count), &buf) _ffi_vec_Foo_to_rust(item.x.0.y, &buf) _ffi_write(UInt(item.x.1.count), &buf) _ffi_vec_Bar_to_rust(item.x.1, &buf) _ffi_write(UInt(item.y.count), &buf) _ffi_vec__i32_f32_bool_to_rust(item.y, &buf) } } private func _ffi_vec__i32_f32_bool_to_rust(_ items: [((), Int32, (Float32, Bool))], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.1, &buf) _ffi_write(item.2.0, &buf) _ffi_write(item.2.1, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_combo_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, foo_x_0_y_len: usize, foo_x_1_len: usize, foo_y_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_combo(Foo { x: ( Bar { x: foo_x_0_x, y: _ffi_vec_Foo_from_swift(foo_x_0_y_len, &mut buf_end) }, _ffi_vec_Bar_from_swift(foo_x_1_len, &mut buf_end) ), y: _ffi_vec__i32_f32_bool_from_swift(foo_y_len, &mut buf_end) })); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Bar_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_swift(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Foo { x: ( Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_swift(_ffi_read::(end), end) }, _ffi_vec_Bar_from_swift(_ffi_read::(end), end) ), y: _ffi_vec__i32_f32_bool_from_swift(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_from_swift(len: usize, end: &mut *const u8) -> Vec<((), (i32,), (f32, bool))> { let mut items = Vec::<((), (i32,), (f32, bool))>::with_capacity(len); for _ in 0..len { items.push(((), (_ffi_read::(end),), (_ffi_read::(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/swift_fn_combo_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_check_combo(int32_t foo_x_0_x, const void* buf_ptr, uintptr_t foo_x_0_y_len, uintptr_t foo_x_1_len, uintptr_t foo_y_len); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_combo_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct Foo { var x: (Bar, [Bar]) var y: [((), Int32, (Float32, Bool))] } struct Bar { var x: Int32 var y: [Foo] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func check_combo(_ foo: Foo) -> String { var buf = ContiguousArray() let foo_x_0_y_len = UInt(foo.x.0.y.count) _ffi_vec_Foo_to_rust(foo.x.0.y, &buf) let foo_x_1_len = UInt(foo.x.1.count) _ffi_vec_Bar_to_rust(foo.x.1, &buf) let foo_y_len = UInt(foo.y.count) _ffi_vec__i32_f32_bool_to_rust(foo.y, &buf) let multi_ret = _ffi_fn_check_combo(foo.x.0.x, _ffi_vec_to_rust(buf), foo_x_0_y_len, foo_x_1_len, foo_y_len) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_vec_Bar_to_rust(_ items: [Bar], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.x, &buf) _ffi_write(UInt(item.y.count), &buf) _ffi_vec_Foo_to_rust(item.y, &buf) } } private func _ffi_vec_Foo_to_rust(_ items: [Foo], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.x.0.x, &buf) _ffi_write(UInt(item.x.0.y.count), &buf) _ffi_vec_Foo_to_rust(item.x.0.y, &buf) _ffi_write(UInt(item.x.1.count), &buf) _ffi_vec_Bar_to_rust(item.x.1, &buf) _ffi_write(UInt(item.y.count), &buf) _ffi_vec__i32_f32_bool_to_rust(item.y, &buf) } } private func _ffi_vec__i32_f32_bool_to_rust(_ items: [((), Int32, (Float32, Bool))], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.1, &buf) _ffi_write(item.2.0, &buf) _ffi_write(item.2.1, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_combo_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, foo_x_0_y_len: usize, foo_x_1_len: usize, foo_y_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_combo(Foo { x: ( Bar { x: foo_x_0_x, y: _ffi_vec_Foo_from_swift(foo_x_0_y_len, &mut buf_end) }, _ffi_vec_Bar_from_swift(foo_x_1_len, &mut buf_end) ), y: _ffi_vec__i32_f32_bool_from_swift(foo_y_len, &mut buf_end) })); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Bar_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_swift(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Foo { x: ( Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_swift(_ffi_read::(end), end) }, _ffi_vec_Bar_from_swift(_ffi_read::(end), end) ), y: _ffi_vec__i32_f32_bool_from_swift(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_from_swift(len: usize, end: &mut *const u8) -> Vec<((), (i32,), (f32, bool))> { let mut items = Vec::<((), (i32,), (f32, bool))>::with_capacity(len); for _ in 0..len { items.push(((), (_ffi_read::(end),), (_ffi_read::(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/swift_fn_combo_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { int32_t _0; const void* _1; uintptr_t _2; uintptr_t _3; uintptr_t _4; uintptr_t _5; } _ffi_ret_i32_ptr_4_usize; _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo1(); _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo2(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_combo_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct Foo : Equatable { var x: (Bar, [Bar]) var y: [((), Int32, (Float32, Bool))] static func == (a: Foo, b: Foo) -> Bool { return ( a.x.0 == b.x.0 && a.x.1 == b.x.1 && a.y.elementsEqual(b.y, by: { a, b in a.1 == b.1 && a.2.0 == b.2.0 && a.2.1 == b.2.1 }) ) } } struct Bar : Equatable { var x: Int32 var y: [Foo] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func check_combo1() -> Foo { let multi_ret = _ffi_fn_check_combo1() let ret_x_0_x = multi_ret._0 let buf_ptr = multi_ret._1 let buf_cap = multi_ret._2 let ret_x_0_y_len = multi_ret._3 let ret_x_1_len = multi_ret._4 let ret_y_len = multi_ret._5 var buf_end = buf_ptr! let ret = Foo( x: ( Bar(x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(Int(ret_x_0_y_len), &buf_end)), _ffi_vec_Bar_from_rust(Int(ret_x_1_len), &buf_end) ), y: _ffi_vec__i32_f32_bool_from_rust(Int(ret_y_len), &buf_end) ) _ffi_dealloc(buf_ptr, buf_cap) return ret } func check_combo2() -> Foo { let multi_ret = _ffi_fn_check_combo2() let ret_x_0_x = multi_ret._0 let buf_ptr = multi_ret._1 let buf_cap = multi_ret._2 let ret_x_0_y_len = multi_ret._3 let ret_x_1_len = multi_ret._4 let ret_y_len = multi_ret._5 var buf_end = buf_ptr! let ret = Foo( x: ( Bar(x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(Int(ret_x_0_y_len), &buf_end)), _ffi_vec_Bar_from_rust(Int(ret_x_1_len), &buf_end) ), y: _ffi_vec__i32_f32_bool_from_rust(Int(ret_y_len), &buf_end) ) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_vec_Bar_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Bar] { var items: [Bar] = [] items.reserveCapacity(len) while items.count < len { items.append(Bar(x: _ffi_read(&end) as Int32, y: _ffi_vec_Foo_from_rust(Int(_ffi_read(&end) as UInt), &end))) } return items } private func _ffi_vec_Foo_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Foo] { var items: [Foo] = [] items.reserveCapacity(len) while items.count < len { items.append(Foo( x: ( Bar(x: _ffi_read(&end) as Int32, y: _ffi_vec_Foo_from_rust(Int(_ffi_read(&end) as UInt), &end)), _ffi_vec_Bar_from_rust(Int(_ffi_read(&end) as UInt), &end) ), y: _ffi_vec__i32_f32_bool_from_rust(Int(_ffi_read(&end) as UInt), &end) )) } return items } private func _ffi_vec__i32_f32_bool_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [((), Int32, (Float32, Bool))] { var items: [((), Int32, (Float32, Bool))] = [] items.reserveCapacity(len) while items.count < len { items.append(((), _ffi_read(&end) as Int32, (_ffi_read(&end) as Float32, _ffi_read(&end) as Bool))) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_combo_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_combo1() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo1(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_swift(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_swift(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_swift(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[no_mangle] extern "C" fn _ffi_fn_check_combo2() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo2(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_swift(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_swift(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_swift(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Bar_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x, buf); _ffi_write(item.y.len(), buf); _ffi_vec_Foo_to_swift(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec_Foo_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x.0.x, buf); _ffi_write(item.x.0.y.len(), buf); _ffi_vec_Foo_to_swift(item.x.0.y, buf); _ffi_write(item.x.1.len(), buf); _ffi_vec_Bar_to_swift(item.x.1, buf); _ffi_write(item.y.len(), buf); _ffi_vec__i32_f32_bool_to_swift(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_to_swift(items: Vec<((), (i32,), (f32, bool))>, buf: &mut Vec) { for item in items { _ = item.0; _ffi_write(item.1.0, buf); _ffi_write(item.2.0, buf); _ffi_write(item.2.1, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_combo_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { int32_t _0; const void* _1; uintptr_t _2; uintptr_t _3; uintptr_t _4; uintptr_t _5; } _ffi_ret_i32_ptr_4_usize; _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo1(); _ffi_ret_i32_ptr_4_usize _ffi_fn_check_combo2(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_combo_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct Foo : Equatable { var x: (Bar, [Bar]) var y: [((), Int32, (Float32, Bool))] static func == (a: Foo, b: Foo) -> Bool { return ( a.x.0 == b.x.0 && a.x.1 == b.x.1 && a.y.elementsEqual(b.y, by: { a, b in a.1 == b.1 && a.2.0 == b.2.0 && a.2.1 == b.2.1 }) ) } } struct Bar : Equatable { var x: Int32 var y: [Foo] } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func check_combo1() -> Foo { let multi_ret = _ffi_fn_check_combo1() let ret_x_0_x = multi_ret._0 let buf_ptr = multi_ret._1 let buf_cap = multi_ret._2 let ret_x_0_y_len = multi_ret._3 let ret_x_1_len = multi_ret._4 let ret_y_len = multi_ret._5 var buf_end = buf_ptr! let ret = Foo( x: ( Bar(x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(Int(ret_x_0_y_len), &buf_end)), _ffi_vec_Bar_from_rust(Int(ret_x_1_len), &buf_end) ), y: _ffi_vec__i32_f32_bool_from_rust(Int(ret_y_len), &buf_end) ) _ffi_dealloc(buf_ptr, buf_cap) return ret } func check_combo2() -> Foo { let multi_ret = _ffi_fn_check_combo2() let ret_x_0_x = multi_ret._0 let buf_ptr = multi_ret._1 let buf_cap = multi_ret._2 let ret_x_0_y_len = multi_ret._3 let ret_x_1_len = multi_ret._4 let ret_y_len = multi_ret._5 var buf_end = buf_ptr! let ret = Foo( x: ( Bar(x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(Int(ret_x_0_y_len), &buf_end)), _ffi_vec_Bar_from_rust(Int(ret_x_1_len), &buf_end) ), y: _ffi_vec__i32_f32_bool_from_rust(Int(ret_y_len), &buf_end) ) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_vec_Bar_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Bar] { var items: [Bar] = [] items.reserveCapacity(len) while items.count < len { items.append(Bar(x: _ffi_read(&end) as Int32, y: _ffi_vec_Foo_from_rust(Int(_ffi_read(&end) as UInt), &end))) } return items } private func _ffi_vec_Foo_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Foo] { var items: [Foo] = [] items.reserveCapacity(len) while items.count < len { items.append(Foo( x: ( Bar(x: _ffi_read(&end) as Int32, y: _ffi_vec_Foo_from_rust(Int(_ffi_read(&end) as UInt), &end)), _ffi_vec_Bar_from_rust(Int(_ffi_read(&end) as UInt), &end) ), y: _ffi_vec__i32_f32_bool_from_rust(Int(_ffi_read(&end) as UInt), &end) )) } return items } private func _ffi_vec__i32_f32_bool_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [((), Int32, (Float32, Bool))] { var items: [((), Int32, (Float32, Bool))] = [] items.reserveCapacity(len) while items.count < len { items.append(((), _ffi_read(&end) as Int32, (_ffi_read(&end) as Float32, _ffi_read(&end) as Bool))) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_combo_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo1() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo1(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_swift(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_swift(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_swift(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo2() -> _ffi_ret_i32_ptr_4_usize { let ret = check_combo2(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_swift(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_swift(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_swift(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Bar_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x, buf); _ffi_write(item.y.len(), buf); _ffi_vec_Foo_to_swift(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec_Foo_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x.0.x, buf); _ffi_write(item.x.0.y.len(), buf); _ffi_vec_Foo_to_swift(item.x.0.y, buf); _ffi_write(item.x.1.len(), buf); _ffi_vec_Bar_to_swift(item.x.1, buf); _ffi_write(item.y.len(), buf); _ffi_vec__i32_f32_bool_to_swift(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_to_swift(items: Vec<((), (i32,), (f32, bool))>, buf: &mut Vec) { for item in items { _ = item.0; _ffi_write(item.1.0, buf); _ffi_write(item.2.0, buf); _ffi_write(item.2.1, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_enum_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); int32_t _ffi_fn_big_to_i32(int32_t big_raw); int32_t _ffi_fn_foo_to_i32(int32_t foo_raw); void _ffi_fn_long_in(const void* buf_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_enum_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo: Int32 { case Zero = 0 case One = 1 case Hundred = 100 } enum Big: Int32 { case Min = -2147483648 case Max = 2147483647 } enum LongEnum { case Empty case ShortTuple(Int32) case ShortStruct(a: Int32) case LongTuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) case LongStruct(a: Int32, b: Int32, c: Int32, d: Int32, e: Int32, f: Int32) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func foo_to_i32(_ foo: Foo) -> Int32 { return _ffi_fn_foo_to_i32(foo.rawValue) } func big_to_i32(_ big: Big) -> Int32 { return _ffi_fn_big_to_i32(big.rawValue) } func long_in(_ _1: LongEnum) { var buf = ContiguousArray() _ffi_enum_LongEnum_to_rust(_1, &buf) _ffi_fn_long_in(_ffi_vec_to_rust(buf)) } private func _ffi_enum_LongEnum_to_rust(_ val: LongEnum, _ buf: inout ContiguousArray) { switch val { case .Empty: _ffi_write(0 as Int32, &buf) case let .ShortTuple(x): _ffi_write(1 as Int32, &buf) _ffi_write(x, &buf) case let .ShortStruct(a): _ffi_write(2 as Int32, &buf) _ffi_write(a, &buf) case let .LongTuple(x0, x1, x2, x3, x4, x5, x6, x7): _ffi_write(3 as Int32, &buf) _ffi_write(x0, &buf) _ffi_write(x1, &buf) _ffi_write(x2, &buf) _ffi_write(x3, &buf) _ffi_write(x4, &buf) _ffi_write(x5, &buf) _ffi_write(x6, &buf) _ffi_write(x7, &buf) case let .LongStruct(a, b, c, d, e, f): _ffi_write(4 as Int32, &buf) _ffi_write(a, &buf) _ffi_write(b, &buf) _ffi_write(c, &buf) _ffi_write(d, &buf) _ffi_write(e, &buf) _ffi_write(f, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_enum_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Big_from_swift(val: i32) -> Big { match val { -2147483648 => Big::Min, 2147483647 => Big::Max, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_swift(val: i32) -> Foo { match val { 0 => Foo::Zero, 1 => Foo::One, 100 => Foo::Hundred, _ => panic!(), } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_from_swift(end: &mut *const u8) -> LongEnum { match _ffi_read::(end) { 0 => LongEnum::Empty, 1 => LongEnum::ShortTuple(_ffi_read::(end)), 2 => LongEnum::ShortStruct { a: _ffi_read::(end) }, 3 => LongEnum::LongTuple( _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end) ), 4 => LongEnum::LongStruct { a: _ffi_read::(end), b: _ffi_read::(end), c: _ffi_read::(end), d: _ffi_read::(end), e: _ffi_read::(end), f: _ffi_read::(end) }, _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 { big_to_i32(_ffi_enum_Big_from_swift(big_raw)) } #[no_mangle] extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 { foo_to_i32(_ffi_enum_Foo_from_swift(foo_raw)) } #[no_mangle] extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) { let mut buf_end = buf_ptr; long_in(_ffi_enum_LongEnum_from_swift(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_fn_enum_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); int32_t _ffi_fn_big_to_i32(int32_t big_raw); int32_t _ffi_fn_foo_to_i32(int32_t foo_raw); void _ffi_fn_long_in(const void* buf_ptr); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_enum_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo: Int32 { case Zero = 0 case One = 1 case Hundred = 100 } enum Big: Int32 { case Min = -2147483648 case Max = 2147483647 } enum LongEnum { case Empty case ShortTuple(Int32) case ShortStruct(a: Int32) case LongTuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) case LongStruct(a: Int32, b: Int32, c: Int32, d: Int32, e: Int32, f: Int32) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func foo_to_i32(_ foo: Foo) -> Int32 { return _ffi_fn_foo_to_i32(foo.rawValue) } func big_to_i32(_ big: Big) -> Int32 { return _ffi_fn_big_to_i32(big.rawValue) } func long_in(_ _1: LongEnum) { var buf = ContiguousArray() _ffi_enum_LongEnum_to_rust(_1, &buf) _ffi_fn_long_in(_ffi_vec_to_rust(buf)) } private func _ffi_enum_LongEnum_to_rust(_ val: LongEnum, _ buf: inout ContiguousArray) { switch val { case .Empty: _ffi_write(0 as Int32, &buf) case let .ShortTuple(x): _ffi_write(1 as Int32, &buf) _ffi_write(x, &buf) case let .ShortStruct(a): _ffi_write(2 as Int32, &buf) _ffi_write(a, &buf) case let .LongTuple(x0, x1, x2, x3, x4, x5, x6, x7): _ffi_write(3 as Int32, &buf) _ffi_write(x0, &buf) _ffi_write(x1, &buf) _ffi_write(x2, &buf) _ffi_write(x3, &buf) _ffi_write(x4, &buf) _ffi_write(x5, &buf) _ffi_write(x6, &buf) _ffi_write(x7, &buf) case let .LongStruct(a, b, c, d, e, f): _ffi_write(4 as Int32, &buf) _ffi_write(a, &buf) _ffi_write(b, &buf) _ffi_write(c, &buf) _ffi_write(d, &buf) _ffi_write(e, &buf) _ffi_write(f, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_enum_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Big_from_swift(val: i32) -> Big { match val { -2147483648 => Big::Min, 2147483647 => Big::Max, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_swift(val: i32) -> Foo { match val { 0 => Foo::Zero, 1 => Foo::One, 100 => Foo::Hundred, _ => panic!(), } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_from_swift(end: &mut *const u8) -> LongEnum { match _ffi_read::(end) { 0 => LongEnum::Empty, 1 => LongEnum::ShortTuple(_ffi_read::(end)), 2 => LongEnum::ShortStruct { a: _ffi_read::(end) }, 3 => LongEnum::LongTuple( _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end) ), 4 => LongEnum::LongStruct { a: _ffi_read::(end), b: _ffi_read::(end), c: _ffi_read::(end), d: _ffi_read::(end), e: _ffi_read::(end), f: _ffi_read::(end) }, _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 { big_to_i32(_ffi_enum_Big_from_swift(big_raw)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 { foo_to_i32(_ffi_enum_Foo_from_swift(foo_raw)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) { let mut buf_end = buf_ptr; long_in(_ffi_enum_LongEnum_from_swift(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/swift_fn_enum_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); int32_t _ffi_fn_i32_to_big(int32_t big); int32_t _ffi_fn_i32_to_foo(int32_t foo); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; _ffi_ret_ptr_usize _ffi_fn_long_out(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_enum_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo: Int32 { case Zero = 0 case One = 1 case Hundred = 100 } enum Big: Int32 { case Min = -2147483648 case Max = 2147483647 } enum LongEnum { case Empty case ShortTuple(Int32) case ShortStruct(a: Int32) case LongTuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) case LongStruct(a: Int32, b: Int32, c: Int32, d: Int32, e: Int32, f: Int32) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func i32_to_foo(_ foo: Int32) -> Foo { let ret_raw = _ffi_fn_i32_to_foo(foo) return Foo(rawValue: ret_raw)! } func i32_to_big(_ big: Int32) -> Big { let ret_raw = _ffi_fn_i32_to_big(big) return Big(rawValue: ret_raw)! } func long_out() -> LongEnum { let multi_ret = _ffi_fn_long_out() let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 var buf_end = buf_ptr! let ret = _ffi_enum_LongEnum_from_rust(&buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_enum_LongEnum_from_rust(_ end: inout UnsafeRawPointer) -> LongEnum { switch _ffi_read(&end) as Int32 { case 0: return .Empty case 1: return .ShortTuple(_ffi_read(&end) as Int32) case 2: return .ShortStruct(a: _ffi_read(&end) as Int32) case 3: return .LongTuple( _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32 ) case 4: return .LongStruct( a: _ffi_read(&end) as Int32, b: _ffi_read(&end) as Int32, c: _ffi_read(&end) as Int32, d: _ffi_read(&end) as Int32, e: _ffi_read(&end) as Int32, f: _ffi_read(&end) as Int32 ) default: fatalError() } } ================================================ FILE: src/tests/snapshots/swift_fn_enum_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_to_swift(val: LongEnum, buf: &mut Vec) { match val { LongEnum::Empty => _ffi_write(0 as i32, buf), LongEnum::ShortTuple(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } LongEnum::ShortStruct { a } => { _ffi_write(2 as i32, buf); _ffi_write(a, buf); } LongEnum::LongTuple(x0, x1, x2, x3, x4, x5, x6, x7) => { _ffi_write(3 as i32, buf); _ffi_write(x0, buf); _ffi_write(x1, buf); _ffi_write(x2, buf); _ffi_write(x3, buf); _ffi_write(x4, buf); _ffi_write(x5, buf); _ffi_write(x6, buf); _ffi_write(x7, buf); } LongEnum::LongStruct { a, b, c, d, e, f } => { _ffi_write(4 as i32, buf); _ffi_write(a, buf); _ffi_write(b, buf); _ffi_write(c, buf); _ffi_write(d, buf); _ffi_write(e, buf); _ffi_write(f, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 { i32_to_big(big) as i32 } #[no_mangle] extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 { i32_to_foo(foo) as i32 } #[no_mangle] extern "C" fn _ffi_fn_long_out() -> _ffi_ret_ptr_usize { let mut buf = Vec::::new(); _ffi_enum_LongEnum_to_swift(long_out(), &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); ================================================ FILE: src/tests/snapshots/swift_fn_enum_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); int32_t _ffi_fn_i32_to_big(int32_t big); int32_t _ffi_fn_i32_to_foo(int32_t foo); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; _ffi_ret_ptr_usize _ffi_fn_long_out(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_enum_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo: Int32 { case Zero = 0 case One = 1 case Hundred = 100 } enum Big: Int32 { case Min = -2147483648 case Max = 2147483647 } enum LongEnum { case Empty case ShortTuple(Int32) case ShortStruct(a: Int32) case LongTuple(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) case LongStruct(a: Int32, b: Int32, c: Int32, d: Int32, e: Int32, f: Int32) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func i32_to_foo(_ foo: Int32) -> Foo { let ret_raw = _ffi_fn_i32_to_foo(foo) return Foo(rawValue: ret_raw)! } func i32_to_big(_ big: Int32) -> Big { let ret_raw = _ffi_fn_i32_to_big(big) return Big(rawValue: ret_raw)! } func long_out() -> LongEnum { let multi_ret = _ffi_fn_long_out() let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 var buf_end = buf_ptr! let ret = _ffi_enum_LongEnum_from_rust(&buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_enum_LongEnum_from_rust(_ end: inout UnsafeRawPointer) -> LongEnum { switch _ffi_read(&end) as Int32 { case 0: return .Empty case 1: return .ShortTuple(_ffi_read(&end) as Int32) case 2: return .ShortStruct(a: _ffi_read(&end) as Int32) case 3: return .LongTuple( _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32, _ffi_read(&end) as Int32 ) case 4: return .LongStruct( a: _ffi_read(&end) as Int32, b: _ffi_read(&end) as Int32, c: _ffi_read(&end) as Int32, d: _ffi_read(&end) as Int32, e: _ffi_read(&end) as Int32, f: _ffi_read(&end) as Int32 ) default: fatalError() } } ================================================ FILE: src/tests/snapshots/swift_fn_enum_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_to_swift(val: LongEnum, buf: &mut Vec) { match val { LongEnum::Empty => _ffi_write(0 as i32, buf), LongEnum::ShortTuple(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } LongEnum::ShortStruct { a } => { _ffi_write(2 as i32, buf); _ffi_write(a, buf); } LongEnum::LongTuple(x0, x1, x2, x3, x4, x5, x6, x7) => { _ffi_write(3 as i32, buf); _ffi_write(x0, buf); _ffi_write(x1, buf); _ffi_write(x2, buf); _ffi_write(x3, buf); _ffi_write(x4, buf); _ffi_write(x5, buf); _ffi_write(x6, buf); _ffi_write(x7, buf); } LongEnum::LongStruct { a, b, c, d, e, f } => { _ffi_write(4 as i32, buf); _ffi_write(a, buf); _ffi_write(b, buf); _ffi_write(c, buf); _ffi_write(d, buf); _ffi_write(e, buf); _ffi_write(f, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 { i32_to_big(big) as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 { i32_to_foo(foo) as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_long_out() -> _ffi_ret_ptr_usize { let mut buf = Vec::::new(); _ffi_enum_LongEnum_to_swift(long_out(), &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize(buf_ptr, buf_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); ================================================ FILE: src/tests/snapshots/swift_fn_nested_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test(int32_t x_0, const void* x_1_ptr_ptr, const void* buf_ptr, uintptr_t x_2_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_nested_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Bar: AnyObject { func get() -> Int32 } struct Foo { var empty: () var ptr: Bar } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test(_ x: (Int32, Foo, [(Int32, Foo)])) -> Int32 { let x_1_ptr_ptr = UnsafeRawPointer(Unmanaged.passRetained(x.1.ptr as AnyObject).toOpaque()) var buf = ContiguousArray() let x_2_len = UInt(x.2.count) _ffi_vec_i32_Foo_to_rust(x.2, &buf) return _ffi_fn_test(x.0, x_1_ptr_ptr, _ffi_vec_to_rust(buf), x_2_len) } @_cdecl("_ffi_swift_Bar__get") func _ffi_swift_Bar__get(_self: UnsafeRawPointer?) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Bar return _self.get() } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } private func _ffi_vec_i32_Foo_to_rust(_ items: [(Int32, Foo)], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.0, &buf) _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item.1.ptr as AnyObject).toOpaque()), &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_nested_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *const u8, x_2_len: usize) -> i32 { let x_1 = Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(x_1_ptr_ptr)) }; let mut buf_end = buf_ptr; let ret = test((x_0, x_1, _ffi_vec_i32_Foo_from_swift(x_2_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_camel_case_types)] struct _ffi_rs_Bar(*const u8); impl Drop for _ffi_rs_Bar { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Bar for _ffi_rs_Bar { fn get(&self) -> i32 { extern "C" { fn _ffi_swift_Bar__get(_: *const u8) -> i32; } unsafe { _ffi_swift_Bar__get(self.0) } } } #[allow(non_snake_case)] fn _ffi_vec_i32_Foo_from_swift(len: usize, end: &mut *const u8) -> Vec<(i32, Foo)> { let mut items = Vec::<(i32, Foo)>::with_capacity(len); for _ in 0..len { items.push(( _ffi_read::(end), Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(_ffi_read::<*const u8>(end))) } )); } items } ================================================ FILE: src/tests/snapshots/swift_fn_nested_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_test(int32_t x_0, const void* x_1_ptr_ptr, const void* buf_ptr, uintptr_t x_2_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_nested_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Bar: AnyObject { func get() -> Int32 } struct Foo { var empty: () var ptr: Bar } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test(_ x: (Int32, Foo, [(Int32, Foo)])) -> Int32 { let x_1_ptr_ptr = UnsafeRawPointer(Unmanaged.passRetained(x.1.ptr as AnyObject).toOpaque()) var buf = ContiguousArray() let x_2_len = UInt(x.2.count) _ffi_vec_i32_Foo_to_rust(x.2, &buf) return _ffi_fn_test(x.0, x_1_ptr_ptr, _ffi_vec_to_rust(buf), x_2_len) } @_cdecl("_ffi_swift_Bar__get") func _ffi_swift_Bar__get(_self: UnsafeRawPointer?) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Bar return _self.get() } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } private func _ffi_vec_i32_Foo_to_rust(_ items: [(Int32, Foo)], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item.0, &buf) _ffi_write(UnsafeRawPointer(Unmanaged.passRetained(item.1.ptr as AnyObject).toOpaque()), &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_nested_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *const u8, x_2_len: usize) -> i32 { let x_1 = Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(x_1_ptr_ptr)) }; let mut buf_end = buf_ptr; let ret = test((x_0, x_1, _ffi_vec_i32_Foo_from_swift(x_2_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_camel_case_types)] struct _ffi_rs_Bar(*const u8); impl Drop for _ffi_rs_Bar { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Bar for _ffi_rs_Bar { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_swift_Bar__get(_: *const u8) -> i32; } unsafe { _ffi_swift_Bar__get(self.0) } } } #[allow(non_snake_case)] fn _ffi_vec_i32_Foo_from_swift(len: usize, end: &mut *const u8) -> Vec<(i32, Foo)> { let mut items = Vec::<(i32, Foo)>::with_capacity(len); for _ in 0..len { items.push(( _ffi_read::(end), Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(_ffi_read::<*const u8>(end))) } )); } items } ================================================ FILE: src/tests/snapshots/swift_fn_nested_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Bar__get(const void*); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { int32_t _0; const void* _1; } _ffi_ret_i32_ptr; _ffi_ret_i32_ptr _ffi_fn_test(int32_t x); void _ffi_rs_drop_Rc_Bar(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_nested_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Bar: AnyObject { func get() -> Int32 } struct Foo { var ptr: Bar } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test(_ x: Int32) -> (Int32, Foo) { let multi_ret = _ffi_fn_test(x) let ret_0 = multi_ret._0 let ret_1_ptr_ptr = multi_ret._1 return (ret_0, Foo(ptr: _ffi_Rc_Bar(ret_1_ptr_ptr))) } private class _ffi_Rc_Bar : Bar { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Bar(_ffi) } func get() -> Int32 { return _ffi_Rc_Bar__get(_ffi) } } ================================================ FILE: src/tests/snapshots/swift_fn_nested_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(x: i32) -> _ffi_ret_i32_ptr { let ret = test(x); let ret_0 = ret.0; let ret_1 = ret.1; _ffi_ret_i32_ptr(ret_0, Box::into_raw(Box::new(ret_1.ptr)) as *const u8) } #[repr(C)] struct _ffi_ret_i32_ptr(i32, *const u8); #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Bar(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_fn_nested_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Bar__get(const void*); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { int32_t _0; const void* _1; } _ffi_ret_i32_ptr; _ffi_ret_i32_ptr _ffi_fn_test(int32_t x); void _ffi_rs_drop_Rc_Bar(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_nested_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Bar: AnyObject { func get() -> Int32 } struct Foo { var ptr: Bar } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func test(_ x: Int32) -> (Int32, Foo) { let multi_ret = _ffi_fn_test(x) let ret_0 = multi_ret._0 let ret_1_ptr_ptr = multi_ret._1 return (ret_0, Foo(ptr: _ffi_Rc_Bar(ret_1_ptr_ptr))) } private class _ffi_Rc_Bar : Bar { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Bar(_ffi) } func get() -> Int32 { return _ffi_Rc_Bar__get(_ffi) } } ================================================ FILE: src/tests/snapshots/swift_fn_nested_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(x: i32) -> _ffi_ret_i32_ptr { let ret = test(x); let ret_0 = ret.0; let ret_1 = ret.1; _ffi_ret_i32_ptr(ret_0, Box::into_raw(Box::new(ret_1.ptr)) as *const u8) } #[repr(C)] struct _ffi_ret_i32_ptr(i32, *const u8); #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Bar(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_fn_option_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); int32_t _ffi_fn_add_all(const void* buf_ptr, uintptr_t x_len); int32_t _ffi_fn_add_nested(const void* buf_ptr, _Bool has_x, _Bool has_y); int32_t _ffi_fn_add_option(const void* buf_ptr, _Bool has_x, _Bool has_y); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_join_all(const void* buf_ptr, uintptr_t x_len); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_option_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func add_option(_ x: Int32?, _ y: Int32?) -> Int32 { var buf = ContiguousArray() let has_x = x != nil if let x_val = x { _ffi_write(x_val, &buf) } let has_y = y != nil if let y_val = y { _ffi_write(y_val, &buf) } return _ffi_fn_add_option(_ffi_vec_to_rust(buf), has_x, has_y) } func add_nested(_ x: Int32??, _ y: Int32??) -> Int32 { var buf = ContiguousArray() let has_x = x != nil if let x_val = x { _ffi_write(x_val != nil, &buf) if let x_val_val = x_val { _ffi_write(x_val_val, &buf) } } let has_y = y != nil if let y_val = y { _ffi_write(y_val != nil, &buf) if let y_val_val = y_val { _ffi_write(y_val_val, &buf) } } return _ffi_fn_add_nested(_ffi_vec_to_rust(buf), has_x, has_y) } func add_all(_ x: [Int32?]) -> Int32 { var buf = ContiguousArray() let x_len = UInt(x.count) _ffi_vec_option_i32_to_rust(x, &buf) return _ffi_fn_add_all(_ffi_vec_to_rust(buf), x_len) } func join_all(_ x: [String?]) -> String { var buf = ContiguousArray() let x_len = UInt(x.count) _ffi_vec_option_string_to_rust(x, &buf) let multi_ret = _ffi_fn_join_all(_ffi_vec_to_rust(buf), x_len) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } private func _ffi_vec_option_i32_to_rust(_ items: [Int32?], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item != nil, &buf) if let item_val = item { _ffi_write(item_val, &buf) } } } private func _ffi_vec_option_string_to_rust(_ items: [String?], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item != nil, &buf) if let item_val = item { let (item_val_ptr, item_val_len) = _ffi_string_to_rust(item_val); _ffi_write(item_val_ptr, &buf) _ffi_write(item_val_len, &buf) } } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_option_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = add_all(_ffi_vec_option_i32_from_swift(x_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_nested( has_x.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))), has_y.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))) ); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_option(has_x.then(|| _ffi_read::(&mut buf_end)), has_y.then(|| _ffi_read::(&mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(join_all(_ffi_vec_option_string_from_swift(x_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_read::(end))); } items } fn _ffi_vec_option_string_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/swift_fn_option_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); int32_t _ffi_fn_add_all(const void* buf_ptr, uintptr_t x_len); int32_t _ffi_fn_add_nested(const void* buf_ptr, _Bool has_x, _Bool has_y); int32_t _ffi_fn_add_option(const void* buf_ptr, _Bool has_x, _Bool has_y); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_join_all(const void* buf_ptr, uintptr_t x_len); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_option_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func add_option(_ x: Int32?, _ y: Int32?) -> Int32 { var buf = ContiguousArray() let has_x = x != nil if let x_val = x { _ffi_write(x_val, &buf) } let has_y = y != nil if let y_val = y { _ffi_write(y_val, &buf) } return _ffi_fn_add_option(_ffi_vec_to_rust(buf), has_x, has_y) } func add_nested(_ x: Int32??, _ y: Int32??) -> Int32 { var buf = ContiguousArray() let has_x = x != nil if let x_val = x { _ffi_write(x_val != nil, &buf) if let x_val_val = x_val { _ffi_write(x_val_val, &buf) } } let has_y = y != nil if let y_val = y { _ffi_write(y_val != nil, &buf) if let y_val_val = y_val { _ffi_write(y_val_val, &buf) } } return _ffi_fn_add_nested(_ffi_vec_to_rust(buf), has_x, has_y) } func add_all(_ x: [Int32?]) -> Int32 { var buf = ContiguousArray() let x_len = UInt(x.count) _ffi_vec_option_i32_to_rust(x, &buf) return _ffi_fn_add_all(_ffi_vec_to_rust(buf), x_len) } func join_all(_ x: [String?]) -> String { var buf = ContiguousArray() let x_len = UInt(x.count) _ffi_vec_option_string_to_rust(x, &buf) let multi_ret = _ffi_fn_join_all(_ffi_vec_to_rust(buf), x_len) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } private func _ffi_vec_option_i32_to_rust(_ items: [Int32?], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item != nil, &buf) if let item_val = item { _ffi_write(item_val, &buf) } } } private func _ffi_vec_option_string_to_rust(_ items: [String?], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item != nil, &buf) if let item_val = item { let (item_val_ptr, item_val_len) = _ffi_string_to_rust(item_val); _ffi_write(item_val_ptr, &buf) _ffi_write(item_val_len, &buf) } } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_option_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = add_all(_ffi_vec_option_i32_from_swift(x_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_nested( has_x.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))), has_y.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))) ); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_option(has_x.then(|| _ffi_read::(&mut buf_end)), has_y.then(|| _ffi_read::(&mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(join_all(_ffi_vec_option_string_from_swift(x_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_read::(end))); } items } fn _ffi_vec_option_string_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/swift_fn_option_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; _Bool _2; } _ffi_ret_ptr_usize_bool; _ffi_ret_ptr_usize_bool _ffi_fn_opt_int(_Bool x, int32_t y); _ffi_ret_ptr_usize_bool _ffi_fn_opt_opt_int(_Bool x, _Bool y, int32_t z); _ffi_ret_ptr_usize_bool _ffi_fn_opt_vec_opt_string(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_vec_opt_int(int32_t n); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_option_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func opt_int(_ x: Bool, _ y: Int32) -> Int32? { let multi_ret = _ffi_fn_opt_int(x, y) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let has_ret = multi_ret._2 var buf_end = buf_ptr! let ret = has_ret ? _ffi_read(&buf_end) as Int32 : nil _ffi_dealloc(buf_ptr, buf_cap) return ret } func opt_opt_int(_ x: Bool, _ y: Bool, _ z: Int32) -> Int32?? { let multi_ret = _ffi_fn_opt_opt_int(x, y, z) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let has_ret = multi_ret._2 var buf_end = buf_ptr! let ret = has_ret ? Optional.some(_ffi_read(&buf_end) as Bool ? _ffi_read(&buf_end) as Int32 : nil) : nil _ffi_dealloc(buf_ptr, buf_cap) return ret } func vec_opt_int(_ n: Int32) -> [Int32?] { let multi_ret = _ffi_fn_vec_opt_int(n) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_option_i32_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } func opt_vec_opt_string(_ n: Int32) -> [String?]? { let multi_ret = _ffi_fn_opt_vec_opt_string(n) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let has_ret = multi_ret._2 var buf_end = buf_ptr! let ret = has_ret ? _ffi_vec_option_string_from_rust(Int(_ffi_read(&buf_end) as UInt), &buf_end) : nil _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_vec_option_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32?] { var items: [Int32?] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Bool ? _ffi_read(&end) as Int32 : nil) } return items } private func _ffi_vec_option_string_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [String?] { var items: [String?] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Bool ? _ffi_string_from_rust(_ffi_read(&end) as UnsafeRawPointer?, Int(_ffi_read(&end) as UInt), _ffi_read(&end) as UInt) : nil) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_option_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_int(x, y); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[no_mangle] extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_opt_int(x, y, z); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.is_some(), &mut buf); if let Some(ret_val_val) = ret_val { _ffi_write(ret_val_val, &mut buf); } } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[no_mangle] extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_vec_opt_string(n); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.len(), &mut buf); _ffi_vec_option_string_to_swift(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> _ffi_ret_ptr_2_usize { let ret = vec_opt_int(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_option_i32_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { _ffi_write(item_val, buf); } } } fn _ffi_vec_option_string_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { let (item_val_ptr, item_val_len, item_val_cap) = _ffi_string_to_host(item_val); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); _ffi_write(item_val_cap, buf); } } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_option_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; _Bool _2; } _ffi_ret_ptr_usize_bool; _ffi_ret_ptr_usize_bool _ffi_fn_opt_int(_Bool x, int32_t y); _ffi_ret_ptr_usize_bool _ffi_fn_opt_opt_int(_Bool x, _Bool y, int32_t z); _ffi_ret_ptr_usize_bool _ffi_fn_opt_vec_opt_string(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_vec_opt_int(int32_t n); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_option_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func opt_int(_ x: Bool, _ y: Int32) -> Int32? { let multi_ret = _ffi_fn_opt_int(x, y) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let has_ret = multi_ret._2 var buf_end = buf_ptr! let ret = has_ret ? _ffi_read(&buf_end) as Int32 : nil _ffi_dealloc(buf_ptr, buf_cap) return ret } func opt_opt_int(_ x: Bool, _ y: Bool, _ z: Int32) -> Int32?? { let multi_ret = _ffi_fn_opt_opt_int(x, y, z) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let has_ret = multi_ret._2 var buf_end = buf_ptr! let ret = has_ret ? Optional.some(_ffi_read(&buf_end) as Bool ? _ffi_read(&buf_end) as Int32 : nil) : nil _ffi_dealloc(buf_ptr, buf_cap) return ret } func vec_opt_int(_ n: Int32) -> [Int32?] { let multi_ret = _ffi_fn_vec_opt_int(n) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_option_i32_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } func opt_vec_opt_string(_ n: Int32) -> [String?]? { let multi_ret = _ffi_fn_opt_vec_opt_string(n) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let has_ret = multi_ret._2 var buf_end = buf_ptr! let ret = has_ret ? _ffi_vec_option_string_from_rust(Int(_ffi_read(&buf_end) as UInt), &buf_end) : nil _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_vec_option_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32?] { var items: [Int32?] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Bool ? _ffi_read(&end) as Int32 : nil) } return items } private func _ffi_vec_option_string_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [String?] { var items: [String?] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Bool ? _ffi_string_from_rust(_ffi_read(&end) as UnsafeRawPointer?, Int(_ffi_read(&end) as UInt), _ffi_read(&end) as UInt) : nil) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_option_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_int(x, y); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_opt_int(x, y, z); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.is_some(), &mut buf); if let Some(ret_val_val) = ret_val { _ffi_write(ret_val_val, &mut buf); } } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> _ffi_ret_ptr_usize_bool { let ret = opt_vec_opt_string(n); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.len(), &mut buf); _ffi_vec_option_string_to_swift(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> _ffi_ret_ptr_2_usize { let ret = vec_opt_int(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_option_i32_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { _ffi_write(item_val, buf); } } } fn _ffi_vec_option_string_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { let (item_val_ptr, item_val_len, item_val_cap) = _ffi_string_to_host(item_val); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); _ffi_write(item_val_cap, buf); } } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_payload_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); _Bool _ffi_fn_set_tests(const void* buf_ptr, uintptr_t tests_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_payload_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo : Equatable { case Empty case Single(Int32) case Point(x: Int32, y: Int32) indirect case Nested(Foo) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_tests(_ tests: [Foo]) -> Bool { var buf = ContiguousArray() let tests_len = UInt(tests.count) _ffi_vec_Foo_to_rust(tests, &buf) return _ffi_fn_set_tests(_ffi_vec_to_rust(buf), tests_len) } private func _ffi_box_Foo_to_rust(_ val: Foo, _ buf: inout ContiguousArray) { _ffi_enum_Foo_to_rust(val, &buf) } private func _ffi_enum_Foo_to_rust(_ val: Foo, _ buf: inout ContiguousArray) { switch val { case .Empty: _ffi_write(0 as Int32, &buf) case let .Single(x): _ffi_write(1 as Int32, &buf) _ffi_write(x, &buf) case let .Point(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) case let .Nested(x): _ffi_write(3 as Int32, &buf) _ffi_box_Foo_to_rust(x, &buf) } } private func _ffi_vec_Foo_to_rust(_ items: [Foo], _ buf: inout ContiguousArray) { for item in items { _ffi_enum_Foo_to_rust(item, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_payload_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_from_swift(end: &mut *const u8) -> Box { Box::new(_ffi_enum_Foo_from_swift(end)) } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_swift(end: &mut *const u8) -> Foo { match _ffi_read::(end) { 0 => Foo::Empty, 1 => Foo::Single(_ffi_read::(end)), 2 => Foo::Point { x: _ffi_read::(end), y: _ffi_read::(end) }, 3 => Foo::Nested(_ffi_box_Foo_from_swift(end)), _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) -> bool { let mut buf_end = buf_ptr; let ret = set_tests(_ffi_vec_Foo_from_swift(tests_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_enum_Foo_from_swift(end)); } items } ================================================ FILE: src/tests/snapshots/swift_fn_payload_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); uintptr_t _ffi_fn_rust_mem_leaked(); _Bool _ffi_fn_set_tests(const void* buf_ptr, uintptr_t tests_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_payload_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo : Equatable { case Empty case Single(Int32) case Point(x: Int32, y: Int32) indirect case Nested(Foo) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_tests(_ tests: [Foo]) -> Bool { var buf = ContiguousArray() let tests_len = UInt(tests.count) _ffi_vec_Foo_to_rust(tests, &buf) return _ffi_fn_set_tests(_ffi_vec_to_rust(buf), tests_len) } private func _ffi_box_Foo_to_rust(_ val: Foo, _ buf: inout ContiguousArray) { _ffi_enum_Foo_to_rust(val, &buf) } private func _ffi_enum_Foo_to_rust(_ val: Foo, _ buf: inout ContiguousArray) { switch val { case .Empty: _ffi_write(0 as Int32, &buf) case let .Single(x): _ffi_write(1 as Int32, &buf) _ffi_write(x, &buf) case let .Point(x, y): _ffi_write(2 as Int32, &buf) _ffi_write(x, &buf) _ffi_write(y, &buf) case let .Nested(x): _ffi_write(3 as Int32, &buf) _ffi_box_Foo_to_rust(x, &buf) } } private func _ffi_vec_Foo_to_rust(_ items: [Foo], _ buf: inout ContiguousArray) { for item in items { _ffi_enum_Foo_to_rust(item, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_payload_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_from_swift(end: &mut *const u8) -> Box { Box::new(_ffi_enum_Foo_from_swift(end)) } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_swift(end: &mut *const u8) -> Foo { match _ffi_read::(end) { 0 => Foo::Empty, 1 => Foo::Single(_ffi_read::(end)), 2 => Foo::Point { x: _ffi_read::(end), y: _ffi_read::(end) }, 3 => Foo::Nested(_ffi_box_Foo_from_swift(end)), _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) -> bool { let mut buf_end = buf_ptr; let ret = set_tests(_ffi_vec_Foo_from_swift(tests_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_enum_Foo_from_swift(end)); } items } ================================================ FILE: src/tests/snapshots/swift_fn_payload_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_get_tests(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_payload_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo : Equatable { case Empty case Single(Int32) case Point(x: Int32, y: Int32) indirect case Nested(Foo) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_tests() -> [Foo] { let multi_ret = _ffi_fn_get_tests() let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_Foo_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_box_Foo_from_rust(_ end: inout UnsafeRawPointer) -> Foo { return _ffi_enum_Foo_from_rust(&end) } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_enum_Foo_from_rust(_ end: inout UnsafeRawPointer) -> Foo { switch _ffi_read(&end) as Int32 { case 0: return .Empty case 1: return .Single(_ffi_read(&end) as Int32) case 2: return .Point(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) case 3: return .Nested(_ffi_box_Foo_from_rust(&end)) default: fatalError() } } private func _ffi_vec_Foo_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Foo] { var items: [Foo] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_enum_Foo_from_rust(&end)) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_payload_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_to_swift(val: Foo, buf: &mut Vec) { _ffi_enum_Foo_to_swift(val, buf); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Foo_to_swift(val: Foo, buf: &mut Vec) { match val { Foo::Empty => _ffi_write(0 as i32, buf), Foo::Single(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } Foo::Point { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } Foo::Nested(x) => { _ffi_write(3 as i32, buf); _ffi_box_Foo_to_swift(*x, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_get_tests() -> _ffi_ret_ptr_2_usize { let ret = get_tests(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Foo_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Foo_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_enum_Foo_to_swift(item, buf); } } ================================================ FILE: src/tests/snapshots/swift_fn_payload_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_get_tests(); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_payload_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. enum Foo : Equatable { case Empty case Single(Int32) case Point(x: Int32, y: Int32) indirect case Nested(Foo) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_tests() -> [Foo] { let multi_ret = _ffi_fn_get_tests() let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_Foo_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_box_Foo_from_rust(_ end: inout UnsafeRawPointer) -> Foo { return _ffi_enum_Foo_from_rust(&end) } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_enum_Foo_from_rust(_ end: inout UnsafeRawPointer) -> Foo { switch _ffi_read(&end) as Int32 { case 0: return .Empty case 1: return .Single(_ffi_read(&end) as Int32) case 2: return .Point(x: _ffi_read(&end) as Int32, y: _ffi_read(&end) as Int32) case 3: return .Nested(_ffi_box_Foo_from_rust(&end)) default: fatalError() } } private func _ffi_vec_Foo_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Foo] { var items: [Foo] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_enum_Foo_from_rust(&end)) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_payload_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_to_swift(val: Foo, buf: &mut Vec) { _ffi_enum_Foo_to_swift(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Foo_to_swift(val: Foo, buf: &mut Vec) { match val { Foo::Empty => _ffi_write(0 as i32, buf), Foo::Single(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } Foo::Point { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } Foo::Nested(x) => { _ffi_write(3 as i32, buf); _ffi_box_Foo_to_swift(*x, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_tests() -> _ffi_ret_ptr_2_usize { let ret = get_tests(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Foo_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[allow(non_snake_case)] fn _ffi_vec_Foo_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_enum_Foo_to_swift(item, buf); } } ================================================ FILE: src/tests/snapshots/swift_fn_string_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_get_string(); int32_t _ffi_fn_get_string_len(); void _ffi_fn_reset(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_set_str(const void* x_ptr, uintptr_t x_len); void _ffi_fn_set_string(const void* x_ptr, uintptr_t x_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_string_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func reset() { _ffi_fn_reset() } func get_string_len() -> Int32 { return _ffi_fn_get_string_len() } func get_string() -> String { let multi_ret = _ffi_fn_get_string() let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } func set_string(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_fn_set_string(x_ptr, x_len) } func set_str(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_fn_set_str(x_ptr, x_len) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } ================================================ FILE: src/tests/snapshots/swift_fn_string_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_get_string() -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_get_string_len() -> i32 { get_string_len() } #[no_mangle] extern "C" fn _ffi_fn_reset() { reset(); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) { set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) { set_string(_ffi_string_from_host(x_ptr, x_len)); } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/swift_fn_string_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_get_string(); int32_t _ffi_fn_get_string_len(); void _ffi_fn_reset(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_fn_set_str(const void* x_ptr, uintptr_t x_len); void _ffi_fn_set_string(const void* x_ptr, uintptr_t x_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_string_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func reset() { _ffi_fn_reset() } func get_string_len() -> Int32 { return _ffi_fn_get_string_len() } func get_string() -> String { let multi_ret = _ffi_fn_get_string() let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } func set_string(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_fn_set_string(x_ptr, x_len) } func set_str(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_fn_set_str(x_ptr, x_len) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } ================================================ FILE: src/tests/snapshots/swift_fn_string_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_string() -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_string_len() -> i32 { get_string_len() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_reset() { reset(); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) { set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) { set_string(_ffi_string_from_host(x_ptr, x_len)); } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_x, float ab_y, float cd_x, float cd_y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_struct_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct EmptyStruct { } struct SingleElementStruct { var _0: Int32 } struct PairStruct { var x: Float32 var y: Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_tuple(_ x: Int32, _ foo: EmptyStruct, _ y: Int32) -> Int32 { return _ffi_fn_empty_tuple(x, y) } func single_element_tuple(_ x: SingleElementStruct, _ y: SingleElementStruct) -> Int32 { return _ffi_fn_single_element_tuple(x._0, y._0) } func multiply_pairs(_ ab: PairStruct, _ cd: PairStruct) -> Float32 { return _ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, EmptyStruct, y) } #[no_mangle] extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32 { multiply_pairs(PairStruct { x: ab_x, y: ab_y }, PairStruct { x: cd_x, y: cd_y }) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple(SingleElementStruct(x_0), SingleElementStruct(y_0)) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_x, float ab_y, float cd_x, float cd_y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_struct_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct EmptyStruct { } struct SingleElementStruct { var _0: Int32 } struct PairStruct { var x: Float32 var y: Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_tuple(_ x: Int32, _ foo: EmptyStruct, _ y: Int32) -> Int32 { return _ffi_fn_empty_tuple(x, y) } func single_element_tuple(_ x: SingleElementStruct, _ y: SingleElementStruct) -> Int32 { return _ffi_fn_single_element_tuple(x._0, y._0) } func multiply_pairs(_ ab: PairStruct, _ cd: PairStruct) -> Float32 { return _ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, EmptyStruct, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32 { multiply_pairs(PairStruct { x: ab_x, y: ab_y }, PairStruct { x: cd_x, y: cd_y }) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple(SingleElementStruct(x_0), SingleElementStruct(y_0)) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_fn_empty_struct(); typedef struct { float _0; float _1; } _ffi_ret_2_f32; _ffi_ret_2_f32 _ffi_fn_make_pair(float x, float y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_struct(int32_t x); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_struct_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct EmptyStruct : Equatable { } struct SingleElementStruct : Equatable { var _0: Int32 } struct PairStruct : Equatable { var x: Float32 var y: Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_struct() -> EmptyStruct { _ffi_fn_empty_struct() return EmptyStruct() } func single_element_struct(_ x: Int32) -> SingleElementStruct { let ret_0 = _ffi_fn_single_element_struct(x) return SingleElementStruct(_0: ret_0) } func make_pair(_ x: Float32, _ y: Float32) -> PairStruct { let multi_ret = _ffi_fn_make_pair(x, y) let ret_x = multi_ret._0 let ret_y = multi_ret._1 return PairStruct(x: ret_x, y: ret_y) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(); } #[no_mangle] extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> _ffi_ret_2_f32 { let ret = make_pair(x, y); _ffi_ret_2_f32(ret.x, ret.y) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 { let ret = single_element_struct(x); ret.0 } #[repr(C)] struct _ffi_ret_2_f32(f32, f32); ================================================ FILE: src/tests/snapshots/swift_fn_struct_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_fn_empty_struct(); typedef struct { float _0; float _1; } _ffi_ret_2_f32; _ffi_ret_2_f32 _ffi_fn_make_pair(float x, float y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_struct(int32_t x); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_struct_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. struct EmptyStruct : Equatable { } struct SingleElementStruct : Equatable { var _0: Int32 } struct PairStruct : Equatable { var x: Float32 var y: Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_struct() -> EmptyStruct { _ffi_fn_empty_struct() return EmptyStruct() } func single_element_struct(_ x: Int32) -> SingleElementStruct { let ret_0 = _ffi_fn_single_element_struct(x) return SingleElementStruct(_0: ret_0) } func make_pair(_ x: Float32, _ y: Float32) -> PairStruct { let multi_ret = _ffi_fn_make_pair(x, y) let ret_x = multi_ret._0 let ret_y = multi_ret._1 return PairStruct(x: ret_x, y: ret_y) } ================================================ FILE: src/tests/snapshots/swift_fn_struct_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> _ffi_ret_2_f32 { let ret = make_pair(x, y); _ffi_ret_2_f32(ret.x, ret.y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 { let ret = single_element_struct(x); ret.0 } #[repr(C)] struct _ffi_ret_2_f32(f32, f32); ================================================ FILE: src/tests/snapshots/swift_fn_tuple_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_0, float ab_1, float cd_0, float cd_1); int32_t _ffi_fn_nesting(int32_t x_0, int32_t x_2_0, int32_t x_2_1_0); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_tuple_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_tuple(_ x: Int32, _ foo: (), _ y: Int32) -> Int32 { return _ffi_fn_empty_tuple(x, y) } func single_element_tuple(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_fn_single_element_tuple(x, y) } func multiply_pairs(_ ab: (Float32, Float32), _ cd: (Float32, Float32)) -> Float32 { return _ffi_fn_multiply_pairs(ab.0, ab.1, cd.0, cd.1) } func nesting(_ x: (Int32, (), (Int32, Int32))) -> Int32 { return _ffi_fn_nesting(x.0, x.2.0, x.2.1) } ================================================ FILE: src/tests/snapshots/swift_fn_tuple_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, (), y) } #[no_mangle] extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32 { multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } #[no_mangle] extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 { nesting((x_0, (), (x_2_0, (x_2_1_0,)))) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple((x_0,), (y_0,)) } ================================================ FILE: src/tests/snapshots/swift_fn_tuple_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_fn_empty_tuple(int32_t x, int32_t y); float _ffi_fn_multiply_pairs(float ab_0, float ab_1, float cd_0, float cd_1); int32_t _ffi_fn_nesting(int32_t x_0, int32_t x_2_0, int32_t x_2_1_0); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x_0, int32_t y_0); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_tuple_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func empty_tuple(_ x: Int32, _ foo: (), _ y: Int32) -> Int32 { return _ffi_fn_empty_tuple(x, y) } func single_element_tuple(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_fn_single_element_tuple(x, y) } func multiply_pairs(_ ab: (Float32, Float32), _ cd: (Float32, Float32)) -> Float32 { return _ffi_fn_multiply_pairs(ab.0, ab.1, cd.0, cd.1) } func nesting(_ x: (Int32, (), (Int32, Int32))) -> Int32 { return _ffi_fn_nesting(x.0, x.2.0, x.2.1) } ================================================ FILE: src/tests/snapshots/swift_fn_tuple_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, (), y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32 { multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 { nesting((x_0, (), (x_2_0, (x_2_1_0,)))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple((x_0,), (y_0,)) } ================================================ FILE: src/tests/snapshots/swift_fn_tuple_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif typedef struct { float _0; _Bool _1; } _ffi_ret_f32_bool; _ffi_ret_f32_bool _ffi_fn_return_pair(float x, _Bool y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_tuple_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func single_element_tuple(_ x: Int32) -> Int32 { let ret_0 = _ffi_fn_single_element_tuple(x) return ret_0 } func return_pair(_ x: Float32, _ y: Bool) -> (Float32, Bool) { let multi_ret = _ffi_fn_return_pair(x, y) let ret_0 = multi_ret._0 let ret_1 = multi_ret._1 return (ret_0, ret_1) } ================================================ FILE: src/tests/snapshots/swift_fn_tuple_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> _ffi_ret_f32_bool { let ret = return_pair(x, y); _ffi_ret_f32_bool(ret.0, ret.1) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 { let ret = single_element_tuple(x); ret.0 } #[repr(C)] struct _ffi_ret_f32_bool(f32, bool); ================================================ FILE: src/tests/snapshots/swift_fn_tuple_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif typedef struct { float _0; _Bool _1; } _ffi_ret_f32_bool; _ffi_ret_f32_bool _ffi_fn_return_pair(float x, _Bool y); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_single_element_tuple(int32_t x); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_tuple_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func single_element_tuple(_ x: Int32) -> Int32 { let ret_0 = _ffi_fn_single_element_tuple(x) return ret_0 } func return_pair(_ x: Float32, _ y: Bool) -> (Float32, Bool) { let multi_ret = _ffi_fn_return_pair(x, y) let ret_0 = multi_ret._0 let ret_1 = multi_ret._1 return (ret_0, ret_1) } ================================================ FILE: src/tests/snapshots/swift_fn_tuple_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> _ffi_ret_f32_bool { let ret = return_pair(x, y); _ffi_ret_f32_bool(ret.0, ret.1) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 { let ret = single_element_tuple(x); ret.0 } #[repr(C)] struct _ffi_ret_f32_bool(f32, bool); ================================================ FILE: src/tests/snapshots/swift_fn_vec_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_check_nested(const void* buf_ptr, uintptr_t values_len); uintptr_t _ffi_fn_rust_mem_leaked(); float _ffi_fn_sum_f32(const void* buf_ptr, uintptr_t values_len); double _ffi_fn_sum_f64(const void* buf_ptr, uintptr_t values_len); int16_t _ffi_fn_sum_i16(const void* buf_ptr, uintptr_t values_len); int32_t _ffi_fn_sum_i32(const void* buf_ptr, uintptr_t values_len); int64_t _ffi_fn_sum_i64(const void* buf_ptr, uintptr_t values_len); int8_t _ffi_fn_sum_i8(const void* buf_ptr, uintptr_t values_len); intptr_t _ffi_fn_sum_isize(const void* buf_ptr, uintptr_t values_len); uint16_t _ffi_fn_sum_u16(const void* buf_ptr, uintptr_t values_len); uint32_t _ffi_fn_sum_u32(const void* buf_ptr, uintptr_t values_len); uint64_t _ffi_fn_sum_u64(const void* buf_ptr, uintptr_t values_len); uint8_t _ffi_fn_sum_u8(const void* buf_ptr, uintptr_t values_len); uintptr_t _ffi_fn_sum_usize(const void* buf_ptr, uintptr_t values_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_vec_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func sum_u8(_ values: [UInt8]) -> UInt8 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u8_to_rust(values, &buf) return _ffi_fn_sum_u8(_ffi_vec_to_rust(buf), values_len) } func sum_u16(_ values: [UInt16]) -> UInt16 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u16_to_rust(values, &buf) return _ffi_fn_sum_u16(_ffi_vec_to_rust(buf), values_len) } func sum_u32(_ values: [UInt32]) -> UInt32 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u32_to_rust(values, &buf) return _ffi_fn_sum_u32(_ffi_vec_to_rust(buf), values_len) } func sum_usize(_ values: [UInt]) -> UInt { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_usize_to_rust(values, &buf) return _ffi_fn_sum_usize(_ffi_vec_to_rust(buf), values_len) } func sum_u64(_ values: [UInt64]) -> UInt64 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u64_to_rust(values, &buf) return _ffi_fn_sum_u64(_ffi_vec_to_rust(buf), values_len) } func sum_i8(_ values: [Int8]) -> Int8 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i8_to_rust(values, &buf) return _ffi_fn_sum_i8(_ffi_vec_to_rust(buf), values_len) } func sum_i16(_ values: [Int16]) -> Int16 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i16_to_rust(values, &buf) return _ffi_fn_sum_i16(_ffi_vec_to_rust(buf), values_len) } func sum_i32(_ values: [Int32]) -> Int32 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i32_to_rust(values, &buf) return _ffi_fn_sum_i32(_ffi_vec_to_rust(buf), values_len) } func sum_isize(_ values: [Int]) -> Int { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_isize_to_rust(values, &buf) return _ffi_fn_sum_isize(_ffi_vec_to_rust(buf), values_len) } func sum_i64(_ values: [Int64]) -> Int64 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i64_to_rust(values, &buf) return _ffi_fn_sum_i64(_ffi_vec_to_rust(buf), values_len) } func sum_f32(_ values: [Float32]) -> Float32 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_f32_to_rust(values, &buf) return _ffi_fn_sum_f32(_ffi_vec_to_rust(buf), values_len) } func sum_f64(_ values: [Float64]) -> Float64 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_f64_to_rust(values, &buf) return _ffi_fn_sum_f64(_ffi_vec_to_rust(buf), values_len) } func check_nested(_ values: [[Int32]]) -> String { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_vec_i32_to_rust(values, &buf) let multi_ret = _ffi_fn_check_nested(_ffi_vec_to_rust(buf), values_len) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_vec_f32_to_rust(_ items: [Float32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_f64_to_rust(_ items: [Float64], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i16_to_rust(_ items: [Int16], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i32_to_rust(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i64_to_rust(_ items: [Int64], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i8_to_rust(_ items: [Int8], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_isize_to_rust(_ items: [Int], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_vec_u16_to_rust(_ items: [UInt16], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_u32_to_rust(_ items: [UInt32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_u64_to_rust(_ items: [UInt64], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_u8_to_rust(_ items: [UInt8], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_usize_to_rust(_ items: [UInt], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_vec_i32_to_rust(_ items: [[Int32]], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UInt(item.count), &buf) _ffi_vec_i32_to_rust(item, &buf) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_vec_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_nested(_ffi_vec_vec_i32_from_swift(values_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> f32 { let mut buf_end = buf_ptr; let ret = sum_f32(_ffi_vec_f32_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> f64 { let mut buf_end = buf_ptr; let ret = sum_f64(_ffi_vec_f64_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> i16 { let mut buf_end = buf_ptr; let ret = sum_i16(_ffi_vec_i16_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = sum_i32(_ffi_vec_i32_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> i64 { let mut buf_end = buf_ptr; let ret = sum_i64(_ffi_vec_i64_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 { let mut buf_end = buf_ptr; let ret = sum_i8(_ffi_vec_i8_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -> isize { let mut buf_end = buf_ptr; let ret = sum_isize(_ffi_vec_isize_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> u16 { let mut buf_end = buf_ptr; let ret = sum_u16(_ffi_vec_u16_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> u32 { let mut buf_end = buf_ptr; let ret = sum_u32(_ffi_vec_u32_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> u64 { let mut buf_end = buf_ptr; let ret = sum_u64(_ffi_vec_u64_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 { let mut buf_end = buf_ptr; let ret = sum_u8(_ffi_vec_u8_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -> usize { let mut buf_end = buf_ptr; let ret = sum_usize(_ffi_vec_usize_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_f32_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_f64_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i16_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i64_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i8_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_isize_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u16_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u32_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u64_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u8_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_usize_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_vec_i32_from_swift(_ffi_read::(end), end)); } items } ================================================ FILE: src/tests/snapshots/swift_fn_vec_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_check_nested(const void* buf_ptr, uintptr_t values_len); uintptr_t _ffi_fn_rust_mem_leaked(); float _ffi_fn_sum_f32(const void* buf_ptr, uintptr_t values_len); double _ffi_fn_sum_f64(const void* buf_ptr, uintptr_t values_len); int16_t _ffi_fn_sum_i16(const void* buf_ptr, uintptr_t values_len); int32_t _ffi_fn_sum_i32(const void* buf_ptr, uintptr_t values_len); int64_t _ffi_fn_sum_i64(const void* buf_ptr, uintptr_t values_len); int8_t _ffi_fn_sum_i8(const void* buf_ptr, uintptr_t values_len); intptr_t _ffi_fn_sum_isize(const void* buf_ptr, uintptr_t values_len); uint16_t _ffi_fn_sum_u16(const void* buf_ptr, uintptr_t values_len); uint32_t _ffi_fn_sum_u32(const void* buf_ptr, uintptr_t values_len); uint64_t _ffi_fn_sum_u64(const void* buf_ptr, uintptr_t values_len); uint8_t _ffi_fn_sum_u8(const void* buf_ptr, uintptr_t values_len); uintptr_t _ffi_fn_sum_usize(const void* buf_ptr, uintptr_t values_len); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_vec_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func sum_u8(_ values: [UInt8]) -> UInt8 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u8_to_rust(values, &buf) return _ffi_fn_sum_u8(_ffi_vec_to_rust(buf), values_len) } func sum_u16(_ values: [UInt16]) -> UInt16 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u16_to_rust(values, &buf) return _ffi_fn_sum_u16(_ffi_vec_to_rust(buf), values_len) } func sum_u32(_ values: [UInt32]) -> UInt32 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u32_to_rust(values, &buf) return _ffi_fn_sum_u32(_ffi_vec_to_rust(buf), values_len) } func sum_usize(_ values: [UInt]) -> UInt { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_usize_to_rust(values, &buf) return _ffi_fn_sum_usize(_ffi_vec_to_rust(buf), values_len) } func sum_u64(_ values: [UInt64]) -> UInt64 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_u64_to_rust(values, &buf) return _ffi_fn_sum_u64(_ffi_vec_to_rust(buf), values_len) } func sum_i8(_ values: [Int8]) -> Int8 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i8_to_rust(values, &buf) return _ffi_fn_sum_i8(_ffi_vec_to_rust(buf), values_len) } func sum_i16(_ values: [Int16]) -> Int16 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i16_to_rust(values, &buf) return _ffi_fn_sum_i16(_ffi_vec_to_rust(buf), values_len) } func sum_i32(_ values: [Int32]) -> Int32 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i32_to_rust(values, &buf) return _ffi_fn_sum_i32(_ffi_vec_to_rust(buf), values_len) } func sum_isize(_ values: [Int]) -> Int { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_isize_to_rust(values, &buf) return _ffi_fn_sum_isize(_ffi_vec_to_rust(buf), values_len) } func sum_i64(_ values: [Int64]) -> Int64 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_i64_to_rust(values, &buf) return _ffi_fn_sum_i64(_ffi_vec_to_rust(buf), values_len) } func sum_f32(_ values: [Float32]) -> Float32 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_f32_to_rust(values, &buf) return _ffi_fn_sum_f32(_ffi_vec_to_rust(buf), values_len) } func sum_f64(_ values: [Float64]) -> Float64 { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_f64_to_rust(values, &buf) return _ffi_fn_sum_f64(_ffi_vec_to_rust(buf), values_len) } func check_nested(_ values: [[Int32]]) -> String { var buf = ContiguousArray() let values_len = UInt(values.count) _ffi_vec_vec_i32_to_rust(values, &buf) let multi_ret = _ffi_fn_check_nested(_ffi_vec_to_rust(buf), values_len) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_vec_f32_to_rust(_ items: [Float32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_f64_to_rust(_ items: [Float64], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i16_to_rust(_ items: [Int16], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i32_to_rust(_ items: [Int32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i64_to_rust(_ items: [Int64], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_i8_to_rust(_ items: [Int8], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_isize_to_rust(_ items: [Int], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_to_rust(_ vec: ContiguousArray) -> UnsafeRawPointer? { vec.withUnsafeBytes { vec in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count)) return UnsafeRawPointer(buf.baseAddress) } } private func _ffi_vec_u16_to_rust(_ items: [UInt16], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_u32_to_rust(_ items: [UInt32], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_u64_to_rust(_ items: [UInt64], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_u8_to_rust(_ items: [UInt8], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_usize_to_rust(_ items: [UInt], _ buf: inout ContiguousArray) { for item in items { _ffi_write(item, &buf) } } private func _ffi_vec_vec_i32_to_rust(_ items: [[Int32]], _ buf: inout ContiguousArray) { for item in items { _ffi_write(UInt(item.count), &buf) _ffi_vec_i32_to_rust(item, &buf) } } private func _ffi_write(_ val: T, _ buf: inout ContiguousArray) { var val = val withUnsafeBytes(of: &val) { val in buf.append(contentsOf: val) } } ================================================ FILE: src/tests/snapshots/swift_fn_vec_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize) -> _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_nested(_ffi_vec_vec_i32_from_swift(values_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> f32 { let mut buf_end = buf_ptr; let ret = sum_f32(_ffi_vec_f32_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> f64 { let mut buf_end = buf_ptr; let ret = sum_f64(_ffi_vec_f64_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> i16 { let mut buf_end = buf_ptr; let ret = sum_i16(_ffi_vec_i16_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = sum_i32(_ffi_vec_i32_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> i64 { let mut buf_end = buf_ptr; let ret = sum_i64(_ffi_vec_i64_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 { let mut buf_end = buf_ptr; let ret = sum_i8(_ffi_vec_i8_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -> isize { let mut buf_end = buf_ptr; let ret = sum_isize(_ffi_vec_isize_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> u16 { let mut buf_end = buf_ptr; let ret = sum_u16(_ffi_vec_u16_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> u32 { let mut buf_end = buf_ptr; let ret = sum_u32(_ffi_vec_u32_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> u64 { let mut buf_end = buf_ptr; let ret = sum_u64(_ffi_vec_u64_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 { let mut buf_end = buf_ptr; let ret = sum_u8(_ffi_vec_u8_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -> usize { let mut buf_end = buf_ptr; let ret = sum_usize(_ffi_vec_usize_from_swift(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_f32_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_f64_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i16_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i64_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i8_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_isize_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u16_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u32_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u64_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u8_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_usize_from_swift(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_vec_i32_from_swift(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_vec_i32_from_swift(_ffi_read::(end), end)); } items } ================================================ FILE: src/tests/snapshots/swift_fn_vec_out_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_check_nested(); _ffi_ret_ptr_2_usize _ffi_fn_get_vec(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_vec_out_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_vec(_ n: Int32) -> [Int32] { let multi_ret = _ffi_fn_get_vec(n) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_i32_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } func check_nested() -> [[Int32]] { let multi_ret = _ffi_fn_check_nested() let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_vec_i32_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Int32) } return items } private func _ffi_vec_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [[Int32]] { var items: [[Int32]] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_vec_i32_from_rust(Int(_ffi_read(&end) as UInt), &end)) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_vec_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_nested() -> _ffi_ret_ptr_2_usize { let ret = check_nested(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_vec_i32_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[no_mangle] extern "C" fn _ffi_fn_get_vec(n: i32) -> _ffi_ret_ptr_2_usize { let ret = get_vec(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_i32_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_vec_i32_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } fn _ffi_vec_vec_i32_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.len(), buf); _ffi_vec_i32_to_swift(item, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_fn_vec_out_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif void _ffi_dealloc(const void* ptr, uintptr_t capacity); typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_fn_check_nested(); _ffi_ret_ptr_2_usize _ffi_fn_get_vec(int32_t n); uintptr_t _ffi_fn_rust_mem_leaked(); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_fn_vec_out_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_vec(_ n: Int32) -> [Int32] { let multi_ret = _ffi_fn_get_vec(n) let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_i32_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } func check_nested() -> [[Int32]] { let multi_ret = _ffi_fn_check_nested() let buf_ptr = multi_ret._0 let buf_cap = multi_ret._1 let ret_len = multi_ret._2 var buf_end = buf_ptr! let ret = _ffi_vec_vec_i32_from_rust(Int(ret_len), &buf_end) _ffi_dealloc(buf_ptr, buf_cap) return ret } private func _ffi_read(_ ptr: inout UnsafeRawPointer) -> T { let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self) ptr = ptr.advanced(by: MemoryLayout.size) return val } private func _ffi_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [Int32] { var items: [Int32] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_read(&end) as Int32) } return items } private func _ffi_vec_vec_i32_from_rust(_ len: Int, _ end: inout UnsafeRawPointer) -> [[Int32]] { var items: [[Int32]] = [] items.reserveCapacity(len) while items.count < len { items.append(_ffi_vec_i32_from_rust(Int(_ffi_read(&end) as UInt), &end)) } return items } ================================================ FILE: src/tests/snapshots/swift_fn_vec_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested() -> _ffi_ret_ptr_2_usize { let ret = check_nested(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_vec_i32_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_vec(n: i32) -> _ffi_ret_ptr_2_usize { let ret = get_vec(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_i32_to_swift(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); fn _ffi_vec_i32_to_swift(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } fn _ffi_vec_vec_i32_to_swift(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.len(), buf); _ffi_vec_i32_to_swift(item, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/swift_trait_enum_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Box_Foo__get_enum(const void*); void _ffi_Box_Foo__set_enum(const void*, int32_t bar_raw); const void* _ffi_fn_get_foo(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Box_Foo(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_enum_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Foo: AnyObject { func set_enum(_ bar: Bar) func get_enum() -> Bar } enum Bar: Int32 { case A = 0 case B = 1 case C = 2 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_foo() -> Foo { let ret_ptr = _ffi_fn_get_foo() return _ffi_Box_Foo(ret_ptr) } private class _ffi_Box_Foo : Foo { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Foo(_ffi) } func set_enum(_ bar: Bar) { _ffi_Box_Foo__set_enum(_ffi, bar.rawValue) } func get_enum() -> Bar { let ret_raw = _ffi_Box_Foo__get_enum(_ffi) return Bar(rawValue: ret_raw)! } } ================================================ FILE: src/tests/snapshots/swift_trait_enum_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get_enum() as i32 } #[no_mangle] extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) { let _self = unsafe { &*(_self as *const Box) }; _self.set_enum(_ffi_enum_Bar_from_swift(bar_raw)); } #[allow(non_snake_case)] fn _ffi_enum_Bar_from_swift(val: i32) -> Bar { match val { 0 => Bar::A, 1 => Bar::B, 2 => Bar::C, _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_get_foo() -> *const u8 { Box::into_raw(Box::new(get_foo())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Foo(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } ================================================ FILE: src/tests/snapshots/swift_trait_enum_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Box_Foo__get_enum(const void*); void _ffi_Box_Foo__set_enum(const void*, int32_t bar_raw); const void* _ffi_fn_get_foo(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Box_Foo(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_enum_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Foo: AnyObject { func set_enum(_ bar: Bar) func get_enum() -> Bar } enum Bar: Int32 { case A = 0 case B = 1 case C = 2 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_foo() -> Foo { let ret_ptr = _ffi_fn_get_foo() return _ffi_Box_Foo(ret_ptr) } private class _ffi_Box_Foo : Foo { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Foo(_ffi) } func set_enum(_ bar: Bar) { _ffi_Box_Foo__set_enum(_ffi, bar.rawValue) } func get_enum() -> Bar { let ret_raw = _ffi_Box_Foo__get_enum(_ffi) return Bar(rawValue: ret_raw)! } } ================================================ FILE: src/tests/snapshots/swift_trait_enum_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get_enum() as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) { let _self = unsafe { &*(_self as *const Box) }; _self.set_enum(_ffi_enum_Bar_from_swift(bar_raw)); } #[allow(non_snake_case)] fn _ffi_enum_Bar_from_swift(val: i32) -> Bar { match val { 0 => Bar::A, 1 => Bar::B, 2 => Bar::C, _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_foo() -> *const u8 { Box::into_raw(Box::new(get_foo())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Foo(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } ================================================ FILE: src/tests/snapshots/swift_trait_export_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Box_Adder__add(const void*, int32_t x); int32_t _ffi_Rc_Adder__add(const void*, int32_t x); const void* _ffi_fn_get_adder_box(int32_t x); const void* _ffi_fn_get_adder_rc(int32_t x); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Box_Adder(const void* ptr); void _ffi_rs_drop_Rc_Adder(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_export_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Adder: AnyObject { func add(_ x: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_counter() -> UInt32 { return _ffi_fn_get_counter() } func get_adder_rc(_ x: Int32) -> Adder { let ret_ptr = _ffi_fn_get_adder_rc(x) return _ffi_Rc_Adder(ret_ptr) } func get_adder_box(_ x: Int32) -> Adder { let ret_ptr = _ffi_fn_get_adder_box(x) return _ffi_Box_Adder(ret_ptr) } private class _ffi_Box_Adder : Adder { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Adder(_ffi) } func add(_ x: Int32) -> Int32 { return _ffi_Box_Adder__add(_ffi, x) } } private class _ffi_Rc_Adder : Adder { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Adder(_ffi) } func add(_ x: Int32) -> Int32 { return _ffi_Rc_Adder__add(_ffi, x) } } ================================================ FILE: src/tests/snapshots/swift_trait_export_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.add(x) } #[no_mangle] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x) } #[no_mangle] extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_box(x))) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_rc(x))) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_export_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Box_Adder__add(const void*, int32_t x); int32_t _ffi_Rc_Adder__add(const void*, int32_t x); const void* _ffi_fn_get_adder_box(int32_t x); const void* _ffi_fn_get_adder_rc(int32_t x); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Box_Adder(const void* ptr); void _ffi_rs_drop_Rc_Adder(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_export_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Adder: AnyObject { func add(_ x: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_counter() -> UInt32 { return _ffi_fn_get_counter() } func get_adder_rc(_ x: Int32) -> Adder { let ret_ptr = _ffi_fn_get_adder_rc(x) return _ffi_Rc_Adder(ret_ptr) } func get_adder_box(_ x: Int32) -> Adder { let ret_ptr = _ffi_fn_get_adder_box(x) return _ffi_Box_Adder(ret_ptr) } private class _ffi_Box_Adder : Adder { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Box_Adder(_ffi) } func add(_ x: Int32) -> Int32 { return _ffi_Box_Adder__add(_ffi, x) } } private class _ffi_Rc_Adder : Adder { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Adder(_ffi) } func add(_ x: Int32) -> Int32 { return _ffi_Rc_Adder__add(_ffi, x) } } ================================================ FILE: src/tests/snapshots/swift_trait_export_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.add(x) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_box(x))) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_rc(x))) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_export_import_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Exported__run(const void*, const void* imported_ptr); uint32_t _ffi_fn_get_counter(); const void* _ffi_fn_get_exported(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Rc_Exported(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_export_import_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Imported: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } protocol Exported: AnyObject { func run(_ imported: Imported) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_exported() -> Exported { let ret_ptr = _ffi_fn_get_exported() return _ffi_Rc_Exported(ret_ptr) } func get_counter() -> UInt32 { return _ffi_fn_get_counter() } private class _ffi_Rc_Exported : Exported { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Exported(_ffi) } func run(_ imported: Imported) -> Int32 { return _ffi_Rc_Exported__run(_ffi, UnsafeRawPointer(Unmanaged.passRetained(imported as AnyObject).toOpaque())) } } @_cdecl("_ffi_swift_Imported__add") func _ffi_swift_Imported__add(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Imported return _self.add(x, y) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_export_import_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.run(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_get_exported() -> *const u8 { Box::into_raw(Box::new(get_exported())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn add(&self, x: i32, y: i32) -> i32 { extern "C" { fn _ffi_swift_Imported__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_swift_Imported__add(self.0, x, y) } } } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_export_import_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Exported__run(const void*, const void* imported_ptr); uint32_t _ffi_fn_get_counter(); const void* _ffi_fn_get_exported(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Rc_Exported(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_export_import_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Imported: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } protocol Exported: AnyObject { func run(_ imported: Imported) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_exported() -> Exported { let ret_ptr = _ffi_fn_get_exported() return _ffi_Rc_Exported(ret_ptr) } func get_counter() -> UInt32 { return _ffi_fn_get_counter() } private class _ffi_Rc_Exported : Exported { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Exported(_ffi) } func run(_ imported: Imported) -> Int32 { return _ffi_Rc_Exported__run(_ffi, UnsafeRawPointer(Unmanaged.passRetained(imported as AnyObject).toOpaque())) } } @_cdecl("_ffi_swift_Imported__add") func _ffi_swift_Imported__add(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Imported return _self.add(x, y) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_export_import_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.run(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_exported() -> *const u8 { Box::into_raw(Box::new(get_exported())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn add(&self, x: i32, y: i32) -> i32 { unsafe extern "C" { fn _ffi_swift_Imported__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_swift_Imported__add(self.0, x, y) } } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_export_nested_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Adder__add(const void*, int32_t x, int32_t y); const void* _ffi_Rc_Getter__get_adder(const void*); uint32_t _ffi_fn_get_adder_counter(); const void* _ffi_fn_get_getter(); uint32_t _ffi_fn_get_getter_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Rc_Adder(const void* ptr); void _ffi_rs_drop_Rc_Getter(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_export_nested_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Getter: AnyObject { func get_adder() -> Adder } protocol Adder: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_getter_counter() -> UInt32 { return _ffi_fn_get_getter_counter() } func get_adder_counter() -> UInt32 { return _ffi_fn_get_adder_counter() } func get_getter() -> Getter { let ret_ptr = _ffi_fn_get_getter() return _ffi_Rc_Getter(ret_ptr) } private class _ffi_Rc_Adder : Adder { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Adder(_ffi) } func add(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_Rc_Adder__add(_ffi, x, y) } } private class _ffi_Rc_Getter : Getter { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Getter(_ffi) } func get_adder() -> Adder { let ret_ptr = _ffi_Rc_Getter__get_adder(_ffi) return _ffi_Rc_Adder(ret_ptr) } } ================================================ FILE: src/tests/snapshots/swift_trait_export_nested_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[no_mangle] extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; Box::into_raw(Box::new(_self.get_adder())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_adder_counter() -> u32 { get_adder_counter() } #[no_mangle] extern "C" fn _ffi_fn_get_getter() -> *const u8 { Box::into_raw(Box::new(get_getter())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_getter_counter() -> u32 { get_getter_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Getter(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_export_nested_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Adder__add(const void*, int32_t x, int32_t y); const void* _ffi_Rc_Getter__get_adder(const void*); uint32_t _ffi_fn_get_adder_counter(); const void* _ffi_fn_get_getter(); uint32_t _ffi_fn_get_getter_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); void _ffi_rs_drop_Rc_Adder(const void* ptr); void _ffi_rs_drop_Rc_Getter(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_export_nested_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Getter: AnyObject { func get_adder() -> Adder } protocol Adder: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_getter_counter() -> UInt32 { return _ffi_fn_get_getter_counter() } func get_adder_counter() -> UInt32 { return _ffi_fn_get_adder_counter() } func get_getter() -> Getter { let ret_ptr = _ffi_fn_get_getter() return _ffi_Rc_Getter(ret_ptr) } private class _ffi_Rc_Adder : Adder { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Adder(_ffi) } func add(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_Rc_Adder__add(_ffi, x, y) } } private class _ffi_Rc_Getter : Getter { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Getter(_ffi) } func get_adder() -> Adder { let ret_ptr = _ffi_Rc_Getter__get_adder(_ffi) return _ffi_Rc_Adder(ret_ptr) } } ================================================ FILE: src/tests/snapshots/swift_trait_export_nested_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; Box::into_raw(Box::new(_self.get_adder())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_counter() -> u32 { get_adder_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_getter() -> *const u8 { Box::into_raw(Box::new(get_getter())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_getter_counter() -> u32 { get_getter_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Getter(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_import_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_adder_box(const void* adder_ptr); int32_t _ffi_fn_set_adder_rc(const void* adder_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Adder: AnyObject { func add(_ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_adder_rc(_ adder: Adder) -> Int32 { return _ffi_fn_set_adder_rc(UnsafeRawPointer(Unmanaged.passRetained(adder as AnyObject).toOpaque())) } func set_adder_box(_ adder: Adder) -> Int32 { return _ffi_fn_set_adder_box(UnsafeRawPointer(Unmanaged.passRetained(adder as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_Adder__add") func _ffi_swift_Adder__add(_self: UnsafeRawPointer?, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Adder return _self.add(y) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 { set_adder_box(Box::new(_ffi_rs_Adder(adder_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 { set_adder_rc(std::rc::Rc::new(_ffi_rs_Adder(adder_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, y: i32) -> i32 { extern "C" { fn _ffi_swift_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_swift_Adder__add(self.0, y) } } } ================================================ FILE: src/tests/snapshots/swift_trait_import_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_adder_box(const void* adder_ptr); int32_t _ffi_fn_set_adder_rc(const void* adder_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Adder: AnyObject { func add(_ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_adder_rc(_ adder: Adder) -> Int32 { return _ffi_fn_set_adder_rc(UnsafeRawPointer(Unmanaged.passRetained(adder as AnyObject).toOpaque())) } func set_adder_box(_ adder: Adder) -> Int32 { return _ffi_fn_set_adder_box(UnsafeRawPointer(Unmanaged.passRetained(adder as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_Adder__add") func _ffi_swift_Adder__add(_self: UnsafeRawPointer?, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Adder return _self.add(y) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 { set_adder_box(Box::new(_ffi_rs_Adder(adder_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 { set_adder_rc(std::rc::Rc::new(_ffi_rs_Adder(adder_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, y: i32) -> i32 { unsafe extern "C" { fn _ffi_swift_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_swift_Adder__add(self.0, y) } } } ================================================ FILE: src/tests/snapshots/swift_trait_import_export_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Exported__add(const void*, int32_t x, int32_t y); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_imported(const void* imported_ptr); void _ffi_rs_drop_Rc_Exported(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_export_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Imported: AnyObject { func run(_ exported: Exported) -> Int32 } protocol Exported: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_counter() -> UInt32 { return _ffi_fn_get_counter() } func set_imported(_ imported: Imported) -> Int32 { return _ffi_fn_set_imported(UnsafeRawPointer(Unmanaged.passRetained(imported as AnyObject).toOpaque())) } private class _ffi_Rc_Exported : Exported { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Exported(_ffi) } func add(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_Rc_Exported__add(_ffi, x, y) } } @_cdecl("_ffi_swift_Imported__run") func _ffi_swift_Imported__run(_self: UnsafeRawPointer?, exported_ptr: UnsafeRawPointer?) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Imported return _self.run(_ffi_Rc_Exported(exported_ptr)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_export_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 { set_imported(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn run(&self, exported: std::rc::Rc) -> i32 { extern "C" { fn _ffi_swift_Imported__run(_: *const u8, exported_ptr: *const u8) -> i32; } unsafe { _ffi_swift_Imported__run(self.0, Box::into_raw(Box::new(exported)) as *const u8) } } } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_import_export_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif int32_t _ffi_Rc_Exported__add(const void*, int32_t x, int32_t y); uint32_t _ffi_fn_get_counter(); uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_imported(const void* imported_ptr); void _ffi_rs_drop_Rc_Exported(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_export_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Imported: AnyObject { func run(_ exported: Exported) -> Int32 } protocol Exported: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_counter() -> UInt32 { return _ffi_fn_get_counter() } func set_imported(_ imported: Imported) -> Int32 { return _ffi_fn_set_imported(UnsafeRawPointer(Unmanaged.passRetained(imported as AnyObject).toOpaque())) } private class _ffi_Rc_Exported : Exported { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Exported(_ffi) } func add(_ x: Int32, _ y: Int32) -> Int32 { return _ffi_Rc_Exported__add(_ffi, x, y) } } @_cdecl("_ffi_swift_Imported__run") func _ffi_swift_Imported__run(_self: UnsafeRawPointer?, exported_ptr: UnsafeRawPointer?) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Imported return _self.run(_ffi_Rc_Exported(exported_ptr)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_export_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 { set_imported(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn run(&self, exported: std::rc::Rc) -> i32 { unsafe extern "C" { fn _ffi_swift_Imported__run(_: *const u8, exported_ptr: *const u8) -> i32; } unsafe { _ffi_swift_Imported__run(self.0, Box::into_raw(Box::new(exported)) as *const u8) } } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/swift_trait_import_nested_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_getter(const void* getter_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_nested_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Getter: AnyObject { func get_adder() -> Adder } protocol Adder: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_getter(_ getter: Getter) -> Int32 { return _ffi_fn_set_getter(UnsafeRawPointer(Unmanaged.passRetained(getter as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_Adder__add") func _ffi_swift_Adder__add(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Adder return _self.add(x, y) } @_cdecl("_ffi_swift_Getter__get_adder") func _ffi_swift_Getter__get_adder(_self: UnsafeRawPointer?) -> UnsafeRawPointer? { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Getter return UnsafeRawPointer(Unmanaged.passRetained(_self.get_adder() as AnyObject).toOpaque()) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_nested_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 { set_getter(std::rc::Rc::new(_ffi_rs_Getter(getter_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, x: i32, y: i32) -> i32 { extern "C" { fn _ffi_swift_Adder__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_swift_Adder__add(self.0, x, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Getter(*const u8); impl Drop for _ffi_rs_Getter { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Getter for _ffi_rs_Getter { fn get_adder(&self) -> std::rc::Rc { extern "C" { fn _ffi_swift_Getter__get_adder(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_swift_Getter__get_adder(self.0) }; std::rc::Rc::new(_ffi_rs_Adder(ret_ptr)) } } ================================================ FILE: src/tests/snapshots/swift_trait_import_nested_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_getter(const void* getter_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_nested_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Getter: AnyObject { func get_adder() -> Adder } protocol Adder: AnyObject { func add(_ x: Int32, _ y: Int32) -> Int32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_getter(_ getter: Getter) -> Int32 { return _ffi_fn_set_getter(UnsafeRawPointer(Unmanaged.passRetained(getter as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_Adder__add") func _ffi_swift_Adder__add(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Adder return _self.add(x, y) } @_cdecl("_ffi_swift_Getter__get_adder") func _ffi_swift_Getter__get_adder(_self: UnsafeRawPointer?) -> UnsafeRawPointer? { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Getter return UnsafeRawPointer(Unmanaged.passRetained(_self.get_adder() as AnyObject).toOpaque()) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_nested_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 { set_getter(std::rc::Rc::new(_ffi_rs_Getter(getter_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, x: i32, y: i32) -> i32 { unsafe extern "C" { fn _ffi_swift_Adder__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_swift_Adder__add(self.0, x, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Getter(*const u8); impl Drop for _ffi_rs_Getter { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Getter for _ffi_rs_Getter { fn get_adder(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_swift_Getter__get_adder(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_swift_Getter__get_adder(self.0) }; std::rc::Rc::new(_ffi_rs_Adder(ret_ptr)) } } ================================================ FILE: src/tests/snapshots/swift_trait_import_struct_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_struct(const void* struct_in_ptr); float _ffi_fn_set_multiply_pairs(const void* struct_in_ptr); int32_t _ffi_fn_set_single_element_struct(const void* struct_in_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_struct_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol StructIn: AnyObject { func empty_struct(_ x: Int32, _ foo: EmptyStruct, _ y: Int32) -> Int32 func single_element_struct(_ x: SingleElementStruct, _ y: SingleElementStruct) -> Int32 func multiply_pairs(_ ab: PairStruct, _ cd: PairStruct) -> Float32 } struct EmptyStruct { } struct SingleElementStruct { var _0: Int32 } struct PairStruct { var x: Float32 var y: Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_empty_struct(_ struct_in: StructIn) -> Int32 { return _ffi_fn_set_empty_struct(UnsafeRawPointer(Unmanaged.passRetained(struct_in as AnyObject).toOpaque())) } func set_single_element_struct(_ struct_in: StructIn) -> Int32 { return _ffi_fn_set_single_element_struct(UnsafeRawPointer(Unmanaged.passRetained(struct_in as AnyObject).toOpaque())) } func set_multiply_pairs(_ struct_in: StructIn) -> Float32 { return _ffi_fn_set_multiply_pairs(UnsafeRawPointer(Unmanaged.passRetained(struct_in as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_StructIn__empty_struct") func _ffi_swift_StructIn__empty_struct(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! StructIn return _self.empty_struct(x, EmptyStruct(), y) } @_cdecl("_ffi_swift_StructIn__multiply_pairs") func _ffi_swift_StructIn__multiply_pairs(_self: UnsafeRawPointer?, ab_x: Float32, ab_y: Float32, cd_x: Float32, cd_y: Float32) -> Float32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! StructIn return _self.multiply_pairs(PairStruct(x: ab_x, y: ab_y), PairStruct(x: cd_x, y: cd_y)) } @_cdecl("_ffi_swift_StructIn__single_element_struct") func _ffi_swift_StructIn__single_element_struct(_self: UnsafeRawPointer?, x_0: Int32, y_0: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! StructIn return _self.single_element_struct(SingleElementStruct(_0: x_0), SingleElementStruct(_0: y_0)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_struct_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 { set_empty_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8) -> i32 { set_single_element_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_StructIn(*const u8); impl Drop for _ffi_rs_StructIn { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl StructIn for _ffi_rs_StructIn { fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 { extern "C" { fn _ffi_swift_StructIn__empty_struct(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_swift_StructIn__empty_struct(self.0, x, y) } } fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32 { extern "C" { fn _ffi_swift_StructIn__single_element_struct(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_swift_StructIn__single_element_struct(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 { extern "C" { fn _ffi_swift_StructIn__multiply_pairs(_: *const u8, ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32; } unsafe { _ffi_swift_StructIn__multiply_pairs(self.0, ab.x, ab.y, cd.x, cd.y) } } } ================================================ FILE: src/tests/snapshots/swift_trait_import_struct_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_struct(const void* struct_in_ptr); float _ffi_fn_set_multiply_pairs(const void* struct_in_ptr); int32_t _ffi_fn_set_single_element_struct(const void* struct_in_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_struct_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol StructIn: AnyObject { func empty_struct(_ x: Int32, _ foo: EmptyStruct, _ y: Int32) -> Int32 func single_element_struct(_ x: SingleElementStruct, _ y: SingleElementStruct) -> Int32 func multiply_pairs(_ ab: PairStruct, _ cd: PairStruct) -> Float32 } struct EmptyStruct { } struct SingleElementStruct { var _0: Int32 } struct PairStruct { var x: Float32 var y: Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_empty_struct(_ struct_in: StructIn) -> Int32 { return _ffi_fn_set_empty_struct(UnsafeRawPointer(Unmanaged.passRetained(struct_in as AnyObject).toOpaque())) } func set_single_element_struct(_ struct_in: StructIn) -> Int32 { return _ffi_fn_set_single_element_struct(UnsafeRawPointer(Unmanaged.passRetained(struct_in as AnyObject).toOpaque())) } func set_multiply_pairs(_ struct_in: StructIn) -> Float32 { return _ffi_fn_set_multiply_pairs(UnsafeRawPointer(Unmanaged.passRetained(struct_in as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_StructIn__empty_struct") func _ffi_swift_StructIn__empty_struct(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! StructIn return _self.empty_struct(x, EmptyStruct(), y) } @_cdecl("_ffi_swift_StructIn__multiply_pairs") func _ffi_swift_StructIn__multiply_pairs(_self: UnsafeRawPointer?, ab_x: Float32, ab_y: Float32, cd_x: Float32, cd_y: Float32) -> Float32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! StructIn return _self.multiply_pairs(PairStruct(x: ab_x, y: ab_y), PairStruct(x: cd_x, y: cd_y)) } @_cdecl("_ffi_swift_StructIn__single_element_struct") func _ffi_swift_StructIn__single_element_struct(_self: UnsafeRawPointer?, x_0: Int32, y_0: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! StructIn return _self.single_element_struct(SingleElementStruct(_0: x_0), SingleElementStruct(_0: y_0)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_struct_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 { set_empty_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8) -> i32 { set_single_element_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_StructIn(*const u8); impl Drop for _ffi_rs_StructIn { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl StructIn for _ffi_rs_StructIn { fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 { unsafe extern "C" { fn _ffi_swift_StructIn__empty_struct(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_swift_StructIn__empty_struct(self.0, x, y) } } fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32 { unsafe extern "C" { fn _ffi_swift_StructIn__single_element_struct(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_swift_StructIn__single_element_struct(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 { unsafe extern "C" { fn _ffi_swift_StructIn__multiply_pairs(_: *const u8, ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32; } unsafe { _ffi_swift_StructIn__multiply_pairs(self.0, ab.x, ab.y, cd.x, cd.y) } } } ================================================ FILE: src/tests/snapshots/swift_trait_import_tuple_in_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_tuple(const void* tuple_in_ptr); float _ffi_fn_set_multiply_pairs(const void* tuple_in_ptr); int32_t _ffi_fn_set_single_element_tuple(const void* tuple_in_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_tuple_in_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol TupleIn: AnyObject { func empty_tuple(_ x: Int32, _ foo: (), _ y: Int32) -> Int32 func single_element_tuple(_ x: Int32, _ y: Int32) -> Int32 func multiply_pairs(_ ab: (Float32, Float32), _ cd: (Float32, Float32)) -> Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_empty_tuple(_ tuple_in: TupleIn) -> Int32 { return _ffi_fn_set_empty_tuple(UnsafeRawPointer(Unmanaged.passRetained(tuple_in as AnyObject).toOpaque())) } func set_single_element_tuple(_ tuple_in: TupleIn) -> Int32 { return _ffi_fn_set_single_element_tuple(UnsafeRawPointer(Unmanaged.passRetained(tuple_in as AnyObject).toOpaque())) } func set_multiply_pairs(_ tuple_in: TupleIn) -> Float32 { return _ffi_fn_set_multiply_pairs(UnsafeRawPointer(Unmanaged.passRetained(tuple_in as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_TupleIn__empty_tuple") func _ffi_swift_TupleIn__empty_tuple(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! TupleIn return _self.empty_tuple(x, (), y) } @_cdecl("_ffi_swift_TupleIn__multiply_pairs") func _ffi_swift_TupleIn__multiply_pairs(_self: UnsafeRawPointer?, ab_0: Float32, ab_1: Float32, cd_0: Float32, cd_1: Float32) -> Float32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! TupleIn return _self.multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } @_cdecl("_ffi_swift_TupleIn__single_element_tuple") func _ffi_swift_TupleIn__single_element_tuple(_self: UnsafeRawPointer?, x_0: Int32, y_0: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! TupleIn return _self.single_element_tuple(x_0, y_0) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_tuple_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 { set_empty_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) -> i32 { set_single_element_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_TupleIn(*const u8); impl Drop for _ffi_rs_TupleIn { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl TupleIn for _ffi_rs_TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 { extern "C" { fn _ffi_swift_TupleIn__empty_tuple(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_swift_TupleIn__empty_tuple(self.0, x, y) } } fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 { extern "C" { fn _ffi_swift_TupleIn__single_element_tuple(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_swift_TupleIn__single_element_tuple(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 { extern "C" { fn _ffi_swift_TupleIn__multiply_pairs(_: *const u8, ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32; } unsafe { _ffi_swift_TupleIn__multiply_pairs(self.0, ab.0, ab.1, cd.0, cd.1) } } } ================================================ FILE: src/tests/snapshots/swift_trait_import_tuple_in_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif uintptr_t _ffi_fn_rust_mem_leaked(); int32_t _ffi_fn_set_empty_tuple(const void* tuple_in_ptr); float _ffi_fn_set_multiply_pairs(const void* tuple_in_ptr); int32_t _ffi_fn_set_single_element_tuple(const void* tuple_in_ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_import_tuple_in_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol TupleIn: AnyObject { func empty_tuple(_ x: Int32, _ foo: (), _ y: Int32) -> Int32 func single_element_tuple(_ x: Int32, _ y: Int32) -> Int32 func multiply_pairs(_ ab: (Float32, Float32), _ cd: (Float32, Float32)) -> Float32 } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func set_empty_tuple(_ tuple_in: TupleIn) -> Int32 { return _ffi_fn_set_empty_tuple(UnsafeRawPointer(Unmanaged.passRetained(tuple_in as AnyObject).toOpaque())) } func set_single_element_tuple(_ tuple_in: TupleIn) -> Int32 { return _ffi_fn_set_single_element_tuple(UnsafeRawPointer(Unmanaged.passRetained(tuple_in as AnyObject).toOpaque())) } func set_multiply_pairs(_ tuple_in: TupleIn) -> Float32 { return _ffi_fn_set_multiply_pairs(UnsafeRawPointer(Unmanaged.passRetained(tuple_in as AnyObject).toOpaque())) } @_cdecl("_ffi_swift_TupleIn__empty_tuple") func _ffi_swift_TupleIn__empty_tuple(_self: UnsafeRawPointer?, x: Int32, y: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! TupleIn return _self.empty_tuple(x, (), y) } @_cdecl("_ffi_swift_TupleIn__multiply_pairs") func _ffi_swift_TupleIn__multiply_pairs(_self: UnsafeRawPointer?, ab_0: Float32, ab_1: Float32, cd_0: Float32, cd_1: Float32) -> Float32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! TupleIn return _self.multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } @_cdecl("_ffi_swift_TupleIn__single_element_tuple") func _ffi_swift_TupleIn__single_element_tuple(_self: UnsafeRawPointer?, x_0: Int32, y_0: Int32) -> Int32 { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! TupleIn return _self.single_element_tuple(x_0, y_0) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_import_tuple_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 { set_empty_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) -> i32 { set_single_element_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_TupleIn(*const u8); impl Drop for _ffi_rs_TupleIn { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl TupleIn for _ffi_rs_TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 { unsafe extern "C" { fn _ffi_swift_TupleIn__empty_tuple(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_swift_TupleIn__empty_tuple(self.0, x, y) } } fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 { unsafe extern "C" { fn _ffi_swift_TupleIn__single_element_tuple(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_swift_TupleIn__single_element_tuple(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 { unsafe extern "C" { fn _ffi_swift_TupleIn__multiply_pairs(_: *const u8, ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32; } unsafe { _ffi_swift_TupleIn__multiply_pairs(self.0, ab.0, ab.1, cd.0, cd.1) } } } ================================================ FILE: src/tests/snapshots/swift_trait_string_2021/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_Rc_Test__get_string(const void*); void _ffi_Rc_Test__set_str(const void*, const void* x_ptr, uintptr_t x_len); void _ffi_Rc_Test__set_string(const void*, const void* x_ptr, uintptr_t x_len); void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); const void* _ffi_fn_get_test(); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_2_usize _ffi_fn_set_test(const void* test_ptr); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; void _ffi_rs_drop_Rc_Test(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_string_2021/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Test: AnyObject { func get_string() -> String func set_string(_ x: String) func set_str(_ x: String) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_test() -> Test { let ret_ptr = _ffi_fn_get_test() return _ffi_Rc_Test(ret_ptr) } func set_test(_ test: Test) -> String { let multi_ret = _ffi_fn_set_test(UnsafeRawPointer(Unmanaged.passRetained(test as AnyObject).toOpaque())) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private class _ffi_Rc_Test : Test { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Test(_ffi) } func get_string() -> String { let multi_ret = _ffi_Rc_Test__get_string(_ffi) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } func set_string(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_Rc_Test__set_string(_ffi, x_ptr, x_len) } func set_str(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_Rc_Test__set_str(_ffi, x_ptr, x_len) } } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } @_cdecl("_ffi_swift_Test__get_string") func _ffi_swift_Test__get_string(_self: UnsafeRawPointer?) -> _ffi_ret_ptr_usize { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Test let (ret_ptr, ret_len) = _ffi_string_to_rust(_self.get_string()); return _ffi_ret_ptr_usize(_0: ret_ptr, _1: ret_len) } @_cdecl("_ffi_swift_Test__set_str") func _ffi_swift_Test__set_str(_self: UnsafeRawPointer?, x_ptr: UnsafeRawPointer?, x_len: UInt, x_cap: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Test _self.set_str(_ffi_string_from_rust(x_ptr, Int(x_len), x_cap)) } @_cdecl("_ffi_swift_Test__set_string") func _ffi_swift_Test__set_string(_self: UnsafeRawPointer?, x_ptr: UnsafeRawPointer?, x_len: UInt, x_cap: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Test _self.set_string(_ffi_string_from_rust(x_ptr, Int(x_len), x_cap)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_string_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> _ffi_ret_ptr_2_usize { let _self = unsafe { &*(_self as *const std::rc::Rc) }; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(_self.get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[no_mangle] extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_string(_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_fn_get_test() -> *const u8 { Box::into_raw(Box::new(get_test())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(set_test(std::rc::Rc::new(_ffi_rs_Test(test_ptr)))); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Test(*const u8); impl Drop for _ffi_rs_Test { fn drop(&mut self) { extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Test for _ffi_rs_Test { fn get_string(&self) -> String { extern "C" { fn _ffi_swift_Test__get_string(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_swift_Test__get_string(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_string(&self, x: String) { extern "C" { fn _ffi_swift_Test__set_string(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x); unsafe { _ffi_swift_Test__set_string(self.0, x_ptr, x_len, x_cap) }; } fn set_str(&self, x: &str) { extern "C" { fn _ffi_swift_Test__set_str(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x.into()); unsafe { _ffi_swift_Test__set_str(self.0, x_ptr, x_len, x_cap) }; } } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Test(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/swift_trait_string_2024/ffi.h ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #pragma once #include #ifdef __cplusplus extern "C" { #endif typedef struct { const void* _0; uintptr_t _1; uintptr_t _2; } _ffi_ret_ptr_2_usize; _ffi_ret_ptr_2_usize _ffi_Rc_Test__get_string(const void*); void _ffi_Rc_Test__set_str(const void*, const void* x_ptr, uintptr_t x_len); void _ffi_Rc_Test__set_string(const void*, const void* x_ptr, uintptr_t x_len); void* _ffi_alloc(intptr_t len); void _ffi_dealloc(const void* ptr, uintptr_t capacity); const void* _ffi_fn_get_test(); uintptr_t _ffi_fn_rust_mem_leaked(); _ffi_ret_ptr_2_usize _ffi_fn_set_test(const void* test_ptr); typedef struct { const void* _0; uintptr_t _1; } _ffi_ret_ptr_usize; void _ffi_rs_drop_Rc_Test(const void* ptr); #ifdef __cplusplus } #endif ================================================ FILE: src/tests/snapshots/swift_trait_string_2024/ffi.swift ================================================ // This file was generated by miniffi v0.1.0. Do not edit. protocol Test: AnyObject { func get_string() -> String func set_string(_ x: String) func set_str(_ x: String) } func rust_mem_leaked() -> UInt { return _ffi_fn_rust_mem_leaked() } func get_test() -> Test { let ret_ptr = _ffi_fn_get_test() return _ffi_Rc_Test(ret_ptr) } func set_test(_ test: Test) -> String { let multi_ret = _ffi_fn_set_test(UnsafeRawPointer(Unmanaged.passRetained(test as AnyObject).toOpaque())) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } private class _ffi_Rc_Test : Test { private var _ffi: UnsafeRawPointer? init(_ ptr: UnsafeRawPointer?) { _ffi = ptr } deinit { _ffi_rs_drop_Rc_Test(_ffi) } func get_string() -> String { let multi_ret = _ffi_Rc_Test__get_string(_ffi) let ret_ptr = multi_ret._0 let ret_len = multi_ret._1 let ret_cap = multi_ret._2 return _ffi_string_from_rust(ret_ptr, Int(ret_len), ret_cap) } func set_string(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_Rc_Test__set_string(_ffi, x_ptr, x_len) } func set_str(_ x: String) { let (x_ptr, x_len) = _ffi_string_to_rust(x); _ffi_Rc_Test__set_str(_ffi, x_ptr, x_len) } } private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String { let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len) let str = String(decoding: buf, as: UTF8.self) _ffi_dealloc(ptr, cap) return str } private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) { var str = str return str.withUTF8 { str in let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count) buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count)) return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count)) } } @_cdecl("_ffi_swift_Test__get_string") func _ffi_swift_Test__get_string(_self: UnsafeRawPointer?) -> _ffi_ret_ptr_usize { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Test let (ret_ptr, ret_len) = _ffi_string_to_rust(_self.get_string()); return _ffi_ret_ptr_usize(_0: ret_ptr, _1: ret_len) } @_cdecl("_ffi_swift_Test__set_str") func _ffi_swift_Test__set_str(_self: UnsafeRawPointer?, x_ptr: UnsafeRawPointer?, x_len: UInt, x_cap: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Test _self.set_str(_ffi_string_from_rust(x_ptr, Int(x_len), x_cap)) } @_cdecl("_ffi_swift_Test__set_string") func _ffi_swift_Test__set_string(_self: UnsafeRawPointer?, x_ptr: UnsafeRawPointer?, x_len: UInt, x_cap: UInt) { let _self = Unmanaged.fromOpaque(_self!).takeUnretainedValue() as! Test _self.set_string(_ffi_string_from_rust(x_ptr, Int(x_len), x_cap)) } @_cdecl("_ffi_swift_drop") func _ffi_swift_drop(ptr: UnsafeRawPointer?) { _ = Unmanaged.fromOpaque(ptr!).takeRetainedValue() } ================================================ FILE: src/tests/snapshots/swift_trait_string_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> _ffi_ret_ptr_2_usize { let _self = unsafe { &*(_self as *const std::rc::Rc) }; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(_self.get_string()); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_string(_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_test() -> *const u8 { Box::into_raw(Box::new(get_test())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(set_test(std::rc::Rc::new(_ffi_rs_Test(test_ptr)))); _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap) } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); #[allow(non_camel_case_types)] struct _ffi_rs_Test(*const u8); impl Drop for _ffi_rs_Test { fn drop(&mut self) { unsafe extern "C" { fn _ffi_swift_drop(_: *const u8); } unsafe { _ffi_swift_drop(self.0) }; } } impl Test for _ffi_rs_Test { fn get_string(&self) -> String { unsafe extern "C" { fn _ffi_swift_Test__get_string(_: *const u8) -> _ffi_ret_ptr_usize; } let multi_ret = unsafe { _ffi_swift_Test__get_string(self.0) }; let ret_ptr = multi_ret.0; let ret_len = multi_ret.1; _ffi_string_from_host(ret_ptr, ret_len) } fn set_string(&self, x: String) { unsafe extern "C" { fn _ffi_swift_Test__set_string(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x); unsafe { _ffi_swift_Test__set_string(self.0, x_ptr, x_len, x_cap) }; } fn set_str(&self, x: &str) { unsafe extern "C" { fn _ffi_swift_Test__set_str(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x.into()); unsafe { _ffi_swift_Test__set_str(self.0, x_ptr, x_len, x_cap) }; } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Test(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/wasm_demo_app_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Platform { create_window(): Window; } export interface Window { get_title(): string; set_title(title: string): void; get_size(): [number, number]; set_size(width: number, height: number): void; set_handler(handler: Handler): void; child_window(): Window; } export interface Handler { on_draw(canvas: Canvas): void; } export interface Canvas { draw_text_runs(runs: TextRun[]): void; } export interface TextRun { text: string, rect: TextRect, } export interface TextRect { x: number, y: number, w: number, h: number, } export function rust_mem_leaked(): number; export function create_app(platform: Platform): void; ================================================ FILE: src/tests/snapshots/wasm_demo_app_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function create_app(platform) { _ffi_exports._ffi_fn_create_app(_ffi_handle_alloc(platform)); } let _ffi_len = 0; let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_reg_Box_Handler = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Handler(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } const _ffi_Box_Handler = class Handler { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Handler.register(this, _); } on_draw(canvas) { _ffi_exports._ffi_Box_Handler__on_draw(this._, _ffi_handle_alloc(canvas)); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_TextRun_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), rect: { x: _ffi_read_i32(buf), y: _ffi_read_i32(buf), w: _ffi_read_i32(buf), h: _ffi_read_i32(buf) } }); } return items; } let _ffi_exports; const _ffi_imports = { _ffi_js_Canvas__draw_text_runs(self, buf_ptr, buf_cap, runs_len) { let buf = _ffi_new_ReadBuf(buf_ptr); _ffi_handles.get(self).draw_text_runs(_ffi_vec_TextRun_from_rust(runs_len, buf)); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); }, _ffi_js_Platform__create_window(self) { return _ffi_handle_alloc(_ffi_handles.get(self).create_window()); }, _ffi_js_Window__child_window(self) { return _ffi_handle_alloc(_ffi_handles.get(self).child_window()); }, _ffi_js_Window__get_size(self, _ffi_ret_2_i32) { let ret = _ffi_handles.get(self).get_size(); _ffi_update_dv().setInt32(_ffi_ret_2_i32, ret[0], true); _ffi_dv.setInt32(_ffi_ret_2_i32 + 4, ret[1], true); }, _ffi_js_Window__get_title(self, _ffi_ret_ptr_usize) { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_title()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Window__set_handler(self, handler_ptr) { _ffi_handles.get(self).set_handler(new _ffi_Box_Handler(handler_ptr)); }, _ffi_js_Window__set_size(self, width, height) { _ffi_handles.get(self).set_size(width, height); }, _ffi_js_Window__set_title(self, title_ptr, title_len, title_cap) { _ffi_handles.get(self).set_title(_ffi_string_from_rust(title_ptr, title_len, title_cap)); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_app_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Platform { create_window(): Window; } export interface Window { get_title(): string; set_title(title: string): void; get_size(): [number, number]; set_size(width: number, height: number): void; set_handler(handler: Handler): void; child_window(): Window; } export interface Handler { on_draw(canvas: Canvas): void; } export interface Canvas { draw_text_runs(runs: TextRun[]): void; } export interface TextRun { text: string, rect: TextRect, } export interface TextRect { x: number, y: number, w: number, h: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function create_app(platform: Platform): void { _ffi_exports._ffi_fn_create_app(_ffi_handle_alloc(platform)); } let _ffi_len = 0; let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_reg_Box_Handler = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Handler(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8: Uint8Array; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } const _ffi_Box_Handler = class Handler implements Handler { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Handler.register(this, _); } on_draw(canvas: Canvas): void { _ffi_exports._ffi_Box_Handler__on_draw(this._, _ffi_handle_alloc(canvas)); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_TextRun_from_rust(len: number, buf: _ffi_ReadBuf): TextRun[] { let items: TextRun[] = []; while (items.length < len) { items.push({ text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), rect: { x: _ffi_read_i32(buf), y: _ffi_read_i32(buf), w: _ffi_read_i32(buf), h: _ffi_read_i32(buf) } }); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Handler__on_draw: (_self: number, canvas_ptr: number) => void, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_create_app: (platform_ptr: number) => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Box_Handler: (ptr: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Canvas__draw_text_runs(self: number, buf_ptr: number, buf_cap: number, runs_len: number): void { let buf = _ffi_new_ReadBuf(buf_ptr); _ffi_handles.get(self).draw_text_runs(_ffi_vec_TextRun_from_rust(runs_len, buf)); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); }, _ffi_js_Platform__create_window(self: number): number { return _ffi_handle_alloc(_ffi_handles.get(self).create_window()); }, _ffi_js_Window__child_window(self: number): number { return _ffi_handle_alloc(_ffi_handles.get(self).child_window()); }, _ffi_js_Window__get_size(self: number, _ffi_ret_2_i32: number): void { let ret = _ffi_handles.get(self).get_size(); _ffi_update_dv().setInt32(_ffi_ret_2_i32, ret[0], true); _ffi_dv.setInt32(_ffi_ret_2_i32 + 4, ret[1], true); }, _ffi_js_Window__get_title(self: number, _ffi_ret_ptr_usize: number): void { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_title()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Window__set_handler(self: number, handler_ptr: number): void { _ffi_handles.get(self).set_handler(new _ffi_Box_Handler(handler_ptr)); }, _ffi_js_Window__set_size(self: number, width: number, height: number): void { _ffi_handles.get(self).set_size(width, height); }, _ffi_js_Window__set_title(self: number, title_ptr: number, title_len: number, title_cap: number): void { _ffi_handles.get(self).set_title(_ffi_string_from_rust(title_ptr, title_len, title_cap)); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_app_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *const u8) { let _self = unsafe { &*(_self as *const Box) }; _self.on_draw(Box::new(_ffi_rs_Canvas(canvas_ptr))); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) { create_app(Box::new(_ffi_rs_Platform(platform_ptr))); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_2_i32(i32, i32); static mut _FFI_RET_2_I32: _ffi_ret_2_i32 = _ffi_ret_2_i32(0, 0); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); #[allow(non_camel_case_types)] struct _ffi_rs_Canvas(*const u8); impl Drop for _ffi_rs_Canvas { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Canvas for _ffi_rs_Canvas { fn draw_text_runs(&self, runs: Vec) { extern "C" { fn _ffi_js_Canvas__draw_text_runs(_: *const u8, buf_ptr: *const u8, buf_cap: usize, runs_len: usize); } let mut buf = Vec::::new(); let runs_len = runs.len(); _ffi_vec_TextRun_to_js(runs, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _ffi_js_Canvas__draw_text_runs(self.0, buf_ptr, buf_cap, runs_len) }; } } #[allow(non_camel_case_types)] struct _ffi_rs_Platform(*const u8); impl Drop for _ffi_rs_Platform { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Platform for _ffi_rs_Platform { fn create_window(&self) -> std::rc::Rc { extern "C" { fn _ffi_js_Platform__create_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_js_Platform__create_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[allow(non_camel_case_types)] struct _ffi_rs_Window(*const u8); impl Drop for _ffi_rs_Window { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Window for _ffi_rs_Window { fn get_title(&self) -> String { extern "C" { fn _ffi_js_Window__get_title(_: *const u8, _: *const _ffi_ret_ptr_usize); } unsafe { _ffi_js_Window__get_title(self.0, std::ptr::addr_of!(_FFI_RET_PTR_USIZE)) } let ret_ptr = unsafe { _FFI_RET_PTR_USIZE.0 }; let ret_len = unsafe { _FFI_RET_PTR_USIZE.1 }; _ffi_string_from_host(ret_ptr, ret_len) } fn set_title(&self, title: &str) { extern "C" { fn _ffi_js_Window__set_title(_: *const u8, title_ptr: *const u8, title_len: usize, title_cap: usize); } let (title_ptr, title_len, title_cap) = _ffi_string_to_host(title.into()); unsafe { _ffi_js_Window__set_title(self.0, title_ptr, title_len, title_cap) }; } fn get_size(&self) -> (i32, i32) { extern "C" { fn _ffi_js_Window__get_size(_: *const u8, _: *const _ffi_ret_2_i32); } unsafe { _ffi_js_Window__get_size(self.0, std::ptr::addr_of!(_FFI_RET_2_I32)) } let ret_0 = unsafe { _FFI_RET_2_I32.0 }; let ret_1 = unsafe { _FFI_RET_2_I32.1 }; (ret_0, ret_1) } fn set_size(&self, width: i32, height: i32) { extern "C" { fn _ffi_js_Window__set_size(_: *const u8, width: i32, height: i32); } unsafe { _ffi_js_Window__set_size(self.0, width, height) }; } fn set_handler(&self, handler: Box) { extern "C" { fn _ffi_js_Window__set_handler(_: *const u8, handler_ptr: *const u8); } unsafe { _ffi_js_Window__set_handler(self.0, Box::into_raw(Box::new(handler)) as *const u8) }; } fn child_window(&self) -> std::rc::Rc { extern "C" { fn _ffi_js_Window__child_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_js_Window__child_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Handler(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_TextRun_to_js(items: Vec, buf: &mut Vec) { for item in items { let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.rect.x, buf); _ffi_write(item.rect.y, buf); _ffi_write(item.rect.w, buf); _ffi_write(item.rect.h, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_demo_app_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Platform { create_window(): Window; } export interface Window { get_title(): string; set_title(title: string): void; get_size(): [number, number]; set_size(width: number, height: number): void; set_handler(handler: Handler): void; child_window(): Window; } export interface Handler { on_draw(canvas: Canvas): void; } export interface Canvas { draw_text_runs(runs: TextRun[]): void; } export interface TextRun { text: string, rect: TextRect, } export interface TextRect { x: number, y: number, w: number, h: number, } export function rust_mem_leaked(): number; export function create_app(platform: Platform): void; ================================================ FILE: src/tests/snapshots/wasm_demo_app_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function create_app(platform) { _ffi_exports._ffi_fn_create_app(_ffi_handle_alloc(platform)); } let _ffi_len = 0; let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_reg_Box_Handler = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Handler(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } const _ffi_Box_Handler = class Handler { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Handler.register(this, _); } on_draw(canvas) { _ffi_exports._ffi_Box_Handler__on_draw(this._, _ffi_handle_alloc(canvas)); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_TextRun_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), rect: { x: _ffi_read_i32(buf), y: _ffi_read_i32(buf), w: _ffi_read_i32(buf), h: _ffi_read_i32(buf) } }); } return items; } let _ffi_exports; const _ffi_imports = { _ffi_js_Canvas__draw_text_runs(self, buf_ptr, buf_cap, runs_len) { let buf = _ffi_new_ReadBuf(buf_ptr); _ffi_handles.get(self).draw_text_runs(_ffi_vec_TextRun_from_rust(runs_len, buf)); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); }, _ffi_js_Platform__create_window(self) { return _ffi_handle_alloc(_ffi_handles.get(self).create_window()); }, _ffi_js_Window__child_window(self) { return _ffi_handle_alloc(_ffi_handles.get(self).child_window()); }, _ffi_js_Window__get_size(self, _ffi_ret_2_i32) { let ret = _ffi_handles.get(self).get_size(); _ffi_update_dv().setInt32(_ffi_ret_2_i32, ret[0], true); _ffi_dv.setInt32(_ffi_ret_2_i32 + 4, ret[1], true); }, _ffi_js_Window__get_title(self, _ffi_ret_ptr_usize) { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_title()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Window__set_handler(self, handler_ptr) { _ffi_handles.get(self).set_handler(new _ffi_Box_Handler(handler_ptr)); }, _ffi_js_Window__set_size(self, width, height) { _ffi_handles.get(self).set_size(width, height); }, _ffi_js_Window__set_title(self, title_ptr, title_len, title_cap) { _ffi_handles.get(self).set_title(_ffi_string_from_rust(title_ptr, title_len, title_cap)); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_app_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Platform { create_window(): Window; } export interface Window { get_title(): string; set_title(title: string): void; get_size(): [number, number]; set_size(width: number, height: number): void; set_handler(handler: Handler): void; child_window(): Window; } export interface Handler { on_draw(canvas: Canvas): void; } export interface Canvas { draw_text_runs(runs: TextRun[]): void; } export interface TextRun { text: string, rect: TextRect, } export interface TextRect { x: number, y: number, w: number, h: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function create_app(platform: Platform): void { _ffi_exports._ffi_fn_create_app(_ffi_handle_alloc(platform)); } let _ffi_len = 0; let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_reg_Box_Handler = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Handler(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8: Uint8Array; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } const _ffi_Box_Handler = class Handler implements Handler { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Handler.register(this, _); } on_draw(canvas: Canvas): void { _ffi_exports._ffi_Box_Handler__on_draw(this._, _ffi_handle_alloc(canvas)); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_TextRun_from_rust(len: number, buf: _ffi_ReadBuf): TextRun[] { let items: TextRun[] = []; while (items.length < len) { items.push({ text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), rect: { x: _ffi_read_i32(buf), y: _ffi_read_i32(buf), w: _ffi_read_i32(buf), h: _ffi_read_i32(buf) } }); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Handler__on_draw: (_self: number, canvas_ptr: number) => void, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_create_app: (platform_ptr: number) => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Box_Handler: (ptr: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Canvas__draw_text_runs(self: number, buf_ptr: number, buf_cap: number, runs_len: number): void { let buf = _ffi_new_ReadBuf(buf_ptr); _ffi_handles.get(self).draw_text_runs(_ffi_vec_TextRun_from_rust(runs_len, buf)); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); }, _ffi_js_Platform__create_window(self: number): number { return _ffi_handle_alloc(_ffi_handles.get(self).create_window()); }, _ffi_js_Window__child_window(self: number): number { return _ffi_handle_alloc(_ffi_handles.get(self).child_window()); }, _ffi_js_Window__get_size(self: number, _ffi_ret_2_i32: number): void { let ret = _ffi_handles.get(self).get_size(); _ffi_update_dv().setInt32(_ffi_ret_2_i32, ret[0], true); _ffi_dv.setInt32(_ffi_ret_2_i32 + 4, ret[1], true); }, _ffi_js_Window__get_title(self: number, _ffi_ret_ptr_usize: number): void { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_title()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Window__set_handler(self: number, handler_ptr: number): void { _ffi_handles.get(self).set_handler(new _ffi_Box_Handler(handler_ptr)); }, _ffi_js_Window__set_size(self: number, width: number, height: number): void { _ffi_handles.get(self).set_size(width, height); }, _ffi_js_Window__set_title(self: number, title_ptr: number, title_len: number, title_cap: number): void { _ffi_handles.get(self).set_title(_ffi_string_from_rust(title_ptr, title_len, title_cap)); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_app_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *const u8) { let _self = unsafe { &*(_self as *const Box) }; _self.on_draw(Box::new(_ffi_rs_Canvas(canvas_ptr))); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) { create_app(Box::new(_ffi_rs_Platform(platform_ptr))); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_2_i32(i32, i32); static mut _FFI_RET_2_I32: _ffi_ret_2_i32 = _ffi_ret_2_i32(0, 0); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); #[allow(non_camel_case_types)] struct _ffi_rs_Canvas(*const u8); impl Drop for _ffi_rs_Canvas { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Canvas for _ffi_rs_Canvas { fn draw_text_runs(&self, runs: Vec) { unsafe extern "C" { fn _ffi_js_Canvas__draw_text_runs(_: *const u8, buf_ptr: *const u8, buf_cap: usize, runs_len: usize); } let mut buf = Vec::::new(); let runs_len = runs.len(); _ffi_vec_TextRun_to_js(runs, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _ffi_js_Canvas__draw_text_runs(self.0, buf_ptr, buf_cap, runs_len) }; } } #[allow(non_camel_case_types)] struct _ffi_rs_Platform(*const u8); impl Drop for _ffi_rs_Platform { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Platform for _ffi_rs_Platform { fn create_window(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_js_Platform__create_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_js_Platform__create_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[allow(non_camel_case_types)] struct _ffi_rs_Window(*const u8); impl Drop for _ffi_rs_Window { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Window for _ffi_rs_Window { fn get_title(&self) -> String { unsafe extern "C" { fn _ffi_js_Window__get_title(_: *const u8, _: *const _ffi_ret_ptr_usize); } unsafe { _ffi_js_Window__get_title(self.0, std::ptr::addr_of!(_FFI_RET_PTR_USIZE)) } let ret_ptr = unsafe { _FFI_RET_PTR_USIZE.0 }; let ret_len = unsafe { _FFI_RET_PTR_USIZE.1 }; _ffi_string_from_host(ret_ptr, ret_len) } fn set_title(&self, title: &str) { unsafe extern "C" { fn _ffi_js_Window__set_title(_: *const u8, title_ptr: *const u8, title_len: usize, title_cap: usize); } let (title_ptr, title_len, title_cap) = _ffi_string_to_host(title.into()); unsafe { _ffi_js_Window__set_title(self.0, title_ptr, title_len, title_cap) }; } fn get_size(&self) -> (i32, i32) { unsafe extern "C" { fn _ffi_js_Window__get_size(_: *const u8, _: *const _ffi_ret_2_i32); } unsafe { _ffi_js_Window__get_size(self.0, std::ptr::addr_of!(_FFI_RET_2_I32)) } let ret_0 = unsafe { _FFI_RET_2_I32.0 }; let ret_1 = unsafe { _FFI_RET_2_I32.1 }; (ret_0, ret_1) } fn set_size(&self, width: i32, height: i32) { unsafe extern "C" { fn _ffi_js_Window__set_size(_: *const u8, width: i32, height: i32); } unsafe { _ffi_js_Window__set_size(self.0, width, height) }; } fn set_handler(&self, handler: Box) { unsafe extern "C" { fn _ffi_js_Window__set_handler(_: *const u8, handler_ptr: *const u8); } unsafe { _ffi_js_Window__set_handler(self.0, Box::into_raw(Box::new(handler)) as *const u8) }; } fn child_window(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_js_Window__child_window(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_js_Window__child_window(self.0) }; std::rc::Rc::new(_ffi_rs_Window(ret_ptr)) } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Handler(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_TextRun_to_js(items: Vec, buf: &mut Vec) { for item in items { let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.rect.x, buf); _ffi_write(item.rect.y, buf); _ffi_write(item.rect.w, buf); _ffi_write(item.rect.h, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_demo_const_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export const CONST_FALSE: boolean; export const CONST_TRUE: boolean; export const CONST_U8_MIN: number; export const CONST_U8_MAX: number; export const CONST_U16_MIN: number; export const CONST_U16_MAX: number; export const CONST_U32_MIN: number; export const CONST_U32_MAX: number; export const CONST_U64_MIN: bigint; export const CONST_U64_MAX: bigint; export const CONST_I8_MIN: number; export const CONST_I8_MAX: number; export const CONST_I16_MIN: number; export const CONST_I16_MAX: number; export const CONST_I32_MIN: number; export const CONST_I32_MAX: number; export const CONST_I64_MIN: bigint; export const CONST_I64_MAX: bigint; export const CONST_F32_NEG_0: number; export const CONST_F64_NEG_0: number; export const CONST_F32_PI: number; export const CONST_F64_PI: number; export const CONST_STRING: string; export function rust_mem_leaked(): number; ================================================ FILE: src/tests/snapshots/wasm_demo_const_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const CONST_FALSE = false; export const CONST_TRUE = true; export const CONST_U8_MIN = 0; export const CONST_U8_MAX = 255; export const CONST_U16_MIN = 0; export const CONST_U16_MAX = 65535; export const CONST_U32_MIN = 0; export const CONST_U32_MAX = 4294967295; export const CONST_U64_MIN = 0n; export const CONST_U64_MAX = 18446744073709551615n; export const CONST_I8_MIN = -128; export const CONST_I8_MAX = 127; export const CONST_I16_MIN = -32768; export const CONST_I16_MAX = 32767; export const CONST_I32_MIN = -2147483648; export const CONST_I32_MAX = 2147483647; export const CONST_I64_MIN = -9223372036854775808n; export const CONST_I64_MAX = 9223372036854775807n; export const CONST_F32_NEG_0 = -0; export const CONST_F64_NEG_0 = -0; export const CONST_F32_PI = 3.1415927410125732; export const CONST_F64_PI = -3.141592653589793; export const CONST_STRING = "\x00\r\n🦀"; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_const_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export const CONST_FALSE: boolean = false; export const CONST_TRUE: boolean = true; export const CONST_U8_MIN: number = 0; export const CONST_U8_MAX: number = 255; export const CONST_U16_MIN: number = 0; export const CONST_U16_MAX: number = 65535; export const CONST_U32_MIN: number = 0; export const CONST_U32_MAX: number = 4294967295; export const CONST_U64_MIN: bigint = 0n; export const CONST_U64_MAX: bigint = 18446744073709551615n; export const CONST_I8_MIN: number = -128; export const CONST_I8_MAX: number = 127; export const CONST_I16_MIN: number = -32768; export const CONST_I16_MAX: number = 32767; export const CONST_I32_MIN: number = -2147483648; export const CONST_I32_MAX: number = 2147483647; export const CONST_I64_MIN: bigint = -9223372036854775808n; export const CONST_I64_MAX: bigint = 9223372036854775807n; export const CONST_F32_NEG_0: number = -0; export const CONST_F64_NEG_0: number = -0; export const CONST_F32_PI: number = 3.1415927410125732; export const CONST_F64_PI: number = -3.141592653589793; export const CONST_STRING: string = "\x00\r\n🦀"; export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_const_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_demo_const_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export const CONST_FALSE: boolean; export const CONST_TRUE: boolean; export const CONST_U8_MIN: number; export const CONST_U8_MAX: number; export const CONST_U16_MIN: number; export const CONST_U16_MAX: number; export const CONST_U32_MIN: number; export const CONST_U32_MAX: number; export const CONST_U64_MIN: bigint; export const CONST_U64_MAX: bigint; export const CONST_I8_MIN: number; export const CONST_I8_MAX: number; export const CONST_I16_MIN: number; export const CONST_I16_MAX: number; export const CONST_I32_MIN: number; export const CONST_I32_MAX: number; export const CONST_I64_MIN: bigint; export const CONST_I64_MAX: bigint; export const CONST_F32_NEG_0: number; export const CONST_F64_NEG_0: number; export const CONST_F32_PI: number; export const CONST_F64_PI: number; export const CONST_STRING: string; export function rust_mem_leaked(): number; ================================================ FILE: src/tests/snapshots/wasm_demo_const_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const CONST_FALSE = false; export const CONST_TRUE = true; export const CONST_U8_MIN = 0; export const CONST_U8_MAX = 255; export const CONST_U16_MIN = 0; export const CONST_U16_MAX = 65535; export const CONST_U32_MIN = 0; export const CONST_U32_MAX = 4294967295; export const CONST_U64_MIN = 0n; export const CONST_U64_MAX = 18446744073709551615n; export const CONST_I8_MIN = -128; export const CONST_I8_MAX = 127; export const CONST_I16_MIN = -32768; export const CONST_I16_MAX = 32767; export const CONST_I32_MIN = -2147483648; export const CONST_I32_MAX = 2147483647; export const CONST_I64_MIN = -9223372036854775808n; export const CONST_I64_MAX = 9223372036854775807n; export const CONST_F32_NEG_0 = -0; export const CONST_F64_NEG_0 = -0; export const CONST_F32_PI = 3.1415927410125732; export const CONST_F64_PI = -3.141592653589793; export const CONST_STRING = "\x00\r\n🦀"; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_const_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export const CONST_FALSE: boolean = false; export const CONST_TRUE: boolean = true; export const CONST_U8_MIN: number = 0; export const CONST_U8_MAX: number = 255; export const CONST_U16_MIN: number = 0; export const CONST_U16_MAX: number = 65535; export const CONST_U32_MIN: number = 0; export const CONST_U32_MAX: number = 4294967295; export const CONST_U64_MIN: bigint = 0n; export const CONST_U64_MAX: bigint = 18446744073709551615n; export const CONST_I8_MIN: number = -128; export const CONST_I8_MAX: number = 127; export const CONST_I16_MIN: number = -32768; export const CONST_I16_MAX: number = 32767; export const CONST_I32_MIN: number = -2147483648; export const CONST_I32_MAX: number = 2147483647; export const CONST_I64_MIN: bigint = -9223372036854775808n; export const CONST_I64_MAX: bigint = 9223372036854775807n; export const CONST_F32_NEG_0: number = -0; export const CONST_F64_NEG_0: number = -0; export const CONST_F32_PI: number = 3.1415927410125732; export const CONST_F64_PI: number = -3.141592653589793; export const CONST_STRING: string = "\x00\r\n🦀"; export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_const_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type EnumBoxTup = | { readonly $: "Foo", 0: [number, number] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumVecTup = | { readonly $: "Foo", 0: [number, number][] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumOptTup = | { readonly $: "Foo", 0: [number, number] | null } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export interface EmptyStruct { } export interface BoxTup0 { 0: undefined, } export interface BoxTup1 { 0: [number], } export interface BoxTup2 { 0: [number, number], } export interface VecTup0 { 0: undefined[], } export interface VecTup1 { 0: [number][], } export interface VecTup2 { 0: [number, number][], } export interface OptTup0 { 0: undefined | null, } export interface OptTup1 { 0: [number] | null, } export interface OptTup2 { 0: [number, number] | null, } export interface TupBox { 0: [number, boolean], } export interface VecBox { 0: number[], } export interface BoxVec { 0: number[], } export interface OptBox { 0: number | null, } export interface BoxOpt { 0: number | null, } export interface VecBoxVec { 0: number[][], } export interface BoxVecBox { 0: number[], } export interface OptBoxOpt { 0: number | null, } export interface BoxOptBox { 0: number | null, } export function rust_mem_leaked(): number; export function empty_tuple(x: undefined): undefined; export function empty_struct(x: EmptyStruct): EmptyStruct; export function box_tup_0(x: BoxTup0): BoxTup0; export function box_tup_1(x: BoxTup1): BoxTup1; export function box_tup_2(x: BoxTup2): BoxTup2; export function vec_tup_0(x: VecTup0): VecTup0; export function vec_tup_1(x: VecTup1): VecTup1; export function vec_tup_2(x: VecTup2): VecTup2; export function opt_tup_0(x: OptTup0): OptTup0; export function opt_tup_1(x: OptTup1): OptTup1; export function opt_tup_2(x: OptTup2): OptTup2; export function enum_box_tup(x: EnumBoxTup): EnumBoxTup; export function enum_vec_tup(x: EnumVecTup): EnumVecTup; export function enum_opt_tup(x: EnumOptTup): EnumOptTup; export function tup_box(x: TupBox): TupBox; export function vec_box(x: VecBox): VecBox; export function box_vec(x: BoxVec): BoxVec; export function opt_box(x: OptBox): OptBox; export function box_opt(x: BoxOpt): BoxOpt; export function vec_box_vec(x: VecBoxVec): VecBoxVec; export function box_vec_box(x: BoxVecBox): BoxVecBox; export function opt_box_opt(x: OptBoxOpt): OptBoxOpt; export function box_opt_box(x: BoxOptBox): BoxOptBox; ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x) { _ffi_exports._ffi_fn_empty_tuple(); return undefined; } export function empty_struct(x) { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function box_tup_0(x) { let buf = _ffi_new_WriteBuf(); _ffi_box__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_0(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box__from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_1(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_1(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_2(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_2(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_i32_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_0(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_0(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec__from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_1(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_1(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_2(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_2(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_i32_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_0(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; } let multi_ret = _ffi_exports._ffi_fn_opt_tup_0(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? undefined : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_1(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_1(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? [_ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_2(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); _ffi_write_i32(buf, x_0_val[1]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_2(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? [_ffi_read_i32(buf2), _ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_box_tup(x) { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumBoxTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_box_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_enum_EnumBoxTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_vec_tup(x) { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumVecTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_vec_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_enum_EnumVecTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_opt_tup(x) { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumOptTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_opt_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_enum_EnumOptTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function tup_box(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust2(x[0][0], buf); _ffi_box_bool_to_rust(x[0][1], buf); let multi_ret = _ffi_exports._ffi_fn_tup_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: [_ffi_box_i32_from_rust2(buf2), _ffi_box_bool_from_rust(buf2)] }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_box_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_vec_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_i32_to_rust2(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? _ffi_box_i32_from_rust2(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_option_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_option_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box_vec(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box_vec(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_box_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec_box(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_vec_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box_opt(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_option_i32_to_rust(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box_opt(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? _ffi_box_option_i32_from_rust(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt_box(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_option_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_option_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_enum_EnumBoxTup__Bar = { $: "Bar" }; let _ffi_enum_EnumOptTup__Bar = { $: "Bar" }; let _ffi_enum_EnumVecTup__Bar = { $: "Bar" }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box__from_rust(buf) { return undefined; } function _ffi_box__to_rust(val, buf) { } function _ffi_box_bool_from_rust(buf) { return !!_ffi_read_u8(buf); } function _ffi_box_bool_to_rust(val, buf) { _ffi_write_i8(buf, +val); } function _ffi_box_i32_from_rust(buf) { return [_ffi_read_i32(buf)]; } function _ffi_box_i32_from_rust2(buf) { return _ffi_read_i32(buf); } function _ffi_box_i32_i32_from_rust(buf) { return [_ffi_read_i32(buf), _ffi_read_i32(buf)]; } function _ffi_box_i32_i32_to_rust(val, buf) { _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); } function _ffi_box_i32_to_rust(val, buf) { _ffi_write_i32(buf, val[0]); } function _ffi_box_i32_to_rust2(val, buf) { _ffi_write_i32(buf, val); } function _ffi_box_option_box_i32_from_rust(buf) { return _ffi_read_u8(buf) ? _ffi_box_i32_from_rust2(buf) : null; } function _ffi_box_option_box_i32_to_rust(val, buf) { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { let val_val = val; _ffi_box_i32_to_rust2(val_val, buf); } } function _ffi_box_option_i32_from_rust(buf) { return _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null; } function _ffi_box_option_i32_to_rust(val, buf) { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { _ffi_write_i32(buf, val); } } function _ffi_box_vec_box_i32_from_rust(buf) { return _ffi_vec_box_i32_from_rust(_ffi_read_u32(buf), buf); } function _ffi_box_vec_box_i32_to_rust(val, buf) { _ffi_write_i32(buf, val.length); _ffi_vec_box_i32_to_rust(val, buf); } function _ffi_box_vec_i32_from_rust(buf) { return _ffi_vec_i32_from_rust2(_ffi_read_u32(buf), buf); } function _ffi_box_vec_i32_to_rust(val, buf) { _ffi_write_i32(buf, val.length); _ffi_vec_i32_to_rust2(val, buf); } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_EnumBoxTup_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_box_i32_i32_from_rust(buf) }; case 1: return _ffi_enum_EnumBoxTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumBoxTup_to_rust(val, buf) { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_box_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumBoxTup\""); } } function _ffi_enum_EnumOptTup_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_read_u8(buf) ? [_ffi_read_i32(buf), _ffi_read_i32(buf)] : null }; case 1: return _ffi_enum_EnumOptTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumOptTup_to_rust(val, buf) { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i8(buf, +(val[0] !== null)); if (val[0] !== null) { let x_val = val[0]; _ffi_write_i32(buf, x_val[0]); _ffi_write_i32(buf, x_val[1]); } break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumOptTup\""); } } function _ffi_enum_EnumVecTup_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_vec_i32_i32_from_rust(_ffi_read_u32(buf), buf) }; case 1: return _ffi_enum_EnumVecTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumVecTup_to_rust(val, buf) { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i32(buf, val[0].length); _ffi_vec_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumVecTup\""); } } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } function _ffi_vec__from_rust(len, buf) { let items = []; while (items.length < len) { items.push(undefined); } return items; } function _ffi_vec__to_rust(items, buf) { } function _ffi_vec_box_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_box_i32_from_rust2(buf)); } return items; } function _ffi_vec_box_i32_to_rust(items, buf) { for (const item of items) { _ffi_box_i32_to_rust2(item, buf); } } function _ffi_vec_box_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_box_vec_i32_from_rust(buf)); } return items; } function _ffi_vec_box_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_box_vec_i32_to_rust(item, buf); } } function _ffi_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push([_ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_from_rust2(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_i32_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push([_ffi_read_i32(buf), _ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, item[1]); } } function _ffi_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[0]); } } function _ffi_vec_i32_to_rust2(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type EnumBoxTup = | { readonly $: "Foo", 0: [number, number] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumVecTup = | { readonly $: "Foo", 0: [number, number][] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumOptTup = | { readonly $: "Foo", 0: [number, number] | null } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export interface EmptyStruct { } export interface BoxTup0 { 0: undefined, } export interface BoxTup1 { 0: [number], } export interface BoxTup2 { 0: [number, number], } export interface VecTup0 { 0: undefined[], } export interface VecTup1 { 0: [number][], } export interface VecTup2 { 0: [number, number][], } export interface OptTup0 { 0: undefined | null, } export interface OptTup1 { 0: [number] | null, } export interface OptTup2 { 0: [number, number] | null, } export interface TupBox { 0: [number, boolean], } export interface VecBox { 0: number[], } export interface BoxVec { 0: number[], } export interface OptBox { 0: number | null, } export interface BoxOpt { 0: number | null, } export interface VecBoxVec { 0: number[][], } export interface BoxVecBox { 0: number[], } export interface OptBoxOpt { 0: number | null, } export interface BoxOptBox { 0: number | null, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x: undefined): undefined { _ffi_exports._ffi_fn_empty_tuple(); return undefined; } export function empty_struct(x: EmptyStruct): EmptyStruct { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function box_tup_0(x: BoxTup0): BoxTup0 { let buf = _ffi_new_WriteBuf(); _ffi_box__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_0(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxTup0 = { 0: _ffi_box__from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_1(x: BoxTup1): BoxTup1 { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_1(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxTup1 = { 0: _ffi_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_2(x: BoxTup2): BoxTup2 { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_2(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxTup2 = { 0: _ffi_box_i32_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_0(x: VecTup0): VecTup0 { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_0(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecTup0 = { 0: _ffi_vec__from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_1(x: VecTup1): VecTup1 { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_1(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecTup1 = { 0: _ffi_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_2(x: VecTup2): VecTup2 { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_2(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecTup2 = { 0: _ffi_vec_i32_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_0(x: OptTup0): OptTup0 { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; } let multi_ret = _ffi_exports._ffi_fn_opt_tup_0(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptTup0 = { 0: has_ret_0 ? undefined : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_1(x: OptTup1): OptTup1 { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_1(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptTup1 = { 0: has_ret_0 ? [_ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_2(x: OptTup2): OptTup2 { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); _ffi_write_i32(buf, x_0_val[1]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_2(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptTup2 = { 0: has_ret_0 ? [_ffi_read_i32(buf2), _ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_box_tup(x: EnumBoxTup): EnumBoxTup { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumBoxTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_box_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: EnumBoxTup = _ffi_enum_EnumBoxTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_vec_tup(x: EnumVecTup): EnumVecTup { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumVecTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_vec_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: EnumVecTup = _ffi_enum_EnumVecTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_opt_tup(x: EnumOptTup): EnumOptTup { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumOptTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_opt_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: EnumOptTup = _ffi_enum_EnumOptTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function tup_box(x: TupBox): TupBox { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust2(x[0][0], buf); _ffi_box_bool_to_rust(x[0][1], buf); let multi_ret = _ffi_exports._ffi_fn_tup_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: TupBox = { 0: [_ffi_box_i32_from_rust2(buf2), _ffi_box_bool_from_rust(buf2)] }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box(x: VecBox): VecBox { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecBox = { 0: _ffi_vec_box_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec(x: BoxVec): BoxVec { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxVec = { 0: _ffi_box_vec_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box(x: OptBox): OptBox { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_i32_to_rust2(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptBox = { 0: has_ret_0 ? _ffi_box_i32_from_rust2(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt(x: BoxOpt): BoxOpt { let buf = _ffi_new_WriteBuf(); _ffi_box_option_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxOpt = { 0: _ffi_box_option_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box_vec(x: VecBoxVec): VecBoxVec { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box_vec(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecBoxVec = { 0: _ffi_vec_box_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec_box(x: BoxVecBox): BoxVecBox { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxVecBox = { 0: _ffi_box_vec_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box_opt(x: OptBoxOpt): OptBoxOpt { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_option_i32_to_rust(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box_opt(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptBoxOpt = { 0: has_ret_0 ? _ffi_box_option_i32_from_rust(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt_box(x: BoxOptBox): BoxOptBox { let buf = _ffi_new_WriteBuf(); _ffi_box_option_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxOptBox = { 0: _ffi_box_option_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_enum_EnumBoxTup__Bar: EnumBoxTup = { $: "Bar" }; let _ffi_enum_EnumOptTup__Bar: EnumOptTup = { $: "Bar" }; let _ffi_enum_EnumVecTup__Bar: EnumVecTup = { $: "Bar" }; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_box__from_rust(buf: _ffi_ReadBuf): undefined { return undefined; } function _ffi_box__to_rust(val: undefined, buf: _ffi_WriteBuf): void { } function _ffi_box_bool_from_rust(buf: _ffi_ReadBuf): boolean { return !!_ffi_read_u8(buf); } function _ffi_box_bool_to_rust(val: boolean, buf: _ffi_WriteBuf): void { _ffi_write_i8(buf, +val); } function _ffi_box_i32_from_rust(buf: _ffi_ReadBuf): [number] { return [_ffi_read_i32(buf)]; } function _ffi_box_i32_from_rust2(buf: _ffi_ReadBuf): number { return _ffi_read_i32(buf); } function _ffi_box_i32_i32_from_rust(buf: _ffi_ReadBuf): [number, number] { return [_ffi_read_i32(buf), _ffi_read_i32(buf)]; } function _ffi_box_i32_i32_to_rust(val: [number, number], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); } function _ffi_box_i32_to_rust(val: [number], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val[0]); } function _ffi_box_i32_to_rust2(val: number, buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val); } function _ffi_box_option_box_i32_from_rust(buf: _ffi_ReadBuf): number | null { return _ffi_read_u8(buf) ? _ffi_box_i32_from_rust2(buf) : null; } function _ffi_box_option_box_i32_to_rust(val: number | null, buf: _ffi_WriteBuf): void { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { let val_val = val; _ffi_box_i32_to_rust2(val_val, buf); } } function _ffi_box_option_i32_from_rust(buf: _ffi_ReadBuf): number | null { return _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null; } function _ffi_box_option_i32_to_rust(val: number | null, buf: _ffi_WriteBuf): void { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { _ffi_write_i32(buf, val); } } function _ffi_box_vec_box_i32_from_rust(buf: _ffi_ReadBuf): number[] { return _ffi_vec_box_i32_from_rust(_ffi_read_u32(buf), buf); } function _ffi_box_vec_box_i32_to_rust(val: number[], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val.length); _ffi_vec_box_i32_to_rust(val, buf); } function _ffi_box_vec_i32_from_rust(buf: _ffi_ReadBuf): number[] { return _ffi_vec_i32_from_rust2(_ffi_read_u32(buf), buf); } function _ffi_box_vec_i32_to_rust(val: number[], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val.length); _ffi_vec_i32_to_rust2(val, buf); } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_EnumBoxTup_from_rust(buf: _ffi_ReadBuf): EnumBoxTup { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_box_i32_i32_from_rust(buf) }; case 1: return _ffi_enum_EnumBoxTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumBoxTup_to_rust(val: EnumBoxTup, buf: _ffi_WriteBuf): void { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_box_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumBoxTup\""); } } function _ffi_enum_EnumOptTup_from_rust(buf: _ffi_ReadBuf): EnumOptTup { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_read_u8(buf) ? [_ffi_read_i32(buf), _ffi_read_i32(buf)] : null }; case 1: return _ffi_enum_EnumOptTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumOptTup_to_rust(val: EnumOptTup, buf: _ffi_WriteBuf): void { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i8(buf, +(val[0] !== null)); if (val[0] !== null) { let x_val = val[0]; _ffi_write_i32(buf, x_val[0]); _ffi_write_i32(buf, x_val[1]); } break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumOptTup\""); } } function _ffi_enum_EnumVecTup_from_rust(buf: _ffi_ReadBuf): EnumVecTup { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_vec_i32_i32_from_rust(_ffi_read_u32(buf), buf) }; case 1: return _ffi_enum_EnumVecTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumVecTup_to_rust(val: EnumVecTup, buf: _ffi_WriteBuf): void { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i32(buf, val[0].length); _ffi_vec_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumVecTup\""); } } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } function _ffi_vec__from_rust(len: number, buf: _ffi_ReadBuf): undefined[] { let items: undefined[] = []; while (items.length < len) { items.push(undefined); } return items; } function _ffi_vec__to_rust(items: undefined[], buf: _ffi_WriteBuf): void { } function _ffi_vec_box_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[] { let items: number[] = []; while (items.length < len) { items.push(_ffi_box_i32_from_rust2(buf)); } return items; } function _ffi_vec_box_i32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_box_i32_to_rust2(item, buf); } } function _ffi_vec_box_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[][] { let items: number[][] = []; while (items.length < len) { items.push(_ffi_box_vec_i32_from_rust(buf)); } return items; } function _ffi_vec_box_vec_i32_to_rust(items: number[][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_box_vec_i32_to_rust(item, buf); } } function _ffi_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): [number][] { let items: [number][] = []; while (items.length < len) { items.push([_ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_from_rust2(len: number, buf: _ffi_ReadBuf): number[] { let items: number[] = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_i32_i32_from_rust(len: number, buf: _ffi_ReadBuf): [number, number][] { let items: [number, number][] = []; while (items.length < len) { items.push([_ffi_read_i32(buf), _ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_i32_to_rust(items: [number, number][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, item[1]); } } function _ffi_vec_i32_to_rust(items: [number][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[0]); } } function _ffi_vec_i32_to_rust2(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_box_opt: (buf_ptr: number) => number, _ffi_fn_box_opt_box: (buf_ptr: number) => number, _ffi_fn_box_tup_0: (buf_ptr: number) => number, _ffi_fn_box_tup_1: (buf_ptr: number) => number, _ffi_fn_box_tup_2: (buf_ptr: number) => number, _ffi_fn_box_vec: (buf_ptr: number) => number, _ffi_fn_box_vec_box: (buf_ptr: number) => number, _ffi_fn_empty_struct: () => void, _ffi_fn_empty_tuple: () => void, _ffi_fn_enum_box_tup: (buf_ptr: number) => number, _ffi_fn_enum_opt_tup: (buf_ptr: number) => number, _ffi_fn_enum_vec_tup: (buf_ptr: number) => number, _ffi_fn_opt_box: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_box_opt: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_tup_0: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_tup_1: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_tup_2: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_tup_box: (buf_ptr: number) => number, _ffi_fn_vec_box: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_box_vec: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_tup_0: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_tup_1: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_tup_2: (buf_ptr: number, x_0_len: number) => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box__from_js(_: &mut *const u8) -> Box<()> { Box::new(()) } #[allow(non_snake_case)] fn _ffi_box__to_js(val: (), _: &mut Vec) { _ = val; } fn _ffi_box_bool_from_js(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_bool_to_js(val: bool, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_i32_from_js(end: &mut *const u8) -> Box<(i32,)> { Box::new((_ffi_read::(end),)) } fn _ffi_box_i32_from_js2(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_i32_i32_from_js(end: &mut *const u8) -> Box<(i32, i32)> { Box::new((_ffi_read::(end), _ffi_read::(end))) } fn _ffi_box_i32_i32_to_js(val: (i32, i32), buf: &mut Vec) { _ffi_write(val.0, buf); _ffi_write(val.1, buf); } fn _ffi_box_i32_to_js(val: (i32,), buf: &mut Vec) { _ffi_write(val.0, buf); } fn _ffi_box_i32_to_js2(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_option_box_i32_from_js(end: &mut *const u8) -> Box>> { Box::new(_ffi_read::(end).then(|| _ffi_box_i32_from_js2(end))) } fn _ffi_box_option_box_i32_to_js(val: Option>, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_box_i32_to_js2(*val_val, buf); } } fn _ffi_box_option_i32_from_js(end: &mut *const u8) -> Box> { Box::new(_ffi_read::(end).then(|| _ffi_read::(end))) } fn _ffi_box_option_i32_to_js(val: Option, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_write(val_val, buf); } } fn _ffi_box_vec_box_i32_from_js(end: &mut *const u8) -> Box>> { Box::new(_ffi_vec_box_i32_from_js(_ffi_read::(end), end)) } fn _ffi_box_vec_box_i32_to_js(val: Vec>, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_box_i32_to_js(val, buf); } fn _ffi_box_vec_i32_from_js(end: &mut *const u8) -> Box> { Box::new(_ffi_vec_i32_from_js2(_ffi_read::(end), end)) } fn _ffi_box_vec_i32_to_js(val: Vec, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_i32_to_js2(val, buf); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_from_js(end: &mut *const u8) -> EnumBoxTup { match _ffi_read::(end) { 0 => EnumBoxTup::Foo(_ffi_box_i32_i32_from_js(end)), 1 => EnumBoxTup::Bar, 2 => EnumBoxTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_to_js(val: EnumBoxTup, buf: &mut Vec) { match val { EnumBoxTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_box_i32_i32_to_js(*x, buf); } EnumBoxTup::Bar => _ffi_write(1 as i32, buf), EnumBoxTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_from_js(end: &mut *const u8) -> EnumOptTup { match _ffi_read::(end) { 0 => EnumOptTup::Foo(_ffi_read::(end).then(|| (_ffi_read::(end), _ffi_read::(end)))), 1 => EnumOptTup::Bar, 2 => EnumOptTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_to_js(val: EnumOptTup, buf: &mut Vec) { match val { EnumOptTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.is_some(), buf); if let Some(x_val) = x { _ffi_write(x_val.0, buf); _ffi_write(x_val.1, buf); } } EnumOptTup::Bar => _ffi_write(1 as i32, buf), EnumOptTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_from_js(end: &mut *const u8) -> EnumVecTup { match _ffi_read::(end) { 0 => EnumVecTup::Foo(_ffi_vec_i32_i32_from_js(_ffi_read::(end), end)), 1 => EnumVecTup::Bar, 2 => EnumVecTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_to_js(val: EnumVecTup, buf: &mut Vec) { match val { EnumVecTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.len(), buf); _ffi_vec_i32_i32_to_js(x, buf); } EnumVecTup::Bar => _ffi_write(1 as i32, buf), EnumVecTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt(BoxOpt(_ffi_box_option_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_option_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt_box(BoxOptBox(_ffi_box_option_box_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_option_box_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_0(BoxTup0(_ffi_box__from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box__to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_1(BoxTup1(_ffi_box_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_2(BoxTup2(_ffi_box_i32_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_i32_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec(BoxVec(_ffi_box_vec_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_vec_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec_box(BoxVecBox(_ffi_box_vec_box_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_vec_box_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(EmptyStruct); } #[no_mangle] extern "C" fn _ffi_fn_empty_tuple() { _ = empty_tuple(()); } #[no_mangle] extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumBoxTup_to_js(enum_box_tup(_ffi_enum_EnumBoxTup_from_js(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumOptTup_to_js(enum_opt_tup(_ffi_enum_EnumOptTup_from_js(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumVecTup_to_js(enum_vec_tup(_ffi_enum_EnumVecTup_from_js(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box(OptBox(has_x_0.then(|| _ffi_box_i32_from_js2(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_i32_to_js2(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box_opt(OptBoxOpt(has_x_0.then(|| _ffi_box_option_i32_from_js(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_option_i32_to_js(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let buf_end = buf_ptr; let ret = opt_tup_0(OptTup0(has_x_0.then(|| ()))); let ret_0 = ret.0; let buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ = ret_0_val; } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_1(OptTup1(has_x_0.then(|| (_ffi_read::(&mut buf_end),)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_2(OptTup2(has_x_0.then(|| (_ffi_read::(&mut buf_end), _ffi_read::(&mut buf_end))))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); _ffi_write(ret_0_val.1, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = tup_box(TupBox((_ffi_box_i32_from_js2(&mut buf_end), _ffi_box_bool_from_js(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_js2(*ret_0.0, &mut buf2); _ffi_box_bool_to_js(*ret_0.1, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box(VecBox(_ffi_vec_box_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box_vec(VecBoxVec(_ffi_vec_box_vec_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_vec_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_0(VecTup0(_ffi_vec__from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec__to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_1(VecTup1(_ffi_vec_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_2(VecTup2(_ffi_vec_i32_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); static mut _FFI_RET_PTR_USIZE_BOOL: _ffi_ret_ptr_usize_bool = _ffi_ret_ptr_usize_bool(std::ptr::null(), 0, false); #[allow(non_snake_case)] fn _ffi_vec__from_js(len: usize, _: &mut *const u8) -> Vec<()> { let mut items = Vec::<()>::with_capacity(len); for _ in 0..len { items.push(()); } items } #[allow(non_snake_case)] fn _ffi_vec__to_js(items: Vec<()>, _: &mut Vec) { for item in items { _ = item; } } fn _ffi_vec_box_i32_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_i32_from_js2(end)); } items } fn _ffi_vec_box_i32_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_box_i32_to_js2(*item, buf); } } fn _ffi_vec_box_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec>> { let mut items = Vec::>>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_vec_i32_from_js(end)); } items } fn _ffi_vec_box_vec_i32_to_js(items: Vec>>, buf: &mut Vec) { for item in items { _ffi_box_vec_i32_to_js(*item, buf); } } fn _ffi_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec<(i32,)> { let mut items = Vec::<(i32,)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end),)); } items } fn _ffi_vec_i32_from_js2(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_i32_from_js(len: usize, end: &mut *const u8) -> Vec<(i32, i32)> { let mut items = Vec::<(i32, i32)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end), _ffi_read::(end))); } items } fn _ffi_vec_i32_i32_to_js(items: Vec<(i32, i32)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); _ffi_write(item.1, buf); } } fn _ffi_vec_i32_to_js(items: Vec<(i32,)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); } } fn _ffi_vec_i32_to_js2(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type EnumBoxTup = | { readonly $: "Foo", 0: [number, number] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumVecTup = | { readonly $: "Foo", 0: [number, number][] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumOptTup = | { readonly $: "Foo", 0: [number, number] | null } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export interface EmptyStruct { } export interface BoxTup0 { 0: undefined, } export interface BoxTup1 { 0: [number], } export interface BoxTup2 { 0: [number, number], } export interface VecTup0 { 0: undefined[], } export interface VecTup1 { 0: [number][], } export interface VecTup2 { 0: [number, number][], } export interface OptTup0 { 0: undefined | null, } export interface OptTup1 { 0: [number] | null, } export interface OptTup2 { 0: [number, number] | null, } export interface TupBox { 0: [number, boolean], } export interface VecBox { 0: number[], } export interface BoxVec { 0: number[], } export interface OptBox { 0: number | null, } export interface BoxOpt { 0: number | null, } export interface VecBoxVec { 0: number[][], } export interface BoxVecBox { 0: number[], } export interface OptBoxOpt { 0: number | null, } export interface BoxOptBox { 0: number | null, } export function rust_mem_leaked(): number; export function empty_tuple(x: undefined): undefined; export function empty_struct(x: EmptyStruct): EmptyStruct; export function box_tup_0(x: BoxTup0): BoxTup0; export function box_tup_1(x: BoxTup1): BoxTup1; export function box_tup_2(x: BoxTup2): BoxTup2; export function vec_tup_0(x: VecTup0): VecTup0; export function vec_tup_1(x: VecTup1): VecTup1; export function vec_tup_2(x: VecTup2): VecTup2; export function opt_tup_0(x: OptTup0): OptTup0; export function opt_tup_1(x: OptTup1): OptTup1; export function opt_tup_2(x: OptTup2): OptTup2; export function enum_box_tup(x: EnumBoxTup): EnumBoxTup; export function enum_vec_tup(x: EnumVecTup): EnumVecTup; export function enum_opt_tup(x: EnumOptTup): EnumOptTup; export function tup_box(x: TupBox): TupBox; export function vec_box(x: VecBox): VecBox; export function box_vec(x: BoxVec): BoxVec; export function opt_box(x: OptBox): OptBox; export function box_opt(x: BoxOpt): BoxOpt; export function vec_box_vec(x: VecBoxVec): VecBoxVec; export function box_vec_box(x: BoxVecBox): BoxVecBox; export function opt_box_opt(x: OptBoxOpt): OptBoxOpt; export function box_opt_box(x: BoxOptBox): BoxOptBox; ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x) { _ffi_exports._ffi_fn_empty_tuple(); return undefined; } export function empty_struct(x) { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function box_tup_0(x) { let buf = _ffi_new_WriteBuf(); _ffi_box__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_0(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box__from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_1(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_1(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_2(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_2(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_i32_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_0(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_0(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec__from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_1(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_1(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_2(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_2(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_i32_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_0(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; } let multi_ret = _ffi_exports._ffi_fn_opt_tup_0(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? undefined : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_1(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_1(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? [_ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_2(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); _ffi_write_i32(buf, x_0_val[1]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_2(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? [_ffi_read_i32(buf2), _ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_box_tup(x) { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumBoxTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_box_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_enum_EnumBoxTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_vec_tup(x) { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumVecTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_vec_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_enum_EnumVecTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_opt_tup(x) { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumOptTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_opt_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_enum_EnumOptTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function tup_box(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust2(x[0][0], buf); _ffi_box_bool_to_rust(x[0][1], buf); let multi_ret = _ffi_exports._ffi_fn_tup_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: [_ffi_box_i32_from_rust2(buf2), _ffi_box_bool_from_rust(buf2)] }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_box_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_vec_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_i32_to_rust2(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? _ffi_box_i32_from_rust2(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_option_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_option_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box_vec(x) { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box_vec(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_vec_box_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec_box(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_vec_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box_opt(x) { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_option_i32_to_rust(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box_opt(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: has_ret_0 ? _ffi_box_option_i32_from_rust(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt_box(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_option_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = { 0: _ffi_box_option_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_enum_EnumBoxTup__Bar = { $: "Bar" }; let _ffi_enum_EnumOptTup__Bar = { $: "Bar" }; let _ffi_enum_EnumVecTup__Bar = { $: "Bar" }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box__from_rust(buf) { return undefined; } function _ffi_box__to_rust(val, buf) { } function _ffi_box_bool_from_rust(buf) { return !!_ffi_read_u8(buf); } function _ffi_box_bool_to_rust(val, buf) { _ffi_write_i8(buf, +val); } function _ffi_box_i32_from_rust(buf) { return [_ffi_read_i32(buf)]; } function _ffi_box_i32_from_rust2(buf) { return _ffi_read_i32(buf); } function _ffi_box_i32_i32_from_rust(buf) { return [_ffi_read_i32(buf), _ffi_read_i32(buf)]; } function _ffi_box_i32_i32_to_rust(val, buf) { _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); } function _ffi_box_i32_to_rust(val, buf) { _ffi_write_i32(buf, val[0]); } function _ffi_box_i32_to_rust2(val, buf) { _ffi_write_i32(buf, val); } function _ffi_box_option_box_i32_from_rust(buf) { return _ffi_read_u8(buf) ? _ffi_box_i32_from_rust2(buf) : null; } function _ffi_box_option_box_i32_to_rust(val, buf) { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { let val_val = val; _ffi_box_i32_to_rust2(val_val, buf); } } function _ffi_box_option_i32_from_rust(buf) { return _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null; } function _ffi_box_option_i32_to_rust(val, buf) { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { _ffi_write_i32(buf, val); } } function _ffi_box_vec_box_i32_from_rust(buf) { return _ffi_vec_box_i32_from_rust(_ffi_read_u32(buf), buf); } function _ffi_box_vec_box_i32_to_rust(val, buf) { _ffi_write_i32(buf, val.length); _ffi_vec_box_i32_to_rust(val, buf); } function _ffi_box_vec_i32_from_rust(buf) { return _ffi_vec_i32_from_rust2(_ffi_read_u32(buf), buf); } function _ffi_box_vec_i32_to_rust(val, buf) { _ffi_write_i32(buf, val.length); _ffi_vec_i32_to_rust2(val, buf); } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_EnumBoxTup_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_box_i32_i32_from_rust(buf) }; case 1: return _ffi_enum_EnumBoxTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumBoxTup_to_rust(val, buf) { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_box_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumBoxTup\""); } } function _ffi_enum_EnumOptTup_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_read_u8(buf) ? [_ffi_read_i32(buf), _ffi_read_i32(buf)] : null }; case 1: return _ffi_enum_EnumOptTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumOptTup_to_rust(val, buf) { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i8(buf, +(val[0] !== null)); if (val[0] !== null) { let x_val = val[0]; _ffi_write_i32(buf, x_val[0]); _ffi_write_i32(buf, x_val[1]); } break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumOptTup\""); } } function _ffi_enum_EnumVecTup_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_vec_i32_i32_from_rust(_ffi_read_u32(buf), buf) }; case 1: return _ffi_enum_EnumVecTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumVecTup_to_rust(val, buf) { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i32(buf, val[0].length); _ffi_vec_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumVecTup\""); } } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } function _ffi_vec__from_rust(len, buf) { let items = []; while (items.length < len) { items.push(undefined); } return items; } function _ffi_vec__to_rust(items, buf) { } function _ffi_vec_box_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_box_i32_from_rust2(buf)); } return items; } function _ffi_vec_box_i32_to_rust(items, buf) { for (const item of items) { _ffi_box_i32_to_rust2(item, buf); } } function _ffi_vec_box_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_box_vec_i32_from_rust(buf)); } return items; } function _ffi_vec_box_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_box_vec_i32_to_rust(item, buf); } } function _ffi_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push([_ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_from_rust2(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_i32_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push([_ffi_read_i32(buf), _ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, item[1]); } } function _ffi_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[0]); } } function _ffi_vec_i32_to_rust2(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type EnumBoxTup = | { readonly $: "Foo", 0: [number, number] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumVecTup = | { readonly $: "Foo", 0: [number, number][] } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export type EnumOptTup = | { readonly $: "Foo", 0: [number, number] | null } | { readonly $: "Bar" } | { readonly $: "Baz", x: number, y: number } export interface EmptyStruct { } export interface BoxTup0 { 0: undefined, } export interface BoxTup1 { 0: [number], } export interface BoxTup2 { 0: [number, number], } export interface VecTup0 { 0: undefined[], } export interface VecTup1 { 0: [number][], } export interface VecTup2 { 0: [number, number][], } export interface OptTup0 { 0: undefined | null, } export interface OptTup1 { 0: [number] | null, } export interface OptTup2 { 0: [number, number] | null, } export interface TupBox { 0: [number, boolean], } export interface VecBox { 0: number[], } export interface BoxVec { 0: number[], } export interface OptBox { 0: number | null, } export interface BoxOpt { 0: number | null, } export interface VecBoxVec { 0: number[][], } export interface BoxVecBox { 0: number[], } export interface OptBoxOpt { 0: number | null, } export interface BoxOptBox { 0: number | null, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x: undefined): undefined { _ffi_exports._ffi_fn_empty_tuple(); return undefined; } export function empty_struct(x: EmptyStruct): EmptyStruct { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function box_tup_0(x: BoxTup0): BoxTup0 { let buf = _ffi_new_WriteBuf(); _ffi_box__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_0(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxTup0 = { 0: _ffi_box__from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_1(x: BoxTup1): BoxTup1 { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_1(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxTup1 = { 0: _ffi_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_tup_2(x: BoxTup2): BoxTup2 { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_tup_2(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxTup2 = { 0: _ffi_box_i32_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_0(x: VecTup0): VecTup0 { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec__to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_0(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecTup0 = { 0: _ffi_vec__from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_1(x: VecTup1): VecTup1 { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_1(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecTup1 = { 0: _ffi_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_tup_2(x: VecTup2): VecTup2 { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_i32_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_tup_2(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecTup2 = { 0: _ffi_vec_i32_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_0(x: OptTup0): OptTup0 { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; } let multi_ret = _ffi_exports._ffi_fn_opt_tup_0(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptTup0 = { 0: has_ret_0 ? undefined : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_1(x: OptTup1): OptTup1 { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_1(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptTup1 = { 0: has_ret_0 ? [_ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_tup_2(x: OptTup2): OptTup2 { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_write_i32(buf, x_0_val[0]); _ffi_write_i32(buf, x_0_val[1]); } let multi_ret = _ffi_exports._ffi_fn_opt_tup_2(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptTup2 = { 0: has_ret_0 ? [_ffi_read_i32(buf2), _ffi_read_i32(buf2)] : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_box_tup(x: EnumBoxTup): EnumBoxTup { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumBoxTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_box_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: EnumBoxTup = _ffi_enum_EnumBoxTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_vec_tup(x: EnumVecTup): EnumVecTup { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumVecTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_vec_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: EnumVecTup = _ffi_enum_EnumVecTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function enum_opt_tup(x: EnumOptTup): EnumOptTup { let buf = _ffi_new_WriteBuf(); _ffi_enum_EnumOptTup_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_enum_opt_tup(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: EnumOptTup = _ffi_enum_EnumOptTup_from_rust(buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function tup_box(x: TupBox): TupBox { let buf = _ffi_new_WriteBuf(); _ffi_box_i32_to_rust2(x[0][0], buf); _ffi_box_bool_to_rust(x[0][1], buf); let multi_ret = _ffi_exports._ffi_fn_tup_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: TupBox = { 0: [_ffi_box_i32_from_rust2(buf2), _ffi_box_bool_from_rust(buf2)] }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box(x: VecBox): VecBox { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecBox = { 0: _ffi_vec_box_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec(x: BoxVec): BoxVec { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxVec = { 0: _ffi_box_vec_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box(x: OptBox): OptBox { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_i32_to_rust2(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptBox = { 0: has_ret_0 ? _ffi_box_i32_from_rust2(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt(x: BoxOpt): BoxOpt { let buf = _ffi_new_WriteBuf(); _ffi_box_option_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxOpt = { 0: _ffi_box_option_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function vec_box_vec(x: VecBoxVec): VecBoxVec { let buf = _ffi_new_WriteBuf(); let x_0_len = x[0].length; _ffi_vec_box_vec_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_vec_box_vec(_ffi_buf_to_rust(buf), x_0_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_0_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: VecBoxVec = { 0: _ffi_vec_box_vec_i32_from_rust(ret_0_len, buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_vec_box(x: BoxVecBox): BoxVecBox { let buf = _ffi_new_WriteBuf(); _ffi_box_vec_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_vec_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxVecBox = { 0: _ffi_box_vec_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function opt_box_opt(x: OptBoxOpt): OptBoxOpt { let buf = _ffi_new_WriteBuf(); let has_x_0 = x[0] !== null; if (x[0] !== null) { let x_0_val = x[0]; _ffi_box_option_i32_to_rust(x_0_val, buf); } let multi_ret = _ffi_exports._ffi_fn_opt_box_opt(_ffi_buf_to_rust(buf), has_x_0); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret_0 = _ffi_dv.getUint8(multi_ret + 8); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: OptBoxOpt = { 0: has_ret_0 ? _ffi_box_option_i32_from_rust(buf2) : null }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } export function box_opt_box(x: BoxOptBox): BoxOptBox { let buf = _ffi_new_WriteBuf(); _ffi_box_option_box_i32_to_rust(x[0], buf); let multi_ret = _ffi_exports._ffi_fn_box_opt_box(_ffi_buf_to_rust(buf)); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret: BoxOptBox = { 0: _ffi_box_option_box_i32_from_rust(buf2) }; _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_enum_EnumBoxTup__Bar: EnumBoxTup = { $: "Bar" }; let _ffi_enum_EnumOptTup__Bar: EnumOptTup = { $: "Bar" }; let _ffi_enum_EnumVecTup__Bar: EnumVecTup = { $: "Bar" }; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_box__from_rust(buf: _ffi_ReadBuf): undefined { return undefined; } function _ffi_box__to_rust(val: undefined, buf: _ffi_WriteBuf): void { } function _ffi_box_bool_from_rust(buf: _ffi_ReadBuf): boolean { return !!_ffi_read_u8(buf); } function _ffi_box_bool_to_rust(val: boolean, buf: _ffi_WriteBuf): void { _ffi_write_i8(buf, +val); } function _ffi_box_i32_from_rust(buf: _ffi_ReadBuf): [number] { return [_ffi_read_i32(buf)]; } function _ffi_box_i32_from_rust2(buf: _ffi_ReadBuf): number { return _ffi_read_i32(buf); } function _ffi_box_i32_i32_from_rust(buf: _ffi_ReadBuf): [number, number] { return [_ffi_read_i32(buf), _ffi_read_i32(buf)]; } function _ffi_box_i32_i32_to_rust(val: [number, number], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); } function _ffi_box_i32_to_rust(val: [number], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val[0]); } function _ffi_box_i32_to_rust2(val: number, buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val); } function _ffi_box_option_box_i32_from_rust(buf: _ffi_ReadBuf): number | null { return _ffi_read_u8(buf) ? _ffi_box_i32_from_rust2(buf) : null; } function _ffi_box_option_box_i32_to_rust(val: number | null, buf: _ffi_WriteBuf): void { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { let val_val = val; _ffi_box_i32_to_rust2(val_val, buf); } } function _ffi_box_option_i32_from_rust(buf: _ffi_ReadBuf): number | null { return _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null; } function _ffi_box_option_i32_to_rust(val: number | null, buf: _ffi_WriteBuf): void { _ffi_write_i8(buf, +(val !== null)); if (val !== null) { _ffi_write_i32(buf, val); } } function _ffi_box_vec_box_i32_from_rust(buf: _ffi_ReadBuf): number[] { return _ffi_vec_box_i32_from_rust(_ffi_read_u32(buf), buf); } function _ffi_box_vec_box_i32_to_rust(val: number[], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val.length); _ffi_vec_box_i32_to_rust(val, buf); } function _ffi_box_vec_i32_from_rust(buf: _ffi_ReadBuf): number[] { return _ffi_vec_i32_from_rust2(_ffi_read_u32(buf), buf); } function _ffi_box_vec_i32_to_rust(val: number[], buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val.length); _ffi_vec_i32_to_rust2(val, buf); } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_EnumBoxTup_from_rust(buf: _ffi_ReadBuf): EnumBoxTup { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_box_i32_i32_from_rust(buf) }; case 1: return _ffi_enum_EnumBoxTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumBoxTup_to_rust(val: EnumBoxTup, buf: _ffi_WriteBuf): void { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_box_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumBoxTup\""); } } function _ffi_enum_EnumOptTup_from_rust(buf: _ffi_ReadBuf): EnumOptTup { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_read_u8(buf) ? [_ffi_read_i32(buf), _ffi_read_i32(buf)] : null }; case 1: return _ffi_enum_EnumOptTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumOptTup_to_rust(val: EnumOptTup, buf: _ffi_WriteBuf): void { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i8(buf, +(val[0] !== null)); if (val[0] !== null) { let x_val = val[0]; _ffi_write_i32(buf, x_val[0]); _ffi_write_i32(buf, x_val[1]); } break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumOptTup\""); } } function _ffi_enum_EnumVecTup_from_rust(buf: _ffi_ReadBuf): EnumVecTup { switch (_ffi_read_i32(buf)) { case 0: return { $: "Foo", 0: _ffi_vec_i32_i32_from_rust(_ffi_read_u32(buf), buf) }; case 1: return _ffi_enum_EnumVecTup__Bar; case 2: return { $: "Baz", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_enum_EnumVecTup_to_rust(val: EnumVecTup, buf: _ffi_WriteBuf): void { switch (val.$) { case "Foo": _ffi_write_i32(buf, 0); _ffi_write_i32(buf, val[0].length); _ffi_vec_i32_i32_to_rust(val[0], buf); break; case "Bar": _ffi_write_i32(buf, 1); break; case "Baz": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; default: throw TypeError("Invalid value for enum \"EnumVecTup\""); } } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } function _ffi_vec__from_rust(len: number, buf: _ffi_ReadBuf): undefined[] { let items: undefined[] = []; while (items.length < len) { items.push(undefined); } return items; } function _ffi_vec__to_rust(items: undefined[], buf: _ffi_WriteBuf): void { } function _ffi_vec_box_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[] { let items: number[] = []; while (items.length < len) { items.push(_ffi_box_i32_from_rust2(buf)); } return items; } function _ffi_vec_box_i32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_box_i32_to_rust2(item, buf); } } function _ffi_vec_box_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[][] { let items: number[][] = []; while (items.length < len) { items.push(_ffi_box_vec_i32_from_rust(buf)); } return items; } function _ffi_vec_box_vec_i32_to_rust(items: number[][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_box_vec_i32_to_rust(item, buf); } } function _ffi_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): [number][] { let items: [number][] = []; while (items.length < len) { items.push([_ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_from_rust2(len: number, buf: _ffi_ReadBuf): number[] { let items: number[] = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_i32_i32_from_rust(len: number, buf: _ffi_ReadBuf): [number, number][] { let items: [number, number][] = []; while (items.length < len) { items.push([_ffi_read_i32(buf), _ffi_read_i32(buf)]); } return items; } function _ffi_vec_i32_i32_to_rust(items: [number, number][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, item[1]); } } function _ffi_vec_i32_to_rust(items: [number][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[0]); } } function _ffi_vec_i32_to_rust2(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_box_opt: (buf_ptr: number) => number, _ffi_fn_box_opt_box: (buf_ptr: number) => number, _ffi_fn_box_tup_0: (buf_ptr: number) => number, _ffi_fn_box_tup_1: (buf_ptr: number) => number, _ffi_fn_box_tup_2: (buf_ptr: number) => number, _ffi_fn_box_vec: (buf_ptr: number) => number, _ffi_fn_box_vec_box: (buf_ptr: number) => number, _ffi_fn_empty_struct: () => void, _ffi_fn_empty_tuple: () => void, _ffi_fn_enum_box_tup: (buf_ptr: number) => number, _ffi_fn_enum_opt_tup: (buf_ptr: number) => number, _ffi_fn_enum_vec_tup: (buf_ptr: number) => number, _ffi_fn_opt_box: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_box_opt: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_tup_0: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_tup_1: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_opt_tup_2: (buf_ptr: number, has_x_0: boolean) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_tup_box: (buf_ptr: number) => number, _ffi_fn_vec_box: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_box_vec: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_tup_0: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_tup_1: (buf_ptr: number, x_0_len: number) => number, _ffi_fn_vec_tup_2: (buf_ptr: number, x_0_len: number) => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_derive_eq_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box__from_js(_: &mut *const u8) -> Box<()> { Box::new(()) } #[allow(non_snake_case)] fn _ffi_box__to_js(val: (), _: &mut Vec) { _ = val; } fn _ffi_box_bool_from_js(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_bool_to_js(val: bool, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_i32_from_js(end: &mut *const u8) -> Box<(i32,)> { Box::new((_ffi_read::(end),)) } fn _ffi_box_i32_from_js2(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } fn _ffi_box_i32_i32_from_js(end: &mut *const u8) -> Box<(i32, i32)> { Box::new((_ffi_read::(end), _ffi_read::(end))) } fn _ffi_box_i32_i32_to_js(val: (i32, i32), buf: &mut Vec) { _ffi_write(val.0, buf); _ffi_write(val.1, buf); } fn _ffi_box_i32_to_js(val: (i32,), buf: &mut Vec) { _ffi_write(val.0, buf); } fn _ffi_box_i32_to_js2(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } fn _ffi_box_option_box_i32_from_js(end: &mut *const u8) -> Box>> { Box::new(_ffi_read::(end).then(|| _ffi_box_i32_from_js2(end))) } fn _ffi_box_option_box_i32_to_js(val: Option>, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_box_i32_to_js2(*val_val, buf); } } fn _ffi_box_option_i32_from_js(end: &mut *const u8) -> Box> { Box::new(_ffi_read::(end).then(|| _ffi_read::(end))) } fn _ffi_box_option_i32_to_js(val: Option, buf: &mut Vec) { _ffi_write(val.is_some(), buf); if let Some(val_val) = val { _ffi_write(val_val, buf); } } fn _ffi_box_vec_box_i32_from_js(end: &mut *const u8) -> Box>> { Box::new(_ffi_vec_box_i32_from_js(_ffi_read::(end), end)) } fn _ffi_box_vec_box_i32_to_js(val: Vec>, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_box_i32_to_js(val, buf); } fn _ffi_box_vec_i32_from_js(end: &mut *const u8) -> Box> { Box::new(_ffi_vec_i32_from_js2(_ffi_read::(end), end)) } fn _ffi_box_vec_i32_to_js(val: Vec, buf: &mut Vec) { _ffi_write(val.len(), buf); _ffi_vec_i32_to_js2(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_from_js(end: &mut *const u8) -> EnumBoxTup { match _ffi_read::(end) { 0 => EnumBoxTup::Foo(_ffi_box_i32_i32_from_js(end)), 1 => EnumBoxTup::Bar, 2 => EnumBoxTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_EnumBoxTup_to_js(val: EnumBoxTup, buf: &mut Vec) { match val { EnumBoxTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_box_i32_i32_to_js(*x, buf); } EnumBoxTup::Bar => _ffi_write(1 as i32, buf), EnumBoxTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_from_js(end: &mut *const u8) -> EnumOptTup { match _ffi_read::(end) { 0 => EnumOptTup::Foo(_ffi_read::(end).then(|| (_ffi_read::(end), _ffi_read::(end)))), 1 => EnumOptTup::Bar, 2 => EnumOptTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumOptTup_to_js(val: EnumOptTup, buf: &mut Vec) { match val { EnumOptTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.is_some(), buf); if let Some(x_val) = x { _ffi_write(x_val.0, buf); _ffi_write(x_val.1, buf); } } EnumOptTup::Bar => _ffi_write(1 as i32, buf), EnumOptTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_from_js(end: &mut *const u8) -> EnumVecTup { match _ffi_read::(end) { 0 => EnumVecTup::Foo(_ffi_vec_i32_i32_from_js(_ffi_read::(end), end)), 1 => EnumVecTup::Bar, 2 => EnumVecTup::Baz { x: _ffi_read::(end), y: _ffi_read::(end) }, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_EnumVecTup_to_js(val: EnumVecTup, buf: &mut Vec) { match val { EnumVecTup::Foo(x) => { _ffi_write(0 as i32, buf); _ffi_write(x.len(), buf); _ffi_vec_i32_i32_to_js(x, buf); } EnumVecTup::Bar => _ffi_write(1 as i32, buf), EnumVecTup::Baz { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt(BoxOpt(_ffi_box_option_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_option_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_opt_box(BoxOptBox(_ffi_box_option_box_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_option_box_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_0(BoxTup0(_ffi_box__from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box__to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_1(BoxTup1(_ffi_box_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_tup_2(BoxTup2(_ffi_box_i32_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_i32_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec(BoxVec(_ffi_box_vec_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_vec_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = box_vec_box(BoxVecBox(_ffi_box_vec_box_i32_from_js(&mut buf_end))); let mut buf2 = Vec::::new(); _ffi_box_vec_box_i32_to_js(*ret.0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(EmptyStruct); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple() { _ = empty_tuple(()); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumBoxTup_to_js(enum_box_tup(_ffi_enum_EnumBoxTup_from_js(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumOptTup_to_js(enum_opt_tup(_ffi_enum_EnumOptTup_from_js(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let mut buf2 = Vec::::new(); _ffi_enum_EnumVecTup_to_js(enum_vec_tup(_ffi_enum_EnumVecTup_from_js(&mut buf_end)), &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box(OptBox(has_x_0.then(|| _ffi_box_i32_from_js2(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_i32_to_js2(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_box_opt(OptBoxOpt(has_x_0.then(|| _ffi_box_option_i32_from_js(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_box_option_i32_to_js(*ret_0_val, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let buf_end = buf_ptr; let ret = opt_tup_0(OptTup0(has_x_0.then(|| ()))); let ret_0 = ret.0; let buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ = ret_0_val; } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_1(OptTup1(has_x_0.then(|| (_ffi_read::(&mut buf_end),)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> *const _ffi_ret_ptr_usize_bool { let mut buf_end = buf_ptr; let ret = opt_tup_2(OptTup2(has_x_0.then(|| (_ffi_read::(&mut buf_end), _ffi_read::(&mut buf_end))))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let has_ret_0 = ret_0.is_some(); if let Some(ret_0_val) = ret_0 { _ffi_write(ret_0_val.0, &mut buf2); _ffi_write(ret_0_val.1, &mut buf2); } _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr2, buf_cap, has_ret_0); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> *const _ffi_ret_ptr_usize { let mut buf_end = buf_ptr; let ret = tup_box(TupBox((_ffi_box_i32_from_js2(&mut buf_end), _ffi_box_bool_from_js(&mut buf_end)))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); _ffi_box_i32_to_js2(*ret_0.0, &mut buf2); _ffi_box_bool_to_js(*ret_0.1, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr2, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box(VecBox(_ffi_vec_box_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_box_vec(VecBoxVec(_ffi_vec_box_vec_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_box_vec_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_0(VecTup0(_ffi_vec__from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec__to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_1(VecTup1(_ffi_vec_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = vec_tup_2(VecTup2(_ffi_vec_i32_i32_from_js(x_0_len, &mut buf_end))); let ret_0 = ret.0; let mut buf2 = Vec::::new(); let ret_0_len = ret_0.len(); _ffi_vec_i32_i32_to_js(ret_0, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_0_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); static mut _FFI_RET_PTR_USIZE_BOOL: _ffi_ret_ptr_usize_bool = _ffi_ret_ptr_usize_bool(std::ptr::null(), 0, false); #[allow(non_snake_case)] fn _ffi_vec__from_js(len: usize, _: &mut *const u8) -> Vec<()> { let mut items = Vec::<()>::with_capacity(len); for _ in 0..len { items.push(()); } items } #[allow(non_snake_case)] fn _ffi_vec__to_js(items: Vec<()>, _: &mut Vec) { for item in items { _ = item; } } fn _ffi_vec_box_i32_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_i32_from_js2(end)); } items } fn _ffi_vec_box_i32_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_box_i32_to_js2(*item, buf); } } fn _ffi_vec_box_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec>> { let mut items = Vec::>>::with_capacity(len); for _ in 0..len { items.push(_ffi_box_vec_i32_from_js(end)); } items } fn _ffi_vec_box_vec_i32_to_js(items: Vec>>, buf: &mut Vec) { for item in items { _ffi_box_vec_i32_to_js(*item, buf); } } fn _ffi_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec<(i32,)> { let mut items = Vec::<(i32,)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end),)); } items } fn _ffi_vec_i32_from_js2(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_i32_from_js(len: usize, end: &mut *const u8) -> Vec<(i32, i32)> { let mut items = Vec::<(i32, i32)>::with_capacity(len); for _ in 0..len { items.push((_ffi_read::(end), _ffi_read::(end))); } items } fn _ffi_vec_i32_i32_to_js(items: Vec<(i32, i32)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); _ffi_write(item.1, buf); } } fn _ffi_vec_i32_to_js(items: Vec<(i32,)>, buf: &mut Vec) { for item in items { _ffi_write(item.0, buf); } } fn _ffi_vec_i32_to_js2(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type NestedBox = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedBox } export type NestedVec = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedVec[] } export type NestedOption = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedOption | null } export type NestedTuple = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, NestedTuple] } export type NestedStruct = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerStruct] } export type NestedEnum = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerEnum] } export type InnerEnum = | { readonly $: "Foo", 0: NestedEnum } export interface InnerStruct { x: NestedStruct, } export function rust_mem_leaked(): number; ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type NestedBox = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedBox } export type NestedVec = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedVec[] } export type NestedOption = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedOption | null } export type NestedTuple = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, NestedTuple] } export type NestedStruct = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerStruct] } export type NestedEnum = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerEnum] } export type InnerEnum = | { readonly $: "Foo", 0: NestedEnum } export interface InnerStruct { x: NestedStruct, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type NestedBox = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedBox } export type NestedVec = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedVec[] } export type NestedOption = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedOption | null } export type NestedTuple = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, NestedTuple] } export type NestedStruct = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerStruct] } export type NestedEnum = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerEnum] } export type InnerEnum = | { readonly $: "Foo", 0: NestedEnum } export interface InnerStruct { x: NestedStruct, } export function rust_mem_leaked(): number; ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type NestedBox = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedBox } export type NestedVec = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedVec[] } export type NestedOption = | { readonly $: "Foo" } | { readonly $: "Bar", 0: NestedOption | null } export type NestedTuple = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, NestedTuple] } export type NestedStruct = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerStruct] } export type NestedEnum = | { readonly $: "Foo" } | { readonly $: "Bar", 0: [number, InnerEnum] } export type InnerEnum = | { readonly $: "Foo", 0: NestedEnum } export interface InnerStruct { x: NestedStruct, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_enum_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function test_alignas(alignas: number): number; export function test_alignof(alignof: number): number; export function test_and(and: number): number; export function test_and_eq(and_eq: number): number; export function test_asm(asm: number): number; export function test_associatedtype(associatedtype: number): number; export function test_associativity(associativity: number): number; export function test_atomic_cancel(atomic_cancel: number): number; export function test_atomic_commit(atomic_commit: number): number; export function test_atomic_noexcept(atomic_noexcept: number): number; export function test_auto(auto: number): number; export function test_bitand(bitand: number): number; export function test_bitor(bitor: number): number; export function test_bool(bool: number): number; export function test_boolean(boolean2: number): number; export function test_borrowing(borrowing: number): number; export function test_byte(byte2: number): number; export function test_case(case2: number): number; export function test_catch(catch2: number): number; export function test_char(char2: number): number; export function test_char16_t(char16_t: number): number; export function test_char32_t(char32_t: number): number; export function test_char8_t(char8_t: number): number; export function test_class(class2: number): number; export function test_co_await(co_await: number): number; export function test_co_return(co_return: number): number; export function test_co_yield(co_yield: number): number; export function test_compl(compl: number): number; export function test_concept(concept: number): number; export function test_const_cast(const_cast: number): number; export function test_consteval(consteval: number): number; export function test_constexpr(constexpr: number): number; export function test_constinit(constinit: number): number; export function test_consuming(consuming: number): number; export function test_contract_assert(contract_assert: number): number; export function test_convenience(convenience: number): number; export function test_debugger(debugger2: number): number; export function test_decltype(decltype: number): number; export function test_default(default2: number): number; export function test_defer(defer: number): number; export function test_deinit(deinit: number): number; export function test_delete(delete2: number): number; export function test_double(double2: number): number; export function test_dynamic(dynamic: number): number; export function test_dynamic_cast(dynamic_cast: number): number; export function test_explicit(explicit: number): number; export function test_export(export2: number): number; export function test_extends(extends2: number): number; export function test_extension(extension: number): number; export function test_fallthrough(fallthrough: number): number; export function test_fileprivate(fileprivate: number): number; export function test_finally(finally2: number): number; export function test_float(float2: number): number; export function test_friend(friend: number): number; export function test_func(func: number): number; export function test_function(function2: number): number; export function test_get(get: number): number; export function test_goto(goto2: number): number; export function test_guard(guard: number): number; export function test_implements(implements2: number): number; export function test_import(import2: number): number; export function test_indirect(indirect: number): number; export function test_infix(infix: number): number; export function test_init(init: number): number; export function test_inline(inline: number): number; export function test_inout(inout: number): number; export function test_instanceof(instanceof2: number): number; export function test_int(int2: number): number; export function test_interface(interface2: number): number; export function test_internal(internal: number): number; export function test_is(is: number): number; export function test_lazy(lazy: number): number; export function test_left(left: number): number; export function test_long(long2: number): number; export function test_mutable(mutable: number): number; export function test_mutating(mutating: number): number; export function test_namespace(namespace: number): number; export function test_native(native2: number): number; export function test_new(new2: number): number; export function test_nil(nil: number): number; export function test_noexcept(noexcept: number): number; export function test_none(none: number): number; export function test_nonisolated(nonisolated: number): number; export function test_nonmutating(nonmutating: number): number; export function test_not(not: number): number; export function test_not_eq(not_eq: number): number; export function test_null(null2: number): number; export function test_nullptr(nullptr: number): number; export function test_open(open: number): number; export function test_operator(operator: number): number; export function test_optional(optional: number): number; export function test_or(or: number): number; export function test_or_eq(or_eq: number): number; export function test_package(package2: number): number; export function test_postfix(postfix: number): number; export function test_precedence(precedence: number): number; export function test_precedencegroup(precedencegroup: number): number; export function test_prefix(prefix: number): number; export function test_private(private2: number): number; export function test_protected(protected2: number): number; export function test_protocol(protocol: number): number; export function test_public(public2: number): number; export function test_reflexpr(reflexpr: number): number; export function test_register(register: number): number; export function test_reinterpret_cast(reinterpret_cast: number): number; export function test_repeat(repeat: number): number; export function test_required(required: number): number; export function test_requires(requires: number): number; export function test_rethrows(rethrows: number): number; export function test_right(right: number): number; export function test_set(set: number): number; export function test_short(short2: number): number; export function test_signed(signed: number): number; export function test_sizeof(sizeof: number): number; export function test_some(some: number): number; export function test_static_assert(static_assert: number): number; export function test_static_cast(static_cast: number): number; export function test_subscript(subscript: number): number; export function test_switch(switch2: number): number; export function test_synchronized(synchronized2: number): number; export function test_template(template: number): number; export function test_this(this2: number): number; export function test_thread_local(thread_local: number): number; export function test_throw(throw2: number): number; export function test_throws(throws2: number): number; export function test_transient(transient2: number): number; export function test_typealias(typealias: number): number; export function test_typedef(typedef: number): number; export function test_typeid(typeid: number): number; export function test_typename(typename: number): number; export function test_undefined(undefined2: number): number; export function test_union(union: number): number; export function test_unowned(unowned: number): number; export function test_unsigned(unsigned: number): number; export function test_using(using: number): number; export function test_var(var2: number): number; export function test_void(void2: number): number; export function test_volatile(volatile2: number): number; export function test_wchar_t(wchar_t: number): number; export function test_weak(weak: number): number; export function test_with(with2: number): number; export function test_xor(xor: number): number; export function test_xor_eq(xor_eq: number): number; ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test_alignas(alignas) { return _ffi_exports._ffi_fn_test_alignas(alignas); } export function test_alignof(alignof) { return _ffi_exports._ffi_fn_test_alignof(alignof); } export function test_and(and) { return _ffi_exports._ffi_fn_test_and(and); } export function test_and_eq(and_eq) { return _ffi_exports._ffi_fn_test_and_eq(and_eq); } export function test_asm(asm) { return _ffi_exports._ffi_fn_test_asm(asm); } export function test_associatedtype(associatedtype) { return _ffi_exports._ffi_fn_test_associatedtype(associatedtype); } export function test_associativity(associativity) { return _ffi_exports._ffi_fn_test_associativity(associativity); } export function test_atomic_cancel(atomic_cancel) { return _ffi_exports._ffi_fn_test_atomic_cancel(atomic_cancel); } export function test_atomic_commit(atomic_commit) { return _ffi_exports._ffi_fn_test_atomic_commit(atomic_commit); } export function test_atomic_noexcept(atomic_noexcept) { return _ffi_exports._ffi_fn_test_atomic_noexcept(atomic_noexcept); } export function test_auto(auto) { return _ffi_exports._ffi_fn_test_auto(auto); } export function test_bitand(bitand) { return _ffi_exports._ffi_fn_test_bitand(bitand); } export function test_bitor(bitor) { return _ffi_exports._ffi_fn_test_bitor(bitor); } export function test_bool(bool) { return _ffi_exports._ffi_fn_test_bool(bool); } export function test_boolean(boolean2) { return _ffi_exports._ffi_fn_test_boolean(boolean2); } export function test_borrowing(borrowing) { return _ffi_exports._ffi_fn_test_borrowing(borrowing); } export function test_byte(byte2) { return _ffi_exports._ffi_fn_test_byte(byte2); } export function test_case(case2) { return _ffi_exports._ffi_fn_test_case(case2); } export function test_catch(catch2) { return _ffi_exports._ffi_fn_test_catch(catch2); } export function test_char(char2) { return _ffi_exports._ffi_fn_test_char(char2); } export function test_char16_t(char16_t) { return _ffi_exports._ffi_fn_test_char16_t(char16_t); } export function test_char32_t(char32_t) { return _ffi_exports._ffi_fn_test_char32_t(char32_t); } export function test_char8_t(char8_t) { return _ffi_exports._ffi_fn_test_char8_t(char8_t); } export function test_class(class2) { return _ffi_exports._ffi_fn_test_class(class2); } export function test_co_await(co_await) { return _ffi_exports._ffi_fn_test_co_await(co_await); } export function test_co_return(co_return) { return _ffi_exports._ffi_fn_test_co_return(co_return); } export function test_co_yield(co_yield) { return _ffi_exports._ffi_fn_test_co_yield(co_yield); } export function test_compl(compl) { return _ffi_exports._ffi_fn_test_compl(compl); } export function test_concept(concept) { return _ffi_exports._ffi_fn_test_concept(concept); } export function test_const_cast(const_cast) { return _ffi_exports._ffi_fn_test_const_cast(const_cast); } export function test_consteval(consteval) { return _ffi_exports._ffi_fn_test_consteval(consteval); } export function test_constexpr(constexpr) { return _ffi_exports._ffi_fn_test_constexpr(constexpr); } export function test_constinit(constinit) { return _ffi_exports._ffi_fn_test_constinit(constinit); } export function test_consuming(consuming) { return _ffi_exports._ffi_fn_test_consuming(consuming); } export function test_contract_assert(contract_assert) { return _ffi_exports._ffi_fn_test_contract_assert(contract_assert); } export function test_convenience(convenience) { return _ffi_exports._ffi_fn_test_convenience(convenience); } export function test_debugger(debugger2) { return _ffi_exports._ffi_fn_test_debugger(debugger2); } export function test_decltype(decltype) { return _ffi_exports._ffi_fn_test_decltype(decltype); } export function test_default(default2) { return _ffi_exports._ffi_fn_test_default(default2); } export function test_defer(defer) { return _ffi_exports._ffi_fn_test_defer(defer); } export function test_deinit(deinit) { return _ffi_exports._ffi_fn_test_deinit(deinit); } export function test_delete(delete2) { return _ffi_exports._ffi_fn_test_delete(delete2); } export function test_double(double2) { return _ffi_exports._ffi_fn_test_double(double2); } export function test_dynamic(dynamic) { return _ffi_exports._ffi_fn_test_dynamic(dynamic); } export function test_dynamic_cast(dynamic_cast) { return _ffi_exports._ffi_fn_test_dynamic_cast(dynamic_cast); } export function test_explicit(explicit) { return _ffi_exports._ffi_fn_test_explicit(explicit); } export function test_export(export2) { return _ffi_exports._ffi_fn_test_export(export2); } export function test_extends(extends2) { return _ffi_exports._ffi_fn_test_extends(extends2); } export function test_extension(extension) { return _ffi_exports._ffi_fn_test_extension(extension); } export function test_fallthrough(fallthrough) { return _ffi_exports._ffi_fn_test_fallthrough(fallthrough); } export function test_fileprivate(fileprivate) { return _ffi_exports._ffi_fn_test_fileprivate(fileprivate); } export function test_finally(finally2) { return _ffi_exports._ffi_fn_test_finally(finally2); } export function test_float(float2) { return _ffi_exports._ffi_fn_test_float(float2); } export function test_friend(friend) { return _ffi_exports._ffi_fn_test_friend(friend); } export function test_func(func) { return _ffi_exports._ffi_fn_test_func(func); } export function test_function(function2) { return _ffi_exports._ffi_fn_test_function(function2); } export function test_get(get) { return _ffi_exports._ffi_fn_test_get(get); } export function test_goto(goto2) { return _ffi_exports._ffi_fn_test_goto(goto2); } export function test_guard(guard) { return _ffi_exports._ffi_fn_test_guard(guard); } export function test_implements(implements2) { return _ffi_exports._ffi_fn_test_implements(implements2); } export function test_import(import2) { return _ffi_exports._ffi_fn_test_import(import2); } export function test_indirect(indirect) { return _ffi_exports._ffi_fn_test_indirect(indirect); } export function test_infix(infix) { return _ffi_exports._ffi_fn_test_infix(infix); } export function test_init(init) { return _ffi_exports._ffi_fn_test_init(init); } export function test_inline(inline) { return _ffi_exports._ffi_fn_test_inline(inline); } export function test_inout(inout) { return _ffi_exports._ffi_fn_test_inout(inout); } export function test_instanceof(instanceof2) { return _ffi_exports._ffi_fn_test_instanceof(instanceof2); } export function test_int(int2) { return _ffi_exports._ffi_fn_test_int(int2); } export function test_interface(interface2) { return _ffi_exports._ffi_fn_test_interface(interface2); } export function test_internal(internal) { return _ffi_exports._ffi_fn_test_internal(internal); } export function test_is(is) { return _ffi_exports._ffi_fn_test_is(is); } export function test_lazy(lazy) { return _ffi_exports._ffi_fn_test_lazy(lazy); } export function test_left(left) { return _ffi_exports._ffi_fn_test_left(left); } export function test_long(long2) { return _ffi_exports._ffi_fn_test_long(long2); } export function test_mutable(mutable) { return _ffi_exports._ffi_fn_test_mutable(mutable); } export function test_mutating(mutating) { return _ffi_exports._ffi_fn_test_mutating(mutating); } export function test_namespace(namespace) { return _ffi_exports._ffi_fn_test_namespace(namespace); } export function test_native(native2) { return _ffi_exports._ffi_fn_test_native(native2); } export function test_new(new2) { return _ffi_exports._ffi_fn_test_new(new2); } export function test_nil(nil) { return _ffi_exports._ffi_fn_test_nil(nil); } export function test_noexcept(noexcept) { return _ffi_exports._ffi_fn_test_noexcept(noexcept); } export function test_none(none) { return _ffi_exports._ffi_fn_test_none(none); } export function test_nonisolated(nonisolated) { return _ffi_exports._ffi_fn_test_nonisolated(nonisolated); } export function test_nonmutating(nonmutating) { return _ffi_exports._ffi_fn_test_nonmutating(nonmutating); } export function test_not(not) { return _ffi_exports._ffi_fn_test_not(not); } export function test_not_eq(not_eq) { return _ffi_exports._ffi_fn_test_not_eq(not_eq); } export function test_null(null2) { return _ffi_exports._ffi_fn_test_null(null2); } export function test_nullptr(nullptr) { return _ffi_exports._ffi_fn_test_nullptr(nullptr); } export function test_open(open) { return _ffi_exports._ffi_fn_test_open(open); } export function test_operator(operator) { return _ffi_exports._ffi_fn_test_operator(operator); } export function test_optional(optional) { return _ffi_exports._ffi_fn_test_optional(optional); } export function test_or(or) { return _ffi_exports._ffi_fn_test_or(or); } export function test_or_eq(or_eq) { return _ffi_exports._ffi_fn_test_or_eq(or_eq); } export function test_package(package2) { return _ffi_exports._ffi_fn_test_package(package2); } export function test_postfix(postfix) { return _ffi_exports._ffi_fn_test_postfix(postfix); } export function test_precedence(precedence) { return _ffi_exports._ffi_fn_test_precedence(precedence); } export function test_precedencegroup(precedencegroup) { return _ffi_exports._ffi_fn_test_precedencegroup(precedencegroup); } export function test_prefix(prefix) { return _ffi_exports._ffi_fn_test_prefix(prefix); } export function test_private(private2) { return _ffi_exports._ffi_fn_test_private(private2); } export function test_protected(protected2) { return _ffi_exports._ffi_fn_test_protected(protected2); } export function test_protocol(protocol) { return _ffi_exports._ffi_fn_test_protocol(protocol); } export function test_public(public2) { return _ffi_exports._ffi_fn_test_public(public2); } export function test_reflexpr(reflexpr) { return _ffi_exports._ffi_fn_test_reflexpr(reflexpr); } export function test_register(register) { return _ffi_exports._ffi_fn_test_register(register); } export function test_reinterpret_cast(reinterpret_cast) { return _ffi_exports._ffi_fn_test_reinterpret_cast(reinterpret_cast); } export function test_repeat(repeat) { return _ffi_exports._ffi_fn_test_repeat(repeat); } export function test_required(required) { return _ffi_exports._ffi_fn_test_required(required); } export function test_requires(requires) { return _ffi_exports._ffi_fn_test_requires(requires); } export function test_rethrows(rethrows) { return _ffi_exports._ffi_fn_test_rethrows(rethrows); } export function test_right(right) { return _ffi_exports._ffi_fn_test_right(right); } export function test_set(set) { return _ffi_exports._ffi_fn_test_set(set); } export function test_short(short2) { return _ffi_exports._ffi_fn_test_short(short2); } export function test_signed(signed) { return _ffi_exports._ffi_fn_test_signed(signed); } export function test_sizeof(sizeof) { return _ffi_exports._ffi_fn_test_sizeof(sizeof); } export function test_some(some) { return _ffi_exports._ffi_fn_test_some(some); } export function test_static_assert(static_assert) { return _ffi_exports._ffi_fn_test_static_assert(static_assert); } export function test_static_cast(static_cast) { return _ffi_exports._ffi_fn_test_static_cast(static_cast); } export function test_subscript(subscript) { return _ffi_exports._ffi_fn_test_subscript(subscript); } export function test_switch(switch2) { return _ffi_exports._ffi_fn_test_switch(switch2); } export function test_synchronized(synchronized2) { return _ffi_exports._ffi_fn_test_synchronized(synchronized2); } export function test_template(template) { return _ffi_exports._ffi_fn_test_template(template); } export function test_this(this2) { return _ffi_exports._ffi_fn_test_this(this2); } export function test_thread_local(thread_local) { return _ffi_exports._ffi_fn_test_thread_local(thread_local); } export function test_throw(throw2) { return _ffi_exports._ffi_fn_test_throw(throw2); } export function test_throws(throws2) { return _ffi_exports._ffi_fn_test_throws(throws2); } export function test_transient(transient2) { return _ffi_exports._ffi_fn_test_transient(transient2); } export function test_typealias(typealias) { return _ffi_exports._ffi_fn_test_typealias(typealias); } export function test_typedef(typedef) { return _ffi_exports._ffi_fn_test_typedef(typedef); } export function test_typeid(typeid) { return _ffi_exports._ffi_fn_test_typeid(typeid); } export function test_typename(typename) { return _ffi_exports._ffi_fn_test_typename(typename); } export function test_undefined(undefined2) { return _ffi_exports._ffi_fn_test_undefined(undefined2); } export function test_union(union) { return _ffi_exports._ffi_fn_test_union(union); } export function test_unowned(unowned) { return _ffi_exports._ffi_fn_test_unowned(unowned); } export function test_unsigned(unsigned) { return _ffi_exports._ffi_fn_test_unsigned(unsigned); } export function test_using(using) { return _ffi_exports._ffi_fn_test_using(using); } export function test_var(var2) { return _ffi_exports._ffi_fn_test_var(var2); } export function test_void(void2) { return _ffi_exports._ffi_fn_test_void(void2); } export function test_volatile(volatile2) { return _ffi_exports._ffi_fn_test_volatile(volatile2); } export function test_wchar_t(wchar_t) { return _ffi_exports._ffi_fn_test_wchar_t(wchar_t); } export function test_weak(weak) { return _ffi_exports._ffi_fn_test_weak(weak); } export function test_with(with2) { return _ffi_exports._ffi_fn_test_with(with2); } export function test_xor(xor) { return _ffi_exports._ffi_fn_test_xor(xor); } export function test_xor_eq(xor_eq) { return _ffi_exports._ffi_fn_test_xor_eq(xor_eq); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test_alignas(alignas: number): number { return _ffi_exports._ffi_fn_test_alignas(alignas); } export function test_alignof(alignof: number): number { return _ffi_exports._ffi_fn_test_alignof(alignof); } export function test_and(and: number): number { return _ffi_exports._ffi_fn_test_and(and); } export function test_and_eq(and_eq: number): number { return _ffi_exports._ffi_fn_test_and_eq(and_eq); } export function test_asm(asm: number): number { return _ffi_exports._ffi_fn_test_asm(asm); } export function test_associatedtype(associatedtype: number): number { return _ffi_exports._ffi_fn_test_associatedtype(associatedtype); } export function test_associativity(associativity: number): number { return _ffi_exports._ffi_fn_test_associativity(associativity); } export function test_atomic_cancel(atomic_cancel: number): number { return _ffi_exports._ffi_fn_test_atomic_cancel(atomic_cancel); } export function test_atomic_commit(atomic_commit: number): number { return _ffi_exports._ffi_fn_test_atomic_commit(atomic_commit); } export function test_atomic_noexcept(atomic_noexcept: number): number { return _ffi_exports._ffi_fn_test_atomic_noexcept(atomic_noexcept); } export function test_auto(auto: number): number { return _ffi_exports._ffi_fn_test_auto(auto); } export function test_bitand(bitand: number): number { return _ffi_exports._ffi_fn_test_bitand(bitand); } export function test_bitor(bitor: number): number { return _ffi_exports._ffi_fn_test_bitor(bitor); } export function test_bool(bool: number): number { return _ffi_exports._ffi_fn_test_bool(bool); } export function test_boolean(boolean2: number): number { return _ffi_exports._ffi_fn_test_boolean(boolean2); } export function test_borrowing(borrowing: number): number { return _ffi_exports._ffi_fn_test_borrowing(borrowing); } export function test_byte(byte2: number): number { return _ffi_exports._ffi_fn_test_byte(byte2); } export function test_case(case2: number): number { return _ffi_exports._ffi_fn_test_case(case2); } export function test_catch(catch2: number): number { return _ffi_exports._ffi_fn_test_catch(catch2); } export function test_char(char2: number): number { return _ffi_exports._ffi_fn_test_char(char2); } export function test_char16_t(char16_t: number): number { return _ffi_exports._ffi_fn_test_char16_t(char16_t); } export function test_char32_t(char32_t: number): number { return _ffi_exports._ffi_fn_test_char32_t(char32_t); } export function test_char8_t(char8_t: number): number { return _ffi_exports._ffi_fn_test_char8_t(char8_t); } export function test_class(class2: number): number { return _ffi_exports._ffi_fn_test_class(class2); } export function test_co_await(co_await: number): number { return _ffi_exports._ffi_fn_test_co_await(co_await); } export function test_co_return(co_return: number): number { return _ffi_exports._ffi_fn_test_co_return(co_return); } export function test_co_yield(co_yield: number): number { return _ffi_exports._ffi_fn_test_co_yield(co_yield); } export function test_compl(compl: number): number { return _ffi_exports._ffi_fn_test_compl(compl); } export function test_concept(concept: number): number { return _ffi_exports._ffi_fn_test_concept(concept); } export function test_const_cast(const_cast: number): number { return _ffi_exports._ffi_fn_test_const_cast(const_cast); } export function test_consteval(consteval: number): number { return _ffi_exports._ffi_fn_test_consteval(consteval); } export function test_constexpr(constexpr: number): number { return _ffi_exports._ffi_fn_test_constexpr(constexpr); } export function test_constinit(constinit: number): number { return _ffi_exports._ffi_fn_test_constinit(constinit); } export function test_consuming(consuming: number): number { return _ffi_exports._ffi_fn_test_consuming(consuming); } export function test_contract_assert(contract_assert: number): number { return _ffi_exports._ffi_fn_test_contract_assert(contract_assert); } export function test_convenience(convenience: number): number { return _ffi_exports._ffi_fn_test_convenience(convenience); } export function test_debugger(debugger2: number): number { return _ffi_exports._ffi_fn_test_debugger(debugger2); } export function test_decltype(decltype: number): number { return _ffi_exports._ffi_fn_test_decltype(decltype); } export function test_default(default2: number): number { return _ffi_exports._ffi_fn_test_default(default2); } export function test_defer(defer: number): number { return _ffi_exports._ffi_fn_test_defer(defer); } export function test_deinit(deinit: number): number { return _ffi_exports._ffi_fn_test_deinit(deinit); } export function test_delete(delete2: number): number { return _ffi_exports._ffi_fn_test_delete(delete2); } export function test_double(double2: number): number { return _ffi_exports._ffi_fn_test_double(double2); } export function test_dynamic(dynamic: number): number { return _ffi_exports._ffi_fn_test_dynamic(dynamic); } export function test_dynamic_cast(dynamic_cast: number): number { return _ffi_exports._ffi_fn_test_dynamic_cast(dynamic_cast); } export function test_explicit(explicit: number): number { return _ffi_exports._ffi_fn_test_explicit(explicit); } export function test_export(export2: number): number { return _ffi_exports._ffi_fn_test_export(export2); } export function test_extends(extends2: number): number { return _ffi_exports._ffi_fn_test_extends(extends2); } export function test_extension(extension: number): number { return _ffi_exports._ffi_fn_test_extension(extension); } export function test_fallthrough(fallthrough: number): number { return _ffi_exports._ffi_fn_test_fallthrough(fallthrough); } export function test_fileprivate(fileprivate: number): number { return _ffi_exports._ffi_fn_test_fileprivate(fileprivate); } export function test_finally(finally2: number): number { return _ffi_exports._ffi_fn_test_finally(finally2); } export function test_float(float2: number): number { return _ffi_exports._ffi_fn_test_float(float2); } export function test_friend(friend: number): number { return _ffi_exports._ffi_fn_test_friend(friend); } export function test_func(func: number): number { return _ffi_exports._ffi_fn_test_func(func); } export function test_function(function2: number): number { return _ffi_exports._ffi_fn_test_function(function2); } export function test_get(get: number): number { return _ffi_exports._ffi_fn_test_get(get); } export function test_goto(goto2: number): number { return _ffi_exports._ffi_fn_test_goto(goto2); } export function test_guard(guard: number): number { return _ffi_exports._ffi_fn_test_guard(guard); } export function test_implements(implements2: number): number { return _ffi_exports._ffi_fn_test_implements(implements2); } export function test_import(import2: number): number { return _ffi_exports._ffi_fn_test_import(import2); } export function test_indirect(indirect: number): number { return _ffi_exports._ffi_fn_test_indirect(indirect); } export function test_infix(infix: number): number { return _ffi_exports._ffi_fn_test_infix(infix); } export function test_init(init: number): number { return _ffi_exports._ffi_fn_test_init(init); } export function test_inline(inline: number): number { return _ffi_exports._ffi_fn_test_inline(inline); } export function test_inout(inout: number): number { return _ffi_exports._ffi_fn_test_inout(inout); } export function test_instanceof(instanceof2: number): number { return _ffi_exports._ffi_fn_test_instanceof(instanceof2); } export function test_int(int2: number): number { return _ffi_exports._ffi_fn_test_int(int2); } export function test_interface(interface2: number): number { return _ffi_exports._ffi_fn_test_interface(interface2); } export function test_internal(internal: number): number { return _ffi_exports._ffi_fn_test_internal(internal); } export function test_is(is: number): number { return _ffi_exports._ffi_fn_test_is(is); } export function test_lazy(lazy: number): number { return _ffi_exports._ffi_fn_test_lazy(lazy); } export function test_left(left: number): number { return _ffi_exports._ffi_fn_test_left(left); } export function test_long(long2: number): number { return _ffi_exports._ffi_fn_test_long(long2); } export function test_mutable(mutable: number): number { return _ffi_exports._ffi_fn_test_mutable(mutable); } export function test_mutating(mutating: number): number { return _ffi_exports._ffi_fn_test_mutating(mutating); } export function test_namespace(namespace: number): number { return _ffi_exports._ffi_fn_test_namespace(namespace); } export function test_native(native2: number): number { return _ffi_exports._ffi_fn_test_native(native2); } export function test_new(new2: number): number { return _ffi_exports._ffi_fn_test_new(new2); } export function test_nil(nil: number): number { return _ffi_exports._ffi_fn_test_nil(nil); } export function test_noexcept(noexcept: number): number { return _ffi_exports._ffi_fn_test_noexcept(noexcept); } export function test_none(none: number): number { return _ffi_exports._ffi_fn_test_none(none); } export function test_nonisolated(nonisolated: number): number { return _ffi_exports._ffi_fn_test_nonisolated(nonisolated); } export function test_nonmutating(nonmutating: number): number { return _ffi_exports._ffi_fn_test_nonmutating(nonmutating); } export function test_not(not: number): number { return _ffi_exports._ffi_fn_test_not(not); } export function test_not_eq(not_eq: number): number { return _ffi_exports._ffi_fn_test_not_eq(not_eq); } export function test_null(null2: number): number { return _ffi_exports._ffi_fn_test_null(null2); } export function test_nullptr(nullptr: number): number { return _ffi_exports._ffi_fn_test_nullptr(nullptr); } export function test_open(open: number): number { return _ffi_exports._ffi_fn_test_open(open); } export function test_operator(operator: number): number { return _ffi_exports._ffi_fn_test_operator(operator); } export function test_optional(optional: number): number { return _ffi_exports._ffi_fn_test_optional(optional); } export function test_or(or: number): number { return _ffi_exports._ffi_fn_test_or(or); } export function test_or_eq(or_eq: number): number { return _ffi_exports._ffi_fn_test_or_eq(or_eq); } export function test_package(package2: number): number { return _ffi_exports._ffi_fn_test_package(package2); } export function test_postfix(postfix: number): number { return _ffi_exports._ffi_fn_test_postfix(postfix); } export function test_precedence(precedence: number): number { return _ffi_exports._ffi_fn_test_precedence(precedence); } export function test_precedencegroup(precedencegroup: number): number { return _ffi_exports._ffi_fn_test_precedencegroup(precedencegroup); } export function test_prefix(prefix: number): number { return _ffi_exports._ffi_fn_test_prefix(prefix); } export function test_private(private2: number): number { return _ffi_exports._ffi_fn_test_private(private2); } export function test_protected(protected2: number): number { return _ffi_exports._ffi_fn_test_protected(protected2); } export function test_protocol(protocol: number): number { return _ffi_exports._ffi_fn_test_protocol(protocol); } export function test_public(public2: number): number { return _ffi_exports._ffi_fn_test_public(public2); } export function test_reflexpr(reflexpr: number): number { return _ffi_exports._ffi_fn_test_reflexpr(reflexpr); } export function test_register(register: number): number { return _ffi_exports._ffi_fn_test_register(register); } export function test_reinterpret_cast(reinterpret_cast: number): number { return _ffi_exports._ffi_fn_test_reinterpret_cast(reinterpret_cast); } export function test_repeat(repeat: number): number { return _ffi_exports._ffi_fn_test_repeat(repeat); } export function test_required(required: number): number { return _ffi_exports._ffi_fn_test_required(required); } export function test_requires(requires: number): number { return _ffi_exports._ffi_fn_test_requires(requires); } export function test_rethrows(rethrows: number): number { return _ffi_exports._ffi_fn_test_rethrows(rethrows); } export function test_right(right: number): number { return _ffi_exports._ffi_fn_test_right(right); } export function test_set(set: number): number { return _ffi_exports._ffi_fn_test_set(set); } export function test_short(short2: number): number { return _ffi_exports._ffi_fn_test_short(short2); } export function test_signed(signed: number): number { return _ffi_exports._ffi_fn_test_signed(signed); } export function test_sizeof(sizeof: number): number { return _ffi_exports._ffi_fn_test_sizeof(sizeof); } export function test_some(some: number): number { return _ffi_exports._ffi_fn_test_some(some); } export function test_static_assert(static_assert: number): number { return _ffi_exports._ffi_fn_test_static_assert(static_assert); } export function test_static_cast(static_cast: number): number { return _ffi_exports._ffi_fn_test_static_cast(static_cast); } export function test_subscript(subscript: number): number { return _ffi_exports._ffi_fn_test_subscript(subscript); } export function test_switch(switch2: number): number { return _ffi_exports._ffi_fn_test_switch(switch2); } export function test_synchronized(synchronized2: number): number { return _ffi_exports._ffi_fn_test_synchronized(synchronized2); } export function test_template(template: number): number { return _ffi_exports._ffi_fn_test_template(template); } export function test_this(this2: number): number { return _ffi_exports._ffi_fn_test_this(this2); } export function test_thread_local(thread_local: number): number { return _ffi_exports._ffi_fn_test_thread_local(thread_local); } export function test_throw(throw2: number): number { return _ffi_exports._ffi_fn_test_throw(throw2); } export function test_throws(throws2: number): number { return _ffi_exports._ffi_fn_test_throws(throws2); } export function test_transient(transient2: number): number { return _ffi_exports._ffi_fn_test_transient(transient2); } export function test_typealias(typealias: number): number { return _ffi_exports._ffi_fn_test_typealias(typealias); } export function test_typedef(typedef: number): number { return _ffi_exports._ffi_fn_test_typedef(typedef); } export function test_typeid(typeid: number): number { return _ffi_exports._ffi_fn_test_typeid(typeid); } export function test_typename(typename: number): number { return _ffi_exports._ffi_fn_test_typename(typename); } export function test_undefined(undefined2: number): number { return _ffi_exports._ffi_fn_test_undefined(undefined2); } export function test_union(union: number): number { return _ffi_exports._ffi_fn_test_union(union); } export function test_unowned(unowned: number): number { return _ffi_exports._ffi_fn_test_unowned(unowned); } export function test_unsigned(unsigned: number): number { return _ffi_exports._ffi_fn_test_unsigned(unsigned); } export function test_using(using: number): number { return _ffi_exports._ffi_fn_test_using(using); } export function test_var(var2: number): number { return _ffi_exports._ffi_fn_test_var(var2); } export function test_void(void2: number): number { return _ffi_exports._ffi_fn_test_void(void2); } export function test_volatile(volatile2: number): number { return _ffi_exports._ffi_fn_test_volatile(volatile2); } export function test_wchar_t(wchar_t: number): number { return _ffi_exports._ffi_fn_test_wchar_t(wchar_t); } export function test_weak(weak: number): number { return _ffi_exports._ffi_fn_test_weak(weak); } export function test_with(with2: number): number { return _ffi_exports._ffi_fn_test_with(with2); } export function test_xor(xor: number): number { return _ffi_exports._ffi_fn_test_xor(xor); } export function test_xor_eq(xor_eq: number): number { return _ffi_exports._ffi_fn_test_xor_eq(xor_eq); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test_alignas: (alignas: number) => number, _ffi_fn_test_alignof: (alignof: number) => number, _ffi_fn_test_and: (and: number) => number, _ffi_fn_test_and_eq: (and_eq: number) => number, _ffi_fn_test_asm: (asm: number) => number, _ffi_fn_test_associatedtype: (associatedtype: number) => number, _ffi_fn_test_associativity: (associativity: number) => number, _ffi_fn_test_atomic_cancel: (atomic_cancel: number) => number, _ffi_fn_test_atomic_commit: (atomic_commit: number) => number, _ffi_fn_test_atomic_noexcept: (atomic_noexcept: number) => number, _ffi_fn_test_auto: (auto: number) => number, _ffi_fn_test_bitand: (bitand: number) => number, _ffi_fn_test_bitor: (bitor: number) => number, _ffi_fn_test_bool: (bool: number) => number, _ffi_fn_test_boolean: (boolean2: number) => number, _ffi_fn_test_borrowing: (borrowing: number) => number, _ffi_fn_test_byte: (byte2: number) => number, _ffi_fn_test_case: (case2: number) => number, _ffi_fn_test_catch: (catch2: number) => number, _ffi_fn_test_char: (char2: number) => number, _ffi_fn_test_char16_t: (char16_t: number) => number, _ffi_fn_test_char32_t: (char32_t: number) => number, _ffi_fn_test_char8_t: (char8_t: number) => number, _ffi_fn_test_class: (class2: number) => number, _ffi_fn_test_co_await: (co_await: number) => number, _ffi_fn_test_co_return: (co_return: number) => number, _ffi_fn_test_co_yield: (co_yield: number) => number, _ffi_fn_test_compl: (compl: number) => number, _ffi_fn_test_concept: (concept: number) => number, _ffi_fn_test_const_cast: (const_cast: number) => number, _ffi_fn_test_consteval: (consteval: number) => number, _ffi_fn_test_constexpr: (constexpr: number) => number, _ffi_fn_test_constinit: (constinit: number) => number, _ffi_fn_test_consuming: (consuming: number) => number, _ffi_fn_test_contract_assert: (contract_assert: number) => number, _ffi_fn_test_convenience: (convenience: number) => number, _ffi_fn_test_debugger: (debugger2: number) => number, _ffi_fn_test_decltype: (decltype: number) => number, _ffi_fn_test_default: (default2: number) => number, _ffi_fn_test_defer: (defer: number) => number, _ffi_fn_test_deinit: (deinit: number) => number, _ffi_fn_test_delete: (delete2: number) => number, _ffi_fn_test_double: (double2: number) => number, _ffi_fn_test_dynamic: (dynamic: number) => number, _ffi_fn_test_dynamic_cast: (dynamic_cast: number) => number, _ffi_fn_test_explicit: (explicit: number) => number, _ffi_fn_test_export: (export2: number) => number, _ffi_fn_test_extends: (extends2: number) => number, _ffi_fn_test_extension: (extension: number) => number, _ffi_fn_test_fallthrough: (fallthrough: number) => number, _ffi_fn_test_fileprivate: (fileprivate: number) => number, _ffi_fn_test_finally: (finally2: number) => number, _ffi_fn_test_float: (float2: number) => number, _ffi_fn_test_friend: (friend: number) => number, _ffi_fn_test_func: (func: number) => number, _ffi_fn_test_function: (function2: number) => number, _ffi_fn_test_get: (get: number) => number, _ffi_fn_test_goto: (goto2: number) => number, _ffi_fn_test_guard: (guard: number) => number, _ffi_fn_test_implements: (implements2: number) => number, _ffi_fn_test_import: (import2: number) => number, _ffi_fn_test_indirect: (indirect: number) => number, _ffi_fn_test_infix: (infix: number) => number, _ffi_fn_test_init: (init: number) => number, _ffi_fn_test_inline: (inline: number) => number, _ffi_fn_test_inout: (inout: number) => number, _ffi_fn_test_instanceof: (instanceof2: number) => number, _ffi_fn_test_int: (int2: number) => number, _ffi_fn_test_interface: (interface2: number) => number, _ffi_fn_test_internal: (internal: number) => number, _ffi_fn_test_is: (is: number) => number, _ffi_fn_test_lazy: (lazy: number) => number, _ffi_fn_test_left: (left: number) => number, _ffi_fn_test_long: (long2: number) => number, _ffi_fn_test_mutable: (mutable: number) => number, _ffi_fn_test_mutating: (mutating: number) => number, _ffi_fn_test_namespace: (namespace: number) => number, _ffi_fn_test_native: (native2: number) => number, _ffi_fn_test_new: (new2: number) => number, _ffi_fn_test_nil: (nil: number) => number, _ffi_fn_test_noexcept: (noexcept: number) => number, _ffi_fn_test_none: (none: number) => number, _ffi_fn_test_nonisolated: (nonisolated: number) => number, _ffi_fn_test_nonmutating: (nonmutating: number) => number, _ffi_fn_test_not: (not: number) => number, _ffi_fn_test_not_eq: (not_eq: number) => number, _ffi_fn_test_null: (null2: number) => number, _ffi_fn_test_nullptr: (nullptr: number) => number, _ffi_fn_test_open: (open: number) => number, _ffi_fn_test_operator: (operator: number) => number, _ffi_fn_test_optional: (optional: number) => number, _ffi_fn_test_or: (or: number) => number, _ffi_fn_test_or_eq: (or_eq: number) => number, _ffi_fn_test_package: (package2: number) => number, _ffi_fn_test_postfix: (postfix: number) => number, _ffi_fn_test_precedence: (precedence: number) => number, _ffi_fn_test_precedencegroup: (precedencegroup: number) => number, _ffi_fn_test_prefix: (prefix: number) => number, _ffi_fn_test_private: (private2: number) => number, _ffi_fn_test_protected: (protected2: number) => number, _ffi_fn_test_protocol: (protocol: number) => number, _ffi_fn_test_public: (public2: number) => number, _ffi_fn_test_reflexpr: (reflexpr: number) => number, _ffi_fn_test_register: (register: number) => number, _ffi_fn_test_reinterpret_cast: (reinterpret_cast: number) => number, _ffi_fn_test_repeat: (repeat: number) => number, _ffi_fn_test_required: (required: number) => number, _ffi_fn_test_requires: (requires: number) => number, _ffi_fn_test_rethrows: (rethrows: number) => number, _ffi_fn_test_right: (right: number) => number, _ffi_fn_test_set: (set: number) => number, _ffi_fn_test_short: (short2: number) => number, _ffi_fn_test_signed: (signed: number) => number, _ffi_fn_test_sizeof: (sizeof: number) => number, _ffi_fn_test_some: (some: number) => number, _ffi_fn_test_static_assert: (static_assert: number) => number, _ffi_fn_test_static_cast: (static_cast: number) => number, _ffi_fn_test_subscript: (subscript: number) => number, _ffi_fn_test_switch: (switch2: number) => number, _ffi_fn_test_synchronized: (synchronized2: number) => number, _ffi_fn_test_template: (template: number) => number, _ffi_fn_test_this: (this2: number) => number, _ffi_fn_test_thread_local: (thread_local: number) => number, _ffi_fn_test_throw: (throw2: number) => number, _ffi_fn_test_throws: (throws2: number) => number, _ffi_fn_test_transient: (transient2: number) => number, _ffi_fn_test_typealias: (typealias: number) => number, _ffi_fn_test_typedef: (typedef: number) => number, _ffi_fn_test_typeid: (typeid: number) => number, _ffi_fn_test_typename: (typename: number) => number, _ffi_fn_test_undefined: (undefined2: number) => number, _ffi_fn_test_union: (union: number) => number, _ffi_fn_test_unowned: (unowned: number) => number, _ffi_fn_test_unsigned: (unsigned: number) => number, _ffi_fn_test_using: (using: number) => number, _ffi_fn_test_var: (var2: number) => number, _ffi_fn_test_void: (void2: number) => number, _ffi_fn_test_volatile: (volatile2: number) => number, _ffi_fn_test_wchar_t: (wchar_t: number) => number, _ffi_fn_test_weak: (weak: number) => number, _ffi_fn_test_with: (with2: number) => number, _ffi_fn_test_xor: (xor: number) => number, _ffi_fn_test_xor_eq: (xor_eq: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test_alignas(alignas: i32) -> i32 { test_alignas(alignas) } #[no_mangle] extern "C" fn _ffi_fn_test_alignof(alignof: i32) -> i32 { test_alignof(alignof) } #[no_mangle] extern "C" fn _ffi_fn_test_and(and: i32) -> i32 { test_and(and) } #[no_mangle] extern "C" fn _ffi_fn_test_and_eq(and_eq: i32) -> i32 { test_and_eq(and_eq) } #[no_mangle] extern "C" fn _ffi_fn_test_asm(asm: i32) -> i32 { test_asm(asm) } #[no_mangle] extern "C" fn _ffi_fn_test_associatedtype(associatedtype: i32) -> i32 { test_associatedtype(associatedtype) } #[no_mangle] extern "C" fn _ffi_fn_test_associativity(associativity: i32) -> i32 { test_associativity(associativity) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel: i32) -> i32 { test_atomic_cancel(atomic_cancel) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit: i32) -> i32 { test_atomic_commit(atomic_commit) } #[no_mangle] extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept: i32) -> i32 { test_atomic_noexcept(atomic_noexcept) } #[no_mangle] extern "C" fn _ffi_fn_test_auto(auto: i32) -> i32 { test_auto(auto) } #[no_mangle] extern "C" fn _ffi_fn_test_bitand(bitand: i32) -> i32 { test_bitand(bitand) } #[no_mangle] extern "C" fn _ffi_fn_test_bitor(bitor: i32) -> i32 { test_bitor(bitor) } #[no_mangle] extern "C" fn _ffi_fn_test_bool(bool: i32) -> i32 { test_bool(bool) } #[no_mangle] extern "C" fn _ffi_fn_test_boolean(boolean2: i32) -> i32 { test_boolean(boolean2) } #[no_mangle] extern "C" fn _ffi_fn_test_borrowing(borrowing: i32) -> i32 { test_borrowing(borrowing) } #[no_mangle] extern "C" fn _ffi_fn_test_byte(byte2: i32) -> i32 { test_byte(byte2) } #[no_mangle] extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 { test_case(case2) } #[no_mangle] extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 { test_catch(catch2) } #[no_mangle] extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 { test_char(char2) } #[no_mangle] extern "C" fn _ffi_fn_test_char16_t(char16_t: i32) -> i32 { test_char16_t(char16_t) } #[no_mangle] extern "C" fn _ffi_fn_test_char32_t(char32_t: i32) -> i32 { test_char32_t(char32_t) } #[no_mangle] extern "C" fn _ffi_fn_test_char8_t(char8_t: i32) -> i32 { test_char8_t(char8_t) } #[no_mangle] extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 { test_class(class2) } #[no_mangle] extern "C" fn _ffi_fn_test_co_await(co_await: i32) -> i32 { test_co_await(co_await) } #[no_mangle] extern "C" fn _ffi_fn_test_co_return(co_return: i32) -> i32 { test_co_return(co_return) } #[no_mangle] extern "C" fn _ffi_fn_test_co_yield(co_yield: i32) -> i32 { test_co_yield(co_yield) } #[no_mangle] extern "C" fn _ffi_fn_test_compl(compl: i32) -> i32 { test_compl(compl) } #[no_mangle] extern "C" fn _ffi_fn_test_concept(concept: i32) -> i32 { test_concept(concept) } #[no_mangle] extern "C" fn _ffi_fn_test_const_cast(const_cast: i32) -> i32 { test_const_cast(const_cast) } #[no_mangle] extern "C" fn _ffi_fn_test_consteval(consteval: i32) -> i32 { test_consteval(consteval) } #[no_mangle] extern "C" fn _ffi_fn_test_constexpr(constexpr: i32) -> i32 { test_constexpr(constexpr) } #[no_mangle] extern "C" fn _ffi_fn_test_constinit(constinit: i32) -> i32 { test_constinit(constinit) } #[no_mangle] extern "C" fn _ffi_fn_test_consuming(consuming: i32) -> i32 { test_consuming(consuming) } #[no_mangle] extern "C" fn _ffi_fn_test_contract_assert(contract_assert: i32) -> i32 { test_contract_assert(contract_assert) } #[no_mangle] extern "C" fn _ffi_fn_test_convenience(convenience: i32) -> i32 { test_convenience(convenience) } #[no_mangle] extern "C" fn _ffi_fn_test_debugger(debugger2: i32) -> i32 { test_debugger(debugger2) } #[no_mangle] extern "C" fn _ffi_fn_test_decltype(decltype: i32) -> i32 { test_decltype(decltype) } #[no_mangle] extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 { test_default(default2) } #[no_mangle] extern "C" fn _ffi_fn_test_defer(defer: i32) -> i32 { test_defer(defer) } #[no_mangle] extern "C" fn _ffi_fn_test_deinit(deinit: i32) -> i32 { test_deinit(deinit) } #[no_mangle] extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 { test_delete(delete2) } #[no_mangle] extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 { test_double(double2) } #[no_mangle] extern "C" fn _ffi_fn_test_dynamic(dynamic: i32) -> i32 { test_dynamic(dynamic) } #[no_mangle] extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast: i32) -> i32 { test_dynamic_cast(dynamic_cast) } #[no_mangle] extern "C" fn _ffi_fn_test_explicit(explicit: i32) -> i32 { test_explicit(explicit) } #[no_mangle] extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 { test_export(export2) } #[no_mangle] extern "C" fn _ffi_fn_test_extends(extends2: i32) -> i32 { test_extends(extends2) } #[no_mangle] extern "C" fn _ffi_fn_test_extension(extension: i32) -> i32 { test_extension(extension) } #[no_mangle] extern "C" fn _ffi_fn_test_fallthrough(fallthrough: i32) -> i32 { test_fallthrough(fallthrough) } #[no_mangle] extern "C" fn _ffi_fn_test_fileprivate(fileprivate: i32) -> i32 { test_fileprivate(fileprivate) } #[no_mangle] extern "C" fn _ffi_fn_test_finally(finally2: i32) -> i32 { test_finally(finally2) } #[no_mangle] extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 { test_float(float2) } #[no_mangle] extern "C" fn _ffi_fn_test_friend(friend: i32) -> i32 { test_friend(friend) } #[no_mangle] extern "C" fn _ffi_fn_test_func(func: i32) -> i32 { test_func(func) } #[no_mangle] extern "C" fn _ffi_fn_test_function(function2: i32) -> i32 { test_function(function2) } #[no_mangle] extern "C" fn _ffi_fn_test_get(get: i32) -> i32 { test_get(get) } #[no_mangle] extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 { test_goto(goto2) } #[no_mangle] extern "C" fn _ffi_fn_test_guard(guard: i32) -> i32 { test_guard(guard) } #[no_mangle] extern "C" fn _ffi_fn_test_implements(implements2: i32) -> i32 { test_implements(implements2) } #[no_mangle] extern "C" fn _ffi_fn_test_import(import2: i32) -> i32 { test_import(import2) } #[no_mangle] extern "C" fn _ffi_fn_test_indirect(indirect: i32) -> i32 { test_indirect(indirect) } #[no_mangle] extern "C" fn _ffi_fn_test_infix(infix: i32) -> i32 { test_infix(infix) } #[no_mangle] extern "C" fn _ffi_fn_test_init(init: i32) -> i32 { test_init(init) } #[no_mangle] extern "C" fn _ffi_fn_test_inline(inline: i32) -> i32 { test_inline(inline) } #[no_mangle] extern "C" fn _ffi_fn_test_inout(inout: i32) -> i32 { test_inout(inout) } #[no_mangle] extern "C" fn _ffi_fn_test_instanceof(instanceof2: i32) -> i32 { test_instanceof(instanceof2) } #[no_mangle] extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 { test_int(int2) } #[no_mangle] extern "C" fn _ffi_fn_test_interface(interface2: i32) -> i32 { test_interface(interface2) } #[no_mangle] extern "C" fn _ffi_fn_test_internal(internal: i32) -> i32 { test_internal(internal) } #[no_mangle] extern "C" fn _ffi_fn_test_is(is: i32) -> i32 { test_is(is) } #[no_mangle] extern "C" fn _ffi_fn_test_lazy(lazy: i32) -> i32 { test_lazy(lazy) } #[no_mangle] extern "C" fn _ffi_fn_test_left(left: i32) -> i32 { test_left(left) } #[no_mangle] extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 { test_long(long2) } #[no_mangle] extern "C" fn _ffi_fn_test_mutable(mutable: i32) -> i32 { test_mutable(mutable) } #[no_mangle] extern "C" fn _ffi_fn_test_mutating(mutating: i32) -> i32 { test_mutating(mutating) } #[no_mangle] extern "C" fn _ffi_fn_test_namespace(namespace: i32) -> i32 { test_namespace(namespace) } #[no_mangle] extern "C" fn _ffi_fn_test_native(native2: i32) -> i32 { test_native(native2) } #[no_mangle] extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 { test_new(new2) } #[no_mangle] extern "C" fn _ffi_fn_test_nil(nil: i32) -> i32 { test_nil(nil) } #[no_mangle] extern "C" fn _ffi_fn_test_noexcept(noexcept: i32) -> i32 { test_noexcept(noexcept) } #[no_mangle] extern "C" fn _ffi_fn_test_none(none: i32) -> i32 { test_none(none) } #[no_mangle] extern "C" fn _ffi_fn_test_nonisolated(nonisolated: i32) -> i32 { test_nonisolated(nonisolated) } #[no_mangle] extern "C" fn _ffi_fn_test_nonmutating(nonmutating: i32) -> i32 { test_nonmutating(nonmutating) } #[no_mangle] extern "C" fn _ffi_fn_test_not(not: i32) -> i32 { test_not(not) } #[no_mangle] extern "C" fn _ffi_fn_test_not_eq(not_eq: i32) -> i32 { test_not_eq(not_eq) } #[no_mangle] extern "C" fn _ffi_fn_test_null(null2: i32) -> i32 { test_null(null2) } #[no_mangle] extern "C" fn _ffi_fn_test_nullptr(nullptr: i32) -> i32 { test_nullptr(nullptr) } #[no_mangle] extern "C" fn _ffi_fn_test_open(open: i32) -> i32 { test_open(open) } #[no_mangle] extern "C" fn _ffi_fn_test_operator(operator: i32) -> i32 { test_operator(operator) } #[no_mangle] extern "C" fn _ffi_fn_test_optional(optional: i32) -> i32 { test_optional(optional) } #[no_mangle] extern "C" fn _ffi_fn_test_or(or: i32) -> i32 { test_or(or) } #[no_mangle] extern "C" fn _ffi_fn_test_or_eq(or_eq: i32) -> i32 { test_or_eq(or_eq) } #[no_mangle] extern "C" fn _ffi_fn_test_package(package2: i32) -> i32 { test_package(package2) } #[no_mangle] extern "C" fn _ffi_fn_test_postfix(postfix: i32) -> i32 { test_postfix(postfix) } #[no_mangle] extern "C" fn _ffi_fn_test_precedence(precedence: i32) -> i32 { test_precedence(precedence) } #[no_mangle] extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup: i32) -> i32 { test_precedencegroup(precedencegroup) } #[no_mangle] extern "C" fn _ffi_fn_test_prefix(prefix: i32) -> i32 { test_prefix(prefix) } #[no_mangle] extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 { test_private(private2) } #[no_mangle] extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 { test_protected(protected2) } #[no_mangle] extern "C" fn _ffi_fn_test_protocol(protocol: i32) -> i32 { test_protocol(protocol) } #[no_mangle] extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 { test_public(public2) } #[no_mangle] extern "C" fn _ffi_fn_test_reflexpr(reflexpr: i32) -> i32 { test_reflexpr(reflexpr) } #[no_mangle] extern "C" fn _ffi_fn_test_register(register: i32) -> i32 { test_register(register) } #[no_mangle] extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast: i32) -> i32 { test_reinterpret_cast(reinterpret_cast) } #[no_mangle] extern "C" fn _ffi_fn_test_repeat(repeat: i32) -> i32 { test_repeat(repeat) } #[no_mangle] extern "C" fn _ffi_fn_test_required(required: i32) -> i32 { test_required(required) } #[no_mangle] extern "C" fn _ffi_fn_test_requires(requires: i32) -> i32 { test_requires(requires) } #[no_mangle] extern "C" fn _ffi_fn_test_rethrows(rethrows: i32) -> i32 { test_rethrows(rethrows) } #[no_mangle] extern "C" fn _ffi_fn_test_right(right: i32) -> i32 { test_right(right) } #[no_mangle] extern "C" fn _ffi_fn_test_set(set: i32) -> i32 { test_set(set) } #[no_mangle] extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 { test_short(short2) } #[no_mangle] extern "C" fn _ffi_fn_test_signed(signed: i32) -> i32 { test_signed(signed) } #[no_mangle] extern "C" fn _ffi_fn_test_sizeof(sizeof: i32) -> i32 { test_sizeof(sizeof) } #[no_mangle] extern "C" fn _ffi_fn_test_some(some: i32) -> i32 { test_some(some) } #[no_mangle] extern "C" fn _ffi_fn_test_static_assert(static_assert: i32) -> i32 { test_static_assert(static_assert) } #[no_mangle] extern "C" fn _ffi_fn_test_static_cast(static_cast: i32) -> i32 { test_static_cast(static_cast) } #[no_mangle] extern "C" fn _ffi_fn_test_subscript(subscript: i32) -> i32 { test_subscript(subscript) } #[no_mangle] extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 { test_switch(switch2) } #[no_mangle] extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 { test_synchronized(synchronized2) } #[no_mangle] extern "C" fn _ffi_fn_test_template(template: i32) -> i32 { test_template(template) } #[no_mangle] extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 { test_this(this2) } #[no_mangle] extern "C" fn _ffi_fn_test_thread_local(thread_local: i32) -> i32 { test_thread_local(thread_local) } #[no_mangle] extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 { test_throw(throw2) } #[no_mangle] extern "C" fn _ffi_fn_test_throws(throws2: i32) -> i32 { test_throws(throws2) } #[no_mangle] extern "C" fn _ffi_fn_test_transient(transient2: i32) -> i32 { test_transient(transient2) } #[no_mangle] extern "C" fn _ffi_fn_test_typealias(typealias: i32) -> i32 { test_typealias(typealias) } #[no_mangle] extern "C" fn _ffi_fn_test_typedef(typedef: i32) -> i32 { test_typedef(typedef) } #[no_mangle] extern "C" fn _ffi_fn_test_typeid(typeid: i32) -> i32 { test_typeid(typeid) } #[no_mangle] extern "C" fn _ffi_fn_test_typename(typename: i32) -> i32 { test_typename(typename) } #[no_mangle] extern "C" fn _ffi_fn_test_undefined(undefined2: i32) -> i32 { test_undefined(undefined2) } #[no_mangle] extern "C" fn _ffi_fn_test_union(union: i32) -> i32 { test_union(union) } #[no_mangle] extern "C" fn _ffi_fn_test_unowned(unowned: i32) -> i32 { test_unowned(unowned) } #[no_mangle] extern "C" fn _ffi_fn_test_unsigned(unsigned: i32) -> i32 { test_unsigned(unsigned) } #[no_mangle] extern "C" fn _ffi_fn_test_using(using: i32) -> i32 { test_using(using) } #[no_mangle] extern "C" fn _ffi_fn_test_var(var2: i32) -> i32 { test_var(var2) } #[no_mangle] extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 { test_void(void2) } #[no_mangle] extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 { test_volatile(volatile2) } #[no_mangle] extern "C" fn _ffi_fn_test_wchar_t(wchar_t: i32) -> i32 { test_wchar_t(wchar_t) } #[no_mangle] extern "C" fn _ffi_fn_test_weak(weak: i32) -> i32 { test_weak(weak) } #[no_mangle] extern "C" fn _ffi_fn_test_with(with2: i32) -> i32 { test_with(with2) } #[no_mangle] extern "C" fn _ffi_fn_test_xor(xor: i32) -> i32 { test_xor(xor) } #[no_mangle] extern "C" fn _ffi_fn_test_xor_eq(xor_eq: i32) -> i32 { test_xor_eq(xor_eq) } ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function test_alignas(alignas: number): number; export function test_alignof(alignof: number): number; export function test_and(and: number): number; export function test_and_eq(and_eq: number): number; export function test_asm(asm: number): number; export function test_associatedtype(associatedtype: number): number; export function test_associativity(associativity: number): number; export function test_atomic_cancel(atomic_cancel: number): number; export function test_atomic_commit(atomic_commit: number): number; export function test_atomic_noexcept(atomic_noexcept: number): number; export function test_auto(auto: number): number; export function test_bitand(bitand: number): number; export function test_bitor(bitor: number): number; export function test_bool(bool: number): number; export function test_boolean(boolean2: number): number; export function test_borrowing(borrowing: number): number; export function test_byte(byte2: number): number; export function test_case(case2: number): number; export function test_catch(catch2: number): number; export function test_char(char2: number): number; export function test_char16_t(char16_t: number): number; export function test_char32_t(char32_t: number): number; export function test_char8_t(char8_t: number): number; export function test_class(class2: number): number; export function test_co_await(co_await: number): number; export function test_co_return(co_return: number): number; export function test_co_yield(co_yield: number): number; export function test_compl(compl: number): number; export function test_concept(concept: number): number; export function test_const_cast(const_cast: number): number; export function test_consteval(consteval: number): number; export function test_constexpr(constexpr: number): number; export function test_constinit(constinit: number): number; export function test_consuming(consuming: number): number; export function test_contract_assert(contract_assert: number): number; export function test_convenience(convenience: number): number; export function test_debugger(debugger2: number): number; export function test_decltype(decltype: number): number; export function test_default(default2: number): number; export function test_defer(defer: number): number; export function test_deinit(deinit: number): number; export function test_delete(delete2: number): number; export function test_double(double2: number): number; export function test_dynamic(dynamic: number): number; export function test_dynamic_cast(dynamic_cast: number): number; export function test_explicit(explicit: number): number; export function test_export(export2: number): number; export function test_extends(extends2: number): number; export function test_extension(extension: number): number; export function test_fallthrough(fallthrough: number): number; export function test_fileprivate(fileprivate: number): number; export function test_finally(finally2: number): number; export function test_float(float2: number): number; export function test_friend(friend: number): number; export function test_func(func: number): number; export function test_function(function2: number): number; export function test_get(get: number): number; export function test_goto(goto2: number): number; export function test_guard(guard: number): number; export function test_implements(implements2: number): number; export function test_import(import2: number): number; export function test_indirect(indirect: number): number; export function test_infix(infix: number): number; export function test_init(init: number): number; export function test_inline(inline: number): number; export function test_inout(inout: number): number; export function test_instanceof(instanceof2: number): number; export function test_int(int2: number): number; export function test_interface(interface2: number): number; export function test_internal(internal: number): number; export function test_is(is: number): number; export function test_lazy(lazy: number): number; export function test_left(left: number): number; export function test_long(long2: number): number; export function test_mutable(mutable: number): number; export function test_mutating(mutating: number): number; export function test_namespace(namespace: number): number; export function test_native(native2: number): number; export function test_new(new2: number): number; export function test_nil(nil: number): number; export function test_noexcept(noexcept: number): number; export function test_none(none: number): number; export function test_nonisolated(nonisolated: number): number; export function test_nonmutating(nonmutating: number): number; export function test_not(not: number): number; export function test_not_eq(not_eq: number): number; export function test_null(null2: number): number; export function test_nullptr(nullptr: number): number; export function test_open(open: number): number; export function test_operator(operator: number): number; export function test_optional(optional: number): number; export function test_or(or: number): number; export function test_or_eq(or_eq: number): number; export function test_package(package2: number): number; export function test_postfix(postfix: number): number; export function test_precedence(precedence: number): number; export function test_precedencegroup(precedencegroup: number): number; export function test_prefix(prefix: number): number; export function test_private(private2: number): number; export function test_protected(protected2: number): number; export function test_protocol(protocol: number): number; export function test_public(public2: number): number; export function test_reflexpr(reflexpr: number): number; export function test_register(register: number): number; export function test_reinterpret_cast(reinterpret_cast: number): number; export function test_repeat(repeat: number): number; export function test_required(required: number): number; export function test_requires(requires: number): number; export function test_rethrows(rethrows: number): number; export function test_right(right: number): number; export function test_set(set: number): number; export function test_short(short2: number): number; export function test_signed(signed: number): number; export function test_sizeof(sizeof: number): number; export function test_some(some: number): number; export function test_static_assert(static_assert: number): number; export function test_static_cast(static_cast: number): number; export function test_subscript(subscript: number): number; export function test_switch(switch2: number): number; export function test_synchronized(synchronized2: number): number; export function test_template(template: number): number; export function test_this(this2: number): number; export function test_thread_local(thread_local: number): number; export function test_throw(throw2: number): number; export function test_throws(throws2: number): number; export function test_transient(transient2: number): number; export function test_typealias(typealias: number): number; export function test_typedef(typedef: number): number; export function test_typeid(typeid: number): number; export function test_typename(typename: number): number; export function test_undefined(undefined2: number): number; export function test_union(union: number): number; export function test_unowned(unowned: number): number; export function test_unsigned(unsigned: number): number; export function test_using(using: number): number; export function test_var(var2: number): number; export function test_void(void2: number): number; export function test_volatile(volatile2: number): number; export function test_wchar_t(wchar_t: number): number; export function test_weak(weak: number): number; export function test_with(with2: number): number; export function test_xor(xor: number): number; export function test_xor_eq(xor_eq: number): number; ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test_alignas(alignas) { return _ffi_exports._ffi_fn_test_alignas(alignas); } export function test_alignof(alignof) { return _ffi_exports._ffi_fn_test_alignof(alignof); } export function test_and(and) { return _ffi_exports._ffi_fn_test_and(and); } export function test_and_eq(and_eq) { return _ffi_exports._ffi_fn_test_and_eq(and_eq); } export function test_asm(asm) { return _ffi_exports._ffi_fn_test_asm(asm); } export function test_associatedtype(associatedtype) { return _ffi_exports._ffi_fn_test_associatedtype(associatedtype); } export function test_associativity(associativity) { return _ffi_exports._ffi_fn_test_associativity(associativity); } export function test_atomic_cancel(atomic_cancel) { return _ffi_exports._ffi_fn_test_atomic_cancel(atomic_cancel); } export function test_atomic_commit(atomic_commit) { return _ffi_exports._ffi_fn_test_atomic_commit(atomic_commit); } export function test_atomic_noexcept(atomic_noexcept) { return _ffi_exports._ffi_fn_test_atomic_noexcept(atomic_noexcept); } export function test_auto(auto) { return _ffi_exports._ffi_fn_test_auto(auto); } export function test_bitand(bitand) { return _ffi_exports._ffi_fn_test_bitand(bitand); } export function test_bitor(bitor) { return _ffi_exports._ffi_fn_test_bitor(bitor); } export function test_bool(bool) { return _ffi_exports._ffi_fn_test_bool(bool); } export function test_boolean(boolean2) { return _ffi_exports._ffi_fn_test_boolean(boolean2); } export function test_borrowing(borrowing) { return _ffi_exports._ffi_fn_test_borrowing(borrowing); } export function test_byte(byte2) { return _ffi_exports._ffi_fn_test_byte(byte2); } export function test_case(case2) { return _ffi_exports._ffi_fn_test_case(case2); } export function test_catch(catch2) { return _ffi_exports._ffi_fn_test_catch(catch2); } export function test_char(char2) { return _ffi_exports._ffi_fn_test_char(char2); } export function test_char16_t(char16_t) { return _ffi_exports._ffi_fn_test_char16_t(char16_t); } export function test_char32_t(char32_t) { return _ffi_exports._ffi_fn_test_char32_t(char32_t); } export function test_char8_t(char8_t) { return _ffi_exports._ffi_fn_test_char8_t(char8_t); } export function test_class(class2) { return _ffi_exports._ffi_fn_test_class(class2); } export function test_co_await(co_await) { return _ffi_exports._ffi_fn_test_co_await(co_await); } export function test_co_return(co_return) { return _ffi_exports._ffi_fn_test_co_return(co_return); } export function test_co_yield(co_yield) { return _ffi_exports._ffi_fn_test_co_yield(co_yield); } export function test_compl(compl) { return _ffi_exports._ffi_fn_test_compl(compl); } export function test_concept(concept) { return _ffi_exports._ffi_fn_test_concept(concept); } export function test_const_cast(const_cast) { return _ffi_exports._ffi_fn_test_const_cast(const_cast); } export function test_consteval(consteval) { return _ffi_exports._ffi_fn_test_consteval(consteval); } export function test_constexpr(constexpr) { return _ffi_exports._ffi_fn_test_constexpr(constexpr); } export function test_constinit(constinit) { return _ffi_exports._ffi_fn_test_constinit(constinit); } export function test_consuming(consuming) { return _ffi_exports._ffi_fn_test_consuming(consuming); } export function test_contract_assert(contract_assert) { return _ffi_exports._ffi_fn_test_contract_assert(contract_assert); } export function test_convenience(convenience) { return _ffi_exports._ffi_fn_test_convenience(convenience); } export function test_debugger(debugger2) { return _ffi_exports._ffi_fn_test_debugger(debugger2); } export function test_decltype(decltype) { return _ffi_exports._ffi_fn_test_decltype(decltype); } export function test_default(default2) { return _ffi_exports._ffi_fn_test_default(default2); } export function test_defer(defer) { return _ffi_exports._ffi_fn_test_defer(defer); } export function test_deinit(deinit) { return _ffi_exports._ffi_fn_test_deinit(deinit); } export function test_delete(delete2) { return _ffi_exports._ffi_fn_test_delete(delete2); } export function test_double(double2) { return _ffi_exports._ffi_fn_test_double(double2); } export function test_dynamic(dynamic) { return _ffi_exports._ffi_fn_test_dynamic(dynamic); } export function test_dynamic_cast(dynamic_cast) { return _ffi_exports._ffi_fn_test_dynamic_cast(dynamic_cast); } export function test_explicit(explicit) { return _ffi_exports._ffi_fn_test_explicit(explicit); } export function test_export(export2) { return _ffi_exports._ffi_fn_test_export(export2); } export function test_extends(extends2) { return _ffi_exports._ffi_fn_test_extends(extends2); } export function test_extension(extension) { return _ffi_exports._ffi_fn_test_extension(extension); } export function test_fallthrough(fallthrough) { return _ffi_exports._ffi_fn_test_fallthrough(fallthrough); } export function test_fileprivate(fileprivate) { return _ffi_exports._ffi_fn_test_fileprivate(fileprivate); } export function test_finally(finally2) { return _ffi_exports._ffi_fn_test_finally(finally2); } export function test_float(float2) { return _ffi_exports._ffi_fn_test_float(float2); } export function test_friend(friend) { return _ffi_exports._ffi_fn_test_friend(friend); } export function test_func(func) { return _ffi_exports._ffi_fn_test_func(func); } export function test_function(function2) { return _ffi_exports._ffi_fn_test_function(function2); } export function test_get(get) { return _ffi_exports._ffi_fn_test_get(get); } export function test_goto(goto2) { return _ffi_exports._ffi_fn_test_goto(goto2); } export function test_guard(guard) { return _ffi_exports._ffi_fn_test_guard(guard); } export function test_implements(implements2) { return _ffi_exports._ffi_fn_test_implements(implements2); } export function test_import(import2) { return _ffi_exports._ffi_fn_test_import(import2); } export function test_indirect(indirect) { return _ffi_exports._ffi_fn_test_indirect(indirect); } export function test_infix(infix) { return _ffi_exports._ffi_fn_test_infix(infix); } export function test_init(init) { return _ffi_exports._ffi_fn_test_init(init); } export function test_inline(inline) { return _ffi_exports._ffi_fn_test_inline(inline); } export function test_inout(inout) { return _ffi_exports._ffi_fn_test_inout(inout); } export function test_instanceof(instanceof2) { return _ffi_exports._ffi_fn_test_instanceof(instanceof2); } export function test_int(int2) { return _ffi_exports._ffi_fn_test_int(int2); } export function test_interface(interface2) { return _ffi_exports._ffi_fn_test_interface(interface2); } export function test_internal(internal) { return _ffi_exports._ffi_fn_test_internal(internal); } export function test_is(is) { return _ffi_exports._ffi_fn_test_is(is); } export function test_lazy(lazy) { return _ffi_exports._ffi_fn_test_lazy(lazy); } export function test_left(left) { return _ffi_exports._ffi_fn_test_left(left); } export function test_long(long2) { return _ffi_exports._ffi_fn_test_long(long2); } export function test_mutable(mutable) { return _ffi_exports._ffi_fn_test_mutable(mutable); } export function test_mutating(mutating) { return _ffi_exports._ffi_fn_test_mutating(mutating); } export function test_namespace(namespace) { return _ffi_exports._ffi_fn_test_namespace(namespace); } export function test_native(native2) { return _ffi_exports._ffi_fn_test_native(native2); } export function test_new(new2) { return _ffi_exports._ffi_fn_test_new(new2); } export function test_nil(nil) { return _ffi_exports._ffi_fn_test_nil(nil); } export function test_noexcept(noexcept) { return _ffi_exports._ffi_fn_test_noexcept(noexcept); } export function test_none(none) { return _ffi_exports._ffi_fn_test_none(none); } export function test_nonisolated(nonisolated) { return _ffi_exports._ffi_fn_test_nonisolated(nonisolated); } export function test_nonmutating(nonmutating) { return _ffi_exports._ffi_fn_test_nonmutating(nonmutating); } export function test_not(not) { return _ffi_exports._ffi_fn_test_not(not); } export function test_not_eq(not_eq) { return _ffi_exports._ffi_fn_test_not_eq(not_eq); } export function test_null(null2) { return _ffi_exports._ffi_fn_test_null(null2); } export function test_nullptr(nullptr) { return _ffi_exports._ffi_fn_test_nullptr(nullptr); } export function test_open(open) { return _ffi_exports._ffi_fn_test_open(open); } export function test_operator(operator) { return _ffi_exports._ffi_fn_test_operator(operator); } export function test_optional(optional) { return _ffi_exports._ffi_fn_test_optional(optional); } export function test_or(or) { return _ffi_exports._ffi_fn_test_or(or); } export function test_or_eq(or_eq) { return _ffi_exports._ffi_fn_test_or_eq(or_eq); } export function test_package(package2) { return _ffi_exports._ffi_fn_test_package(package2); } export function test_postfix(postfix) { return _ffi_exports._ffi_fn_test_postfix(postfix); } export function test_precedence(precedence) { return _ffi_exports._ffi_fn_test_precedence(precedence); } export function test_precedencegroup(precedencegroup) { return _ffi_exports._ffi_fn_test_precedencegroup(precedencegroup); } export function test_prefix(prefix) { return _ffi_exports._ffi_fn_test_prefix(prefix); } export function test_private(private2) { return _ffi_exports._ffi_fn_test_private(private2); } export function test_protected(protected2) { return _ffi_exports._ffi_fn_test_protected(protected2); } export function test_protocol(protocol) { return _ffi_exports._ffi_fn_test_protocol(protocol); } export function test_public(public2) { return _ffi_exports._ffi_fn_test_public(public2); } export function test_reflexpr(reflexpr) { return _ffi_exports._ffi_fn_test_reflexpr(reflexpr); } export function test_register(register) { return _ffi_exports._ffi_fn_test_register(register); } export function test_reinterpret_cast(reinterpret_cast) { return _ffi_exports._ffi_fn_test_reinterpret_cast(reinterpret_cast); } export function test_repeat(repeat) { return _ffi_exports._ffi_fn_test_repeat(repeat); } export function test_required(required) { return _ffi_exports._ffi_fn_test_required(required); } export function test_requires(requires) { return _ffi_exports._ffi_fn_test_requires(requires); } export function test_rethrows(rethrows) { return _ffi_exports._ffi_fn_test_rethrows(rethrows); } export function test_right(right) { return _ffi_exports._ffi_fn_test_right(right); } export function test_set(set) { return _ffi_exports._ffi_fn_test_set(set); } export function test_short(short2) { return _ffi_exports._ffi_fn_test_short(short2); } export function test_signed(signed) { return _ffi_exports._ffi_fn_test_signed(signed); } export function test_sizeof(sizeof) { return _ffi_exports._ffi_fn_test_sizeof(sizeof); } export function test_some(some) { return _ffi_exports._ffi_fn_test_some(some); } export function test_static_assert(static_assert) { return _ffi_exports._ffi_fn_test_static_assert(static_assert); } export function test_static_cast(static_cast) { return _ffi_exports._ffi_fn_test_static_cast(static_cast); } export function test_subscript(subscript) { return _ffi_exports._ffi_fn_test_subscript(subscript); } export function test_switch(switch2) { return _ffi_exports._ffi_fn_test_switch(switch2); } export function test_synchronized(synchronized2) { return _ffi_exports._ffi_fn_test_synchronized(synchronized2); } export function test_template(template) { return _ffi_exports._ffi_fn_test_template(template); } export function test_this(this2) { return _ffi_exports._ffi_fn_test_this(this2); } export function test_thread_local(thread_local) { return _ffi_exports._ffi_fn_test_thread_local(thread_local); } export function test_throw(throw2) { return _ffi_exports._ffi_fn_test_throw(throw2); } export function test_throws(throws2) { return _ffi_exports._ffi_fn_test_throws(throws2); } export function test_transient(transient2) { return _ffi_exports._ffi_fn_test_transient(transient2); } export function test_typealias(typealias) { return _ffi_exports._ffi_fn_test_typealias(typealias); } export function test_typedef(typedef) { return _ffi_exports._ffi_fn_test_typedef(typedef); } export function test_typeid(typeid) { return _ffi_exports._ffi_fn_test_typeid(typeid); } export function test_typename(typename) { return _ffi_exports._ffi_fn_test_typename(typename); } export function test_undefined(undefined2) { return _ffi_exports._ffi_fn_test_undefined(undefined2); } export function test_union(union) { return _ffi_exports._ffi_fn_test_union(union); } export function test_unowned(unowned) { return _ffi_exports._ffi_fn_test_unowned(unowned); } export function test_unsigned(unsigned) { return _ffi_exports._ffi_fn_test_unsigned(unsigned); } export function test_using(using) { return _ffi_exports._ffi_fn_test_using(using); } export function test_var(var2) { return _ffi_exports._ffi_fn_test_var(var2); } export function test_void(void2) { return _ffi_exports._ffi_fn_test_void(void2); } export function test_volatile(volatile2) { return _ffi_exports._ffi_fn_test_volatile(volatile2); } export function test_wchar_t(wchar_t) { return _ffi_exports._ffi_fn_test_wchar_t(wchar_t); } export function test_weak(weak) { return _ffi_exports._ffi_fn_test_weak(weak); } export function test_with(with2) { return _ffi_exports._ffi_fn_test_with(with2); } export function test_xor(xor) { return _ffi_exports._ffi_fn_test_xor(xor); } export function test_xor_eq(xor_eq) { return _ffi_exports._ffi_fn_test_xor_eq(xor_eq); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test_alignas(alignas: number): number { return _ffi_exports._ffi_fn_test_alignas(alignas); } export function test_alignof(alignof: number): number { return _ffi_exports._ffi_fn_test_alignof(alignof); } export function test_and(and: number): number { return _ffi_exports._ffi_fn_test_and(and); } export function test_and_eq(and_eq: number): number { return _ffi_exports._ffi_fn_test_and_eq(and_eq); } export function test_asm(asm: number): number { return _ffi_exports._ffi_fn_test_asm(asm); } export function test_associatedtype(associatedtype: number): number { return _ffi_exports._ffi_fn_test_associatedtype(associatedtype); } export function test_associativity(associativity: number): number { return _ffi_exports._ffi_fn_test_associativity(associativity); } export function test_atomic_cancel(atomic_cancel: number): number { return _ffi_exports._ffi_fn_test_atomic_cancel(atomic_cancel); } export function test_atomic_commit(atomic_commit: number): number { return _ffi_exports._ffi_fn_test_atomic_commit(atomic_commit); } export function test_atomic_noexcept(atomic_noexcept: number): number { return _ffi_exports._ffi_fn_test_atomic_noexcept(atomic_noexcept); } export function test_auto(auto: number): number { return _ffi_exports._ffi_fn_test_auto(auto); } export function test_bitand(bitand: number): number { return _ffi_exports._ffi_fn_test_bitand(bitand); } export function test_bitor(bitor: number): number { return _ffi_exports._ffi_fn_test_bitor(bitor); } export function test_bool(bool: number): number { return _ffi_exports._ffi_fn_test_bool(bool); } export function test_boolean(boolean2: number): number { return _ffi_exports._ffi_fn_test_boolean(boolean2); } export function test_borrowing(borrowing: number): number { return _ffi_exports._ffi_fn_test_borrowing(borrowing); } export function test_byte(byte2: number): number { return _ffi_exports._ffi_fn_test_byte(byte2); } export function test_case(case2: number): number { return _ffi_exports._ffi_fn_test_case(case2); } export function test_catch(catch2: number): number { return _ffi_exports._ffi_fn_test_catch(catch2); } export function test_char(char2: number): number { return _ffi_exports._ffi_fn_test_char(char2); } export function test_char16_t(char16_t: number): number { return _ffi_exports._ffi_fn_test_char16_t(char16_t); } export function test_char32_t(char32_t: number): number { return _ffi_exports._ffi_fn_test_char32_t(char32_t); } export function test_char8_t(char8_t: number): number { return _ffi_exports._ffi_fn_test_char8_t(char8_t); } export function test_class(class2: number): number { return _ffi_exports._ffi_fn_test_class(class2); } export function test_co_await(co_await: number): number { return _ffi_exports._ffi_fn_test_co_await(co_await); } export function test_co_return(co_return: number): number { return _ffi_exports._ffi_fn_test_co_return(co_return); } export function test_co_yield(co_yield: number): number { return _ffi_exports._ffi_fn_test_co_yield(co_yield); } export function test_compl(compl: number): number { return _ffi_exports._ffi_fn_test_compl(compl); } export function test_concept(concept: number): number { return _ffi_exports._ffi_fn_test_concept(concept); } export function test_const_cast(const_cast: number): number { return _ffi_exports._ffi_fn_test_const_cast(const_cast); } export function test_consteval(consteval: number): number { return _ffi_exports._ffi_fn_test_consteval(consteval); } export function test_constexpr(constexpr: number): number { return _ffi_exports._ffi_fn_test_constexpr(constexpr); } export function test_constinit(constinit: number): number { return _ffi_exports._ffi_fn_test_constinit(constinit); } export function test_consuming(consuming: number): number { return _ffi_exports._ffi_fn_test_consuming(consuming); } export function test_contract_assert(contract_assert: number): number { return _ffi_exports._ffi_fn_test_contract_assert(contract_assert); } export function test_convenience(convenience: number): number { return _ffi_exports._ffi_fn_test_convenience(convenience); } export function test_debugger(debugger2: number): number { return _ffi_exports._ffi_fn_test_debugger(debugger2); } export function test_decltype(decltype: number): number { return _ffi_exports._ffi_fn_test_decltype(decltype); } export function test_default(default2: number): number { return _ffi_exports._ffi_fn_test_default(default2); } export function test_defer(defer: number): number { return _ffi_exports._ffi_fn_test_defer(defer); } export function test_deinit(deinit: number): number { return _ffi_exports._ffi_fn_test_deinit(deinit); } export function test_delete(delete2: number): number { return _ffi_exports._ffi_fn_test_delete(delete2); } export function test_double(double2: number): number { return _ffi_exports._ffi_fn_test_double(double2); } export function test_dynamic(dynamic: number): number { return _ffi_exports._ffi_fn_test_dynamic(dynamic); } export function test_dynamic_cast(dynamic_cast: number): number { return _ffi_exports._ffi_fn_test_dynamic_cast(dynamic_cast); } export function test_explicit(explicit: number): number { return _ffi_exports._ffi_fn_test_explicit(explicit); } export function test_export(export2: number): number { return _ffi_exports._ffi_fn_test_export(export2); } export function test_extends(extends2: number): number { return _ffi_exports._ffi_fn_test_extends(extends2); } export function test_extension(extension: number): number { return _ffi_exports._ffi_fn_test_extension(extension); } export function test_fallthrough(fallthrough: number): number { return _ffi_exports._ffi_fn_test_fallthrough(fallthrough); } export function test_fileprivate(fileprivate: number): number { return _ffi_exports._ffi_fn_test_fileprivate(fileprivate); } export function test_finally(finally2: number): number { return _ffi_exports._ffi_fn_test_finally(finally2); } export function test_float(float2: number): number { return _ffi_exports._ffi_fn_test_float(float2); } export function test_friend(friend: number): number { return _ffi_exports._ffi_fn_test_friend(friend); } export function test_func(func: number): number { return _ffi_exports._ffi_fn_test_func(func); } export function test_function(function2: number): number { return _ffi_exports._ffi_fn_test_function(function2); } export function test_get(get: number): number { return _ffi_exports._ffi_fn_test_get(get); } export function test_goto(goto2: number): number { return _ffi_exports._ffi_fn_test_goto(goto2); } export function test_guard(guard: number): number { return _ffi_exports._ffi_fn_test_guard(guard); } export function test_implements(implements2: number): number { return _ffi_exports._ffi_fn_test_implements(implements2); } export function test_import(import2: number): number { return _ffi_exports._ffi_fn_test_import(import2); } export function test_indirect(indirect: number): number { return _ffi_exports._ffi_fn_test_indirect(indirect); } export function test_infix(infix: number): number { return _ffi_exports._ffi_fn_test_infix(infix); } export function test_init(init: number): number { return _ffi_exports._ffi_fn_test_init(init); } export function test_inline(inline: number): number { return _ffi_exports._ffi_fn_test_inline(inline); } export function test_inout(inout: number): number { return _ffi_exports._ffi_fn_test_inout(inout); } export function test_instanceof(instanceof2: number): number { return _ffi_exports._ffi_fn_test_instanceof(instanceof2); } export function test_int(int2: number): number { return _ffi_exports._ffi_fn_test_int(int2); } export function test_interface(interface2: number): number { return _ffi_exports._ffi_fn_test_interface(interface2); } export function test_internal(internal: number): number { return _ffi_exports._ffi_fn_test_internal(internal); } export function test_is(is: number): number { return _ffi_exports._ffi_fn_test_is(is); } export function test_lazy(lazy: number): number { return _ffi_exports._ffi_fn_test_lazy(lazy); } export function test_left(left: number): number { return _ffi_exports._ffi_fn_test_left(left); } export function test_long(long2: number): number { return _ffi_exports._ffi_fn_test_long(long2); } export function test_mutable(mutable: number): number { return _ffi_exports._ffi_fn_test_mutable(mutable); } export function test_mutating(mutating: number): number { return _ffi_exports._ffi_fn_test_mutating(mutating); } export function test_namespace(namespace: number): number { return _ffi_exports._ffi_fn_test_namespace(namespace); } export function test_native(native2: number): number { return _ffi_exports._ffi_fn_test_native(native2); } export function test_new(new2: number): number { return _ffi_exports._ffi_fn_test_new(new2); } export function test_nil(nil: number): number { return _ffi_exports._ffi_fn_test_nil(nil); } export function test_noexcept(noexcept: number): number { return _ffi_exports._ffi_fn_test_noexcept(noexcept); } export function test_none(none: number): number { return _ffi_exports._ffi_fn_test_none(none); } export function test_nonisolated(nonisolated: number): number { return _ffi_exports._ffi_fn_test_nonisolated(nonisolated); } export function test_nonmutating(nonmutating: number): number { return _ffi_exports._ffi_fn_test_nonmutating(nonmutating); } export function test_not(not: number): number { return _ffi_exports._ffi_fn_test_not(not); } export function test_not_eq(not_eq: number): number { return _ffi_exports._ffi_fn_test_not_eq(not_eq); } export function test_null(null2: number): number { return _ffi_exports._ffi_fn_test_null(null2); } export function test_nullptr(nullptr: number): number { return _ffi_exports._ffi_fn_test_nullptr(nullptr); } export function test_open(open: number): number { return _ffi_exports._ffi_fn_test_open(open); } export function test_operator(operator: number): number { return _ffi_exports._ffi_fn_test_operator(operator); } export function test_optional(optional: number): number { return _ffi_exports._ffi_fn_test_optional(optional); } export function test_or(or: number): number { return _ffi_exports._ffi_fn_test_or(or); } export function test_or_eq(or_eq: number): number { return _ffi_exports._ffi_fn_test_or_eq(or_eq); } export function test_package(package2: number): number { return _ffi_exports._ffi_fn_test_package(package2); } export function test_postfix(postfix: number): number { return _ffi_exports._ffi_fn_test_postfix(postfix); } export function test_precedence(precedence: number): number { return _ffi_exports._ffi_fn_test_precedence(precedence); } export function test_precedencegroup(precedencegroup: number): number { return _ffi_exports._ffi_fn_test_precedencegroup(precedencegroup); } export function test_prefix(prefix: number): number { return _ffi_exports._ffi_fn_test_prefix(prefix); } export function test_private(private2: number): number { return _ffi_exports._ffi_fn_test_private(private2); } export function test_protected(protected2: number): number { return _ffi_exports._ffi_fn_test_protected(protected2); } export function test_protocol(protocol: number): number { return _ffi_exports._ffi_fn_test_protocol(protocol); } export function test_public(public2: number): number { return _ffi_exports._ffi_fn_test_public(public2); } export function test_reflexpr(reflexpr: number): number { return _ffi_exports._ffi_fn_test_reflexpr(reflexpr); } export function test_register(register: number): number { return _ffi_exports._ffi_fn_test_register(register); } export function test_reinterpret_cast(reinterpret_cast: number): number { return _ffi_exports._ffi_fn_test_reinterpret_cast(reinterpret_cast); } export function test_repeat(repeat: number): number { return _ffi_exports._ffi_fn_test_repeat(repeat); } export function test_required(required: number): number { return _ffi_exports._ffi_fn_test_required(required); } export function test_requires(requires: number): number { return _ffi_exports._ffi_fn_test_requires(requires); } export function test_rethrows(rethrows: number): number { return _ffi_exports._ffi_fn_test_rethrows(rethrows); } export function test_right(right: number): number { return _ffi_exports._ffi_fn_test_right(right); } export function test_set(set: number): number { return _ffi_exports._ffi_fn_test_set(set); } export function test_short(short2: number): number { return _ffi_exports._ffi_fn_test_short(short2); } export function test_signed(signed: number): number { return _ffi_exports._ffi_fn_test_signed(signed); } export function test_sizeof(sizeof: number): number { return _ffi_exports._ffi_fn_test_sizeof(sizeof); } export function test_some(some: number): number { return _ffi_exports._ffi_fn_test_some(some); } export function test_static_assert(static_assert: number): number { return _ffi_exports._ffi_fn_test_static_assert(static_assert); } export function test_static_cast(static_cast: number): number { return _ffi_exports._ffi_fn_test_static_cast(static_cast); } export function test_subscript(subscript: number): number { return _ffi_exports._ffi_fn_test_subscript(subscript); } export function test_switch(switch2: number): number { return _ffi_exports._ffi_fn_test_switch(switch2); } export function test_synchronized(synchronized2: number): number { return _ffi_exports._ffi_fn_test_synchronized(synchronized2); } export function test_template(template: number): number { return _ffi_exports._ffi_fn_test_template(template); } export function test_this(this2: number): number { return _ffi_exports._ffi_fn_test_this(this2); } export function test_thread_local(thread_local: number): number { return _ffi_exports._ffi_fn_test_thread_local(thread_local); } export function test_throw(throw2: number): number { return _ffi_exports._ffi_fn_test_throw(throw2); } export function test_throws(throws2: number): number { return _ffi_exports._ffi_fn_test_throws(throws2); } export function test_transient(transient2: number): number { return _ffi_exports._ffi_fn_test_transient(transient2); } export function test_typealias(typealias: number): number { return _ffi_exports._ffi_fn_test_typealias(typealias); } export function test_typedef(typedef: number): number { return _ffi_exports._ffi_fn_test_typedef(typedef); } export function test_typeid(typeid: number): number { return _ffi_exports._ffi_fn_test_typeid(typeid); } export function test_typename(typename: number): number { return _ffi_exports._ffi_fn_test_typename(typename); } export function test_undefined(undefined2: number): number { return _ffi_exports._ffi_fn_test_undefined(undefined2); } export function test_union(union: number): number { return _ffi_exports._ffi_fn_test_union(union); } export function test_unowned(unowned: number): number { return _ffi_exports._ffi_fn_test_unowned(unowned); } export function test_unsigned(unsigned: number): number { return _ffi_exports._ffi_fn_test_unsigned(unsigned); } export function test_using(using: number): number { return _ffi_exports._ffi_fn_test_using(using); } export function test_var(var2: number): number { return _ffi_exports._ffi_fn_test_var(var2); } export function test_void(void2: number): number { return _ffi_exports._ffi_fn_test_void(void2); } export function test_volatile(volatile2: number): number { return _ffi_exports._ffi_fn_test_volatile(volatile2); } export function test_wchar_t(wchar_t: number): number { return _ffi_exports._ffi_fn_test_wchar_t(wchar_t); } export function test_weak(weak: number): number { return _ffi_exports._ffi_fn_test_weak(weak); } export function test_with(with2: number): number { return _ffi_exports._ffi_fn_test_with(with2); } export function test_xor(xor: number): number { return _ffi_exports._ffi_fn_test_xor(xor); } export function test_xor_eq(xor_eq: number): number { return _ffi_exports._ffi_fn_test_xor_eq(xor_eq); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test_alignas: (alignas: number) => number, _ffi_fn_test_alignof: (alignof: number) => number, _ffi_fn_test_and: (and: number) => number, _ffi_fn_test_and_eq: (and_eq: number) => number, _ffi_fn_test_asm: (asm: number) => number, _ffi_fn_test_associatedtype: (associatedtype: number) => number, _ffi_fn_test_associativity: (associativity: number) => number, _ffi_fn_test_atomic_cancel: (atomic_cancel: number) => number, _ffi_fn_test_atomic_commit: (atomic_commit: number) => number, _ffi_fn_test_atomic_noexcept: (atomic_noexcept: number) => number, _ffi_fn_test_auto: (auto: number) => number, _ffi_fn_test_bitand: (bitand: number) => number, _ffi_fn_test_bitor: (bitor: number) => number, _ffi_fn_test_bool: (bool: number) => number, _ffi_fn_test_boolean: (boolean2: number) => number, _ffi_fn_test_borrowing: (borrowing: number) => number, _ffi_fn_test_byte: (byte2: number) => number, _ffi_fn_test_case: (case2: number) => number, _ffi_fn_test_catch: (catch2: number) => number, _ffi_fn_test_char: (char2: number) => number, _ffi_fn_test_char16_t: (char16_t: number) => number, _ffi_fn_test_char32_t: (char32_t: number) => number, _ffi_fn_test_char8_t: (char8_t: number) => number, _ffi_fn_test_class: (class2: number) => number, _ffi_fn_test_co_await: (co_await: number) => number, _ffi_fn_test_co_return: (co_return: number) => number, _ffi_fn_test_co_yield: (co_yield: number) => number, _ffi_fn_test_compl: (compl: number) => number, _ffi_fn_test_concept: (concept: number) => number, _ffi_fn_test_const_cast: (const_cast: number) => number, _ffi_fn_test_consteval: (consteval: number) => number, _ffi_fn_test_constexpr: (constexpr: number) => number, _ffi_fn_test_constinit: (constinit: number) => number, _ffi_fn_test_consuming: (consuming: number) => number, _ffi_fn_test_contract_assert: (contract_assert: number) => number, _ffi_fn_test_convenience: (convenience: number) => number, _ffi_fn_test_debugger: (debugger2: number) => number, _ffi_fn_test_decltype: (decltype: number) => number, _ffi_fn_test_default: (default2: number) => number, _ffi_fn_test_defer: (defer: number) => number, _ffi_fn_test_deinit: (deinit: number) => number, _ffi_fn_test_delete: (delete2: number) => number, _ffi_fn_test_double: (double2: number) => number, _ffi_fn_test_dynamic: (dynamic: number) => number, _ffi_fn_test_dynamic_cast: (dynamic_cast: number) => number, _ffi_fn_test_explicit: (explicit: number) => number, _ffi_fn_test_export: (export2: number) => number, _ffi_fn_test_extends: (extends2: number) => number, _ffi_fn_test_extension: (extension: number) => number, _ffi_fn_test_fallthrough: (fallthrough: number) => number, _ffi_fn_test_fileprivate: (fileprivate: number) => number, _ffi_fn_test_finally: (finally2: number) => number, _ffi_fn_test_float: (float2: number) => number, _ffi_fn_test_friend: (friend: number) => number, _ffi_fn_test_func: (func: number) => number, _ffi_fn_test_function: (function2: number) => number, _ffi_fn_test_get: (get: number) => number, _ffi_fn_test_goto: (goto2: number) => number, _ffi_fn_test_guard: (guard: number) => number, _ffi_fn_test_implements: (implements2: number) => number, _ffi_fn_test_import: (import2: number) => number, _ffi_fn_test_indirect: (indirect: number) => number, _ffi_fn_test_infix: (infix: number) => number, _ffi_fn_test_init: (init: number) => number, _ffi_fn_test_inline: (inline: number) => number, _ffi_fn_test_inout: (inout: number) => number, _ffi_fn_test_instanceof: (instanceof2: number) => number, _ffi_fn_test_int: (int2: number) => number, _ffi_fn_test_interface: (interface2: number) => number, _ffi_fn_test_internal: (internal: number) => number, _ffi_fn_test_is: (is: number) => number, _ffi_fn_test_lazy: (lazy: number) => number, _ffi_fn_test_left: (left: number) => number, _ffi_fn_test_long: (long2: number) => number, _ffi_fn_test_mutable: (mutable: number) => number, _ffi_fn_test_mutating: (mutating: number) => number, _ffi_fn_test_namespace: (namespace: number) => number, _ffi_fn_test_native: (native2: number) => number, _ffi_fn_test_new: (new2: number) => number, _ffi_fn_test_nil: (nil: number) => number, _ffi_fn_test_noexcept: (noexcept: number) => number, _ffi_fn_test_none: (none: number) => number, _ffi_fn_test_nonisolated: (nonisolated: number) => number, _ffi_fn_test_nonmutating: (nonmutating: number) => number, _ffi_fn_test_not: (not: number) => number, _ffi_fn_test_not_eq: (not_eq: number) => number, _ffi_fn_test_null: (null2: number) => number, _ffi_fn_test_nullptr: (nullptr: number) => number, _ffi_fn_test_open: (open: number) => number, _ffi_fn_test_operator: (operator: number) => number, _ffi_fn_test_optional: (optional: number) => number, _ffi_fn_test_or: (or: number) => number, _ffi_fn_test_or_eq: (or_eq: number) => number, _ffi_fn_test_package: (package2: number) => number, _ffi_fn_test_postfix: (postfix: number) => number, _ffi_fn_test_precedence: (precedence: number) => number, _ffi_fn_test_precedencegroup: (precedencegroup: number) => number, _ffi_fn_test_prefix: (prefix: number) => number, _ffi_fn_test_private: (private2: number) => number, _ffi_fn_test_protected: (protected2: number) => number, _ffi_fn_test_protocol: (protocol: number) => number, _ffi_fn_test_public: (public2: number) => number, _ffi_fn_test_reflexpr: (reflexpr: number) => number, _ffi_fn_test_register: (register: number) => number, _ffi_fn_test_reinterpret_cast: (reinterpret_cast: number) => number, _ffi_fn_test_repeat: (repeat: number) => number, _ffi_fn_test_required: (required: number) => number, _ffi_fn_test_requires: (requires: number) => number, _ffi_fn_test_rethrows: (rethrows: number) => number, _ffi_fn_test_right: (right: number) => number, _ffi_fn_test_set: (set: number) => number, _ffi_fn_test_short: (short2: number) => number, _ffi_fn_test_signed: (signed: number) => number, _ffi_fn_test_sizeof: (sizeof: number) => number, _ffi_fn_test_some: (some: number) => number, _ffi_fn_test_static_assert: (static_assert: number) => number, _ffi_fn_test_static_cast: (static_cast: number) => number, _ffi_fn_test_subscript: (subscript: number) => number, _ffi_fn_test_switch: (switch2: number) => number, _ffi_fn_test_synchronized: (synchronized2: number) => number, _ffi_fn_test_template: (template: number) => number, _ffi_fn_test_this: (this2: number) => number, _ffi_fn_test_thread_local: (thread_local: number) => number, _ffi_fn_test_throw: (throw2: number) => number, _ffi_fn_test_throws: (throws2: number) => number, _ffi_fn_test_transient: (transient2: number) => number, _ffi_fn_test_typealias: (typealias: number) => number, _ffi_fn_test_typedef: (typedef: number) => number, _ffi_fn_test_typeid: (typeid: number) => number, _ffi_fn_test_typename: (typename: number) => number, _ffi_fn_test_undefined: (undefined2: number) => number, _ffi_fn_test_union: (union: number) => number, _ffi_fn_test_unowned: (unowned: number) => number, _ffi_fn_test_unsigned: (unsigned: number) => number, _ffi_fn_test_using: (using: number) => number, _ffi_fn_test_var: (var2: number) => number, _ffi_fn_test_void: (void2: number) => number, _ffi_fn_test_volatile: (volatile2: number) => number, _ffi_fn_test_wchar_t: (wchar_t: number) => number, _ffi_fn_test_weak: (weak: number) => number, _ffi_fn_test_with: (with2: number) => number, _ffi_fn_test_xor: (xor: number) => number, _ffi_fn_test_xor_eq: (xor_eq: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_keyword_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_alignas(alignas: i32) -> i32 { test_alignas(alignas) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_alignof(alignof: i32) -> i32 { test_alignof(alignof) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_and(and: i32) -> i32 { test_and(and) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_and_eq(and_eq: i32) -> i32 { test_and_eq(and_eq) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_asm(asm: i32) -> i32 { test_asm(asm) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_associatedtype(associatedtype: i32) -> i32 { test_associatedtype(associatedtype) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_associativity(associativity: i32) -> i32 { test_associativity(associativity) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel: i32) -> i32 { test_atomic_cancel(atomic_cancel) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit: i32) -> i32 { test_atomic_commit(atomic_commit) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept: i32) -> i32 { test_atomic_noexcept(atomic_noexcept) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_auto(auto: i32) -> i32 { test_auto(auto) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bitand(bitand: i32) -> i32 { test_bitand(bitand) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bitor(bitor: i32) -> i32 { test_bitor(bitor) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_bool(bool: i32) -> i32 { test_bool(bool) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_boolean(boolean2: i32) -> i32 { test_boolean(boolean2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_borrowing(borrowing: i32) -> i32 { test_borrowing(borrowing) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_byte(byte2: i32) -> i32 { test_byte(byte2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 { test_case(case2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 { test_catch(catch2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 { test_char(char2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char16_t(char16_t: i32) -> i32 { test_char16_t(char16_t) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char32_t(char32_t: i32) -> i32 { test_char32_t(char32_t) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_char8_t(char8_t: i32) -> i32 { test_char8_t(char8_t) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 { test_class(class2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_await(co_await: i32) -> i32 { test_co_await(co_await) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_return(co_return: i32) -> i32 { test_co_return(co_return) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_co_yield(co_yield: i32) -> i32 { test_co_yield(co_yield) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_compl(compl: i32) -> i32 { test_compl(compl) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_concept(concept: i32) -> i32 { test_concept(concept) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_const_cast(const_cast: i32) -> i32 { test_const_cast(const_cast) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_consteval(consteval: i32) -> i32 { test_consteval(consteval) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_constexpr(constexpr: i32) -> i32 { test_constexpr(constexpr) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_constinit(constinit: i32) -> i32 { test_constinit(constinit) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_consuming(consuming: i32) -> i32 { test_consuming(consuming) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_contract_assert(contract_assert: i32) -> i32 { test_contract_assert(contract_assert) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_convenience(convenience: i32) -> i32 { test_convenience(convenience) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_debugger(debugger2: i32) -> i32 { test_debugger(debugger2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_decltype(decltype: i32) -> i32 { test_decltype(decltype) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 { test_default(default2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_defer(defer: i32) -> i32 { test_defer(defer) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_deinit(deinit: i32) -> i32 { test_deinit(deinit) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 { test_delete(delete2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 { test_double(double2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_dynamic(dynamic: i32) -> i32 { test_dynamic(dynamic) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast: i32) -> i32 { test_dynamic_cast(dynamic_cast) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_explicit(explicit: i32) -> i32 { test_explicit(explicit) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 { test_export(export2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_extends(extends2: i32) -> i32 { test_extends(extends2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_extension(extension: i32) -> i32 { test_extension(extension) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_fallthrough(fallthrough: i32) -> i32 { test_fallthrough(fallthrough) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_fileprivate(fileprivate: i32) -> i32 { test_fileprivate(fileprivate) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_finally(finally2: i32) -> i32 { test_finally(finally2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 { test_float(float2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_friend(friend: i32) -> i32 { test_friend(friend) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_func(func: i32) -> i32 { test_func(func) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_function(function2: i32) -> i32 { test_function(function2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_get(get: i32) -> i32 { test_get(get) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 { test_goto(goto2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_guard(guard: i32) -> i32 { test_guard(guard) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_implements(implements2: i32) -> i32 { test_implements(implements2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_import(import2: i32) -> i32 { test_import(import2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_indirect(indirect: i32) -> i32 { test_indirect(indirect) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_infix(infix: i32) -> i32 { test_infix(infix) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_init(init: i32) -> i32 { test_init(init) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_inline(inline: i32) -> i32 { test_inline(inline) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_inout(inout: i32) -> i32 { test_inout(inout) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_instanceof(instanceof2: i32) -> i32 { test_instanceof(instanceof2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 { test_int(int2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_interface(interface2: i32) -> i32 { test_interface(interface2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_internal(internal: i32) -> i32 { test_internal(internal) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_is(is: i32) -> i32 { test_is(is) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_lazy(lazy: i32) -> i32 { test_lazy(lazy) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_left(left: i32) -> i32 { test_left(left) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 { test_long(long2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_mutable(mutable: i32) -> i32 { test_mutable(mutable) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_mutating(mutating: i32) -> i32 { test_mutating(mutating) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_namespace(namespace: i32) -> i32 { test_namespace(namespace) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_native(native2: i32) -> i32 { test_native(native2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 { test_new(new2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nil(nil: i32) -> i32 { test_nil(nil) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_noexcept(noexcept: i32) -> i32 { test_noexcept(noexcept) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_none(none: i32) -> i32 { test_none(none) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nonisolated(nonisolated: i32) -> i32 { test_nonisolated(nonisolated) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nonmutating(nonmutating: i32) -> i32 { test_nonmutating(nonmutating) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_not(not: i32) -> i32 { test_not(not) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_not_eq(not_eq: i32) -> i32 { test_not_eq(not_eq) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_null(null2: i32) -> i32 { test_null(null2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_nullptr(nullptr: i32) -> i32 { test_nullptr(nullptr) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_open(open: i32) -> i32 { test_open(open) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_operator(operator: i32) -> i32 { test_operator(operator) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_optional(optional: i32) -> i32 { test_optional(optional) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_or(or: i32) -> i32 { test_or(or) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_or_eq(or_eq: i32) -> i32 { test_or_eq(or_eq) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_package(package2: i32) -> i32 { test_package(package2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_postfix(postfix: i32) -> i32 { test_postfix(postfix) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_precedence(precedence: i32) -> i32 { test_precedence(precedence) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup: i32) -> i32 { test_precedencegroup(precedencegroup) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_prefix(prefix: i32) -> i32 { test_prefix(prefix) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 { test_private(private2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 { test_protected(protected2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_protocol(protocol: i32) -> i32 { test_protocol(protocol) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 { test_public(public2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_reflexpr(reflexpr: i32) -> i32 { test_reflexpr(reflexpr) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_register(register: i32) -> i32 { test_register(register) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast: i32) -> i32 { test_reinterpret_cast(reinterpret_cast) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_repeat(repeat: i32) -> i32 { test_repeat(repeat) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_required(required: i32) -> i32 { test_required(required) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_requires(requires: i32) -> i32 { test_requires(requires) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_rethrows(rethrows: i32) -> i32 { test_rethrows(rethrows) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_right(right: i32) -> i32 { test_right(right) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_set(set: i32) -> i32 { test_set(set) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 { test_short(short2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_signed(signed: i32) -> i32 { test_signed(signed) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_sizeof(sizeof: i32) -> i32 { test_sizeof(sizeof) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_some(some: i32) -> i32 { test_some(some) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_static_assert(static_assert: i32) -> i32 { test_static_assert(static_assert) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_static_cast(static_cast: i32) -> i32 { test_static_cast(static_cast) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_subscript(subscript: i32) -> i32 { test_subscript(subscript) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 { test_switch(switch2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 { test_synchronized(synchronized2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_template(template: i32) -> i32 { test_template(template) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 { test_this(this2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_thread_local(thread_local: i32) -> i32 { test_thread_local(thread_local) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 { test_throw(throw2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_throws(throws2: i32) -> i32 { test_throws(throws2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_transient(transient2: i32) -> i32 { test_transient(transient2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typealias(typealias: i32) -> i32 { test_typealias(typealias) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typedef(typedef: i32) -> i32 { test_typedef(typedef) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typeid(typeid: i32) -> i32 { test_typeid(typeid) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_typename(typename: i32) -> i32 { test_typename(typename) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_undefined(undefined2: i32) -> i32 { test_undefined(undefined2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_union(union: i32) -> i32 { test_union(union) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_unowned(unowned: i32) -> i32 { test_unowned(unowned) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_unsigned(unsigned: i32) -> i32 { test_unsigned(unsigned) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_using(using: i32) -> i32 { test_using(using) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_var(var2: i32) -> i32 { test_var(var2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 { test_void(void2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 { test_volatile(volatile2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_wchar_t(wchar_t: i32) -> i32 { test_wchar_t(wchar_t) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_weak(weak: i32) -> i32 { test_weak(weak) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_with(with2: i32) -> i32 { test_with(with2) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_xor(xor: i32) -> i32 { test_xor(xor) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test_xor_eq(xor_eq: i32) -> i32 { test_xor_eq(xor_eq) } ================================================ FILE: src/tests/snapshots/wasm_demo_order_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface FirstTrait { second(): SecondTrait; } export interface SecondTrait { first(): FirstTrait; } export type EarlyInsideEnum = | { readonly $: "Value", 0: boolean } export type LaterOutsideEnum = | { readonly $: "Value", 0: EarlyInsideEnum } export type EarlyOutsideEnum = | { readonly $: "Value", 0: LaterInsideEnum } export type LaterInsideEnum = | { readonly $: "Value", 0: boolean } export type FirstEnum = | { readonly $: "Second", 0: SecondEnum[] } export type SecondEnum = | { readonly $: "First", 0: FirstEnum[] } export interface EarlyInsideStruct { y: boolean, } export interface LaterOutsideStruct { x: EarlyInsideStruct, } export interface EarlyOutsideStruct { x: LaterInsideStruct, } export interface LaterInsideStruct { y: boolean, } export interface FirstStruct { second: SecondStruct[], } export interface SecondStruct { first: FirstStruct[], } export function rust_mem_leaked(): number; ================================================ FILE: src/tests/snapshots/wasm_demo_order_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_order_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface FirstTrait { second(): SecondTrait; } export interface SecondTrait { first(): FirstTrait; } export type EarlyInsideEnum = | { readonly $: "Value", 0: boolean } export type LaterOutsideEnum = | { readonly $: "Value", 0: EarlyInsideEnum } export type EarlyOutsideEnum = | { readonly $: "Value", 0: LaterInsideEnum } export type LaterInsideEnum = | { readonly $: "Value", 0: boolean } export type FirstEnum = | { readonly $: "Second", 0: SecondEnum[] } export type SecondEnum = | { readonly $: "First", 0: FirstEnum[] } export interface EarlyInsideStruct { y: boolean, } export interface LaterOutsideStruct { x: EarlyInsideStruct, } export interface EarlyOutsideStruct { x: LaterInsideStruct, } export interface LaterInsideStruct { y: boolean, } export interface FirstStruct { second: SecondStruct[], } export interface SecondStruct { first: FirstStruct[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_order_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_demo_order_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface FirstTrait { second(): SecondTrait; } export interface SecondTrait { first(): FirstTrait; } export type EarlyInsideEnum = | { readonly $: "Value", 0: boolean } export type LaterOutsideEnum = | { readonly $: "Value", 0: EarlyInsideEnum } export type EarlyOutsideEnum = | { readonly $: "Value", 0: LaterInsideEnum } export type LaterInsideEnum = | { readonly $: "Value", 0: boolean } export type FirstEnum = | { readonly $: "Second", 0: SecondEnum[] } export type SecondEnum = | { readonly $: "First", 0: FirstEnum[] } export interface EarlyInsideStruct { y: boolean, } export interface LaterOutsideStruct { x: EarlyInsideStruct, } export interface EarlyOutsideStruct { x: LaterInsideStruct, } export interface LaterInsideStruct { y: boolean, } export interface FirstStruct { second: SecondStruct[], } export interface SecondStruct { first: FirstStruct[], } export function rust_mem_leaked(): number; ================================================ FILE: src/tests/snapshots/wasm_demo_order_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_order_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface FirstTrait { second(): SecondTrait; } export interface SecondTrait { first(): FirstTrait; } export type EarlyInsideEnum = | { readonly $: "Value", 0: boolean } export type LaterOutsideEnum = | { readonly $: "Value", 0: EarlyInsideEnum } export type EarlyOutsideEnum = | { readonly $: "Value", 0: LaterInsideEnum } export type LaterInsideEnum = | { readonly $: "Value", 0: boolean } export type FirstEnum = | { readonly $: "Second", 0: SecondEnum[] } export type SecondEnum = | { readonly $: "First", 0: FirstEnum[] } export interface EarlyInsideStruct { y: boolean, } export interface LaterOutsideStruct { x: EarlyInsideStruct, } export interface EarlyOutsideStruct { x: LaterInsideStruct, } export interface LaterInsideStruct { y: boolean, } export interface FirstStruct { second: SecondStruct[], } export interface SecondStruct { first: FirstStruct[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_demo_order_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Trait { get(): number; } export interface Example { box_ptr: Trait, rc_ptr: Trait, text: string, vec_box: Trait[], vec_rc: Trait[], } export function rust_mem_leaked(): number; export function test(vec: Example[]): Example[]; ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(vec) { let buf = _ffi_new_WriteBuf(); let vec_len = vec.length; _ffi_vec_Example_to_rust(vec, buf); let multi_ret = _ffi_exports._ffi_fn_test(_ffi_buf_to_rust(buf), vec_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_vec_Example_from_rust(ret_len, buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_len = 0; let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_reg_Box_Trait = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Trait(ptr)); let _ffi_reg_Rc_Trait = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Trait(ptr)); let _ffi_u8; let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } const _ffi_Box_Trait = class Trait { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Trait.register(this, _); } get() { return _ffi_exports._ffi_Box_Trait__get(this._); } }; const _ffi_Rc_Trait = class Trait { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Trait.register(this, _); } get() { return _ffi_exports._ffi_Rc_Trait__get(this._); } }; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_Example_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ box_ptr: new _ffi_Box_Trait(_ffi_read_i32(buf)), rc_ptr: new _ffi_Rc_Trait(_ffi_read_i32(buf)), text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), vec_box: _ffi_vec_box_dyn_Trait_from_rust(_ffi_read_u32(buf), buf), vec_rc: _ffi_vec_rc_dyn_Trait_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Example_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item.box_ptr)); _ffi_write_i32(buf, _ffi_handle_alloc(item.rc_ptr)); let item_text_ptr = _ffi_string_to_rust(item.text), item_text_len = _ffi_len; _ffi_write_i32(buf, item_text_ptr); _ffi_write_i32(buf, item_text_len); _ffi_write_i32(buf, item.vec_box.length); _ffi_vec_box_dyn_Trait_to_rust(item.vec_box, buf); _ffi_write_i32(buf, item.vec_rc.length); _ffi_vec_rc_dyn_Trait_to_rust(item.vec_rc, buf); } } function _ffi_vec_box_dyn_Trait_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(new _ffi_Box_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_box_dyn_Trait_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_vec_rc_dyn_Trait_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(new _ffi_Rc_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_rc_dyn_Trait_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = { _ffi_js_Trait__get(self) { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Trait { get(): number; } export interface Example { box_ptr: Trait, rc_ptr: Trait, text: string, vec_box: Trait[], vec_rc: Trait[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(vec: Example[]): Example[] { let buf = _ffi_new_WriteBuf(); let vec_len = vec.length; _ffi_vec_Example_to_rust(vec, buf); let multi_ret = _ffi_exports._ffi_fn_test(_ffi_buf_to_rust(buf), vec_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_vec_Example_from_rust(ret_len, buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_len = 0; let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_reg_Box_Trait = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Trait(ptr)); let _ffi_reg_Rc_Trait = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Trait(ptr)); let _ffi_u8: Uint8Array; let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } const _ffi_Box_Trait = class Trait implements Trait { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Trait.register(this, _); } get(): number { return _ffi_exports._ffi_Box_Trait__get(this._); } }; const _ffi_Rc_Trait = class Trait implements Trait { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Trait.register(this, _); } get(): number { return _ffi_exports._ffi_Rc_Trait__get(this._); } }; function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_Example_from_rust(len: number, buf: _ffi_ReadBuf): Example[] { let items: Example[] = []; while (items.length < len) { items.push({ box_ptr: new _ffi_Box_Trait(_ffi_read_i32(buf)), rc_ptr: new _ffi_Rc_Trait(_ffi_read_i32(buf)), text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), vec_box: _ffi_vec_box_dyn_Trait_from_rust(_ffi_read_u32(buf), buf), vec_rc: _ffi_vec_rc_dyn_Trait_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Example_to_rust(items: Example[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item.box_ptr)); _ffi_write_i32(buf, _ffi_handle_alloc(item.rc_ptr)); let item_text_ptr = _ffi_string_to_rust(item.text), item_text_len = _ffi_len; _ffi_write_i32(buf, item_text_ptr); _ffi_write_i32(buf, item_text_len); _ffi_write_i32(buf, item.vec_box.length); _ffi_vec_box_dyn_Trait_to_rust(item.vec_box, buf); _ffi_write_i32(buf, item.vec_rc.length); _ffi_vec_rc_dyn_Trait_to_rust(item.vec_rc, buf); } } function _ffi_vec_box_dyn_Trait_from_rust(len: number, buf: _ffi_ReadBuf): Trait[] { let items: Trait[] = []; while (items.length < len) { items.push(new _ffi_Box_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_box_dyn_Trait_to_rust(items: Trait[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_vec_rc_dyn_Trait_from_rust(len: number, buf: _ffi_ReadBuf): Trait[] { let items: Trait[] = []; while (items.length < len) { items.push(new _ffi_Rc_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_rc_dyn_Trait_to_rust(items: Trait[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Trait__get: (_self: number) => number, _ffi_Rc_Trait__get: (_self: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test: (buf_ptr: number, vec_len: number) => number, _ffi_rs_drop_Box_Trait: (ptr: number) => void, _ffi_rs_drop_Rc_Trait: (ptr: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Trait__get(self: number): number { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get() } #[no_mangle] extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = test(_ffi_vec_Example_from_js(vec_len, &mut buf_end)); let mut buf2 = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Example_to_js(ret, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[allow(non_camel_case_types)] struct _ffi_rs_Trait(*const u8); impl Drop for _ffi_rs_Trait { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Trait for _ffi_rs_Trait { fn get(&self) -> i32 { extern "C" { fn _ffi_js_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_js_Trait__get(self.0) } } } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Example_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Example { box_ptr: Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), rc_ptr: std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), text: _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)), vec_box: _ffi_vec_box_dyn_Trait_from_js(_ffi_read::(end), end), vec_rc: _ffi_vec_rc_dyn_Trait_from_js(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Example_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item.box_ptr)) as *const u8, buf); _ffi_write(Box::into_raw(Box::new(item.rc_ptr)) as *const u8, buf); let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.vec_box.len(), buf); _ffi_vec_box_dyn_Trait_to_js(item.vec_box, buf); _ffi_write(item.vec_rc.len(), buf); _ffi_vec_rc_dyn_Trait_to_js(item.vec_rc, buf); } } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Trait { get(): number; } export interface Example { box_ptr: Trait, rc_ptr: Trait, text: string, vec_box: Trait[], vec_rc: Trait[], } export function rust_mem_leaked(): number; export function test(vec: Example[]): Example[]; ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(vec) { let buf = _ffi_new_WriteBuf(); let vec_len = vec.length; _ffi_vec_Example_to_rust(vec, buf); let multi_ret = _ffi_exports._ffi_fn_test(_ffi_buf_to_rust(buf), vec_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_vec_Example_from_rust(ret_len, buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_len = 0; let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_reg_Box_Trait = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Trait(ptr)); let _ffi_reg_Rc_Trait = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Trait(ptr)); let _ffi_u8; let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } const _ffi_Box_Trait = class Trait { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Trait.register(this, _); } get() { return _ffi_exports._ffi_Box_Trait__get(this._); } }; const _ffi_Rc_Trait = class Trait { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Trait.register(this, _); } get() { return _ffi_exports._ffi_Rc_Trait__get(this._); } }; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_Example_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ box_ptr: new _ffi_Box_Trait(_ffi_read_i32(buf)), rc_ptr: new _ffi_Rc_Trait(_ffi_read_i32(buf)), text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), vec_box: _ffi_vec_box_dyn_Trait_from_rust(_ffi_read_u32(buf), buf), vec_rc: _ffi_vec_rc_dyn_Trait_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Example_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item.box_ptr)); _ffi_write_i32(buf, _ffi_handle_alloc(item.rc_ptr)); let item_text_ptr = _ffi_string_to_rust(item.text), item_text_len = _ffi_len; _ffi_write_i32(buf, item_text_ptr); _ffi_write_i32(buf, item_text_len); _ffi_write_i32(buf, item.vec_box.length); _ffi_vec_box_dyn_Trait_to_rust(item.vec_box, buf); _ffi_write_i32(buf, item.vec_rc.length); _ffi_vec_rc_dyn_Trait_to_rust(item.vec_rc, buf); } } function _ffi_vec_box_dyn_Trait_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(new _ffi_Box_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_box_dyn_Trait_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_vec_rc_dyn_Trait_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(new _ffi_Rc_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_rc_dyn_Trait_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = { _ffi_js_Trait__get(self) { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Trait { get(): number; } export interface Example { box_ptr: Trait, rc_ptr: Trait, text: string, vec_box: Trait[], vec_rc: Trait[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(vec: Example[]): Example[] { let buf = _ffi_new_WriteBuf(); let vec_len = vec.length; _ffi_vec_Example_to_rust(vec, buf); let multi_ret = _ffi_exports._ffi_fn_test(_ffi_buf_to_rust(buf), vec_len); let buf_ptr2 = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf2 = _ffi_new_ReadBuf(buf_ptr2); let ret = _ffi_vec_Example_from_rust(ret_len, buf2); _ffi_exports._ffi_dealloc(buf_ptr2, buf_cap); return ret; } let _ffi_len = 0; let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_reg_Box_Trait = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Trait(ptr)); let _ffi_reg_Rc_Trait = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Trait(ptr)); let _ffi_u8: Uint8Array; let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } const _ffi_Box_Trait = class Trait implements Trait { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Trait.register(this, _); } get(): number { return _ffi_exports._ffi_Box_Trait__get(this._); } }; const _ffi_Rc_Trait = class Trait implements Trait { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Trait.register(this, _); } get(): number { return _ffi_exports._ffi_Rc_Trait__get(this._); } }; function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_vec_Example_from_rust(len: number, buf: _ffi_ReadBuf): Example[] { let items: Example[] = []; while (items.length < len) { items.push({ box_ptr: new _ffi_Box_Trait(_ffi_read_i32(buf)), rc_ptr: new _ffi_Rc_Trait(_ffi_read_i32(buf)), text: _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)), vec_box: _ffi_vec_box_dyn_Trait_from_rust(_ffi_read_u32(buf), buf), vec_rc: _ffi_vec_rc_dyn_Trait_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Example_to_rust(items: Example[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item.box_ptr)); _ffi_write_i32(buf, _ffi_handle_alloc(item.rc_ptr)); let item_text_ptr = _ffi_string_to_rust(item.text), item_text_len = _ffi_len; _ffi_write_i32(buf, item_text_ptr); _ffi_write_i32(buf, item_text_len); _ffi_write_i32(buf, item.vec_box.length); _ffi_vec_box_dyn_Trait_to_rust(item.vec_box, buf); _ffi_write_i32(buf, item.vec_rc.length); _ffi_vec_rc_dyn_Trait_to_rust(item.vec_rc, buf); } } function _ffi_vec_box_dyn_Trait_from_rust(len: number, buf: _ffi_ReadBuf): Trait[] { let items: Trait[] = []; while (items.length < len) { items.push(new _ffi_Box_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_box_dyn_Trait_to_rust(items: Trait[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_vec_rc_dyn_Trait_from_rust(len: number, buf: _ffi_ReadBuf): Trait[] { let items: Trait[] = []; while (items.length < len) { items.push(new _ffi_Rc_Trait(_ffi_read_i32(buf))); } return items; } function _ffi_vec_rc_dyn_Trait_to_rust(items: Trait[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, _ffi_handle_alloc(item)); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Trait__get: (_self: number) => number, _ffi_Rc_Trait__get: (_self: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test: (buf_ptr: number, vec_len: number) => number, _ffi_rs_drop_Box_Trait: (ptr: number) => void, _ffi_rs_drop_Rc_Trait: (ptr: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Trait__get(self: number): number { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_demo_trait_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let ret = test(_ffi_vec_Example_from_js(vec_len, &mut buf_end)); let mut buf2 = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Example_to_js(ret, &mut buf2); _ffi_buf_from_host(buf_ptr, buf_end); let (buf_ptr2, buf_cap) = _ffi_buf_to_host(buf2); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr2, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[allow(non_camel_case_types)] struct _ffi_rs_Trait(*const u8); impl Drop for _ffi_rs_Trait { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Trait for _ffi_rs_Trait { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_js_Trait__get(_: *const u8) -> i32; } unsafe { _ffi_js_Trait__get(self.0) } } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Trait(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Example_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Example { box_ptr: Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), rc_ptr: std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end))), text: _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)), vec_box: _ffi_vec_box_dyn_Trait_from_js(_ffi_read::(end), end), vec_rc: _ffi_vec_rc_dyn_Trait_from_js(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Example_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item.box_ptr)) as *const u8, buf); _ffi_write(Box::into_raw(Box::new(item.rc_ptr)) as *const u8, buf); let (item_text_ptr, item_text_len, item_text_cap) = _ffi_string_to_host(item.text); _ffi_write(item_text_ptr, buf); _ffi_write(item_text_len, buf); _ffi_write(item_text_cap, buf); _ffi_write(item.vec_box.len(), buf); _ffi_vec_box_dyn_Trait_to_js(item.vec_box, buf); _ffi_write(item.vec_rc.len(), buf); _ffi_vec_rc_dyn_Trait_to_js(item.vec_rc, buf); } } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(Box::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_box_dyn_Trait_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(std::rc::Rc::new(_ffi_rs_Trait(_ffi_read::<*const u8>(end)))); } items } #[allow(non_snake_case)] fn _ffi_vec_rc_dyn_Trait_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(Box::into_raw(Box::new(item)) as *const u8, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function add_bool(x: boolean, y: boolean): boolean; export function add_u8(x: number, y: number): number; export function add_u16(x: number, y: number): number; export function add_u32(x: number, y: number): number; export function add_usize(x: number, y: number): number; export function add_u64(x: bigint, y: bigint): bigint; export function add_i8(x: number, y: number): number; export function add_i16(x: number, y: number): number; export function add_i32(x: number, y: number): number; export function add_isize(x: number, y: number): number; export function add_i64(x: bigint, y: bigint): bigint; export function add_f32(x: number, y: number): number; export function add_f64(x: number, y: number): number; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_bool(x, y) { let ret = _ffi_exports._ffi_fn_add_bool(x, y); return !!ret; } export function add_u8(x, y) { return _ffi_exports._ffi_fn_add_u8(x, y); } export function add_u16(x, y) { return _ffi_exports._ffi_fn_add_u16(x, y); } export function add_u32(x, y) { return _ffi_exports._ffi_fn_add_u32(x, y); } export function add_usize(x, y) { return _ffi_exports._ffi_fn_add_usize(x, y); } export function add_u64(x, y) { return _ffi_exports._ffi_fn_add_u64(x, y); } export function add_i8(x, y) { return _ffi_exports._ffi_fn_add_i8(x, y); } export function add_i16(x, y) { return _ffi_exports._ffi_fn_add_i16(x, y); } export function add_i32(x, y) { return _ffi_exports._ffi_fn_add_i32(x, y); } export function add_isize(x, y) { return _ffi_exports._ffi_fn_add_isize(x, y); } export function add_i64(x, y) { return _ffi_exports._ffi_fn_add_i64(x, y); } export function add_f32(x, y) { return _ffi_exports._ffi_fn_add_f32(x, y); } export function add_f64(x, y) { return _ffi_exports._ffi_fn_add_f64(x, y); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_bool(x: boolean, y: boolean): boolean { let ret = _ffi_exports._ffi_fn_add_bool(x, y); return !!ret; } export function add_u8(x: number, y: number): number { return _ffi_exports._ffi_fn_add_u8(x, y); } export function add_u16(x: number, y: number): number { return _ffi_exports._ffi_fn_add_u16(x, y); } export function add_u32(x: number, y: number): number { return _ffi_exports._ffi_fn_add_u32(x, y); } export function add_usize(x: number, y: number): number { return _ffi_exports._ffi_fn_add_usize(x, y); } export function add_u64(x: bigint, y: bigint): bigint { return _ffi_exports._ffi_fn_add_u64(x, y); } export function add_i8(x: number, y: number): number { return _ffi_exports._ffi_fn_add_i8(x, y); } export function add_i16(x: number, y: number): number { return _ffi_exports._ffi_fn_add_i16(x, y); } export function add_i32(x: number, y: number): number { return _ffi_exports._ffi_fn_add_i32(x, y); } export function add_isize(x: number, y: number): number { return _ffi_exports._ffi_fn_add_isize(x, y); } export function add_i64(x: bigint, y: bigint): bigint { return _ffi_exports._ffi_fn_add_i64(x, y); } export function add_f32(x: number, y: number): number { return _ffi_exports._ffi_fn_add_f32(x, y); } export function add_f64(x: number, y: number): number { return _ffi_exports._ffi_fn_add_f64(x, y); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_add_bool: (x: boolean, y: boolean) => boolean, _ffi_fn_add_f32: (x: number, y: number) => number, _ffi_fn_add_f64: (x: number, y: number) => number, _ffi_fn_add_i16: (x: number, y: number) => number, _ffi_fn_add_i32: (x: number, y: number) => number, _ffi_fn_add_i64: (x: bigint, y: bigint) => bigint, _ffi_fn_add_i8: (x: number, y: number) => number, _ffi_fn_add_isize: (x: number, y: number) => number, _ffi_fn_add_u16: (x: number, y: number) => number, _ffi_fn_add_u32: (x: number, y: number) => number, _ffi_fn_add_u64: (x: bigint, y: bigint) => bigint, _ffi_fn_add_u8: (x: number, y: number) => number, _ffi_fn_add_usize: (x: number, y: number) => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool { add_bool(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 { add_f32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 { add_f64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 { add_i16(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 { add_i32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 { add_i64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 { add_i8(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize { add_isize(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 { add_u16(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 { add_u32(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 { add_u64(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 { add_u8(x, y) } #[no_mangle] extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize { add_usize(x, y) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function add_bool(x: boolean, y: boolean): boolean; export function add_u8(x: number, y: number): number; export function add_u16(x: number, y: number): number; export function add_u32(x: number, y: number): number; export function add_usize(x: number, y: number): number; export function add_u64(x: bigint, y: bigint): bigint; export function add_i8(x: number, y: number): number; export function add_i16(x: number, y: number): number; export function add_i32(x: number, y: number): number; export function add_isize(x: number, y: number): number; export function add_i64(x: bigint, y: bigint): bigint; export function add_f32(x: number, y: number): number; export function add_f64(x: number, y: number): number; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_bool(x, y) { let ret = _ffi_exports._ffi_fn_add_bool(x, y); return !!ret; } export function add_u8(x, y) { return _ffi_exports._ffi_fn_add_u8(x, y); } export function add_u16(x, y) { return _ffi_exports._ffi_fn_add_u16(x, y); } export function add_u32(x, y) { return _ffi_exports._ffi_fn_add_u32(x, y); } export function add_usize(x, y) { return _ffi_exports._ffi_fn_add_usize(x, y); } export function add_u64(x, y) { return _ffi_exports._ffi_fn_add_u64(x, y); } export function add_i8(x, y) { return _ffi_exports._ffi_fn_add_i8(x, y); } export function add_i16(x, y) { return _ffi_exports._ffi_fn_add_i16(x, y); } export function add_i32(x, y) { return _ffi_exports._ffi_fn_add_i32(x, y); } export function add_isize(x, y) { return _ffi_exports._ffi_fn_add_isize(x, y); } export function add_i64(x, y) { return _ffi_exports._ffi_fn_add_i64(x, y); } export function add_f32(x, y) { return _ffi_exports._ffi_fn_add_f32(x, y); } export function add_f64(x, y) { return _ffi_exports._ffi_fn_add_f64(x, y); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_bool(x: boolean, y: boolean): boolean { let ret = _ffi_exports._ffi_fn_add_bool(x, y); return !!ret; } export function add_u8(x: number, y: number): number { return _ffi_exports._ffi_fn_add_u8(x, y); } export function add_u16(x: number, y: number): number { return _ffi_exports._ffi_fn_add_u16(x, y); } export function add_u32(x: number, y: number): number { return _ffi_exports._ffi_fn_add_u32(x, y); } export function add_usize(x: number, y: number): number { return _ffi_exports._ffi_fn_add_usize(x, y); } export function add_u64(x: bigint, y: bigint): bigint { return _ffi_exports._ffi_fn_add_u64(x, y); } export function add_i8(x: number, y: number): number { return _ffi_exports._ffi_fn_add_i8(x, y); } export function add_i16(x: number, y: number): number { return _ffi_exports._ffi_fn_add_i16(x, y); } export function add_i32(x: number, y: number): number { return _ffi_exports._ffi_fn_add_i32(x, y); } export function add_isize(x: number, y: number): number { return _ffi_exports._ffi_fn_add_isize(x, y); } export function add_i64(x: bigint, y: bigint): bigint { return _ffi_exports._ffi_fn_add_i64(x, y); } export function add_f32(x: number, y: number): number { return _ffi_exports._ffi_fn_add_f32(x, y); } export function add_f64(x: number, y: number): number { return _ffi_exports._ffi_fn_add_f64(x, y); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_add_bool: (x: boolean, y: boolean) => boolean, _ffi_fn_add_f32: (x: number, y: number) => number, _ffi_fn_add_f64: (x: number, y: number) => number, _ffi_fn_add_i16: (x: number, y: number) => number, _ffi_fn_add_i32: (x: number, y: number) => number, _ffi_fn_add_i64: (x: bigint, y: bigint) => bigint, _ffi_fn_add_i8: (x: number, y: number) => number, _ffi_fn_add_isize: (x: number, y: number) => number, _ffi_fn_add_u16: (x: number, y: number) => number, _ffi_fn_add_u32: (x: number, y: number) => number, _ffi_fn_add_u64: (x: bigint, y: bigint) => bigint, _ffi_fn_add_u8: (x: number, y: number) => number, _ffi_fn_add_usize: (x: number, y: number) => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool { add_bool(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 { add_f32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 { add_f64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 { add_i16(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 { add_i32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 { add_i64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 { add_i8(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize { add_isize(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 { add_u16(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 { add_u32(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 { add_u64(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 { add_u8(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize { add_usize(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function add_void(x: number, y: number): void; export function add_empty_tuple(x: number, y: number): undefined; export function get_result(): number; export function wild_arg(_1: number, _2: undefined, _3: number): undefined; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_void(x, y) { _ffi_exports._ffi_fn_add_void(x, y); } export function add_empty_tuple(x, y) { _ffi_exports._ffi_fn_add_empty_tuple(x, y); return undefined; } export function get_result() { return _ffi_exports._ffi_fn_get_result(); } export function wild_arg(_1, _2, _3) { _ffi_exports._ffi_fn_wild_arg(_1, _3); return undefined; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_void(x: number, y: number): void { _ffi_exports._ffi_fn_add_void(x, y); } export function add_empty_tuple(x: number, y: number): undefined { _ffi_exports._ffi_fn_add_empty_tuple(x, y); return undefined; } export function get_result(): number { return _ffi_exports._ffi_fn_get_result(); } export function wild_arg(_1: number, _2: undefined, _3: number): undefined { _ffi_exports._ffi_fn_wild_arg(_1, _3); return undefined; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_add_empty_tuple: (x: number, y: number) => void, _ffi_fn_add_void: (x: number, y: number) => void, _ffi_fn_get_result: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_wild_arg: (_1: number, _3: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) { _ = add_empty_tuple(x, y); } #[no_mangle] extern "C" fn _ffi_fn_add_void(x: i32, y: i32) { add_void(x, y); } #[no_mangle] extern "C" fn _ffi_fn_get_result() -> i32 { get_result() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) { _ = wild_arg(_1, (), _3); } ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function add_void(x: number, y: number): void; export function add_empty_tuple(x: number, y: number): undefined; export function get_result(): number; export function wild_arg(_1: number, _2: undefined, _3: number): undefined; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_void(x, y) { _ffi_exports._ffi_fn_add_void(x, y); } export function add_empty_tuple(x, y) { _ffi_exports._ffi_fn_add_empty_tuple(x, y); return undefined; } export function get_result() { return _ffi_exports._ffi_fn_get_result(); } export function wild_arg(_1, _2, _3) { _ffi_exports._ffi_fn_wild_arg(_1, _3); return undefined; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_void(x: number, y: number): void { _ffi_exports._ffi_fn_add_void(x, y); } export function add_empty_tuple(x: number, y: number): undefined { _ffi_exports._ffi_fn_add_empty_tuple(x, y); return undefined; } export function get_result(): number { return _ffi_exports._ffi_fn_get_result(); } export function wild_arg(_1: number, _2: undefined, _3: number): undefined { _ffi_exports._ffi_fn_wild_arg(_1, _3); return undefined; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_add_empty_tuple: (x: number, y: number) => void, _ffi_fn_add_void: (x: number, y: number) => void, _ffi_fn_get_result: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_wild_arg: (_1: number, _3: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_basic_void_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) { _ = add_empty_tuple(x, y); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_void(x: i32, y: i32) { add_void(x, y); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_result() -> i32 { get_result() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) { _ = wild_arg(_1, (), _3); } ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Tree { value: number, left: Tree | null, right: Tree | null, } export function rust_mem_leaked(): number; export function sum_tree(tree: Tree): number; export function check_nested(x: number): number; ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_tree(tree) { let buf = _ffi_new_WriteBuf(); let has_tree_left = tree.left !== null; if (tree.left !== null) { let tree_left_val = tree.left; _ffi_box_Tree_to_rust(tree_left_val, buf); } let has_tree_right = tree.right !== null; if (tree.right !== null) { let tree_right_val = tree.right; _ffi_box_Tree_to_rust(tree_right_val, buf); } return _ffi_exports._ffi_fn_sum_tree(tree.value, _ffi_buf_to_rust(buf), has_tree_left, has_tree_right); } export function check_nested(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_box_box_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; function _ffi_box_Tree_to_rust(val, buf) { _ffi_write_i32(buf, val.value); _ffi_write_i8(buf, +(val.left !== null)); if (val.left !== null) { let val_left_val = val.left; _ffi_box_Tree_to_rust(val_left_val, buf); } _ffi_write_i8(buf, +(val.right !== null)); if (val.right !== null) { let val_right_val = val.right; _ffi_box_Tree_to_rust(val_right_val, buf); } } function _ffi_box_box_box_i32_to_rust(val, buf) { _ffi_box_box_i32_to_rust(val, buf); } function _ffi_box_box_i32_to_rust(val, buf) { _ffi_box_i32_to_rust(val, buf); } function _ffi_box_i32_to_rust(val, buf) { _ffi_write_i32(buf, val); } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Tree { value: number, left: Tree | null, right: Tree | null, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_tree(tree: Tree): number { let buf = _ffi_new_WriteBuf(); let has_tree_left = tree.left !== null; if (tree.left !== null) { let tree_left_val = tree.left; _ffi_box_Tree_to_rust(tree_left_val, buf); } let has_tree_right = tree.right !== null; if (tree.right !== null) { let tree_right_val = tree.right; _ffi_box_Tree_to_rust(tree_right_val, buf); } return _ffi_exports._ffi_fn_sum_tree(tree.value, _ffi_buf_to_rust(buf), has_tree_left, has_tree_right); } export function check_nested(x: number): number { let buf = _ffi_new_WriteBuf(); _ffi_box_box_box_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_box_Tree_to_rust(val: Tree, buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val.value); _ffi_write_i8(buf, +(val.left !== null)); if (val.left !== null) { let val_left_val = val.left; _ffi_box_Tree_to_rust(val_left_val, buf); } _ffi_write_i8(buf, +(val.right !== null)); if (val.right !== null) { let val_right_val = val.right; _ffi_box_Tree_to_rust(val_right_val, buf); } } function _ffi_box_box_box_i32_to_rust(val: number, buf: _ffi_WriteBuf): void { _ffi_box_box_i32_to_rust(val, buf); } function _ffi_box_box_i32_to_rust(val: number, buf: _ffi_WriteBuf): void { _ffi_box_i32_to_rust(val, buf); } function _ffi_box_i32_to_rust(val: number, buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val); } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_check_nested: (buf_ptr: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_sum_tree: (tree_value: number, buf_ptr: number, has_tree_left: boolean, has_tree_right: boolean) => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_from_js(end: &mut *const u8) -> Box { Box::new(Tree { value: _ffi_read::(end), left: _ffi_read::(end).then(|| _ffi_box_Tree_from_js(end)), right: _ffi_read::(end).then(|| _ffi_box_Tree_from_js(end)) }) } fn _ffi_box_box_box_i32_from_js(end: &mut *const u8) -> Box>> { Box::new(_ffi_box_box_i32_from_js(end)) } fn _ffi_box_box_i32_from_js(end: &mut *const u8) -> Box> { Box::new(_ffi_box_i32_from_js(end)) } fn _ffi_box_i32_from_js(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 { let mut buf_end = buf_ptr; let ret = check_nested(_ffi_box_box_box_i32_from_js(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_tree_left: bool, has_tree_right: bool) -> i32 { let mut buf_end = buf_ptr; let ret = sum_tree(Tree { value: tree_value, left: has_tree_left.then(|| _ffi_box_Tree_from_js(&mut buf_end)), right: has_tree_right.then(|| _ffi_box_Tree_from_js(&mut buf_end)) }); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Tree { value: number, left: Tree | null, right: Tree | null, } export function rust_mem_leaked(): number; export function sum_tree(tree: Tree): number; export function check_nested(x: number): number; ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_tree(tree) { let buf = _ffi_new_WriteBuf(); let has_tree_left = tree.left !== null; if (tree.left !== null) { let tree_left_val = tree.left; _ffi_box_Tree_to_rust(tree_left_val, buf); } let has_tree_right = tree.right !== null; if (tree.right !== null) { let tree_right_val = tree.right; _ffi_box_Tree_to_rust(tree_right_val, buf); } return _ffi_exports._ffi_fn_sum_tree(tree.value, _ffi_buf_to_rust(buf), has_tree_left, has_tree_right); } export function check_nested(x) { let buf = _ffi_new_WriteBuf(); _ffi_box_box_box_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; function _ffi_box_Tree_to_rust(val, buf) { _ffi_write_i32(buf, val.value); _ffi_write_i8(buf, +(val.left !== null)); if (val.left !== null) { let val_left_val = val.left; _ffi_box_Tree_to_rust(val_left_val, buf); } _ffi_write_i8(buf, +(val.right !== null)); if (val.right !== null) { let val_right_val = val.right; _ffi_box_Tree_to_rust(val_right_val, buf); } } function _ffi_box_box_box_i32_to_rust(val, buf) { _ffi_box_box_i32_to_rust(val, buf); } function _ffi_box_box_i32_to_rust(val, buf) { _ffi_box_i32_to_rust(val, buf); } function _ffi_box_i32_to_rust(val, buf) { _ffi_write_i32(buf, val); } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Tree { value: number, left: Tree | null, right: Tree | null, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_tree(tree: Tree): number { let buf = _ffi_new_WriteBuf(); let has_tree_left = tree.left !== null; if (tree.left !== null) { let tree_left_val = tree.left; _ffi_box_Tree_to_rust(tree_left_val, buf); } let has_tree_right = tree.right !== null; if (tree.right !== null) { let tree_right_val = tree.right; _ffi_box_Tree_to_rust(tree_right_val, buf); } return _ffi_exports._ffi_fn_sum_tree(tree.value, _ffi_buf_to_rust(buf), has_tree_left, has_tree_right); } export function check_nested(x: number): number { let buf = _ffi_new_WriteBuf(); _ffi_box_box_box_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_box_Tree_to_rust(val: Tree, buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val.value); _ffi_write_i8(buf, +(val.left !== null)); if (val.left !== null) { let val_left_val = val.left; _ffi_box_Tree_to_rust(val_left_val, buf); } _ffi_write_i8(buf, +(val.right !== null)); if (val.right !== null) { let val_right_val = val.right; _ffi_box_Tree_to_rust(val_right_val, buf); } } function _ffi_box_box_box_i32_to_rust(val: number, buf: _ffi_WriteBuf): void { _ffi_box_box_i32_to_rust(val, buf); } function _ffi_box_box_i32_to_rust(val: number, buf: _ffi_WriteBuf): void { _ffi_box_i32_to_rust(val, buf); } function _ffi_box_i32_to_rust(val: number, buf: _ffi_WriteBuf): void { _ffi_write_i32(buf, val); } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_check_nested: (buf_ptr: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_sum_tree: (tree_value: number, buf_ptr: number, has_tree_left: boolean, has_tree_right: boolean) => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_from_js(end: &mut *const u8) -> Box { Box::new(Tree { value: _ffi_read::(end), left: _ffi_read::(end).then(|| _ffi_box_Tree_from_js(end)), right: _ffi_read::(end).then(|| _ffi_box_Tree_from_js(end)) }) } fn _ffi_box_box_box_i32_from_js(end: &mut *const u8) -> Box>> { Box::new(_ffi_box_box_i32_from_js(end)) } fn _ffi_box_box_i32_from_js(end: &mut *const u8) -> Box> { Box::new(_ffi_box_i32_from_js(end)) } fn _ffi_box_i32_from_js(end: &mut *const u8) -> Box { Box::new(_ffi_read::(end)) } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 { let mut buf_end = buf_ptr; let ret = check_nested(_ffi_box_box_box_i32_from_js(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_tree_left: bool, has_tree_right: bool) -> i32 { let mut buf_end = buf_ptr; let ret = sum_tree(Tree { value: tree_value, left: has_tree_left.then(|| _ffi_box_Tree_from_js(&mut buf_end)), right: has_tree_right.then(|| _ffi_box_Tree_from_js(&mut buf_end)) }); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Tree { value: number, left: Tree | null, right: Tree | null, } export interface Nested { 0: number, } export function rust_mem_leaked(): number; export function get_tree(): Tree; export function check_nested(x: number): Nested; ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tree() { let multi_ret = _ffi_exports._ffi_fn_get_tree(); let ret_value = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let has_ret_left = _ffi_dv.getUint8(multi_ret + 12); let has_ret_right = _ffi_dv.getUint8(multi_ret + 13); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { value: ret_value, left: has_ret_left ? _ffi_box_Tree_from_rust(buf) : null, right: has_ret_right ? _ffi_box_Tree_from_rust(buf) : null }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested(x) { let multi_ret = _ffi_exports._ffi_fn_check_nested(x); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { 0: _ffi_box_box_box_i32_from_rust(buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Tree_from_rust(buf) { return { value: _ffi_read_i32(buf), left: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null, right: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null }; } function _ffi_box_box_box_i32_from_rust(buf) { return _ffi_box_box_i32_from_rust(buf); } function _ffi_box_box_i32_from_rust(buf) { return _ffi_box_i32_from_rust(buf); } function _ffi_box_i32_from_rust(buf) { return _ffi_read_i32(buf); } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Tree { value: number, left: Tree | null, right: Tree | null, } export interface Nested { 0: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tree(): Tree { let multi_ret = _ffi_exports._ffi_fn_get_tree(); let ret_value = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let has_ret_left = _ffi_dv.getUint8(multi_ret + 12); let has_ret_right = _ffi_dv.getUint8(multi_ret + 13); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Tree = { value: ret_value, left: has_ret_left ? _ffi_box_Tree_from_rust(buf) : null, right: has_ret_right ? _ffi_box_Tree_from_rust(buf) : null }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested(x: number): Nested { let multi_ret = _ffi_exports._ffi_fn_check_nested(x); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Nested = { 0: _ffi_box_box_box_i32_from_rust(buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Tree_from_rust(buf: _ffi_ReadBuf): Tree { return { value: _ffi_read_i32(buf), left: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null, right: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null }; } function _ffi_box_box_box_i32_from_rust(buf: _ffi_ReadBuf): number { return _ffi_box_box_i32_from_rust(buf); } function _ffi_box_box_i32_from_rust(buf: _ffi_ReadBuf): number { return _ffi_box_i32_from_rust(buf); } function _ffi_box_i32_from_rust(buf: _ffi_ReadBuf): number { return _ffi_read_i32(buf); } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_check_nested: (x: number) => number, _ffi_fn_get_tree: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_to_js(val: Tree, buf: &mut Vec) { _ffi_write(val.value, buf); _ffi_write(val.left.is_some(), buf); if let Some(val_left_val) = val.left { _ffi_box_Tree_to_js(*val_left_val, buf); } _ffi_write(val.right.is_some(), buf); if let Some(val_right_val) = val.right { _ffi_box_Tree_to_js(*val_right_val, buf); } } fn _ffi_box_box_box_i32_to_js(val: Box>, buf: &mut Vec) { _ffi_box_box_i32_to_js(*val, buf); } fn _ffi_box_box_i32_to_js(val: Box, buf: &mut Vec) { _ffi_box_i32_to_js(*val, buf); } fn _ffi_box_i32_to_js(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_nested(x: i32) -> *const _ffi_ret_ptr_usize { let ret = check_nested(x); let mut buf = Vec::::new(); _ffi_box_box_box_i32_to_js(*ret.0, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_get_tree() -> *const _ffi_ret_i32_ptr_usize_2_bool { let ret = get_tree(); let ret_value = ret.value; let ret_left = ret.left; let mut buf = Vec::::new(); let has_ret_left = ret_left.is_some(); if let Some(ret_left_val) = ret_left { _ffi_box_Tree_to_js(*ret_left_val, &mut buf); } let ret_right = ret.right; let has_ret_right = ret_right.is_some(); if let Some(ret_right_val) = ret_right { _ffi_box_Tree_to_js(*ret_right_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_I32_PTR_USIZE_2_BOOL = _ffi_ret_i32_ptr_usize_2_bool(ret_value, buf_ptr, buf_cap, has_ret_left, has_ret_right); std::ptr::addr_of!(_FFI_RET_I32_PTR_USIZE_2_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool); static mut _FFI_RET_I32_PTR_USIZE_2_BOOL: _ffi_ret_i32_ptr_usize_2_bool = _ffi_ret_i32_ptr_usize_2_bool(0, std::ptr::null(), 0, false, false); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Tree { value: number, left: Tree | null, right: Tree | null, } export interface Nested { 0: number, } export function rust_mem_leaked(): number; export function get_tree(): Tree; export function check_nested(x: number): Nested; ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tree() { let multi_ret = _ffi_exports._ffi_fn_get_tree(); let ret_value = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let has_ret_left = _ffi_dv.getUint8(multi_ret + 12); let has_ret_right = _ffi_dv.getUint8(multi_ret + 13); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { value: ret_value, left: has_ret_left ? _ffi_box_Tree_from_rust(buf) : null, right: has_ret_right ? _ffi_box_Tree_from_rust(buf) : null }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested(x) { let multi_ret = _ffi_exports._ffi_fn_check_nested(x); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { 0: _ffi_box_box_box_i32_from_rust(buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Tree_from_rust(buf) { return { value: _ffi_read_i32(buf), left: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null, right: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null }; } function _ffi_box_box_box_i32_from_rust(buf) { return _ffi_box_box_i32_from_rust(buf); } function _ffi_box_box_i32_from_rust(buf) { return _ffi_box_i32_from_rust(buf); } function _ffi_box_i32_from_rust(buf) { return _ffi_read_i32(buf); } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Tree { value: number, left: Tree | null, right: Tree | null, } export interface Nested { 0: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tree(): Tree { let multi_ret = _ffi_exports._ffi_fn_get_tree(); let ret_value = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let has_ret_left = _ffi_dv.getUint8(multi_ret + 12); let has_ret_right = _ffi_dv.getUint8(multi_ret + 13); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Tree = { value: ret_value, left: has_ret_left ? _ffi_box_Tree_from_rust(buf) : null, right: has_ret_right ? _ffi_box_Tree_from_rust(buf) : null }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested(x: number): Nested { let multi_ret = _ffi_exports._ffi_fn_check_nested(x); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Nested = { 0: _ffi_box_box_box_i32_from_rust(buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Tree_from_rust(buf: _ffi_ReadBuf): Tree { return { value: _ffi_read_i32(buf), left: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null, right: _ffi_read_u8(buf) ? _ffi_box_Tree_from_rust(buf) : null }; } function _ffi_box_box_box_i32_from_rust(buf: _ffi_ReadBuf): number { return _ffi_box_box_i32_from_rust(buf); } function _ffi_box_box_i32_from_rust(buf: _ffi_ReadBuf): number { return _ffi_box_i32_from_rust(buf); } function _ffi_box_i32_from_rust(buf: _ffi_ReadBuf): number { return _ffi_read_i32(buf); } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_check_nested: (x: number) => number, _ffi_fn_get_tree: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_box_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Tree_to_js(val: Tree, buf: &mut Vec) { _ffi_write(val.value, buf); _ffi_write(val.left.is_some(), buf); if let Some(val_left_val) = val.left { _ffi_box_Tree_to_js(*val_left_val, buf); } _ffi_write(val.right.is_some(), buf); if let Some(val_right_val) = val.right { _ffi_box_Tree_to_js(*val_right_val, buf); } } fn _ffi_box_box_box_i32_to_js(val: Box>, buf: &mut Vec) { _ffi_box_box_i32_to_js(*val, buf); } fn _ffi_box_box_i32_to_js(val: Box, buf: &mut Vec) { _ffi_box_i32_to_js(*val, buf); } fn _ffi_box_i32_to_js(val: i32, buf: &mut Vec) { _ffi_write(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(x: i32) -> *const _ffi_ret_ptr_usize { let ret = check_nested(x); let mut buf = Vec::::new(); _ffi_box_box_box_i32_to_js(*ret.0, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_tree() -> *const _ffi_ret_i32_ptr_usize_2_bool { let ret = get_tree(); let ret_value = ret.value; let ret_left = ret.left; let mut buf = Vec::::new(); let has_ret_left = ret_left.is_some(); if let Some(ret_left_val) = ret_left { _ffi_box_Tree_to_js(*ret_left_val, &mut buf); } let ret_right = ret.right; let has_ret_right = ret_right.is_some(); if let Some(ret_right_val) = ret_right { _ffi_box_Tree_to_js(*ret_right_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_I32_PTR_USIZE_2_BOOL = _ffi_ret_i32_ptr_usize_2_bool(ret_value, buf_ptr, buf_cap, has_ret_left, has_ret_right); std::ptr::addr_of!(_FFI_RET_I32_PTR_USIZE_2_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool); static mut _FFI_RET_I32_PTR_USIZE_2_BOOL: _ffi_ret_i32_ptr_usize_2_bool = _ffi_ret_i32_ptr_usize_2_bool(0, std::ptr::null(), 0, false, false); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number; export function check_combo(foo: Foo): string; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo(foo) { let buf = _ffi_new_WriteBuf(); let foo_x_0_y_len = foo.x[0].y.length; _ffi_vec_Foo_to_rust(foo.x[0].y, buf); let foo_x_1_len = foo.x[1].length; _ffi_vec_Bar_to_rust(foo.x[1], buf); let foo_y_len = foo.y.length; _ffi_vec__i32_f32_bool_to_rust(foo.y, buf); let multi_ret = _ffi_exports._ffi_fn_check_combo(foo.x[0].x, _ffi_buf_to_rust(buf), foo_x_0_y_len, foo_x_1_len, foo_y_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_Bar_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item.x); _ffi_write_i32(buf, item.y.length); _ffi_vec_Foo_to_rust(item.y, buf); } } function _ffi_vec_Foo_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item.x[0].x); _ffi_write_i32(buf, item.x[0].y.length); _ffi_vec_Foo_to_rust(item.x[0].y, buf); _ffi_write_i32(buf, item.x[1].length); _ffi_vec_Bar_to_rust(item.x[1], buf); _ffi_write_i32(buf, item.y.length); _ffi_vec__i32_f32_bool_to_rust(item.y, buf); } } function _ffi_vec__i32_f32_bool_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[1][0]); _ffi_write_f32(buf, item[2][0]); _ffi_write_i8(buf, +(item[2][1])); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setFloat32(ptr, val, true); } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo(foo: Foo): string { let buf = _ffi_new_WriteBuf(); let foo_x_0_y_len = foo.x[0].y.length; _ffi_vec_Foo_to_rust(foo.x[0].y, buf); let foo_x_1_len = foo.x[1].length; _ffi_vec_Bar_to_rust(foo.x[1], buf); let foo_y_len = foo.y.length; _ffi_vec__i32_f32_bool_to_rust(foo.y, buf); let multi_ret = _ffi_exports._ffi_fn_check_combo(foo.x[0].x, _ffi_buf_to_rust(buf), foo_x_0_y_len, foo_x_1_len, foo_y_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv: DataView; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_Bar_to_rust(items: Bar[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item.x); _ffi_write_i32(buf, item.y.length); _ffi_vec_Foo_to_rust(item.y, buf); } } function _ffi_vec_Foo_to_rust(items: Foo[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item.x[0].x); _ffi_write_i32(buf, item.x[0].y.length); _ffi_vec_Foo_to_rust(item.x[0].y, buf); _ffi_write_i32(buf, item.x[1].length); _ffi_vec_Bar_to_rust(item.x[1], buf); _ffi_write_i32(buf, item.y.length); _ffi_vec__i32_f32_bool_to_rust(item.y, buf); } } function _ffi_vec__i32_f32_bool_to_rust(items: [undefined, [number], [number, boolean]][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[1][0]); _ffi_write_f32(buf, item[2][0]); _ffi_write_i8(buf, +(item[2][1])); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setFloat32(ptr, val, true); } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_check_combo: (foo_x_0_x: number, buf_ptr: number, foo_x_0_y_len: number, foo_x_1_len: number, foo_y_len: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_alloc: (len: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, foo_x_0_y_len: usize, foo_x_1_len: usize, foo_y_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_combo(Foo { x: ( Bar { x: foo_x_0_x, y: _ffi_vec_Foo_from_js(foo_x_0_y_len, &mut buf_end) }, _ffi_vec_Bar_from_js(foo_x_1_len, &mut buf_end) ), y: _ffi_vec__i32_f32_bool_from_js(foo_y_len, &mut buf_end) })); _ffi_buf_from_host(buf_ptr, buf_end); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Bar_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_js(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Foo { x: ( Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_js(_ffi_read::(end), end) }, _ffi_vec_Bar_from_js(_ffi_read::(end), end) ), y: _ffi_vec__i32_f32_bool_from_js(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_from_js(len: usize, end: &mut *const u8) -> Vec<((), (i32,), (f32, bool))> { let mut items = Vec::<((), (i32,), (f32, bool))>::with_capacity(len); for _ in 0..len { items.push(((), (_ffi_read::(end),), (_ffi_read::(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number; export function check_combo(foo: Foo): string; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo(foo) { let buf = _ffi_new_WriteBuf(); let foo_x_0_y_len = foo.x[0].y.length; _ffi_vec_Foo_to_rust(foo.x[0].y, buf); let foo_x_1_len = foo.x[1].length; _ffi_vec_Bar_to_rust(foo.x[1], buf); let foo_y_len = foo.y.length; _ffi_vec__i32_f32_bool_to_rust(foo.y, buf); let multi_ret = _ffi_exports._ffi_fn_check_combo(foo.x[0].x, _ffi_buf_to_rust(buf), foo_x_0_y_len, foo_x_1_len, foo_y_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_Bar_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item.x); _ffi_write_i32(buf, item.y.length); _ffi_vec_Foo_to_rust(item.y, buf); } } function _ffi_vec_Foo_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item.x[0].x); _ffi_write_i32(buf, item.x[0].y.length); _ffi_vec_Foo_to_rust(item.x[0].y, buf); _ffi_write_i32(buf, item.x[1].length); _ffi_vec_Bar_to_rust(item.x[1], buf); _ffi_write_i32(buf, item.y.length); _ffi_vec__i32_f32_bool_to_rust(item.y, buf); } } function _ffi_vec__i32_f32_bool_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[1][0]); _ffi_write_f32(buf, item[2][0]); _ffi_write_i8(buf, +(item[2][1])); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setFloat32(ptr, val, true); } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo(foo: Foo): string { let buf = _ffi_new_WriteBuf(); let foo_x_0_y_len = foo.x[0].y.length; _ffi_vec_Foo_to_rust(foo.x[0].y, buf); let foo_x_1_len = foo.x[1].length; _ffi_vec_Bar_to_rust(foo.x[1], buf); let foo_y_len = foo.y.length; _ffi_vec__i32_f32_bool_to_rust(foo.y, buf); let multi_ret = _ffi_exports._ffi_fn_check_combo(foo.x[0].x, _ffi_buf_to_rust(buf), foo_x_0_y_len, foo_x_1_len, foo_y_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv: DataView; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_Bar_to_rust(items: Bar[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item.x); _ffi_write_i32(buf, item.y.length); _ffi_vec_Foo_to_rust(item.y, buf); } } function _ffi_vec_Foo_to_rust(items: Foo[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item.x[0].x); _ffi_write_i32(buf, item.x[0].y.length); _ffi_vec_Foo_to_rust(item.x[0].y, buf); _ffi_write_i32(buf, item.x[1].length); _ffi_vec_Bar_to_rust(item.x[1], buf); _ffi_write_i32(buf, item.y.length); _ffi_vec__i32_f32_bool_to_rust(item.y, buf); } } function _ffi_vec__i32_f32_bool_to_rust(items: [undefined, [number], [number, boolean]][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[1][0]); _ffi_write_f32(buf, item[2][0]); _ffi_write_i8(buf, +(item[2][1])); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setFloat32(ptr, val, true); } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_check_combo: (foo_x_0_x: number, buf_ptr: number, foo_x_0_y_len: number, foo_x_1_len: number, foo_y_len: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_alloc: (len: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, foo_x_0_y_len: usize, foo_x_1_len: usize, foo_y_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_combo(Foo { x: ( Bar { x: foo_x_0_x, y: _ffi_vec_Foo_from_js(foo_x_0_y_len, &mut buf_end) }, _ffi_vec_Bar_from_js(foo_x_1_len, &mut buf_end) ), y: _ffi_vec__i32_f32_bool_from_js(foo_y_len, &mut buf_end) })); _ffi_buf_from_host(buf_ptr, buf_end); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } #[allow(non_snake_case)] fn _ffi_vec_Bar_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_js(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(Foo { x: ( Bar { x: _ffi_read::(end), y: _ffi_vec_Foo_from_js(_ffi_read::(end), end) }, _ffi_vec_Bar_from_js(_ffi_read::(end), end) ), y: _ffi_vec__i32_f32_bool_from_js(_ffi_read::(end), end) }); } items } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_from_js(len: usize, end: &mut *const u8) -> Vec<((), (i32,), (f32, bool))> { let mut items = Vec::<((), (i32,), (f32, bool))>::with_capacity(len); for _ in 0..len { items.push(((), (_ffi_read::(end),), (_ffi_read::(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number; export function check_combo1(): Foo; export function check_combo2(): Foo; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo1() { let multi_ret = _ffi_exports._ffi_fn_check_combo1(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_combo2() { let multi_ret = _ffi_exports._ffi_fn_check_combo2(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_f32(buf) { let val = buf.dv.getFloat32(buf.off, true); buf.off += 4; return val; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } function _ffi_vec_Bar_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Foo_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ x: [ { x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }, _ffi_vec_Bar_from_rust(_ffi_read_u32(buf), buf) ], y: _ffi_vec__i32_f32_bool_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec__i32_f32_bool_from_rust(len, buf) { let items = []; while (items.length < len) { items.push([undefined, [_ffi_read_i32(buf)], [_ffi_read_f32(buf), !!_ffi_read_u8(buf)]]); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo1(): Foo { let multi_ret = _ffi_exports._ffi_fn_check_combo1(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Foo = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_combo2(): Foo { let multi_ret = _ffi_exports._ffi_fn_check_combo2(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Foo = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_f32(buf: _ffi_ReadBuf): number { let val = buf.dv.getFloat32(buf.off, true); buf.off += 4; return val; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } function _ffi_vec_Bar_from_rust(len: number, buf: _ffi_ReadBuf): Bar[] { let items: Bar[] = []; while (items.length < len) { items.push({ x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Foo_from_rust(len: number, buf: _ffi_ReadBuf): Foo[] { let items: Foo[] = []; while (items.length < len) { items.push({ x: [ { x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }, _ffi_vec_Bar_from_rust(_ffi_read_u32(buf), buf) ], y: _ffi_vec__i32_f32_bool_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec__i32_f32_bool_from_rust(len: number, buf: _ffi_ReadBuf): [undefined, [number], [number, boolean]][] { let items: [undefined, [number], [number, boolean]][] = []; while (items.length < len) { items.push([undefined, [_ffi_read_i32(buf)], [_ffi_read_f32(buf), !!_ffi_read_u8(buf)]]); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_check_combo1: () => number, _ffi_fn_check_combo2: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_combo1() -> *const _ffi_ret_i32_ptr_4_usize { let ret = check_combo1(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_js(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_js(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_js(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_I32_PTR_4_USIZE = _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len); std::ptr::addr_of!(_FFI_RET_I32_PTR_4_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_check_combo2() -> *const _ffi_ret_i32_ptr_4_usize { let ret = check_combo2(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_js(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_js(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_js(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_I32_PTR_4_USIZE = _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len); std::ptr::addr_of!(_FFI_RET_I32_PTR_4_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usize); static mut _FFI_RET_I32_PTR_4_USIZE: _ffi_ret_i32_ptr_4_usize = _ffi_ret_i32_ptr_4_usize(0, std::ptr::null(), 0, 0, 0, 0); #[allow(non_snake_case)] fn _ffi_vec_Bar_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x, buf); _ffi_write(item.y.len(), buf); _ffi_vec_Foo_to_js(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec_Foo_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x.0.x, buf); _ffi_write(item.x.0.y.len(), buf); _ffi_vec_Foo_to_js(item.x.0.y, buf); _ffi_write(item.x.1.len(), buf); _ffi_vec_Bar_to_js(item.x.1, buf); _ffi_write(item.y.len(), buf); _ffi_vec__i32_f32_bool_to_js(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_to_js(items: Vec<((), (i32,), (f32, bool))>, buf: &mut Vec) { for item in items { _ = item.0; _ffi_write(item.1.0, buf); _ffi_write(item.2.0, buf); _ffi_write(item.2.1, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number; export function check_combo1(): Foo; export function check_combo2(): Foo; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo1() { let multi_ret = _ffi_exports._ffi_fn_check_combo1(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_combo2() { let multi_ret = _ffi_exports._ffi_fn_check_combo2(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_f32(buf) { let val = buf.dv.getFloat32(buf.off, true); buf.off += 4; return val; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } function _ffi_vec_Bar_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Foo_from_rust(len, buf) { let items = []; while (items.length < len) { items.push({ x: [ { x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }, _ffi_vec_Bar_from_rust(_ffi_read_u32(buf), buf) ], y: _ffi_vec__i32_f32_bool_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec__i32_f32_bool_from_rust(len, buf) { let items = []; while (items.length < len) { items.push([undefined, [_ffi_read_i32(buf)], [_ffi_read_f32(buf), !!_ffi_read_u8(buf)]]); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Foo { x: [Bar, Bar[]], y: [undefined, [number], [number, boolean]][], } export interface Bar { x: number, y: Foo[], } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function check_combo1(): Foo { let multi_ret = _ffi_exports._ffi_fn_check_combo1(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Foo = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_combo2(): Foo { let multi_ret = _ffi_exports._ffi_fn_check_combo2(); let ret_x_0_x = _ffi_update_dv().getInt32(multi_ret, true); let buf_ptr = _ffi_dv.getInt32(multi_ret + 4, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 8, true); let ret_x_0_y_len = _ffi_dv.getUint32(multi_ret + 12, true); let ret_x_1_len = _ffi_dv.getUint32(multi_ret + 16, true); let ret_y_len = _ffi_dv.getUint32(multi_ret + 20, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: Foo = { x: [ { x: ret_x_0_x, y: _ffi_vec_Foo_from_rust(ret_x_0_y_len, buf) }, _ffi_vec_Bar_from_rust(ret_x_1_len, buf) ], y: _ffi_vec__i32_f32_bool_from_rust(ret_y_len, buf) }; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_f32(buf: _ffi_ReadBuf): number { let val = buf.dv.getFloat32(buf.off, true); buf.off += 4; return val; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } function _ffi_vec_Bar_from_rust(len: number, buf: _ffi_ReadBuf): Bar[] { let items: Bar[] = []; while (items.length < len) { items.push({ x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec_Foo_from_rust(len: number, buf: _ffi_ReadBuf): Foo[] { let items: Foo[] = []; while (items.length < len) { items.push({ x: [ { x: _ffi_read_i32(buf), y: _ffi_vec_Foo_from_rust(_ffi_read_u32(buf), buf) }, _ffi_vec_Bar_from_rust(_ffi_read_u32(buf), buf) ], y: _ffi_vec__i32_f32_bool_from_rust(_ffi_read_u32(buf), buf) }); } return items; } function _ffi_vec__i32_f32_bool_from_rust(len: number, buf: _ffi_ReadBuf): [undefined, [number], [number, boolean]][] { let items: [undefined, [number], [number, boolean]][] = []; while (items.length < len) { items.push([undefined, [_ffi_read_i32(buf)], [_ffi_read_f32(buf), !!_ffi_read_u8(buf)]]); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_check_combo1: () => number, _ffi_fn_check_combo2: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_combo_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo1() -> *const _ffi_ret_i32_ptr_4_usize { let ret = check_combo1(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_js(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_js(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_js(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_I32_PTR_4_USIZE = _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len); std::ptr::addr_of!(_FFI_RET_I32_PTR_4_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_combo2() -> *const _ffi_ret_i32_ptr_4_usize { let ret = check_combo2(); let ret_x = ret.x; let ret_x_0 = ret_x.0; let ret_x_0_x = ret_x_0.x; let ret_x_0_y = ret_x_0.y; let mut buf = Vec::::new(); let ret_x_0_y_len = ret_x_0_y.len(); _ffi_vec_Foo_to_js(ret_x_0_y, &mut buf); let ret_x_1 = ret_x.1; let ret_x_1_len = ret_x_1.len(); _ffi_vec_Bar_to_js(ret_x_1, &mut buf); let ret_y = ret.y; let ret_y_len = ret_y.len(); _ffi_vec__i32_f32_bool_to_js(ret_y, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_I32_PTR_4_USIZE = _ffi_ret_i32_ptr_4_usize(ret_x_0_x, buf_ptr, buf_cap, ret_x_0_y_len, ret_x_1_len, ret_y_len); std::ptr::addr_of!(_FFI_RET_I32_PTR_4_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usize); static mut _FFI_RET_I32_PTR_4_USIZE: _ffi_ret_i32_ptr_4_usize = _ffi_ret_i32_ptr_4_usize(0, std::ptr::null(), 0, 0, 0, 0); #[allow(non_snake_case)] fn _ffi_vec_Bar_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x, buf); _ffi_write(item.y.len(), buf); _ffi_vec_Foo_to_js(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec_Foo_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item.x.0.x, buf); _ffi_write(item.x.0.y.len(), buf); _ffi_vec_Foo_to_js(item.x.0.y, buf); _ffi_write(item.x.1.len(), buf); _ffi_vec_Bar_to_js(item.x.1, buf); _ffi_write(item.y.len(), buf); _ffi_vec__i32_f32_bool_to_js(item.y, buf); } } #[allow(non_snake_case)] fn _ffi_vec__i32_f32_bool_to_js(items: Vec<((), (i32,), (f32, bool))>, buf: &mut Vec) { for item in items { _ = item.0; _ffi_write(item.1.0, buf); _ffi_write(item.2.0, buf); _ffi_write(item.2.1, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number; export function foo_to_i32(foo: Foo): number; export function big_to_i32(big: Big): number; export function long_in(_1: LongEnum): void; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const Foo = { Zero: 0, One: 1, Hundred: 100, }; export const Big = { Min: -2147483648, Max: 2147483647, }; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function foo_to_i32(foo) { return _ffi_exports._ffi_fn_foo_to_i32(foo); } export function big_to_i32(big) { return _ffi_exports._ffi_fn_big_to_i32(big); } export function long_in(_1) { let buf = _ffi_new_WriteBuf(); _ffi_enum_LongEnum_to_rust(_1, buf); _ffi_exports._ffi_fn_long_in(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_LongEnum_to_rust(val, buf) { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "ShortTuple": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "ShortStruct": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.a); break; case "LongTuple": _ffi_write_i32(buf, 3); _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); _ffi_write_i32(buf, val[2]); _ffi_write_i32(buf, val[3]); _ffi_write_i32(buf, val[4]); _ffi_write_i32(buf, val[5]); _ffi_write_i32(buf, val[6]); _ffi_write_i32(buf, val[7]); break; case "LongStruct": _ffi_write_i32(buf, 4); _ffi_write_i32(buf, val.a); _ffi_write_i32(buf, val.b); _ffi_write_i32(buf, val.c); _ffi_write_i32(buf, val.d); _ffi_write_i32(buf, val.e); _ffi_write_i32(buf, val.f); break; default: throw TypeError("Invalid value for enum \"LongEnum\""); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function foo_to_i32(foo: Foo): number { return _ffi_exports._ffi_fn_foo_to_i32(foo); } export function big_to_i32(big: Big): number { return _ffi_exports._ffi_fn_big_to_i32(big); } export function long_in(_1: LongEnum): void { let buf = _ffi_new_WriteBuf(); _ffi_enum_LongEnum_to_rust(_1, buf); _ffi_exports._ffi_fn_long_in(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_LongEnum_to_rust(val: LongEnum, buf: _ffi_WriteBuf): void { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "ShortTuple": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "ShortStruct": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.a); break; case "LongTuple": _ffi_write_i32(buf, 3); _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); _ffi_write_i32(buf, val[2]); _ffi_write_i32(buf, val[3]); _ffi_write_i32(buf, val[4]); _ffi_write_i32(buf, val[5]); _ffi_write_i32(buf, val[6]); _ffi_write_i32(buf, val[7]); break; case "LongStruct": _ffi_write_i32(buf, 4); _ffi_write_i32(buf, val.a); _ffi_write_i32(buf, val.b); _ffi_write_i32(buf, val.c); _ffi_write_i32(buf, val.d); _ffi_write_i32(buf, val.e); _ffi_write_i32(buf, val.f); break; default: throw TypeError("Invalid value for enum \"LongEnum\""); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_big_to_i32: (big_raw: number) => number, _ffi_fn_foo_to_i32: (foo_raw: number) => number, _ffi_fn_long_in: (buf_ptr: number) => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Big_from_js(val: i32) -> Big { match val { -2147483648 => Big::Min, 2147483647 => Big::Max, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_js(val: i32) -> Foo { match val { 0 => Foo::Zero, 1 => Foo::One, 100 => Foo::Hundred, _ => panic!(), } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_from_js(end: &mut *const u8) -> LongEnum { match _ffi_read::(end) { 0 => LongEnum::Empty, 1 => LongEnum::ShortTuple(_ffi_read::(end)), 2 => LongEnum::ShortStruct { a: _ffi_read::(end) }, 3 => LongEnum::LongTuple( _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end) ), 4 => LongEnum::LongStruct { a: _ffi_read::(end), b: _ffi_read::(end), c: _ffi_read::(end), d: _ffi_read::(end), e: _ffi_read::(end), f: _ffi_read::(end) }, _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 { big_to_i32(_ffi_enum_Big_from_js(big_raw)) } #[no_mangle] extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 { foo_to_i32(_ffi_enum_Foo_from_js(foo_raw)) } #[no_mangle] extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) { let mut buf_end = buf_ptr; long_in(_ffi_enum_LongEnum_from_js(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number; export function foo_to_i32(foo: Foo): number; export function big_to_i32(big: Big): number; export function long_in(_1: LongEnum): void; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const Foo = { Zero: 0, One: 1, Hundred: 100, }; export const Big = { Min: -2147483648, Max: 2147483647, }; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function foo_to_i32(foo) { return _ffi_exports._ffi_fn_foo_to_i32(foo); } export function big_to_i32(big) { return _ffi_exports._ffi_fn_big_to_i32(big); } export function long_in(_1) { let buf = _ffi_new_WriteBuf(); _ffi_enum_LongEnum_to_rust(_1, buf); _ffi_exports._ffi_fn_long_in(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_LongEnum_to_rust(val, buf) { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "ShortTuple": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "ShortStruct": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.a); break; case "LongTuple": _ffi_write_i32(buf, 3); _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); _ffi_write_i32(buf, val[2]); _ffi_write_i32(buf, val[3]); _ffi_write_i32(buf, val[4]); _ffi_write_i32(buf, val[5]); _ffi_write_i32(buf, val[6]); _ffi_write_i32(buf, val[7]); break; case "LongStruct": _ffi_write_i32(buf, 4); _ffi_write_i32(buf, val.a); _ffi_write_i32(buf, val.b); _ffi_write_i32(buf, val.c); _ffi_write_i32(buf, val.d); _ffi_write_i32(buf, val.e); _ffi_write_i32(buf, val.f); break; default: throw TypeError("Invalid value for enum \"LongEnum\""); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function foo_to_i32(foo: Foo): number { return _ffi_exports._ffi_fn_foo_to_i32(foo); } export function big_to_i32(big: Big): number { return _ffi_exports._ffi_fn_big_to_i32(big); } export function long_in(_1: LongEnum): void { let buf = _ffi_new_WriteBuf(); _ffi_enum_LongEnum_to_rust(_1, buf); _ffi_exports._ffi_fn_long_in(_ffi_buf_to_rust(buf)); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_LongEnum_to_rust(val: LongEnum, buf: _ffi_WriteBuf): void { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "ShortTuple": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "ShortStruct": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.a); break; case "LongTuple": _ffi_write_i32(buf, 3); _ffi_write_i32(buf, val[0]); _ffi_write_i32(buf, val[1]); _ffi_write_i32(buf, val[2]); _ffi_write_i32(buf, val[3]); _ffi_write_i32(buf, val[4]); _ffi_write_i32(buf, val[5]); _ffi_write_i32(buf, val[6]); _ffi_write_i32(buf, val[7]); break; case "LongStruct": _ffi_write_i32(buf, 4); _ffi_write_i32(buf, val.a); _ffi_write_i32(buf, val.b); _ffi_write_i32(buf, val.c); _ffi_write_i32(buf, val.d); _ffi_write_i32(buf, val.e); _ffi_write_i32(buf, val.f); break; default: throw TypeError("Invalid value for enum \"LongEnum\""); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_big_to_i32: (big_raw: number) => number, _ffi_fn_foo_to_i32: (foo_raw: number) => number, _ffi_fn_long_in: (buf_ptr: number) => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Big_from_js(val: i32) -> Big { match val { -2147483648 => Big::Min, 2147483647 => Big::Max, _ => panic!(), } } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_js(val: i32) -> Foo { match val { 0 => Foo::Zero, 1 => Foo::One, 100 => Foo::Hundred, _ => panic!(), } } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_from_js(end: &mut *const u8) -> LongEnum { match _ffi_read::(end) { 0 => LongEnum::Empty, 1 => LongEnum::ShortTuple(_ffi_read::(end)), 2 => LongEnum::ShortStruct { a: _ffi_read::(end) }, 3 => LongEnum::LongTuple( _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end), _ffi_read::(end) ), 4 => LongEnum::LongStruct { a: _ffi_read::(end), b: _ffi_read::(end), c: _ffi_read::(end), d: _ffi_read::(end), e: _ffi_read::(end), f: _ffi_read::(end) }, _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 { big_to_i32(_ffi_enum_Big_from_js(big_raw)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 { foo_to_i32(_ffi_enum_Foo_from_js(foo_raw)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) { let mut buf_end = buf_ptr; long_in(_ffi_enum_LongEnum_from_js(&mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number; export function i32_to_foo(foo: number): Foo; export function i32_to_big(big: number): Big; export function long_out(): LongEnum; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const Foo = { Zero: 0, One: 1, Hundred: 100, }; export const Big = { Min: -2147483648, Max: 2147483647, }; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function i32_to_foo(foo) { return _ffi_exports._ffi_fn_i32_to_foo(foo); } export function i32_to_big(big) { return _ffi_exports._ffi_fn_i32_to_big(big); } export function long_out() { let multi_ret = _ffi_exports._ffi_fn_long_out(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_enum_LongEnum_from_rust(buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_LongEnum__Empty = { $: "Empty" }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_enum_LongEnum_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_LongEnum__Empty; case 1: return { $: "ShortTuple", 0: _ffi_read_i32(buf) }; case 2: return { $: "ShortStruct", a: _ffi_read_i32(buf) }; case 3: return { $: "LongTuple", 0: _ffi_read_i32(buf), 1: _ffi_read_i32(buf), 2: _ffi_read_i32(buf), 3: _ffi_read_i32(buf), 4: _ffi_read_i32(buf), 5: _ffi_read_i32(buf), 6: _ffi_read_i32(buf), 7: _ffi_read_i32(buf) }; case 4: return { $: "LongStruct", a: _ffi_read_i32(buf), b: _ffi_read_i32(buf), c: _ffi_read_i32(buf), d: _ffi_read_i32(buf), e: _ffi_read_i32(buf), f: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function i32_to_foo(foo: number): Foo { return _ffi_exports._ffi_fn_i32_to_foo(foo); } export function i32_to_big(big: number): Big { return _ffi_exports._ffi_fn_i32_to_big(big); } export function long_out(): LongEnum { let multi_ret = _ffi_exports._ffi_fn_long_out(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: LongEnum = _ffi_enum_LongEnum_from_rust(buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_LongEnum__Empty: LongEnum = { $: "Empty" }; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_enum_LongEnum_from_rust(buf: _ffi_ReadBuf): LongEnum { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_LongEnum__Empty; case 1: return { $: "ShortTuple", 0: _ffi_read_i32(buf) }; case 2: return { $: "ShortStruct", a: _ffi_read_i32(buf) }; case 3: return { $: "LongTuple", 0: _ffi_read_i32(buf), 1: _ffi_read_i32(buf), 2: _ffi_read_i32(buf), 3: _ffi_read_i32(buf), 4: _ffi_read_i32(buf), 5: _ffi_read_i32(buf), 6: _ffi_read_i32(buf), 7: _ffi_read_i32(buf) }; case 4: return { $: "LongStruct", a: _ffi_read_i32(buf), b: _ffi_read_i32(buf), c: _ffi_read_i32(buf), d: _ffi_read_i32(buf), e: _ffi_read_i32(buf), f: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_i32_to_big: (big: number) => number, _ffi_fn_i32_to_foo: (foo: number) => number, _ffi_fn_long_out: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_to_js(val: LongEnum, buf: &mut Vec) { match val { LongEnum::Empty => _ffi_write(0 as i32, buf), LongEnum::ShortTuple(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } LongEnum::ShortStruct { a } => { _ffi_write(2 as i32, buf); _ffi_write(a, buf); } LongEnum::LongTuple(x0, x1, x2, x3, x4, x5, x6, x7) => { _ffi_write(3 as i32, buf); _ffi_write(x0, buf); _ffi_write(x1, buf); _ffi_write(x2, buf); _ffi_write(x3, buf); _ffi_write(x4, buf); _ffi_write(x5, buf); _ffi_write(x6, buf); _ffi_write(x7, buf); } LongEnum::LongStruct { a, b, c, d, e, f } => { _ffi_write(4 as i32, buf); _ffi_write(a, buf); _ffi_write(b, buf); _ffi_write(c, buf); _ffi_write(d, buf); _ffi_write(e, buf); _ffi_write(f, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 { i32_to_big(big) as i32 } #[no_mangle] extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 { i32_to_foo(foo) as i32 } #[no_mangle] extern "C" fn _ffi_fn_long_out() -> *const _ffi_ret_ptr_usize { let mut buf = Vec::::new(); _ffi_enum_LongEnum_to_js(long_out(), &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number; export function i32_to_foo(foo: number): Foo; export function i32_to_big(big: number): Big; export function long_out(): LongEnum; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const Foo = { Zero: 0, One: 1, Hundred: 100, }; export const Big = { Min: -2147483648, Max: 2147483647, }; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function i32_to_foo(foo) { return _ffi_exports._ffi_fn_i32_to_foo(foo); } export function i32_to_big(big) { return _ffi_exports._ffi_fn_i32_to_big(big); } export function long_out() { let multi_ret = _ffi_exports._ffi_fn_long_out(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_enum_LongEnum_from_rust(buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_LongEnum__Empty = { $: "Empty" }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_enum_LongEnum_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_LongEnum__Empty; case 1: return { $: "ShortTuple", 0: _ffi_read_i32(buf) }; case 2: return { $: "ShortStruct", a: _ffi_read_i32(buf) }; case 3: return { $: "LongTuple", 0: _ffi_read_i32(buf), 1: _ffi_read_i32(buf), 2: _ffi_read_i32(buf), 3: _ffi_read_i32(buf), 4: _ffi_read_i32(buf), 5: _ffi_read_i32(buf), 6: _ffi_read_i32(buf), 7: _ffi_read_i32(buf) }; case 4: return { $: "LongStruct", a: _ffi_read_i32(buf), b: _ffi_read_i32(buf), c: _ffi_read_i32(buf), d: _ffi_read_i32(buf), e: _ffi_read_i32(buf), f: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export const enum Foo { Zero, One, Hundred = 100, } export const enum Big { Min = -2147483648, Max = 2147483647, } export type LongEnum = | { readonly $: "Empty" } | { readonly $: "ShortTuple", 0: number } | { readonly $: "ShortStruct", a: number } | { readonly $: "LongTuple", 0: number, 1: number, 2: number, 3: number, 4: number, 5: number, 6: number, 7: number } | { readonly $: "LongStruct", a: number, b: number, c: number, d: number, e: number, f: number } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function i32_to_foo(foo: number): Foo { return _ffi_exports._ffi_fn_i32_to_foo(foo); } export function i32_to_big(big: number): Big { return _ffi_exports._ffi_fn_i32_to_big(big); } export function long_out(): LongEnum { let multi_ret = _ffi_exports._ffi_fn_long_out(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: LongEnum = _ffi_enum_LongEnum_from_rust(buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_LongEnum__Empty: LongEnum = { $: "Empty" }; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_enum_LongEnum_from_rust(buf: _ffi_ReadBuf): LongEnum { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_LongEnum__Empty; case 1: return { $: "ShortTuple", 0: _ffi_read_i32(buf) }; case 2: return { $: "ShortStruct", a: _ffi_read_i32(buf) }; case 3: return { $: "LongTuple", 0: _ffi_read_i32(buf), 1: _ffi_read_i32(buf), 2: _ffi_read_i32(buf), 3: _ffi_read_i32(buf), 4: _ffi_read_i32(buf), 5: _ffi_read_i32(buf), 6: _ffi_read_i32(buf), 7: _ffi_read_i32(buf) }; case 4: return { $: "LongStruct", a: _ffi_read_i32(buf), b: _ffi_read_i32(buf), c: _ffi_read_i32(buf), d: _ffi_read_i32(buf), e: _ffi_read_i32(buf), f: _ffi_read_i32(buf) }; default: throw Error(); } } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_i32_to_big: (big: number) => number, _ffi_fn_i32_to_foo: (foo: number) => number, _ffi_fn_long_out: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_enum_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_LongEnum_to_js(val: LongEnum, buf: &mut Vec) { match val { LongEnum::Empty => _ffi_write(0 as i32, buf), LongEnum::ShortTuple(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } LongEnum::ShortStruct { a } => { _ffi_write(2 as i32, buf); _ffi_write(a, buf); } LongEnum::LongTuple(x0, x1, x2, x3, x4, x5, x6, x7) => { _ffi_write(3 as i32, buf); _ffi_write(x0, buf); _ffi_write(x1, buf); _ffi_write(x2, buf); _ffi_write(x3, buf); _ffi_write(x4, buf); _ffi_write(x5, buf); _ffi_write(x6, buf); _ffi_write(x7, buf); } LongEnum::LongStruct { a, b, c, d, e, f } => { _ffi_write(4 as i32, buf); _ffi_write(a, buf); _ffi_write(b, buf); _ffi_write(c, buf); _ffi_write(d, buf); _ffi_write(e, buf); _ffi_write(f, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 { i32_to_big(big) as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 { i32_to_foo(foo) as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_long_out() -> *const _ffi_ret_ptr_usize { let mut buf = Vec::::new(); _ffi_enum_LongEnum_to_js(long_out(), &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE = _ffi_ret_ptr_usize(buf_ptr, buf_cap); std::ptr::addr_of!(_FFI_RET_PTR_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Bar { get(): number; } export interface Foo { empty: undefined, ptr: Bar, } export function rust_mem_leaked(): number; export function test(x: [number, Foo, [number, Foo][]]): number; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x) { let x_1_ptr_ptr = _ffi_handle_alloc(x[1].ptr); let buf = _ffi_new_WriteBuf(); let x_2_len = x[2].length; _ffi_vec_i32_Foo_to_rust(x[2], buf); return _ffi_exports._ffi_fn_test(x[0], x_1_ptr_ptr, _ffi_buf_to_rust(buf), x_2_len); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_vec_i32_Foo_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, _ffi_handle_alloc(item[1].ptr)); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = { _ffi_js_Bar__get(self) { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Bar { get(): number; } export interface Foo { empty: undefined, ptr: Bar, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x: [number, Foo, [number, Foo][]]): number { let x_1_ptr_ptr = _ffi_handle_alloc(x[1].ptr); let buf = _ffi_new_WriteBuf(); let x_2_len = x[2].length; _ffi_vec_i32_Foo_to_rust(x[2], buf); return _ffi_exports._ffi_fn_test(x[0], x_1_ptr_ptr, _ffi_buf_to_rust(buf), x_2_len); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_vec_i32_Foo_to_rust(items: [number, Foo][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, _ffi_handle_alloc(item[1].ptr)); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test: (x_0: number, x_1_ptr_ptr: number, buf_ptr: number, x_2_len: number) => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Bar__get(self: number): number { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *const u8, x_2_len: usize) -> i32 { let x_1 = Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(x_1_ptr_ptr)) }; let mut buf_end = buf_ptr; let ret = test((x_0, x_1, _ffi_vec_i32_Foo_from_js(x_2_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_camel_case_types)] struct _ffi_rs_Bar(*const u8); impl Drop for _ffi_rs_Bar { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Bar for _ffi_rs_Bar { fn get(&self) -> i32 { extern "C" { fn _ffi_js_Bar__get(_: *const u8) -> i32; } unsafe { _ffi_js_Bar__get(self.0) } } } #[allow(non_snake_case)] fn _ffi_vec_i32_Foo_from_js(len: usize, end: &mut *const u8) -> Vec<(i32, Foo)> { let mut items = Vec::<(i32, Foo)>::with_capacity(len); for _ in 0..len { items.push(( _ffi_read::(end), Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(_ffi_read::<*const u8>(end))) } )); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Bar { get(): number; } export interface Foo { empty: undefined, ptr: Bar, } export function rust_mem_leaked(): number; export function test(x: [number, Foo, [number, Foo][]]): number; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x) { let x_1_ptr_ptr = _ffi_handle_alloc(x[1].ptr); let buf = _ffi_new_WriteBuf(); let x_2_len = x[2].length; _ffi_vec_i32_Foo_to_rust(x[2], buf); return _ffi_exports._ffi_fn_test(x[0], x_1_ptr_ptr, _ffi_buf_to_rust(buf), x_2_len); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_vec_i32_Foo_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, _ffi_handle_alloc(item[1].ptr)); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = { _ffi_js_Bar__get(self) { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Bar { get(): number; } export interface Foo { empty: undefined, ptr: Bar, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x: [number, Foo, [number, Foo][]]): number { let x_1_ptr_ptr = _ffi_handle_alloc(x[1].ptr); let buf = _ffi_new_WriteBuf(); let x_2_len = x[2].length; _ffi_vec_i32_Foo_to_rust(x[2], buf); return _ffi_exports._ffi_fn_test(x[0], x_1_ptr_ptr, _ffi_buf_to_rust(buf), x_2_len); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_vec_i32_Foo_to_rust(items: [number, Foo][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item[0]); _ffi_write_i32(buf, _ffi_handle_alloc(item[1].ptr)); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test: (x_0: number, x_1_ptr_ptr: number, buf_ptr: number, x_2_len: number) => number, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Bar__get(self: number): number { return _ffi_handles.get(self).get(); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *const u8, x_2_len: usize) -> i32 { let x_1 = Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(x_1_ptr_ptr)) }; let mut buf_end = buf_ptr; let ret = test((x_0, x_1, _ffi_vec_i32_Foo_from_js(x_2_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_camel_case_types)] struct _ffi_rs_Bar(*const u8); impl Drop for _ffi_rs_Bar { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Bar for _ffi_rs_Bar { fn get(&self) -> i32 { unsafe extern "C" { fn _ffi_js_Bar__get(_: *const u8) -> i32; } unsafe { _ffi_js_Bar__get(self.0) } } } #[allow(non_snake_case)] fn _ffi_vec_i32_Foo_from_js(len: usize, end: &mut *const u8) -> Vec<(i32, Foo)> { let mut items = Vec::<(i32, Foo)>::with_capacity(len); for _ in 0..len { items.push(( _ffi_read::(end), Foo { empty: (), ptr: std::rc::Rc::new(_ffi_rs_Bar(_ffi_read::<*const u8>(end))) } )); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Bar { get(): number; } export interface Foo { ptr: Bar, } export function rust_mem_leaked(): number; export function test(x: number): [number, Foo]; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x) { let multi_ret = _ffi_exports._ffi_fn_test(x); let ret_0 = _ffi_update_dv().getInt32(multi_ret, true); let ret_1_ptr_ptr = _ffi_dv.getInt32(multi_ret + 4, true); return [ret_0, { ptr: new _ffi_Rc_Bar(ret_1_ptr_ptr) }]; } let _ffi_reg_Rc_Bar = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Bar(ptr)); let _ffi_dv; const _ffi_Rc_Bar = class Bar { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Bar.register(this, _); } get() { return _ffi_exports._ffi_Rc_Bar__get(this._); } }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Bar { get(): number; } export interface Foo { ptr: Bar, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x: number): [number, Foo] { let multi_ret = _ffi_exports._ffi_fn_test(x); let ret_0 = _ffi_update_dv().getInt32(multi_ret, true); let ret_1_ptr_ptr = _ffi_dv.getInt32(multi_ret + 4, true); return [ret_0, { ptr: new _ffi_Rc_Bar(ret_1_ptr_ptr) }]; } let _ffi_reg_Rc_Bar = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Bar(ptr)); let _ffi_dv: DataView; const _ffi_Rc_Bar = class Bar implements Bar { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Bar.register(this, _); } get(): number { return _ffi_exports._ffi_Rc_Bar__get(this._); } }; function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Bar__get: (_self: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test: (x: number) => number, _ffi_rs_drop_Rc_Bar: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_test(x: i32) -> *const _ffi_ret_i32_ptr { let ret = test(x); let ret_0 = ret.0; let ret_1 = ret.1; unsafe { _FFI_RET_I32_PTR = _ffi_ret_i32_ptr(ret_0, Box::into_raw(Box::new(ret_1.ptr)) as *const u8); std::ptr::addr_of!(_FFI_RET_I32_PTR) } } #[repr(C)] struct _ffi_ret_i32_ptr(i32, *const u8); static mut _FFI_RET_I32_PTR: _ffi_ret_i32_ptr = _ffi_ret_i32_ptr(0, std::ptr::null()); #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Bar(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Bar { get(): number; } export interface Foo { ptr: Bar, } export function rust_mem_leaked(): number; export function test(x: number): [number, Foo]; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x) { let multi_ret = _ffi_exports._ffi_fn_test(x); let ret_0 = _ffi_update_dv().getInt32(multi_ret, true); let ret_1_ptr_ptr = _ffi_dv.getInt32(multi_ret + 4, true); return [ret_0, { ptr: new _ffi_Rc_Bar(ret_1_ptr_ptr) }]; } let _ffi_reg_Rc_Bar = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Bar(ptr)); let _ffi_dv; const _ffi_Rc_Bar = class Bar { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Bar.register(this, _); } get() { return _ffi_exports._ffi_Rc_Bar__get(this._); } }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Bar { get(): number; } export interface Foo { ptr: Bar, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function test(x: number): [number, Foo] { let multi_ret = _ffi_exports._ffi_fn_test(x); let ret_0 = _ffi_update_dv().getInt32(multi_ret, true); let ret_1_ptr_ptr = _ffi_dv.getInt32(multi_ret + 4, true); return [ret_0, { ptr: new _ffi_Rc_Bar(ret_1_ptr_ptr) }]; } let _ffi_reg_Rc_Bar = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Bar(ptr)); let _ffi_dv: DataView; const _ffi_Rc_Bar = class Bar implements Bar { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Bar.register(this, _); } get(): number { return _ffi_exports._ffi_Rc_Bar__get(this._); } }; function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Bar__get: (_self: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_test: (x: number) => number, _ffi_rs_drop_Rc_Bar: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_nested_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.get() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_test(x: i32) -> *const _ffi_ret_i32_ptr { let ret = test(x); let ret_0 = ret.0; let ret_1 = ret.1; unsafe { _FFI_RET_I32_PTR = _ffi_ret_i32_ptr(ret_0, Box::into_raw(Box::new(ret_1.ptr)) as *const u8); std::ptr::addr_of!(_FFI_RET_I32_PTR) } } #[repr(C)] struct _ffi_ret_i32_ptr(i32, *const u8); static mut _FFI_RET_I32_PTR: _ffi_ret_i32_ptr = _ffi_ret_i32_ptr(0, std::ptr::null()); #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Bar(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function add_option(x: number | null, y: number | null): number; export function add_nested(x: number | null, y: number | null): number; export function add_all(x: (number | null)[]): number; export function join_all(x: (string | null)[]): string; ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_option(x, y) { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { _ffi_write_i32(buf, x); } let has_y = y !== null; if (y !== null) { _ffi_write_i32(buf, y); } return _ffi_exports._ffi_fn_add_option(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_nested(x, y) { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { let x_val = x; _ffi_write_i8(buf, +(x_val !== null)); if (x_val !== null) { _ffi_write_i32(buf, x_val); } } let has_y = y !== null; if (y !== null) { let y_val = y; _ffi_write_i8(buf, +(y_val !== null)); if (y_val !== null) { _ffi_write_i32(buf, y_val); } } return _ffi_exports._ffi_fn_add_nested(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_all(x) { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_add_all(_ffi_buf_to_rust(buf), x_len); } export function join_all(x) { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_string_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_join_all(_ffi_buf_to_rust(buf), x_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_dv; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_option_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { _ffi_write_i32(buf, item); } } } function _ffi_vec_option_string_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { let item_val_ptr = _ffi_string_to_rust(item), item_val_len = _ffi_len; _ffi_write_i32(buf, item_val_ptr); _ffi_write_i32(buf, item_val_len); } } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_option(x: number | null, y: number | null): number { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { _ffi_write_i32(buf, x); } let has_y = y !== null; if (y !== null) { _ffi_write_i32(buf, y); } return _ffi_exports._ffi_fn_add_option(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_nested(x: number | null, y: number | null): number { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { let x_val = x; _ffi_write_i8(buf, +(x_val !== null)); if (x_val !== null) { _ffi_write_i32(buf, x_val); } } let has_y = y !== null; if (y !== null) { let y_val = y; _ffi_write_i8(buf, +(y_val !== null)); if (y_val !== null) { _ffi_write_i32(buf, y_val); } } return _ffi_exports._ffi_fn_add_nested(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_all(x: (number | null)[]): number { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_add_all(_ffi_buf_to_rust(buf), x_len); } export function join_all(x: (string | null)[]): string { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_string_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_join_all(_ffi_buf_to_rust(buf), x_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_dv: DataView; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_option_i32_to_rust(items: (number | null)[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { _ffi_write_i32(buf, item); } } } function _ffi_vec_option_string_to_rust(items: (string | null)[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { let item_val_ptr = _ffi_string_to_rust(item), item_val_len = _ffi_len; _ffi_write_i32(buf, item_val_ptr); _ffi_write_i32(buf, item_val_len); } } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_add_all: (buf_ptr: number, x_len: number) => number, _ffi_fn_add_nested: (buf_ptr: number, has_x: boolean, has_y: boolean) => number, _ffi_fn_add_option: (buf_ptr: number, has_x: boolean, has_y: boolean) => number, _ffi_fn_join_all: (buf_ptr: number, x_len: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_alloc: (len: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = add_all(_ffi_vec_option_i32_from_js(x_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_nested( has_x.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))), has_y.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))) ); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_option(has_x.then(|| _ffi_read::(&mut buf_end)), has_y.then(|| _ffi_read::(&mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(join_all(_ffi_vec_option_string_from_js(x_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_read::(end))); } items } fn _ffi_vec_option_string_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function add_option(x: number | null, y: number | null): number; export function add_nested(x: number | null, y: number | null): number; export function add_all(x: (number | null)[]): number; export function join_all(x: (string | null)[]): string; ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_option(x, y) { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { _ffi_write_i32(buf, x); } let has_y = y !== null; if (y !== null) { _ffi_write_i32(buf, y); } return _ffi_exports._ffi_fn_add_option(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_nested(x, y) { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { let x_val = x; _ffi_write_i8(buf, +(x_val !== null)); if (x_val !== null) { _ffi_write_i32(buf, x_val); } } let has_y = y !== null; if (y !== null) { let y_val = y; _ffi_write_i8(buf, +(y_val !== null)); if (y_val !== null) { _ffi_write_i32(buf, y_val); } } return _ffi_exports._ffi_fn_add_nested(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_all(x) { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_add_all(_ffi_buf_to_rust(buf), x_len); } export function join_all(x) { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_string_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_join_all(_ffi_buf_to_rust(buf), x_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_dv; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_option_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { _ffi_write_i32(buf, item); } } } function _ffi_vec_option_string_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { let item_val_ptr = _ffi_string_to_rust(item), item_val_len = _ffi_len; _ffi_write_i32(buf, item_val_ptr); _ffi_write_i32(buf, item_val_len); } } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function add_option(x: number | null, y: number | null): number { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { _ffi_write_i32(buf, x); } let has_y = y !== null; if (y !== null) { _ffi_write_i32(buf, y); } return _ffi_exports._ffi_fn_add_option(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_nested(x: number | null, y: number | null): number { let buf = _ffi_new_WriteBuf(); let has_x = x !== null; if (x !== null) { let x_val = x; _ffi_write_i8(buf, +(x_val !== null)); if (x_val !== null) { _ffi_write_i32(buf, x_val); } } let has_y = y !== null; if (y !== null) { let y_val = y; _ffi_write_i8(buf, +(y_val !== null)); if (y_val !== null) { _ffi_write_i32(buf, y_val); } } return _ffi_exports._ffi_fn_add_nested(_ffi_buf_to_rust(buf), has_x, has_y); } export function add_all(x: (number | null)[]): number { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_i32_to_rust(x, buf); return _ffi_exports._ffi_fn_add_all(_ffi_buf_to_rust(buf), x_len); } export function join_all(x: (string | null)[]): string { let buf = _ffi_new_WriteBuf(); let x_len = x.length; _ffi_vec_option_string_to_rust(x, buf); let multi_ret = _ffi_exports._ffi_fn_join_all(_ffi_buf_to_rust(buf), x_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_dv: DataView; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_option_i32_to_rust(items: (number | null)[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { _ffi_write_i32(buf, item); } } } function _ffi_vec_option_string_to_rust(items: (string | null)[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, +(item !== null)); if (item !== null) { let item_val_ptr = _ffi_string_to_rust(item), item_val_len = _ffi_len; _ffi_write_i32(buf, item_val_ptr); _ffi_write_i32(buf, item_val_len); } } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_add_all: (buf_ptr: number, x_len: number) => number, _ffi_fn_add_nested: (buf_ptr: number, has_x: boolean, has_y: boolean) => number, _ffi_fn_add_option: (buf_ptr: number, has_x: boolean, has_y: boolean) => number, _ffi_fn_join_all: (buf_ptr: number, x_len: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_alloc: (len: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = add_all(_ffi_vec_option_i32_from_js(x_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_nested( has_x.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))), has_y.then(|| _ffi_read::(&mut buf_end).then(|| _ffi_read::(&mut buf_end))) ); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y: bool) -> i32 { let mut buf_end = buf_ptr; let ret = add_option(has_x.then(|| _ffi_read::(&mut buf_end)), has_y.then(|| _ffi_read::(&mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(join_all(_ffi_vec_option_string_from_js(x_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_read::(end))); } items } fn _ffi_vec_option_string_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end).then(|| _ffi_string_from_host(_ffi_read::<*const u8>(end), _ffi_read::(end)))); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function opt_int(x: boolean, y: number): number | null; export function opt_opt_int(x: boolean, y: boolean, z: number): number | null; export function vec_opt_int(n: number): (number | null)[]; export function opt_vec_opt_string(n: number): (string | null)[] | null; ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function opt_int(x, y) { let multi_ret = _ffi_exports._ffi_fn_opt_int(x, y); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = has_ret ? _ffi_read_i32(buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_opt_int(x, y, z) { let multi_ret = _ffi_exports._ffi_fn_opt_opt_int(x, y, z); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = has_ret ? _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function vec_opt_int(n) { let multi_ret = _ffi_exports._ffi_fn_vec_opt_int(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_option_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_vec_opt_string(n) { let multi_ret = _ffi_exports._ffi_fn_opt_vec_opt_string(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = has_ret ? _ffi_vec_option_string_from_rust(_ffi_read_u32(buf), buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_decoder = /* @__PURE__ */ new TextDecoder; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_vec_option_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_read_i32(buf) : null); } return items; } function _ffi_vec_option_string_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)) : null); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function opt_int(x: boolean, y: number): number | null { let multi_ret = _ffi_exports._ffi_fn_opt_int(x, y); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: number | null = has_ret ? _ffi_read_i32(buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_opt_int(x: boolean, y: boolean, z: number): number | null { let multi_ret = _ffi_exports._ffi_fn_opt_opt_int(x, y, z); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: number | null = has_ret ? _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function vec_opt_int(n: number): (number | null)[] { let multi_ret = _ffi_exports._ffi_fn_vec_opt_int(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_option_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_vec_opt_string(n: number): (string | null)[] | null { let multi_ret = _ffi_exports._ffi_fn_opt_vec_opt_string(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: (string | null)[] | null = has_ret ? _ffi_vec_option_string_from_rust(_ffi_read_u32(buf), buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_decoder = /* @__PURE__ */ new TextDecoder; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_vec_option_i32_from_rust(len: number, buf: _ffi_ReadBuf): (number | null)[] { let items: (number | null)[] = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_read_i32(buf) : null); } return items; } function _ffi_vec_option_string_from_rust(len: number, buf: _ffi_ReadBuf): (string | null)[] { let items: (string | null)[] = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)) : null); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_opt_int: (x: boolean, y: number) => number, _ffi_fn_opt_opt_int: (x: boolean, y: boolean, z: number) => number, _ffi_fn_opt_vec_opt_string: (n: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_vec_opt_int: (n: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> *const _ffi_ret_ptr_usize_bool { let ret = opt_int(x, y); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> *const _ffi_ret_ptr_usize_bool { let ret = opt_opt_int(x, y, z); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.is_some(), &mut buf); if let Some(ret_val_val) = ret_val { _ffi_write(ret_val_val, &mut buf); } } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> *const _ffi_ret_ptr_usize_bool { let ret = opt_vec_opt_string(n); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.len(), &mut buf); _ffi_vec_option_string_to_js(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> *const _ffi_ret_ptr_2_usize { let ret = vec_opt_int(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_option_i32_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); static mut _FFI_RET_PTR_USIZE_BOOL: _ffi_ret_ptr_usize_bool = _ffi_ret_ptr_usize_bool(std::ptr::null(), 0, false); fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { _ffi_write(item_val, buf); } } } fn _ffi_vec_option_string_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { let (item_val_ptr, item_val_len, item_val_cap) = _ffi_string_to_host(item_val); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); _ffi_write(item_val_cap, buf); } } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function opt_int(x: boolean, y: number): number | null; export function opt_opt_int(x: boolean, y: boolean, z: number): number | null; export function vec_opt_int(n: number): (number | null)[]; export function opt_vec_opt_string(n: number): (string | null)[] | null; ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function opt_int(x, y) { let multi_ret = _ffi_exports._ffi_fn_opt_int(x, y); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = has_ret ? _ffi_read_i32(buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_opt_int(x, y, z) { let multi_ret = _ffi_exports._ffi_fn_opt_opt_int(x, y, z); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = has_ret ? _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function vec_opt_int(n) { let multi_ret = _ffi_exports._ffi_fn_vec_opt_int(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_option_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_vec_opt_string(n) { let multi_ret = _ffi_exports._ffi_fn_opt_vec_opt_string(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = has_ret ? _ffi_vec_option_string_from_rust(_ffi_read_u32(buf), buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_decoder = /* @__PURE__ */ new TextDecoder; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf) { return buf.dv.getUint8(buf.off++); } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_vec_option_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_read_i32(buf) : null); } return items; } function _ffi_vec_option_string_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)) : null); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function opt_int(x: boolean, y: number): number | null { let multi_ret = _ffi_exports._ffi_fn_opt_int(x, y); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: number | null = has_ret ? _ffi_read_i32(buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_opt_int(x: boolean, y: boolean, z: number): number | null { let multi_ret = _ffi_exports._ffi_fn_opt_opt_int(x, y, z); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: number | null = has_ret ? _ffi_read_u8(buf) ? _ffi_read_i32(buf) : null : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function vec_opt_int(n: number): (number | null)[] { let multi_ret = _ffi_exports._ffi_fn_vec_opt_int(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_option_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function opt_vec_opt_string(n: number): (string | null)[] | null { let multi_ret = _ffi_exports._ffi_fn_opt_vec_opt_string(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let has_ret = _ffi_dv.getUint8(multi_ret + 8); let buf = _ffi_new_ReadBuf(buf_ptr); let ret: (string | null)[] | null = has_ret ? _ffi_vec_option_string_from_rust(_ffi_read_u32(buf), buf) : null; _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_decoder = /* @__PURE__ */ new TextDecoder; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u8(buf: _ffi_ReadBuf): number { return buf.dv.getUint8(buf.off++); } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_vec_option_i32_from_rust(len: number, buf: _ffi_ReadBuf): (number | null)[] { let items: (number | null)[] = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_read_i32(buf) : null); } return items; } function _ffi_vec_option_string_from_rust(len: number, buf: _ffi_ReadBuf): (string | null)[] { let items: (string | null)[] = []; while (items.length < len) { items.push(_ffi_read_u8(buf) ? _ffi_string_from_rust(_ffi_read_i32(buf), _ffi_read_u32(buf), _ffi_read_u32(buf)) : null); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_opt_int: (x: boolean, y: number) => number, _ffi_fn_opt_opt_int: (x: boolean, y: boolean, z: number) => number, _ffi_fn_opt_vec_opt_string: (n: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_vec_opt_int: (n: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_option_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> *const _ffi_ret_ptr_usize_bool { let ret = opt_int(x, y); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> *const _ffi_ret_ptr_usize_bool { let ret = opt_opt_int(x, y, z); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.is_some(), &mut buf); if let Some(ret_val_val) = ret_val { _ffi_write(ret_val_val, &mut buf); } } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> *const _ffi_ret_ptr_usize_bool { let ret = opt_vec_opt_string(n); let mut buf = Vec::::new(); let has_ret = ret.is_some(); if let Some(ret_val) = ret { _ffi_write(ret_val.len(), &mut buf); _ffi_vec_option_string_to_js(ret_val, &mut buf); } let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_USIZE_BOOL = _ffi_ret_ptr_usize_bool(buf_ptr, buf_cap, has_ret); std::ptr::addr_of!(_FFI_RET_PTR_USIZE_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> *const _ffi_ret_ptr_2_usize { let ret = vec_opt_int(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_option_i32_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[repr(C)] struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool); static mut _FFI_RET_PTR_USIZE_BOOL: _ffi_ret_ptr_usize_bool = _ffi_ret_ptr_usize_bool(std::ptr::null(), 0, false); fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_option_i32_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { _ffi_write(item_val, buf); } } } fn _ffi_vec_option_string_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.is_some(), buf); if let Some(item_val) = item { let (item_val_ptr, item_val_len, item_val_cap) = _ffi_string_to_host(item_val); _ffi_write(item_val_ptr, buf); _ffi_write(item_val_len, buf); _ffi_write(item_val_cap, buf); } } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number; export function set_tests(tests: Foo[]): boolean; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_tests(tests) { let buf = _ffi_new_WriteBuf(); let tests_len = tests.length; _ffi_vec_Foo_to_rust(tests, buf); let ret = _ffi_exports._ffi_fn_set_tests(_ffi_buf_to_rust(buf), tests_len); return !!ret; } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; function _ffi_box_Foo_to_rust(val, buf) { _ffi_enum_Foo_to_rust(val, buf); } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_Foo_to_rust(val, buf) { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "Single": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "Point": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; case "Nested": _ffi_write_i32(buf, 3); _ffi_box_Foo_to_rust(val[0], buf); break; default: throw TypeError("Invalid value for enum \"Foo\""); } } function _ffi_vec_Foo_to_rust(items, buf) { for (const item of items) { _ffi_enum_Foo_to_rust(item, buf); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_tests(tests: Foo[]): boolean { let buf = _ffi_new_WriteBuf(); let tests_len = tests.length; _ffi_vec_Foo_to_rust(tests, buf); let ret = _ffi_exports._ffi_fn_set_tests(_ffi_buf_to_rust(buf), tests_len); return !!ret; } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_box_Foo_to_rust(val: Foo, buf: _ffi_WriteBuf): void { _ffi_enum_Foo_to_rust(val, buf); } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_Foo_to_rust(val: Foo, buf: _ffi_WriteBuf): void { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "Single": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "Point": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; case "Nested": _ffi_write_i32(buf, 3); _ffi_box_Foo_to_rust(val[0], buf); break; default: throw TypeError("Invalid value for enum \"Foo\""); } } function _ffi_vec_Foo_to_rust(items: Foo[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_enum_Foo_to_rust(item, buf); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_tests: (buf_ptr: number, tests_len: number) => boolean, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_from_js(end: &mut *const u8) -> Box { Box::new(_ffi_enum_Foo_from_js(end)) } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_js(end: &mut *const u8) -> Foo { match _ffi_read::(end) { 0 => Foo::Empty, 1 => Foo::Single(_ffi_read::(end)), 2 => Foo::Point { x: _ffi_read::(end), y: _ffi_read::(end) }, 3 => Foo::Nested(_ffi_box_Foo_from_js(end)), _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) -> bool { let mut buf_end = buf_ptr; let ret = set_tests(_ffi_vec_Foo_from_js(tests_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_enum_Foo_from_js(end)); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number; export function set_tests(tests: Foo[]): boolean; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_tests(tests) { let buf = _ffi_new_WriteBuf(); let tests_len = tests.length; _ffi_vec_Foo_to_rust(tests, buf); let ret = _ffi_exports._ffi_fn_set_tests(_ffi_buf_to_rust(buf), tests_len); return !!ret; } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; function _ffi_box_Foo_to_rust(val, buf) { _ffi_enum_Foo_to_rust(val, buf); } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_Foo_to_rust(val, buf) { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "Single": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "Point": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; case "Nested": _ffi_write_i32(buf, 3); _ffi_box_Foo_to_rust(val[0], buf); break; default: throw TypeError("Invalid value for enum \"Foo\""); } } function _ffi_vec_Foo_to_rust(items, buf) { for (const item of items) { _ffi_enum_Foo_to_rust(item, buf); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_tests(tests: Foo[]): boolean { let buf = _ffi_new_WriteBuf(); let tests_len = tests.length; _ffi_vec_Foo_to_rust(tests, buf); let ret = _ffi_exports._ffi_fn_set_tests(_ffi_buf_to_rust(buf), tests_len); return !!ret; } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_box_Foo_to_rust(val: Foo, buf: _ffi_WriteBuf): void { _ffi_enum_Foo_to_rust(val, buf); } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_enum_Foo_to_rust(val: Foo, buf: _ffi_WriteBuf): void { switch (val.$) { case "Empty": _ffi_write_i32(buf, 0); break; case "Single": _ffi_write_i32(buf, 1); _ffi_write_i32(buf, val[0]); break; case "Point": _ffi_write_i32(buf, 2); _ffi_write_i32(buf, val.x); _ffi_write_i32(buf, val.y); break; case "Nested": _ffi_write_i32(buf, 3); _ffi_box_Foo_to_rust(val[0], buf); break; default: throw TypeError("Invalid value for enum \"Foo\""); } } function _ffi_vec_Foo_to_rust(items: Foo[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_enum_Foo_to_rust(item, buf); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_tests: (buf_ptr: number, tests_len: number) => boolean, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_from_js(end: &mut *const u8) -> Box { Box::new(_ffi_enum_Foo_from_js(end)) } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[allow(non_snake_case)] fn _ffi_enum_Foo_from_js(end: &mut *const u8) -> Foo { match _ffi_read::(end) { 0 => Foo::Empty, 1 => Foo::Single(_ffi_read::(end)), 2 => Foo::Point { x: _ffi_read::(end), y: _ffi_read::(end) }, 3 => Foo::Nested(_ffi_box_Foo_from_js(end)), _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) -> bool { let mut buf_end = buf_ptr; let ret = set_tests(_ffi_vec_Foo_from_js(tests_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[allow(non_snake_case)] fn _ffi_vec_Foo_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_enum_Foo_from_js(end)); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number; export function get_tests(): Foo[]; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tests() { let multi_ret = _ffi_exports._ffi_fn_get_tests(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_Foo_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_Foo__Empty = { $: "Empty" }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Foo_from_rust(buf) { return _ffi_enum_Foo_from_rust(buf); } function _ffi_enum_Foo_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_Foo__Empty; case 1: return { $: "Single", 0: _ffi_read_i32(buf) }; case 2: return { $: "Point", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; case 3: return { $: "Nested", 0: _ffi_box_Foo_from_rust(buf) }; default: throw Error(); } } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_Foo_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_enum_Foo_from_rust(buf)); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tests(): Foo[] { let multi_ret = _ffi_exports._ffi_fn_get_tests(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_Foo_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_Foo__Empty: Foo = { $: "Empty" }; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Foo_from_rust(buf: _ffi_ReadBuf): Foo { return _ffi_enum_Foo_from_rust(buf); } function _ffi_enum_Foo_from_rust(buf: _ffi_ReadBuf): Foo { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_Foo__Empty; case 1: return { $: "Single", 0: _ffi_read_i32(buf) }; case 2: return { $: "Point", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; case 3: return { $: "Nested", 0: _ffi_box_Foo_from_rust(buf) }; default: throw Error(); } } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_Foo_from_rust(len: number, buf: _ffi_ReadBuf): Foo[] { let items: Foo[] = []; while (items.length < len) { items.push(_ffi_enum_Foo_from_rust(buf)); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_get_tests: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_to_js(val: Foo, buf: &mut Vec) { _ffi_enum_Foo_to_js(val, buf); } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Foo_to_js(val: Foo, buf: &mut Vec) { match val { Foo::Empty => _ffi_write(0 as i32, buf), Foo::Single(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } Foo::Point { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } Foo::Nested(x) => { _ffi_write(3 as i32, buf); _ffi_box_Foo_to_js(*x, buf); } } } #[no_mangle] extern "C" fn _ffi_fn_get_tests() -> *const _ffi_ret_ptr_2_usize { let ret = get_tests(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Foo_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[allow(non_snake_case)] fn _ffi_vec_Foo_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_enum_Foo_to_js(item, buf); } } ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number; export function get_tests(): Foo[]; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tests() { let multi_ret = _ffi_exports._ffi_fn_get_tests(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_Foo_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_Foo__Empty = { $: "Empty" }; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Foo_from_rust(buf) { return _ffi_enum_Foo_from_rust(buf); } function _ffi_enum_Foo_from_rust(buf) { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_Foo__Empty; case 1: return { $: "Single", 0: _ffi_read_i32(buf) }; case 2: return { $: "Point", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; case 3: return { $: "Nested", 0: _ffi_box_Foo_from_rust(buf) }; default: throw Error(); } } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_Foo_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_enum_Foo_from_rust(buf)); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export type Foo = | { readonly $: "Empty" } | { readonly $: "Single", 0: number } | { readonly $: "Point", x: number, y: number } | { readonly $: "Nested", 0: Foo } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_tests(): Foo[] { let multi_ret = _ffi_exports._ffi_fn_get_tests(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_Foo_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); let _ffi_enum_Foo__Empty: Foo = { $: "Empty" }; interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_box_Foo_from_rust(buf: _ffi_ReadBuf): Foo { return _ffi_enum_Foo_from_rust(buf); } function _ffi_enum_Foo_from_rust(buf: _ffi_ReadBuf): Foo { switch (_ffi_read_i32(buf)) { case 0: return _ffi_enum_Foo__Empty; case 1: return { $: "Single", 0: _ffi_read_i32(buf) }; case 2: return { $: "Point", x: _ffi_read_i32(buf), y: _ffi_read_i32(buf) }; case 3: return { $: "Nested", 0: _ffi_box_Foo_from_rust(buf) }; default: throw Error(); } } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_Foo_from_rust(len: number, buf: _ffi_ReadBuf): Foo[] { let items: Foo[] = []; while (items.length < len) { items.push(_ffi_enum_Foo_from_rust(buf)); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_get_tests: () => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_payload_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[allow(non_snake_case)] fn _ffi_box_Foo_to_js(val: Foo, buf: &mut Vec) { _ffi_enum_Foo_to_js(val, buf); } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } #[allow(non_snake_case)] fn _ffi_enum_Foo_to_js(val: Foo, buf: &mut Vec) { match val { Foo::Empty => _ffi_write(0 as i32, buf), Foo::Single(x) => { _ffi_write(1 as i32, buf); _ffi_write(x, buf); } Foo::Point { x, y } => { _ffi_write(2 as i32, buf); _ffi_write(x, buf); _ffi_write(y, buf); } Foo::Nested(x) => { _ffi_write(3 as i32, buf); _ffi_box_Foo_to_js(*x, buf); } } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_tests() -> *const _ffi_ret_ptr_2_usize { let ret = get_tests(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_Foo_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[allow(non_snake_case)] fn _ffi_vec_Foo_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_enum_Foo_to_js(item, buf); } } ================================================ FILE: src/tests/snapshots/wasm_fn_string_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function reset(): void; export function get_string_len(): number; export function get_string(): string; export function set_string(x: string): void; export function set_str(x: string): void; ================================================ FILE: src/tests/snapshots/wasm_fn_string_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function reset() { _ffi_exports._ffi_fn_reset(); } export function get_string_len() { return _ffi_exports._ffi_fn_get_string_len(); } export function get_string() { let multi_ret = _ffi_exports._ffi_fn_get_string(); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } export function set_string(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_string(x_ptr, x_len); } export function set_str(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_str(x_ptr, x_len); } let _ffi_len = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8; let _ffi_dv; function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_string_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function reset(): void { _ffi_exports._ffi_fn_reset(); } export function get_string_len(): number { return _ffi_exports._ffi_fn_get_string_len(); } export function get_string(): string { let multi_ret = _ffi_exports._ffi_fn_get_string(); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } export function set_string(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_string(x_ptr, x_len); } export function set_str(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_str(x_ptr, x_len); } let _ffi_len = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8: Uint8Array; let _ffi_dv: DataView; function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_get_string: () => number, _ffi_fn_get_string_len: () => number, _ffi_fn_reset: () => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_str: (x_ptr: number, x_len: number) => void, _ffi_fn_set_string: (x_ptr: number, x_len: number) => void, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_string_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_get_string() -> *const _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(get_string()); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_get_string_len() -> i32 { get_string_len() } #[no_mangle] extern "C" fn _ffi_fn_reset() { reset(); } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) { set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) { set_string(_ffi_string_from_host(x_ptr, x_len)); } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/wasm_fn_string_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function reset(): void; export function get_string_len(): number; export function get_string(): string; export function set_string(x: string): void; export function set_str(x: string): void; ================================================ FILE: src/tests/snapshots/wasm_fn_string_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function reset() { _ffi_exports._ffi_fn_reset(); } export function get_string_len() { return _ffi_exports._ffi_fn_get_string_len(); } export function get_string() { let multi_ret = _ffi_exports._ffi_fn_get_string(); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } export function set_string(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_string(x_ptr, x_len); } export function set_str(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_str(x_ptr, x_len); } let _ffi_len = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8; let _ffi_dv; function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_string_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function reset(): void { _ffi_exports._ffi_fn_reset(); } export function get_string_len(): number { return _ffi_exports._ffi_fn_get_string_len(); } export function get_string(): string { let multi_ret = _ffi_exports._ffi_fn_get_string(); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } export function set_string(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_string(x_ptr, x_len); } export function set_str(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_fn_set_str(x_ptr, x_len); } let _ffi_len = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8: Uint8Array; let _ffi_dv: DataView; function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_get_string: () => number, _ffi_fn_get_string_len: () => number, _ffi_fn_reset: () => void, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_str: (x_ptr: number, x_len: number) => void, _ffi_fn_set_string: (x_ptr: number, x_len: number) => void, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_string_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_string() -> *const _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(get_string()); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_string_len() -> i32 { get_string_len() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_reset() { reset(); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) { set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) { set_string(_ffi_string_from_host(x_ptr, x_len)); } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number; export function empty_tuple(x: number, foo: EmptyStruct, y: number): number; export function single_element_tuple(x: SingleElementStruct, y: SingleElementStruct): number; export function multiply_pairs(ab: PairStruct, cd: PairStruct): number; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x, foo, y) { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x, y) { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab, cd) { return _ffi_exports._ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x: number, foo: EmptyStruct, y: number): number { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x: SingleElementStruct, y: SingleElementStruct): number { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab: PairStruct, cd: PairStruct): number { return _ffi_exports._ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_empty_tuple: (x: number, y: number) => number, _ffi_fn_multiply_pairs: (ab_x: number, ab_y: number, cd_x: number, cd_y: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_tuple: (x_0: number, y_0: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, EmptyStruct, y) } #[no_mangle] extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32 { multiply_pairs(PairStruct { x: ab_x, y: ab_y }, PairStruct { x: cd_x, y: cd_y }) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple(SingleElementStruct(x_0), SingleElementStruct(y_0)) } ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number; export function empty_tuple(x: number, foo: EmptyStruct, y: number): number; export function single_element_tuple(x: SingleElementStruct, y: SingleElementStruct): number; export function multiply_pairs(ab: PairStruct, cd: PairStruct): number; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x, foo, y) { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x, y) { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab, cd) { return _ffi_exports._ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x: number, foo: EmptyStruct, y: number): number { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x: SingleElementStruct, y: SingleElementStruct): number { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab: PairStruct, cd: PairStruct): number { return _ffi_exports._ffi_fn_multiply_pairs(ab.x, ab.y, cd.x, cd.y); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_empty_tuple: (x: number, y: number) => number, _ffi_fn_multiply_pairs: (ab_x: number, ab_y: number, cd_x: number, cd_y: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_tuple: (x_0: number, y_0: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, EmptyStruct, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32 { multiply_pairs(PairStruct { x: ab_x, y: ab_y }, PairStruct { x: cd_x, y: cd_y }) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple(SingleElementStruct(x_0), SingleElementStruct(y_0)) } ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number; export function empty_struct(): EmptyStruct; export function single_element_struct(x: number): SingleElementStruct; export function make_pair(x: number, y: number): PairStruct; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_struct() { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function single_element_struct(x) { let ret_0 = _ffi_exports._ffi_fn_single_element_struct(x); return { 0: ret_0 }; } export function make_pair(x, y) { let multi_ret = _ffi_exports._ffi_fn_make_pair(x, y); let ret_x = _ffi_update_dv().getFloat32(multi_ret, true); let ret_y = _ffi_dv.getFloat32(multi_ret + 4, true); return { x: ret_x, y: ret_y }; } let _ffi_dv; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_struct(): EmptyStruct { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function single_element_struct(x: number): SingleElementStruct { let ret_0 = _ffi_exports._ffi_fn_single_element_struct(x); return { 0: ret_0 }; } export function make_pair(x: number, y: number): PairStruct { let multi_ret = _ffi_exports._ffi_fn_make_pair(x, y); let ret_x = _ffi_update_dv().getFloat32(multi_ret, true); let ret_y = _ffi_dv.getFloat32(multi_ret + 4, true); return { x: ret_x, y: ret_y }; } let _ffi_dv: DataView; function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_empty_struct: () => void, _ffi_fn_make_pair: (x: number, y: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_struct: (x: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(); } #[no_mangle] extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> *const _ffi_ret_2_f32 { let ret = make_pair(x, y); unsafe { _FFI_RET_2_F32 = _ffi_ret_2_f32(ret.x, ret.y); std::ptr::addr_of!(_FFI_RET_2_F32) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 { let ret = single_element_struct(x); ret.0 } #[repr(C)] struct _ffi_ret_2_f32(f32, f32); static mut _FFI_RET_2_F32: _ffi_ret_2_f32 = _ffi_ret_2_f32(0.0, 0.0); ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number; export function empty_struct(): EmptyStruct; export function single_element_struct(x: number): SingleElementStruct; export function make_pair(x: number, y: number): PairStruct; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_struct() { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function single_element_struct(x) { let ret_0 = _ffi_exports._ffi_fn_single_element_struct(x); return { 0: ret_0 }; } export function make_pair(x, y) { let multi_ret = _ffi_exports._ffi_fn_make_pair(x, y); let ret_x = _ffi_update_dv().getFloat32(multi_ret, true); let ret_y = _ffi_dv.getFloat32(multi_ret + 4, true); return { x: ret_x, y: ret_y }; } let _ffi_dv; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_struct(): EmptyStruct { _ffi_exports._ffi_fn_empty_struct(); return {}; } export function single_element_struct(x: number): SingleElementStruct { let ret_0 = _ffi_exports._ffi_fn_single_element_struct(x); return { 0: ret_0 }; } export function make_pair(x: number, y: number): PairStruct { let multi_ret = _ffi_exports._ffi_fn_make_pair(x, y); let ret_x = _ffi_update_dv().getFloat32(multi_ret, true); let ret_y = _ffi_dv.getFloat32(multi_ret + 4, true); return { x: ret_x, y: ret_y }; } let _ffi_dv: DataView; function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_empty_struct: () => void, _ffi_fn_make_pair: (x: number, y: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_struct: (x: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_struct_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_struct() { _ = empty_struct(); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> *const _ffi_ret_2_f32 { let ret = make_pair(x, y); unsafe { _FFI_RET_2_F32 = _ffi_ret_2_f32(ret.x, ret.y); std::ptr::addr_of!(_FFI_RET_2_F32) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 { let ret = single_element_struct(x); ret.0 } #[repr(C)] struct _ffi_ret_2_f32(f32, f32); static mut _FFI_RET_2_F32: _ffi_ret_2_f32 = _ffi_ret_2_f32(0.0, 0.0); ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function empty_tuple(x: number, foo: undefined, y: number): number; export function single_element_tuple(x: [number], y: [number]): number; export function multiply_pairs(ab: [number, number], cd: [number, number]): number; export function nesting(x: [number, undefined, [number, [number]]]): number; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x, foo, y) { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x, y) { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab, cd) { return _ffi_exports._ffi_fn_multiply_pairs(ab[0], ab[1], cd[0], cd[1]); } export function nesting(x) { return _ffi_exports._ffi_fn_nesting(x[0], x[2][0], x[2][1][0]); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x: number, foo: undefined, y: number): number { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x: [number], y: [number]): number { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab: [number, number], cd: [number, number]): number { return _ffi_exports._ffi_fn_multiply_pairs(ab[0], ab[1], cd[0], cd[1]); } export function nesting(x: [number, undefined, [number, [number]]]): number { return _ffi_exports._ffi_fn_nesting(x[0], x[2][0], x[2][1][0]); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_empty_tuple: (x: number, y: number) => number, _ffi_fn_multiply_pairs: (ab_0: number, ab_1: number, cd_0: number, cd_1: number) => number, _ffi_fn_nesting: (x_0: number, x_2_0: number, x_2_1_0: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_tuple: (x_0: number, y_0: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, (), y) } #[no_mangle] extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32 { multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } #[no_mangle] extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 { nesting((x_0, (), (x_2_0, (x_2_1_0,)))) } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple((x_0,), (y_0,)) } ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function empty_tuple(x: number, foo: undefined, y: number): number; export function single_element_tuple(x: [number], y: [number]): number; export function multiply_pairs(ab: [number, number], cd: [number, number]): number; export function nesting(x: [number, undefined, [number, [number]]]): number; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x, foo, y) { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x, y) { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab, cd) { return _ffi_exports._ffi_fn_multiply_pairs(ab[0], ab[1], cd[0], cd[1]); } export function nesting(x) { return _ffi_exports._ffi_fn_nesting(x[0], x[2][0], x[2][1][0]); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function empty_tuple(x: number, foo: undefined, y: number): number { return _ffi_exports._ffi_fn_empty_tuple(x, y); } export function single_element_tuple(x: [number], y: [number]): number { return _ffi_exports._ffi_fn_single_element_tuple(x[0], y[0]); } export function multiply_pairs(ab: [number, number], cd: [number, number]): number { return _ffi_exports._ffi_fn_multiply_pairs(ab[0], ab[1], cd[0], cd[1]); } export function nesting(x: [number, undefined, [number, [number]]]): number { return _ffi_exports._ffi_fn_nesting(x[0], x[2][0], x[2][1][0]); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_empty_tuple: (x: number, y: number) => number, _ffi_fn_multiply_pairs: (ab_0: number, ab_1: number, cd_0: number, cd_1: number) => number, _ffi_fn_nesting: (x_0: number, x_2_0: number, x_2_1_0: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_tuple: (x_0: number, y_0: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 { empty_tuple(x, (), y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32 { multiply_pairs((ab_0, ab_1), (cd_0, cd_1)) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 { nesting((x_0, (), (x_2_0, (x_2_1_0,)))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 { single_element_tuple((x_0,), (y_0,)) } ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function single_element_tuple(x: number): [number]; export function return_pair(x: number, y: boolean): [number, boolean]; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function single_element_tuple(x) { let ret_0 = _ffi_exports._ffi_fn_single_element_tuple(x); return [ret_0]; } export function return_pair(x, y) { let multi_ret = _ffi_exports._ffi_fn_return_pair(x, y); let ret_0 = _ffi_update_dv().getFloat32(multi_ret, true); let ret_1 = _ffi_dv.getUint8(multi_ret + 4); return [ret_0, !!ret_1]; } let _ffi_dv; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function single_element_tuple(x: number): [number] { let ret_0 = _ffi_exports._ffi_fn_single_element_tuple(x); return [ret_0]; } export function return_pair(x: number, y: boolean): [number, boolean] { let multi_ret = _ffi_exports._ffi_fn_return_pair(x, y); let ret_0 = _ffi_update_dv().getFloat32(multi_ret, true); let ret_1 = _ffi_dv.getUint8(multi_ret + 4); return [ret_0, !!ret_1]; } let _ffi_dv: DataView; function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_return_pair: (x: number, y: boolean) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_tuple: (x: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> *const _ffi_ret_f32_bool { let ret = return_pair(x, y); unsafe { _FFI_RET_F32_BOOL = _ffi_ret_f32_bool(ret.0, ret.1); std::ptr::addr_of!(_FFI_RET_F32_BOOL) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 { let ret = single_element_tuple(x); ret.0 } #[repr(C)] struct _ffi_ret_f32_bool(f32, bool); static mut _FFI_RET_F32_BOOL: _ffi_ret_f32_bool = _ffi_ret_f32_bool(0.0, false); ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function single_element_tuple(x: number): [number]; export function return_pair(x: number, y: boolean): [number, boolean]; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function single_element_tuple(x) { let ret_0 = _ffi_exports._ffi_fn_single_element_tuple(x); return [ret_0]; } export function return_pair(x, y) { let multi_ret = _ffi_exports._ffi_fn_return_pair(x, y); let ret_0 = _ffi_update_dv().getFloat32(multi_ret, true); let ret_1 = _ffi_dv.getUint8(multi_ret + 4); return [ret_0, !!ret_1]; } let _ffi_dv; function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function single_element_tuple(x: number): [number] { let ret_0 = _ffi_exports._ffi_fn_single_element_tuple(x); return [ret_0]; } export function return_pair(x: number, y: boolean): [number, boolean] { let multi_ret = _ffi_exports._ffi_fn_return_pair(x, y); let ret_0 = _ffi_update_dv().getFloat32(multi_ret, true); let ret_1 = _ffi_dv.getUint8(multi_ret + 4); return [ret_0, !!ret_1]; } let _ffi_dv: DataView; function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_return_pair: (x: number, y: boolean) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_single_element_tuple: (x: number) => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_tuple_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> *const _ffi_ret_f32_bool { let ret = return_pair(x, y); unsafe { _FFI_RET_F32_BOOL = _ffi_ret_f32_bool(ret.0, ret.1); std::ptr::addr_of!(_FFI_RET_F32_BOOL) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 { let ret = single_element_tuple(x); ret.0 } #[repr(C)] struct _ffi_ret_f32_bool(f32, bool); static mut _FFI_RET_F32_BOOL: _ffi_ret_f32_bool = _ffi_ret_f32_bool(0.0, false); ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function sum_u8(values: number[]): number; export function sum_u16(values: number[]): number; export function sum_u32(values: number[]): number; export function sum_usize(values: number[]): number; export function sum_u64(values: bigint[]): bigint; export function sum_i8(values: number[]): number; export function sum_i16(values: number[]): number; export function sum_i32(values: number[]): number; export function sum_isize(values: number[]): number; export function sum_i64(values: bigint[]): bigint; export function sum_f32(values: number[]): number; export function sum_f64(values: number[]): number; export function check_nested(values: number[][]): string; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_u8(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u8(_ffi_buf_to_rust(buf), values_len); } export function sum_u16(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u16(_ffi_buf_to_rust(buf), values_len); } export function sum_u32(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u32(_ffi_buf_to_rust(buf), values_len); } export function sum_usize(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_usize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_usize(_ffi_buf_to_rust(buf), values_len); } export function sum_u64(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u64(_ffi_buf_to_rust(buf), values_len); } export function sum_i8(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i8(_ffi_buf_to_rust(buf), values_len); } export function sum_i16(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i16(_ffi_buf_to_rust(buf), values_len); } export function sum_i32(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i32(_ffi_buf_to_rust(buf), values_len); } export function sum_isize(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_isize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_isize(_ffi_buf_to_rust(buf), values_len); } export function sum_i64(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i64(_ffi_buf_to_rust(buf), values_len); } export function sum_f32(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f32(_ffi_buf_to_rust(buf), values_len); } export function sum_f64(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f64(_ffi_buf_to_rust(buf), values_len); } export function check_nested(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_vec_i32_to_rust(values, buf); let multi_ret = _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf), values_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_f32_to_rust(items, buf) { for (const item of items) { _ffi_write_f32(buf, item); } } function _ffi_vec_f64_to_rust(items, buf) { for (const item of items) { _ffi_write_f64(buf, item); } } function _ffi_vec_i16_to_rust(items, buf) { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_i64_to_rust(items, buf) { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_i8_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_isize_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u16_to_rust(items, buf) { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_u32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u64_to_rust(items, buf) { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_u8_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_usize_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item.length); _ffi_vec_i32_to_rust(item, buf); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setFloat32(ptr, val, true); } function _ffi_write_f64(buf, val) { let ptr = _ffi_grow(buf, 8); buf.dv.setFloat64(ptr, val, true); } function _ffi_write_i16(buf, val) { let ptr = _ffi_grow(buf, 2); buf.dv.setInt16(ptr, val, true); } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i64(buf, val) { let ptr = _ffi_grow(buf, 8); buf.dv.setBigInt64(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_u8(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u8(_ffi_buf_to_rust(buf), values_len); } export function sum_u16(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u16(_ffi_buf_to_rust(buf), values_len); } export function sum_u32(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u32(_ffi_buf_to_rust(buf), values_len); } export function sum_usize(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_usize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_usize(_ffi_buf_to_rust(buf), values_len); } export function sum_u64(values: bigint[]): bigint { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u64(_ffi_buf_to_rust(buf), values_len); } export function sum_i8(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i8(_ffi_buf_to_rust(buf), values_len); } export function sum_i16(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i16(_ffi_buf_to_rust(buf), values_len); } export function sum_i32(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i32(_ffi_buf_to_rust(buf), values_len); } export function sum_isize(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_isize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_isize(_ffi_buf_to_rust(buf), values_len); } export function sum_i64(values: bigint[]): bigint { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i64(_ffi_buf_to_rust(buf), values_len); } export function sum_f32(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f32(_ffi_buf_to_rust(buf), values_len); } export function sum_f64(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f64(_ffi_buf_to_rust(buf), values_len); } export function check_nested(values: number[][]): string { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_vec_i32_to_rust(values, buf); let multi_ret = _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf), values_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv: DataView; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_f32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_f32(buf, item); } } function _ffi_vec_f64_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_f64(buf, item); } } function _ffi_vec_i16_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_i32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_i64_to_rust(items: bigint[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_i8_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_isize_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u16_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_u32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u64_to_rust(items: bigint[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_u8_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_usize_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_vec_i32_to_rust(items: number[][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item.length); _ffi_vec_i32_to_rust(item, buf); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setFloat32(ptr, val, true); } function _ffi_write_f64(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 8); buf.dv!.setFloat64(ptr, val, true); } function _ffi_write_i16(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 2); buf.dv!.setInt16(ptr, val, true); } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i64(buf: _ffi_WriteBuf, val: bigint): void { let ptr = _ffi_grow(buf, 8); buf.dv!.setBigInt64(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_check_nested: (buf_ptr: number, values_len: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_sum_f32: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_f64: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_i16: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_i32: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_i64: (buf_ptr: number, values_len: number) => bigint, _ffi_fn_sum_i8: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_isize: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_u16: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_u32: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_u64: (buf_ptr: number, values_len: number) => bigint, _ffi_fn_sum_u8: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_usize: (buf_ptr: number, values_len: number) => number, _ffi_alloc: (len: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[no_mangle] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_nested(_ffi_vec_vec_i32_from_js(values_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> f32 { let mut buf_end = buf_ptr; let ret = sum_f32(_ffi_vec_f32_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> f64 { let mut buf_end = buf_ptr; let ret = sum_f64(_ffi_vec_f64_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> i16 { let mut buf_end = buf_ptr; let ret = sum_i16(_ffi_vec_i16_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = sum_i32(_ffi_vec_i32_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> i64 { let mut buf_end = buf_ptr; let ret = sum_i64(_ffi_vec_i64_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 { let mut buf_end = buf_ptr; let ret = sum_i8(_ffi_vec_i8_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -> isize { let mut buf_end = buf_ptr; let ret = sum_isize(_ffi_vec_isize_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> u16 { let mut buf_end = buf_ptr; let ret = sum_u16(_ffi_vec_u16_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> u32 { let mut buf_end = buf_ptr; let ret = sum_u32(_ffi_vec_u32_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> u64 { let mut buf_end = buf_ptr; let ret = sum_u64(_ffi_vec_u64_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 { let mut buf_end = buf_ptr; let ret = sum_u8(_ffi_vec_u8_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[no_mangle] extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -> usize { let mut buf_end = buf_ptr; let ret = sum_usize(_ffi_vec_usize_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_f32_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_f64_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i16_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i64_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i8_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_isize_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u16_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u32_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u64_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u8_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_usize_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_vec_i32_from_js(_ffi_read::(end), end)); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function sum_u8(values: number[]): number; export function sum_u16(values: number[]): number; export function sum_u32(values: number[]): number; export function sum_usize(values: number[]): number; export function sum_u64(values: bigint[]): bigint; export function sum_i8(values: number[]): number; export function sum_i16(values: number[]): number; export function sum_i32(values: number[]): number; export function sum_isize(values: number[]): number; export function sum_i64(values: bigint[]): bigint; export function sum_f32(values: number[]): number; export function sum_f64(values: number[]): number; export function check_nested(values: number[][]): string; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_u8(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u8(_ffi_buf_to_rust(buf), values_len); } export function sum_u16(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u16(_ffi_buf_to_rust(buf), values_len); } export function sum_u32(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u32(_ffi_buf_to_rust(buf), values_len); } export function sum_usize(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_usize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_usize(_ffi_buf_to_rust(buf), values_len); } export function sum_u64(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u64(_ffi_buf_to_rust(buf), values_len); } export function sum_i8(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i8(_ffi_buf_to_rust(buf), values_len); } export function sum_i16(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i16(_ffi_buf_to_rust(buf), values_len); } export function sum_i32(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i32(_ffi_buf_to_rust(buf), values_len); } export function sum_isize(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_isize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_isize(_ffi_buf_to_rust(buf), values_len); } export function sum_i64(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i64(_ffi_buf_to_rust(buf), values_len); } export function sum_f32(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f32(_ffi_buf_to_rust(buf), values_len); } export function sum_f64(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f64(_ffi_buf_to_rust(buf), values_len); } export function check_nested(values) { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_vec_i32_to_rust(values, buf); let multi_ret = _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf), values_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = () => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv; function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }) { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_f32_to_rust(items, buf) { for (const item of items) { _ffi_write_f32(buf, item); } } function _ffi_vec_f64_to_rust(items, buf) { for (const item of items) { _ffi_write_f64(buf, item); } } function _ffi_vec_i16_to_rust(items, buf) { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_i64_to_rust(items, buf) { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_i8_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_isize_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u16_to_rust(items, buf) { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_u32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u64_to_rust(items, buf) { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_u8_to_rust(items, buf) { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_usize_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_vec_i32_to_rust(items, buf) { for (const item of items) { _ffi_write_i32(buf, item.length); _ffi_vec_i32_to_rust(item, buf); } } function _ffi_grow(buf, n) { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setFloat32(ptr, val, true); } function _ffi_write_f64(buf, val) { let ptr = _ffi_grow(buf, 8); buf.dv.setFloat64(ptr, val, true); } function _ffi_write_i16(buf, val) { let ptr = _ffi_grow(buf, 2); buf.dv.setInt16(ptr, val, true); } function _ffi_write_i32(buf, val) { let ptr = _ffi_grow(buf, 4); buf.dv.setInt32(ptr, val, true); } function _ffi_write_i64(buf, val) { let ptr = _ffi_grow(buf, 8); buf.dv.setBigInt64(ptr, val, true); } function _ffi_write_i8(buf, val) { let ptr = _ffi_grow(buf, 1); buf.dv.setInt8(ptr, val); } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function sum_u8(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u8(_ffi_buf_to_rust(buf), values_len); } export function sum_u16(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u16(_ffi_buf_to_rust(buf), values_len); } export function sum_u32(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u32(_ffi_buf_to_rust(buf), values_len); } export function sum_usize(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_usize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_usize(_ffi_buf_to_rust(buf), values_len); } export function sum_u64(values: bigint[]): bigint { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_u64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_u64(_ffi_buf_to_rust(buf), values_len); } export function sum_i8(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i8_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i8(_ffi_buf_to_rust(buf), values_len); } export function sum_i16(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i16_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i16(_ffi_buf_to_rust(buf), values_len); } export function sum_i32(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i32(_ffi_buf_to_rust(buf), values_len); } export function sum_isize(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_isize_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_isize(_ffi_buf_to_rust(buf), values_len); } export function sum_i64(values: bigint[]): bigint { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_i64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_i64(_ffi_buf_to_rust(buf), values_len); } export function sum_f32(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f32_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f32(_ffi_buf_to_rust(buf), values_len); } export function sum_f64(values: number[]): number { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_f64_to_rust(values, buf); return _ffi_exports._ffi_fn_sum_f64(_ffi_buf_to_rust(buf), values_len); } export function check_nested(values: number[][]): string { let buf = _ffi_new_WriteBuf(); let values_len = values.length; _ffi_vec_vec_i32_to_rust(values, buf); let multi_ret = _ffi_exports._ffi_fn_check_nested(_ffi_buf_to_rust(buf), values_len); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_new_WriteBuf = (): _ffi_WriteBuf => ({ u8: new Uint8Array(16), dv: null, off: 0 }); let _ffi_u8: Uint8Array; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_dv: DataView; interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_buf_to_rust({ u8, off }: _ffi_WriteBuf): number { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_vec_f32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_f32(buf, item); } } function _ffi_vec_f64_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_f64(buf, item); } } function _ffi_vec_i16_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_i32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_i64_to_rust(items: bigint[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_i8_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_isize_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u16_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i16(buf, item); } } function _ffi_vec_u32_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_u64_to_rust(items: bigint[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i64(buf, item); } } function _ffi_vec_u8_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i8(buf, item); } } function _ffi_vec_usize_to_rust(items: number[], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item); } } function _ffi_vec_vec_i32_to_rust(items: number[][], buf: _ffi_WriteBuf): void { for (const item of items) { _ffi_write_i32(buf, item.length); _ffi_vec_i32_to_rust(item, buf); } } function _ffi_grow(buf: _ffi_WriteBuf, n: number): number { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } function _ffi_write_f32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setFloat32(ptr, val, true); } function _ffi_write_f64(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 8); buf.dv!.setFloat64(ptr, val, true); } function _ffi_write_i16(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 2); buf.dv!.setInt16(ptr, val, true); } function _ffi_write_i32(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 4); buf.dv!.setInt32(ptr, val, true); } function _ffi_write_i64(buf: _ffi_WriteBuf, val: bigint): void { let ptr = _ffi_grow(buf, 8); buf.dv!.setBigInt64(ptr, val, true); } function _ffi_write_i8(buf: _ffi_WriteBuf, val: number): void { let ptr = _ffi_grow(buf, 1); buf.dv!.setInt8(ptr, val); } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_check_nested: (buf_ptr: number, values_len: number) => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_sum_f32: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_f64: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_i16: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_i32: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_i64: (buf_ptr: number, values_len: number) => bigint, _ffi_fn_sum_i8: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_isize: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_u16: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_u32: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_u64: (buf_ptr: number, values_len: number) => bigint, _ffi_fn_sum_u8: (buf_ptr: number, values_len: number) => number, _ffi_fn_sum_usize: (buf_ptr: number, values_len: number) => number, _ffi_alloc: (len: number) => number, _ffi_dealloc: (ptr: number, capacity: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) { let len = unsafe { end.byte_offset_from(ptr) } as usize; drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize) -> *const _ffi_ret_ptr_2_usize { let mut buf_end = buf_ptr; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(check_nested(_ffi_vec_vec_i32_from_js(values_len, &mut buf_end))); _ffi_buf_from_host(buf_ptr, buf_end); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> f32 { let mut buf_end = buf_ptr; let ret = sum_f32(_ffi_vec_f32_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> f64 { let mut buf_end = buf_ptr; let ret = sum_f64(_ffi_vec_f64_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> i16 { let mut buf_end = buf_ptr; let ret = sum_i16(_ffi_vec_i16_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> i32 { let mut buf_end = buf_ptr; let ret = sum_i32(_ffi_vec_i32_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> i64 { let mut buf_end = buf_ptr; let ret = sum_i64(_ffi_vec_i64_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 { let mut buf_end = buf_ptr; let ret = sum_i8(_ffi_vec_i8_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -> isize { let mut buf_end = buf_ptr; let ret = sum_isize(_ffi_vec_isize_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> u16 { let mut buf_end = buf_ptr; let ret = sum_u16(_ffi_vec_u16_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> u32 { let mut buf_end = buf_ptr; let ret = sum_u32(_ffi_vec_u32_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> u64 { let mut buf_end = buf_ptr; let ret = sum_u64(_ffi_vec_u64_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 { let mut buf_end = buf_ptr; let ret = sum_u8(_ffi_vec_u8_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -> usize { let mut buf_end = buf_ptr; let ret = sum_usize(_ffi_vec_usize_from_js(values_len, &mut buf_end)); _ffi_buf_from_host(buf_ptr, buf_end); ret } fn _ffi_read(ptr: &mut *const u8) -> T { let val = unsafe { (*ptr as *const T).read_unaligned() }; *ptr = unsafe { ptr.byte_offset(std::mem::size_of::() as isize) }; val } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } fn _ffi_vec_f32_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_f64_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i16_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i64_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_i8_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_isize_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u16_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u32_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u64_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_u8_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_usize_from_js(len: usize, end: &mut *const u8) -> Vec { let mut items = Vec::::with_capacity(len); for _ in 0..len { items.push(_ffi_read::(end)); } items } fn _ffi_vec_vec_i32_from_js(len: usize, end: &mut *const u8) -> Vec> { let mut items = Vec::>::with_capacity(len); for _ in 0..len { items.push(_ffi_vec_i32_from_js(_ffi_read::(end), end)); } items } ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function get_vec(n: number): number[]; export function check_nested(): number[][]; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_vec(n) { let multi_ret = _ffi_exports._ffi_fn_get_vec(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested() { let multi_ret = _ffi_exports._ffi_fn_check_nested(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_vec_i32_from_rust(_ffi_read_u32(buf), buf)); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_vec(n: number): number[] { let multi_ret = _ffi_exports._ffi_fn_get_vec(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested(): number[][] { let multi_ret = _ffi_exports._ffi_fn_check_nested(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[] { let items: number[] = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[][] { let items: number[][] = []; while (items.length < len) { items.push(_ffi_vec_i32_from_rust(_ffi_read_u32(buf), buf)); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_check_nested: () => number, _ffi_fn_get_vec: (n: number) => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[no_mangle] extern "C" fn _ffi_fn_check_nested() -> *const _ffi_ret_ptr_2_usize { let ret = check_nested(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_vec_i32_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_get_vec(n: i32) -> *const _ffi_ret_ptr_2_usize { let ret = get_vec(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_i32_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); fn _ffi_vec_i32_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } fn _ffi_vec_vec_i32_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.len(), buf); _ffi_vec_i32_to_js(item, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function rust_mem_leaked(): number; export function get_vec(n: number): number[]; export function check_nested(): number[][]; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_vec(n) { let multi_ret = _ffi_exports._ffi_fn_get_vec(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested() { let multi_ret = _ffi_exports._ffi_fn_check_nested(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv; let _ffi_new_ReadBuf = (off) => ({ dv: _ffi_update_dv(), off }); function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf) { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf) { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_vec_i32_from_rust(len, buf) { let items = []; while (items.length < len) { items.push(_ffi_vec_i32_from_rust(_ffi_read_u32(buf), buf)); } return items; } let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_vec(n: number): number[] { let multi_ret = _ffi_exports._ffi_fn_get_vec(n); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } export function check_nested(): number[][] { let multi_ret = _ffi_exports._ffi_fn_check_nested(); let buf_ptr = _ffi_update_dv().getInt32(multi_ret, true); let buf_cap = _ffi_dv.getUint32(multi_ret + 4, true); let ret_len = _ffi_dv.getUint32(multi_ret + 8, true); let buf = _ffi_new_ReadBuf(buf_ptr); let ret = _ffi_vec_vec_i32_from_rust(ret_len, buf); _ffi_exports._ffi_dealloc(buf_ptr, buf_cap); return ret; } let _ffi_dv: DataView; let _ffi_new_ReadBuf = (off: number): _ffi_ReadBuf => ({ dv: _ffi_update_dv(), off }); interface _ffi_ReadBuf { dv: DataView, off: number, } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } function _ffi_read_i32(buf: _ffi_ReadBuf): number { let val = buf.dv.getInt32(buf.off, true); buf.off += 4; return val; } function _ffi_read_u32(buf: _ffi_ReadBuf): number { let val = buf.dv.getUint32(buf.off, true); buf.off += 4; return val; } function _ffi_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[] { let items: number[] = []; while (items.length < len) { items.push(_ffi_read_i32(buf)); } return items; } function _ffi_vec_vec_i32_from_rust(len: number, buf: _ffi_ReadBuf): number[][] { let items: number[][] = []; while (items.length < len) { items.push(_ffi_vec_i32_from_rust(_ffi_read_u32(buf), buf)); } return items; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_fn_check_nested: () => number, _ffi_fn_get_vec: (n: number) => number, _ffi_fn_rust_mem_leaked: () => number, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_fn_vec_out_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_buf_to_host(buf: Vec) -> (*const u8, usize) { let buf = std::mem::ManuallyDrop::new(buf); (buf.as_ptr(), buf.capacity()) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_check_nested() -> *const _ffi_ret_ptr_2_usize { let ret = check_nested(); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_vec_i32_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_vec(n: i32) -> *const _ffi_ret_ptr_2_usize { let ret = get_vec(n); let mut buf = Vec::::new(); let ret_len = ret.len(); _ffi_vec_i32_to_js(ret, &mut buf); let (buf_ptr, buf_cap) = _ffi_buf_to_host(buf); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(buf_ptr, buf_cap, ret_len); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); fn _ffi_vec_i32_to_js(items: Vec, buf: &mut Vec) { for item in items { _ffi_write(item, buf); } } fn _ffi_vec_vec_i32_to_js(items: Vec>, buf: &mut Vec) { for item in items { _ffi_write(item.len(), buf); _ffi_vec_i32_to_js(item, buf); } } fn _ffi_write(val: T, buf: &mut Vec) { let ptr = std::ptr::addr_of!(val) as *const u8; let len = std::mem::size_of::(); buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Foo { set_enum(bar: Bar): void; get_enum(): Bar; } export const enum Bar { A, B, C, } export function rust_mem_leaked(): number; export function get_foo(): Foo; ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const Bar = { A: 0, B: 1, C: 2, }; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_foo() { let ret_ptr = _ffi_exports._ffi_fn_get_foo(); return new _ffi_Box_Foo(ret_ptr); } let _ffi_reg_Box_Foo = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Foo(ptr)); const _ffi_Box_Foo = class Foo { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Foo.register(this, _); } set_enum(bar) { _ffi_exports._ffi_Box_Foo__set_enum(this._, bar); } get_enum() { return _ffi_exports._ffi_Box_Foo__get_enum(this._); } }; let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Foo { set_enum(bar: Bar): void; get_enum(): Bar; } export const enum Bar { A, B, C, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_foo(): Foo { let ret_ptr = _ffi_exports._ffi_fn_get_foo(); return new _ffi_Box_Foo(ret_ptr); } let _ffi_reg_Box_Foo = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Foo(ptr)); const _ffi_Box_Foo = class Foo implements Foo { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Foo.register(this, _); } set_enum(bar: Bar): void { _ffi_exports._ffi_Box_Foo__set_enum(this._, bar); } get_enum(): Bar { return _ffi_exports._ffi_Box_Foo__get_enum(this._); } }; let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Foo__get_enum: (_self: number) => number, _ffi_Box_Foo__set_enum: (_self: number, bar_raw: number) => void, _ffi_fn_get_foo: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Box_Foo: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get_enum() as i32 } #[no_mangle] extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) { let _self = unsafe { &*(_self as *const Box) }; _self.set_enum(_ffi_enum_Bar_from_js(bar_raw)); } #[allow(non_snake_case)] fn _ffi_enum_Bar_from_js(val: i32) -> Bar { match val { 0 => Bar::A, 1 => Bar::B, 2 => Bar::C, _ => panic!(), } } #[no_mangle] extern "C" fn _ffi_fn_get_foo() -> *const u8 { Box::into_raw(Box::new(get_foo())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Foo(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Foo { set_enum(bar: Bar): void; get_enum(): Bar; } export const enum Bar { A, B, C, } export function rust_mem_leaked(): number; export function get_foo(): Foo; ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export const Bar = { A: 0, B: 1, C: 2, }; export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_foo() { let ret_ptr = _ffi_exports._ffi_fn_get_foo(); return new _ffi_Box_Foo(ret_ptr); } let _ffi_reg_Box_Foo = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Foo(ptr)); const _ffi_Box_Foo = class Foo { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Foo.register(this, _); } set_enum(bar) { _ffi_exports._ffi_Box_Foo__set_enum(this._, bar); } get_enum() { return _ffi_exports._ffi_Box_Foo__get_enum(this._); } }; let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Foo { set_enum(bar: Bar): void; get_enum(): Bar; } export const enum Bar { A, B, C, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_foo(): Foo { let ret_ptr = _ffi_exports._ffi_fn_get_foo(); return new _ffi_Box_Foo(ret_ptr); } let _ffi_reg_Box_Foo = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Foo(ptr)); const _ffi_Box_Foo = class Foo implements Foo { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Foo.register(this, _); } set_enum(bar: Bar): void { _ffi_exports._ffi_Box_Foo__set_enum(this._, bar); } get_enum(): Bar { return _ffi_exports._ffi_Box_Foo__get_enum(this._); } }; let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Foo__get_enum: (_self: number) => number, _ffi_Box_Foo__set_enum: (_self: number, bar_raw: number) => void, _ffi_fn_get_foo: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Box_Foo: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_enum_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.get_enum() as i32 } #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) { let _self = unsafe { &*(_self as *const Box) }; _self.set_enum(_ffi_enum_Bar_from_js(bar_raw)); } #[allow(non_snake_case)] fn _ffi_enum_Bar_from_js(val: i32) -> Bar { match val { 0 => Bar::A, 1 => Bar::B, 2 => Bar::C, _ => panic!(), } } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_foo() -> *const u8 { Box::into_raw(Box::new(get_foo())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Foo(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_export_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Adder { add(x: number): number; } export function rust_mem_leaked(): number; export function get_counter(): number; export function get_adder_rc(x: number): Adder; export function get_adder_box(x: number): Adder; ================================================ FILE: src/tests/snapshots/wasm_trait_export_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter() { return _ffi_exports._ffi_fn_get_counter(); } export function get_adder_rc(x) { let ret_ptr = _ffi_exports._ffi_fn_get_adder_rc(x); return new _ffi_Rc_Adder(ret_ptr); } export function get_adder_box(x) { let ret_ptr = _ffi_exports._ffi_fn_get_adder_box(x); return new _ffi_Box_Adder(ret_ptr); } let _ffi_reg_Box_Adder = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Adder(ptr)); let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); const _ffi_Box_Adder = class Adder { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Adder.register(this, _); } add(x) { return _ffi_exports._ffi_Box_Adder__add(this._, x); } }; const _ffi_Rc_Adder = class Adder { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x) { return _ffi_exports._ffi_Rc_Adder__add(this._, x); } }; let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Adder { add(x: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter(): number { return _ffi_exports._ffi_fn_get_counter(); } export function get_adder_rc(x: number): Adder { let ret_ptr = _ffi_exports._ffi_fn_get_adder_rc(x); return new _ffi_Rc_Adder(ret_ptr); } export function get_adder_box(x: number): Adder { let ret_ptr = _ffi_exports._ffi_fn_get_adder_box(x); return new _ffi_Box_Adder(ret_ptr); } let _ffi_reg_Box_Adder = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Adder(ptr)); let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); const _ffi_Box_Adder = class Adder implements Adder { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Adder.register(this, _); } add(x: number): number { return _ffi_exports._ffi_Box_Adder__add(this._, x); } }; const _ffi_Rc_Adder = class Adder implements Adder { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x: number): number { return _ffi_exports._ffi_Rc_Adder__add(this._, x); } }; let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Adder__add: (_self: number, x: number) => number, _ffi_Rc_Adder__add: (_self: number, x: number) => number, _ffi_fn_get_adder_box: (x: number) => number, _ffi_fn_get_adder_rc: (x: number) => number, _ffi_fn_get_counter: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Box_Adder: (ptr: number) => void, _ffi_rs_drop_Rc_Adder: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.add(x) } #[no_mangle] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x) } #[no_mangle] extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_box(x))) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_rc(x))) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_rs_drop_Box_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_export_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Adder { add(x: number): number; } export function rust_mem_leaked(): number; export function get_counter(): number; export function get_adder_rc(x: number): Adder; export function get_adder_box(x: number): Adder; ================================================ FILE: src/tests/snapshots/wasm_trait_export_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter() { return _ffi_exports._ffi_fn_get_counter(); } export function get_adder_rc(x) { let ret_ptr = _ffi_exports._ffi_fn_get_adder_rc(x); return new _ffi_Rc_Adder(ret_ptr); } export function get_adder_box(x) { let ret_ptr = _ffi_exports._ffi_fn_get_adder_box(x); return new _ffi_Box_Adder(ret_ptr); } let _ffi_reg_Box_Adder = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Box_Adder(ptr)); let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); const _ffi_Box_Adder = class Adder { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Adder.register(this, _); } add(x) { return _ffi_exports._ffi_Box_Adder__add(this._, x); } }; const _ffi_Rc_Adder = class Adder { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x) { return _ffi_exports._ffi_Rc_Adder__add(this._, x); } }; let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Adder { add(x: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter(): number { return _ffi_exports._ffi_fn_get_counter(); } export function get_adder_rc(x: number): Adder { let ret_ptr = _ffi_exports._ffi_fn_get_adder_rc(x); return new _ffi_Rc_Adder(ret_ptr); } export function get_adder_box(x: number): Adder { let ret_ptr = _ffi_exports._ffi_fn_get_adder_box(x); return new _ffi_Box_Adder(ret_ptr); } let _ffi_reg_Box_Adder = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Box_Adder(ptr)); let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); const _ffi_Box_Adder = class Adder implements Adder { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Box_Adder.register(this, _); } add(x: number): number { return _ffi_exports._ffi_Box_Adder__add(this._, x); } }; const _ffi_Rc_Adder = class Adder implements Adder { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x: number): number { return _ffi_exports._ffi_Rc_Adder__add(this._, x); } }; let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Box_Adder__add: (_self: number, x: number) => number, _ffi_Rc_Adder__add: (_self: number, x: number) => number, _ffi_fn_get_adder_box: (x: number) => number, _ffi_fn_get_adder_rc: (x: number) => number, _ffi_fn_get_counter: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Box_Adder: (ptr: number) => void, _ffi_rs_drop_Rc_Adder: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const Box) }; _self.add(x) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_box(x))) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 { Box::into_raw(Box::new(get_adder_rc(x))) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Box_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut Box) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Imported { add(x: number, y: number): number; } export interface Exported { run(imported: Imported): number; } export function rust_mem_leaked(): number; export function get_exported(): Exported; export function get_counter(): number; ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_exported() { let ret_ptr = _ffi_exports._ffi_fn_get_exported(); return new _ffi_Rc_Exported(ret_ptr); } export function get_counter() { return _ffi_exports._ffi_fn_get_counter(); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } run(imported) { return _ffi_exports._ffi_Rc_Exported__run(this._, _ffi_handle_alloc(imported)); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Imported__add(self, x, y) { return _ffi_handles.get(self).add(x, y); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Imported { add(x: number, y: number): number; } export interface Exported { run(imported: Imported): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_exported(): Exported { let ret_ptr = _ffi_exports._ffi_fn_get_exported(); return new _ffi_Rc_Exported(ret_ptr); } export function get_counter(): number { return _ffi_exports._ffi_fn_get_counter(); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported implements Exported { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } run(imported: Imported): number { return _ffi_exports._ffi_Rc_Exported__run(this._, _ffi_handle_alloc(imported)); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Exported__run: (_self: number, imported_ptr: number) => number, _ffi_fn_get_counter: () => number, _ffi_fn_get_exported: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Rc_Exported: (ptr: number) => void, }; const _ffi_imports = { _ffi_js_Imported__add(self: number, x: number, y: number): number { return _ffi_handles.get(self).add(x, y); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.run(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_get_exported() -> *const u8 { Box::into_raw(Box::new(get_exported())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn add(&self, x: i32, y: i32) -> i32 { extern "C" { fn _ffi_js_Imported__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_js_Imported__add(self.0, x, y) } } } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Imported { add(x: number, y: number): number; } export interface Exported { run(imported: Imported): number; } export function rust_mem_leaked(): number; export function get_exported(): Exported; export function get_counter(): number; ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_exported() { let ret_ptr = _ffi_exports._ffi_fn_get_exported(); return new _ffi_Rc_Exported(ret_ptr); } export function get_counter() { return _ffi_exports._ffi_fn_get_counter(); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } run(imported) { return _ffi_exports._ffi_Rc_Exported__run(this._, _ffi_handle_alloc(imported)); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Imported__add(self, x, y) { return _ffi_handles.get(self).add(x, y); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Imported { add(x: number, y: number): number; } export interface Exported { run(imported: Imported): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_exported(): Exported { let ret_ptr = _ffi_exports._ffi_fn_get_exported(); return new _ffi_Rc_Exported(ret_ptr); } export function get_counter(): number { return _ffi_exports._ffi_fn_get_counter(); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported implements Exported { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } run(imported: Imported): number { return _ffi_exports._ffi_Rc_Exported__run(this._, _ffi_handle_alloc(imported)); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Exported__run: (_self: number, imported_ptr: number) => number, _ffi_fn_get_counter: () => number, _ffi_fn_get_exported: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Rc_Exported: (ptr: number) => void, }; const _ffi_imports = { _ffi_js_Imported__add(self: number, x: number, y: number): number { return _ffi_handles.get(self).add(x, y); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_export_import_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *const u8) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.run(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_exported() -> *const u8 { Box::into_raw(Box::new(get_exported())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn add(&self, x: i32, y: i32) -> i32 { unsafe extern "C" { fn _ffi_js_Imported__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_js_Imported__add(self.0, x, y) } } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number; export function get_getter_counter(): number; export function get_adder_counter(): number; export function get_getter(): Getter; ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_getter_counter() { return _ffi_exports._ffi_fn_get_getter_counter(); } export function get_adder_counter() { return _ffi_exports._ffi_fn_get_adder_counter(); } export function get_getter() { let ret_ptr = _ffi_exports._ffi_fn_get_getter(); return new _ffi_Rc_Getter(ret_ptr); } let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); let _ffi_reg_Rc_Getter = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Getter(ptr)); const _ffi_Rc_Adder = class Adder { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x, y) { return _ffi_exports._ffi_Rc_Adder__add(this._, x, y); } }; const _ffi_Rc_Getter = class Getter { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Getter.register(this, _); } get_adder() { let ret_ptr = _ffi_exports._ffi_Rc_Getter__get_adder(this._); return new _ffi_Rc_Adder(ret_ptr); } }; let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_getter_counter(): number { return _ffi_exports._ffi_fn_get_getter_counter(); } export function get_adder_counter(): number { return _ffi_exports._ffi_fn_get_adder_counter(); } export function get_getter(): Getter { let ret_ptr = _ffi_exports._ffi_fn_get_getter(); return new _ffi_Rc_Getter(ret_ptr); } let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); let _ffi_reg_Rc_Getter = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Getter(ptr)); const _ffi_Rc_Adder = class Adder implements Adder { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x: number, y: number): number { return _ffi_exports._ffi_Rc_Adder__add(this._, x, y); } }; const _ffi_Rc_Getter = class Getter implements Getter { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Getter.register(this, _); } get_adder(): Adder { let ret_ptr = _ffi_exports._ffi_Rc_Getter__get_adder(this._); return new _ffi_Rc_Adder(ret_ptr); } }; let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Adder__add: (_self: number, x: number, y: number) => number, _ffi_Rc_Getter__get_adder: (_self: number) => number, _ffi_fn_get_adder_counter: () => number, _ffi_fn_get_getter: () => number, _ffi_fn_get_getter_counter: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Rc_Adder: (ptr: number) => void, _ffi_rs_drop_Rc_Getter: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[no_mangle] extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; Box::into_raw(Box::new(_self.get_adder())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_adder_counter() -> u32 { get_adder_counter() } #[no_mangle] extern "C" fn _ffi_fn_get_getter() -> *const u8 { Box::into_raw(Box::new(get_getter())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_get_getter_counter() -> u32 { get_getter_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Getter(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number; export function get_getter_counter(): number; export function get_adder_counter(): number; export function get_getter(): Getter; ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_getter_counter() { return _ffi_exports._ffi_fn_get_getter_counter(); } export function get_adder_counter() { return _ffi_exports._ffi_fn_get_adder_counter(); } export function get_getter() { let ret_ptr = _ffi_exports._ffi_fn_get_getter(); return new _ffi_Rc_Getter(ret_ptr); } let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); let _ffi_reg_Rc_Getter = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Getter(ptr)); const _ffi_Rc_Adder = class Adder { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x, y) { return _ffi_exports._ffi_Rc_Adder__add(this._, x, y); } }; const _ffi_Rc_Getter = class Getter { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Getter.register(this, _); } get_adder() { let ret_ptr = _ffi_exports._ffi_Rc_Getter__get_adder(this._); return new _ffi_Rc_Adder(ret_ptr); } }; let _ffi_exports; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_getter_counter(): number { return _ffi_exports._ffi_fn_get_getter_counter(); } export function get_adder_counter(): number { return _ffi_exports._ffi_fn_get_adder_counter(); } export function get_getter(): Getter { let ret_ptr = _ffi_exports._ffi_fn_get_getter(); return new _ffi_Rc_Getter(ret_ptr); } let _ffi_reg_Rc_Adder = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Adder(ptr)); let _ffi_reg_Rc_Getter = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Getter(ptr)); const _ffi_Rc_Adder = class Adder implements Adder { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Adder.register(this, _); } add(x: number, y: number): number { return _ffi_exports._ffi_Rc_Adder__add(this._, x, y); } }; const _ffi_Rc_Getter = class Getter implements Getter { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Getter.register(this, _); } get_adder(): Adder { let ret_ptr = _ffi_exports._ffi_Rc_Getter__get_adder(this._); return new _ffi_Rc_Adder(ret_ptr); } }; let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Adder__add: (_self: number, x: number, y: number) => number, _ffi_Rc_Getter__get_adder: (_self: number) => number, _ffi_fn_get_adder_counter: () => number, _ffi_fn_get_getter: () => number, _ffi_fn_get_getter_counter: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_rs_drop_Rc_Adder: (ptr: number) => void, _ffi_rs_drop_Rc_Getter: (ptr: number) => void, }; const _ffi_imports = {}; ================================================ FILE: src/tests/snapshots/wasm_trait_export_nested_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; Box::into_raw(Box::new(_self.get_adder())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_adder_counter() -> u32 { get_adder_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_getter() -> *const u8 { Box::into_raw(Box::new(get_getter())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_getter_counter() -> u32 { get_getter_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Adder(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Getter(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_import_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Adder { add(y: number): number; } export function rust_mem_leaked(): number; export function set_adder_rc(adder: Adder): number; export function set_adder_box(adder: Adder): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_adder_rc(adder) { return _ffi_exports._ffi_fn_set_adder_rc(_ffi_handle_alloc(adder)); } export function set_adder_box(adder) { return _ffi_exports._ffi_fn_set_adder_box(_ffi_handle_alloc(adder)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Adder__add(self, y) { return _ffi_handles.get(self).add(y); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Adder { add(y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_adder_rc(adder: Adder): number { return _ffi_exports._ffi_fn_set_adder_rc(_ffi_handle_alloc(adder)); } export function set_adder_box(adder: Adder): number { return _ffi_exports._ffi_fn_set_adder_box(_ffi_handle_alloc(adder)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_adder_box: (adder_ptr: number) => number, _ffi_fn_set_adder_rc: (adder_ptr: number) => number, }; const _ffi_imports = { _ffi_js_Adder__add(self: number, y: number): number { return _ffi_handles.get(self).add(y); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 { set_adder_box(Box::new(_ffi_rs_Adder(adder_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 { set_adder_rc(std::rc::Rc::new(_ffi_rs_Adder(adder_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, y: i32) -> i32 { extern "C" { fn _ffi_js_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_js_Adder__add(self.0, y) } } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Adder { add(y: number): number; } export function rust_mem_leaked(): number; export function set_adder_rc(adder: Adder): number; export function set_adder_box(adder: Adder): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_adder_rc(adder) { return _ffi_exports._ffi_fn_set_adder_rc(_ffi_handle_alloc(adder)); } export function set_adder_box(adder) { return _ffi_exports._ffi_fn_set_adder_box(_ffi_handle_alloc(adder)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Adder__add(self, y) { return _ffi_handles.get(self).add(y); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Adder { add(y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_adder_rc(adder: Adder): number { return _ffi_exports._ffi_fn_set_adder_rc(_ffi_handle_alloc(adder)); } export function set_adder_box(adder: Adder): number { return _ffi_exports._ffi_fn_set_adder_box(_ffi_handle_alloc(adder)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_adder_box: (adder_ptr: number) => number, _ffi_fn_set_adder_rc: (adder_ptr: number) => number, }; const _ffi_imports = { _ffi_js_Adder__add(self: number, y: number): number { return _ffi_handles.get(self).add(y); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 { set_adder_box(Box::new(_ffi_rs_Adder(adder_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 { set_adder_rc(std::rc::Rc::new(_ffi_rs_Adder(adder_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, y: i32) -> i32 { unsafe extern "C" { fn _ffi_js_Adder__add(_: *const u8, y: i32) -> i32; } unsafe { _ffi_js_Adder__add(self.0, y) } } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Imported { run(exported: Exported): number; } export interface Exported { add(x: number, y: number): number; } export function rust_mem_leaked(): number; export function get_counter(): number; export function set_imported(imported: Imported): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter() { return _ffi_exports._ffi_fn_get_counter(); } export function set_imported(imported) { return _ffi_exports._ffi_fn_set_imported(_ffi_handle_alloc(imported)); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } add(x, y) { return _ffi_exports._ffi_Rc_Exported__add(this._, x, y); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Imported__run(self, exported_ptr) { return _ffi_handles.get(self).run(new _ffi_Rc_Exported(exported_ptr)); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Imported { run(exported: Exported): number; } export interface Exported { add(x: number, y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter(): number { return _ffi_exports._ffi_fn_get_counter(); } export function set_imported(imported: Imported): number { return _ffi_exports._ffi_fn_set_imported(_ffi_handle_alloc(imported)); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported implements Exported { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } add(x: number, y: number): number { return _ffi_exports._ffi_Rc_Exported__add(this._, x, y); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Exported__add: (_self: number, x: number, y: number) => number, _ffi_fn_get_counter: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_imported: (imported_ptr: number) => number, _ffi_rs_drop_Rc_Exported: (ptr: number) => void, }; const _ffi_imports = { _ffi_js_Imported__run(self: number, exported_ptr: number): number { return _ffi_handles.get(self).run(new _ffi_Rc_Exported(exported_ptr)); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[no_mangle] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 { set_imported(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn run(&self, exported: std::rc::Rc) -> i32 { extern "C" { fn _ffi_js_Imported__run(_: *const u8, exported_ptr: *const u8) -> i32; } unsafe { _ffi_js_Imported__run(self.0, Box::into_raw(Box::new(exported)) as *const u8) } } } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Imported { run(exported: Exported): number; } export interface Exported { add(x: number, y: number): number; } export function rust_mem_leaked(): number; export function get_counter(): number; export function set_imported(imported: Imported): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter() { return _ffi_exports._ffi_fn_get_counter(); } export function set_imported(imported) { return _ffi_exports._ffi_fn_set_imported(_ffi_handle_alloc(imported)); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } add(x, y) { return _ffi_exports._ffi_Rc_Exported__add(this._, x, y); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Imported__run(self, exported_ptr) { return _ffi_handles.get(self).run(new _ffi_Rc_Exported(exported_ptr)); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Imported { run(exported: Exported): number; } export interface Exported { add(x: number, y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_counter(): number { return _ffi_exports._ffi_fn_get_counter(); } export function set_imported(imported: Imported): number { return _ffi_exports._ffi_fn_set_imported(_ffi_handle_alloc(imported)); } let _ffi_reg_Rc_Exported = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Exported(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; const _ffi_Rc_Exported = class Exported implements Exported { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Exported.register(this, _); } add(x: number, y: number): number { return _ffi_exports._ffi_Rc_Exported__add(this._, x, y); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Exported__add: (_self: number, x: number, y: number) => number, _ffi_fn_get_counter: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_imported: (imported_ptr: number) => number, _ffi_rs_drop_Rc_Exported: (ptr: number) => void, }; const _ffi_imports = { _ffi_js_Imported__run(self: number, exported_ptr: number): number { return _ffi_handles.get(self).run(new _ffi_Rc_Exported(exported_ptr)); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_export_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) -> i32 { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.add(x, y) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_counter() -> u32 { get_counter() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 { set_imported(std::rc::Rc::new(_ffi_rs_Imported(imported_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Imported(*const u8); impl Drop for _ffi_rs_Imported { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Imported for _ffi_rs_Imported { fn run(&self, exported: std::rc::Rc) -> i32 { unsafe extern "C" { fn _ffi_js_Imported__run(_: *const u8, exported_ptr: *const u8) -> i32; } unsafe { _ffi_js_Imported__run(self.0, Box::into_raw(Box::new(exported)) as *const u8) } } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Exported(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number; export function set_getter(getter: Getter): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_getter(getter) { return _ffi_exports._ffi_fn_set_getter(_ffi_handle_alloc(getter)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Adder__add(self, x, y) { return _ffi_handles.get(self).add(x, y); }, _ffi_js_Getter__get_adder(self) { return _ffi_handle_alloc(_ffi_handles.get(self).get_adder()); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_getter(getter: Getter): number { return _ffi_exports._ffi_fn_set_getter(_ffi_handle_alloc(getter)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_getter: (getter_ptr: number) => number, }; const _ffi_imports = { _ffi_js_Adder__add(self: number, x: number, y: number): number { return _ffi_handles.get(self).add(x, y); }, _ffi_js_Getter__get_adder(self: number): number { return _ffi_handle_alloc(_ffi_handles.get(self).get_adder()); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 { set_getter(std::rc::Rc::new(_ffi_rs_Getter(getter_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, x: i32, y: i32) -> i32 { extern "C" { fn _ffi_js_Adder__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_js_Adder__add(self.0, x, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Getter(*const u8); impl Drop for _ffi_rs_Getter { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Getter for _ffi_rs_Getter { fn get_adder(&self) -> std::rc::Rc { extern "C" { fn _ffi_js_Getter__get_adder(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_js_Getter__get_adder(self.0) }; std::rc::Rc::new(_ffi_rs_Adder(ret_ptr)) } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number; export function set_getter(getter: Getter): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_getter(getter) { return _ffi_exports._ffi_fn_set_getter(_ffi_handle_alloc(getter)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_Adder__add(self, x, y) { return _ffi_handles.get(self).add(x, y); }, _ffi_js_Getter__get_adder(self) { return _ffi_handle_alloc(_ffi_handles.get(self).get_adder()); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Getter { get_adder(): Adder; } export interface Adder { add(x: number, y: number): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_getter(getter: Getter): number { return _ffi_exports._ffi_fn_set_getter(_ffi_handle_alloc(getter)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_getter: (getter_ptr: number) => number, }; const _ffi_imports = { _ffi_js_Adder__add(self: number, x: number, y: number): number { return _ffi_handles.get(self).add(x, y); }, _ffi_js_Getter__get_adder(self: number): number { return _ffi_handle_alloc(_ffi_handles.get(self).get_adder()); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_nested_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 { set_getter(std::rc::Rc::new(_ffi_rs_Getter(getter_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_Adder(*const u8); impl Drop for _ffi_rs_Adder { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Adder for _ffi_rs_Adder { fn add(&self, x: i32, y: i32) -> i32 { unsafe extern "C" { fn _ffi_js_Adder__add(_: *const u8, x: i32, y: i32) -> i32; } unsafe { _ffi_js_Adder__add(self.0, x, y) } } } #[allow(non_camel_case_types)] struct _ffi_rs_Getter(*const u8); impl Drop for _ffi_rs_Getter { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Getter for _ffi_rs_Getter { fn get_adder(&self) -> std::rc::Rc { unsafe extern "C" { fn _ffi_js_Getter__get_adder(_: *const u8) -> *const u8; } let ret_ptr = unsafe { _ffi_js_Getter__get_adder(self.0) }; std::rc::Rc::new(_ffi_rs_Adder(ret_ptr)) } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface StructIn { empty_struct(x: number, foo: EmptyStruct, y: number): number; single_element_struct(x: SingleElementStruct, y: SingleElementStruct): number; multiply_pairs(ab: PairStruct, cd: PairStruct): number; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number; export function set_empty_struct(struct_in: StructIn): number; export function set_single_element_struct(struct_in: StructIn): number; export function set_multiply_pairs(struct_in: StructIn): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_struct(struct_in) { return _ffi_exports._ffi_fn_set_empty_struct(_ffi_handle_alloc(struct_in)); } export function set_single_element_struct(struct_in) { return _ffi_exports._ffi_fn_set_single_element_struct(_ffi_handle_alloc(struct_in)); } export function set_multiply_pairs(struct_in) { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(struct_in)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_StructIn__empty_struct(self, x, y) { return _ffi_handles.get(self).empty_struct(x, {}, y); }, _ffi_js_StructIn__multiply_pairs(self, ab_x, ab_y, cd_x, cd_y) { return _ffi_handles.get(self).multiply_pairs({ x: ab_x, y: ab_y }, { x: cd_x, y: cd_y }); }, _ffi_js_StructIn__single_element_struct(self, x_0, y_0) { return _ffi_handles.get(self).single_element_struct({ 0: x_0 }, { 0: y_0 }); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface StructIn { empty_struct(x: number, foo: EmptyStruct, y: number): number; single_element_struct(x: SingleElementStruct, y: SingleElementStruct): number; multiply_pairs(ab: PairStruct, cd: PairStruct): number; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_struct(struct_in: StructIn): number { return _ffi_exports._ffi_fn_set_empty_struct(_ffi_handle_alloc(struct_in)); } export function set_single_element_struct(struct_in: StructIn): number { return _ffi_exports._ffi_fn_set_single_element_struct(_ffi_handle_alloc(struct_in)); } export function set_multiply_pairs(struct_in: StructIn): number { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(struct_in)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_empty_struct: (struct_in_ptr: number) => number, _ffi_fn_set_multiply_pairs: (struct_in_ptr: number) => number, _ffi_fn_set_single_element_struct: (struct_in_ptr: number) => number, }; const _ffi_imports = { _ffi_js_StructIn__empty_struct(self: number, x: number, y: number): number { return _ffi_handles.get(self).empty_struct(x, {}, y); }, _ffi_js_StructIn__multiply_pairs(self: number, ab_x: number, ab_y: number, cd_x: number, cd_y: number): number { return _ffi_handles.get(self).multiply_pairs({ x: ab_x, y: ab_y }, { x: cd_x, y: cd_y }); }, _ffi_js_StructIn__single_element_struct(self: number, x_0: number, y_0: number): number { return _ffi_handles.get(self).single_element_struct({ 0: x_0 }, { 0: y_0 }); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 { set_empty_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8) -> i32 { set_single_element_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_StructIn(*const u8); impl Drop for _ffi_rs_StructIn { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl StructIn for _ffi_rs_StructIn { fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 { extern "C" { fn _ffi_js_StructIn__empty_struct(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_js_StructIn__empty_struct(self.0, x, y) } } fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32 { extern "C" { fn _ffi_js_StructIn__single_element_struct(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_js_StructIn__single_element_struct(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 { extern "C" { fn _ffi_js_StructIn__multiply_pairs(_: *const u8, ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32; } unsafe { _ffi_js_StructIn__multiply_pairs(self.0, ab.x, ab.y, cd.x, cd.y) } } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface StructIn { empty_struct(x: number, foo: EmptyStruct, y: number): number; single_element_struct(x: SingleElementStruct, y: SingleElementStruct): number; multiply_pairs(ab: PairStruct, cd: PairStruct): number; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number; export function set_empty_struct(struct_in: StructIn): number; export function set_single_element_struct(struct_in: StructIn): number; export function set_multiply_pairs(struct_in: StructIn): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_struct(struct_in) { return _ffi_exports._ffi_fn_set_empty_struct(_ffi_handle_alloc(struct_in)); } export function set_single_element_struct(struct_in) { return _ffi_exports._ffi_fn_set_single_element_struct(_ffi_handle_alloc(struct_in)); } export function set_multiply_pairs(struct_in) { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(struct_in)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_StructIn__empty_struct(self, x, y) { return _ffi_handles.get(self).empty_struct(x, {}, y); }, _ffi_js_StructIn__multiply_pairs(self, ab_x, ab_y, cd_x, cd_y) { return _ffi_handles.get(self).multiply_pairs({ x: ab_x, y: ab_y }, { x: cd_x, y: cd_y }); }, _ffi_js_StructIn__single_element_struct(self, x_0, y_0) { return _ffi_handles.get(self).single_element_struct({ 0: x_0 }, { 0: y_0 }); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface StructIn { empty_struct(x: number, foo: EmptyStruct, y: number): number; single_element_struct(x: SingleElementStruct, y: SingleElementStruct): number; multiply_pairs(ab: PairStruct, cd: PairStruct): number; } export interface EmptyStruct { } export interface SingleElementStruct { 0: number, } export interface PairStruct { x: number, y: number, } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_struct(struct_in: StructIn): number { return _ffi_exports._ffi_fn_set_empty_struct(_ffi_handle_alloc(struct_in)); } export function set_single_element_struct(struct_in: StructIn): number { return _ffi_exports._ffi_fn_set_single_element_struct(_ffi_handle_alloc(struct_in)); } export function set_multiply_pairs(struct_in: StructIn): number { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(struct_in)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_empty_struct: (struct_in_ptr: number) => number, _ffi_fn_set_multiply_pairs: (struct_in_ptr: number) => number, _ffi_fn_set_single_element_struct: (struct_in_ptr: number) => number, }; const _ffi_imports = { _ffi_js_StructIn__empty_struct(self: number, x: number, y: number): number { return _ffi_handles.get(self).empty_struct(x, {}, y); }, _ffi_js_StructIn__multiply_pairs(self: number, ab_x: number, ab_y: number, cd_x: number, cd_y: number): number { return _ffi_handles.get(self).multiply_pairs({ x: ab_x, y: ab_y }, { x: cd_x, y: cd_y }); }, _ffi_js_StructIn__single_element_struct(self: number, x_0: number, y_0: number): number { return _ffi_handles.get(self).single_element_struct({ 0: x_0 }, { 0: y_0 }); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_struct_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 { set_empty_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8) -> i32 { set_single_element_struct(std::rc::Rc::new(_ffi_rs_StructIn(struct_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_StructIn(*const u8); impl Drop for _ffi_rs_StructIn { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl StructIn for _ffi_rs_StructIn { fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 { unsafe extern "C" { fn _ffi_js_StructIn__empty_struct(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_js_StructIn__empty_struct(self.0, x, y) } } fn single_element_struct(&self, x: SingleElementStruct, y: SingleElementStruct) -> i32 { unsafe extern "C" { fn _ffi_js_StructIn__single_element_struct(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_js_StructIn__single_element_struct(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 { unsafe extern "C" { fn _ffi_js_StructIn__multiply_pairs(_: *const u8, ab_x: f32, ab_y: f32, cd_x: f32, cd_y: f32) -> f32; } unsafe { _ffi_js_StructIn__multiply_pairs(self.0, ab.x, ab.y, cd.x, cd.y) } } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface TupleIn { empty_tuple(x: number, foo: undefined, y: number): number; single_element_tuple(x: [number], y: [number]): number; multiply_pairs(ab: [number, number], cd: [number, number]): number; } export function rust_mem_leaked(): number; export function set_empty_tuple(tuple_in: TupleIn): number; export function set_single_element_tuple(tuple_in: TupleIn): number; export function set_multiply_pairs(tuple_in: TupleIn): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_tuple(tuple_in) { return _ffi_exports._ffi_fn_set_empty_tuple(_ffi_handle_alloc(tuple_in)); } export function set_single_element_tuple(tuple_in) { return _ffi_exports._ffi_fn_set_single_element_tuple(_ffi_handle_alloc(tuple_in)); } export function set_multiply_pairs(tuple_in) { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(tuple_in)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_TupleIn__empty_tuple(self, x, y) { return _ffi_handles.get(self).empty_tuple(x, undefined, y); }, _ffi_js_TupleIn__multiply_pairs(self, ab_0, ab_1, cd_0, cd_1) { return _ffi_handles.get(self).multiply_pairs([ab_0, ab_1], [cd_0, cd_1]); }, _ffi_js_TupleIn__single_element_tuple(self, x_0, y_0) { return _ffi_handles.get(self).single_element_tuple([x_0], [y_0]); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface TupleIn { empty_tuple(x: number, foo: undefined, y: number): number; single_element_tuple(x: [number], y: [number]): number; multiply_pairs(ab: [number, number], cd: [number, number]): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_tuple(tuple_in: TupleIn): number { return _ffi_exports._ffi_fn_set_empty_tuple(_ffi_handle_alloc(tuple_in)); } export function set_single_element_tuple(tuple_in: TupleIn): number { return _ffi_exports._ffi_fn_set_single_element_tuple(_ffi_handle_alloc(tuple_in)); } export function set_multiply_pairs(tuple_in: TupleIn): number { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(tuple_in)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_empty_tuple: (tuple_in_ptr: number) => number, _ffi_fn_set_multiply_pairs: (tuple_in_ptr: number) => number, _ffi_fn_set_single_element_tuple: (tuple_in_ptr: number) => number, }; const _ffi_imports = { _ffi_js_TupleIn__empty_tuple(self: number, x: number, y: number): number { return _ffi_handles.get(self).empty_tuple(x, undefined, y); }, _ffi_js_TupleIn__multiply_pairs(self: number, ab_0: number, ab_1: number, cd_0: number, cd_1: number): number { return _ffi_handles.get(self).multiply_pairs([ab_0, ab_1], [cd_0, cd_1]); }, _ffi_js_TupleIn__single_element_tuple(self: number, x_0: number, y_0: number): number { return _ffi_handles.get(self).single_element_tuple([x_0], [y_0]); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 { set_empty_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[no_mangle] extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) -> i32 { set_single_element_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_TupleIn(*const u8); impl Drop for _ffi_rs_TupleIn { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl TupleIn for _ffi_rs_TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 { extern "C" { fn _ffi_js_TupleIn__empty_tuple(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_js_TupleIn__empty_tuple(self.0, x, y) } } fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 { extern "C" { fn _ffi_js_TupleIn__single_element_tuple(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_js_TupleIn__single_element_tuple(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 { extern "C" { fn _ffi_js_TupleIn__multiply_pairs(_: *const u8, ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32; } unsafe { _ffi_js_TupleIn__multiply_pairs(self.0, ab.0, ab.1, cd.0, cd.1) } } } ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface TupleIn { empty_tuple(x: number, foo: undefined, y: number): number; single_element_tuple(x: [number], y: [number]): number; multiply_pairs(ab: [number, number], cd: [number, number]): number; } export function rust_mem_leaked(): number; export function set_empty_tuple(tuple_in: TupleIn): number; export function set_single_element_tuple(tuple_in: TupleIn): number; export function set_multiply_pairs(tuple_in: TupleIn): number; ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_tuple(tuple_in) { return _ffi_exports._ffi_fn_set_empty_tuple(_ffi_handle_alloc(tuple_in)); } export function set_single_element_tuple(tuple_in) { return _ffi_exports._ffi_fn_set_single_element_tuple(_ffi_handle_alloc(tuple_in)); } export function set_multiply_pairs(tuple_in) { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(tuple_in)); } let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports; const _ffi_imports = { _ffi_js_TupleIn__empty_tuple(self, x, y) { return _ffi_handles.get(self).empty_tuple(x, undefined, y); }, _ffi_js_TupleIn__multiply_pairs(self, ab_0, ab_1, cd_0, cd_1) { return _ffi_handles.get(self).multiply_pairs([ab_0, ab_1], [cd_0, cd_1]); }, _ffi_js_TupleIn__single_element_tuple(self, x_0, y_0) { return _ffi_handles.get(self).single_element_tuple([x_0], [y_0]); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface TupleIn { empty_tuple(x: number, foo: undefined, y: number): number; single_element_tuple(x: [number], y: [number]): number; multiply_pairs(ab: [number, number], cd: [number, number]): number; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function set_empty_tuple(tuple_in: TupleIn): number { return _ffi_exports._ffi_fn_set_empty_tuple(_ffi_handle_alloc(tuple_in)); } export function set_single_element_tuple(tuple_in: TupleIn): number { return _ffi_exports._ffi_fn_set_single_element_tuple(_ffi_handle_alloc(tuple_in)); } export function set_multiply_pairs(tuple_in: TupleIn): number { return _ffi_exports._ffi_fn_set_multiply_pairs(_ffi_handle_alloc(tuple_in)); } let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_empty_tuple: (tuple_in_ptr: number) => number, _ffi_fn_set_multiply_pairs: (tuple_in_ptr: number) => number, _ffi_fn_set_single_element_tuple: (tuple_in_ptr: number) => number, }; const _ffi_imports = { _ffi_js_TupleIn__empty_tuple(self: number, x: number, y: number): number { return _ffi_handles.get(self).empty_tuple(x, undefined, y); }, _ffi_js_TupleIn__multiply_pairs(self: number, ab_0: number, ab_1: number, cd_0: number, cd_1: number): number { return _ffi_handles.get(self).multiply_pairs([ab_0, ab_1], [cd_0, cd_1]); }, _ffi_js_TupleIn__single_element_tuple(self: number, x_0: number, y_0: number): number { return _ffi_handles.get(self).single_element_tuple([x_0], [y_0]); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_import_tuple_in_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 { set_empty_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 { set_multiply_pairs(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) -> i32 { set_single_element_tuple(std::rc::Rc::new(_ffi_rs_TupleIn(tuple_in_ptr))) } #[allow(non_camel_case_types)] struct _ffi_rs_TupleIn(*const u8); impl Drop for _ffi_rs_TupleIn { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl TupleIn for _ffi_rs_TupleIn { fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 { unsafe extern "C" { fn _ffi_js_TupleIn__empty_tuple(_: *const u8, x: i32, y: i32) -> i32; } _ = foo; unsafe { _ffi_js_TupleIn__empty_tuple(self.0, x, y) } } fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 { unsafe extern "C" { fn _ffi_js_TupleIn__single_element_tuple(_: *const u8, x_0: i32, y_0: i32) -> i32; } unsafe { _ffi_js_TupleIn__single_element_tuple(self.0, x.0, y.0) } } fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 { unsafe extern "C" { fn _ffi_js_TupleIn__multiply_pairs(_: *const u8, ab_0: f32, ab_1: f32, cd_0: f32, cd_1: f32) -> f32; } unsafe { _ffi_js_TupleIn__multiply_pairs(self.0, ab.0, ab.1, cd.0, cd.1) } } } ================================================ FILE: src/tests/snapshots/wasm_trait_string_2021/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Test { get_string(): string; set_string(x: string): void; set_str(x: string): void; } export function rust_mem_leaked(): number; export function get_test(): Test; export function set_test(test: Test): string; ================================================ FILE: src/tests/snapshots/wasm_trait_string_2021/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_test() { let ret_ptr = _ffi_exports._ffi_fn_get_test(); return new _ffi_Rc_Test(ret_ptr); } export function set_test(test) { let multi_ret = _ffi_exports._ffi_fn_set_test(_ffi_handle_alloc(test)); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_reg_Rc_Test = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Test(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8; let _ffi_dv; const _ffi_Rc_Test = class Test { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Test.register(this, _); } get_string() { let multi_ret = _ffi_exports._ffi_Rc_Test__get_string(this._); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } set_string(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_string(this._, x_ptr, x_len); } set_str(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_str(this._, x_ptr, x_len); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = { _ffi_js_Test__get_string(self, _ffi_ret_ptr_usize) { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_string()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Test__set_str(self, x_ptr, x_len, x_cap) { _ffi_handles.get(self).set_str(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_Test__set_string(self, x_ptr, x_len, x_cap) { _ffi_handles.get(self).set_string(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_string_2021/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Test { get_string(): string; set_string(x: string): void; set_str(x: string): void; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_test(): Test { let ret_ptr = _ffi_exports._ffi_fn_get_test(); return new _ffi_Rc_Test(ret_ptr); } export function set_test(test: Test): string { let multi_ret = _ffi_exports._ffi_fn_set_test(_ffi_handle_alloc(test)); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_reg_Rc_Test = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Test(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8: Uint8Array; let _ffi_dv: DataView; const _ffi_Rc_Test = class Test implements Test { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Test.register(this, _); } get_string(): string { let multi_ret = _ffi_exports._ffi_Rc_Test__get_string(this._); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } set_string(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_string(this._, x_ptr, x_len); } set_str(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_str(this._, x_ptr, x_len); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Test__get_string: (_self: number) => number, _ffi_Rc_Test__set_str: (_self: number, x_ptr: number, x_len: number) => void, _ffi_Rc_Test__set_string: (_self: number, x_ptr: number, x_len: number) => void, _ffi_fn_get_test: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_test: (test_ptr: number) => number, _ffi_rs_drop_Rc_Test: (ptr: number) => void, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Test__get_string(self: number, _ffi_ret_ptr_usize: number): void { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_string()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Test__set_str(self: number, x_ptr: number, x_len: number, x_cap: number): void { _ffi_handles.get(self).set_str(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_Test__set_string(self: number, x_ptr: number, x_len: number, x_cap: number): void { _ffi_handles.get(self).set_string(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_string_2021/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[no_mangle] extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> *const _ffi_ret_ptr_2_usize { let _self = unsafe { &*(_self as *const std::rc::Rc) }; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(_self.get_string()); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[no_mangle] extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_string(_ffi_string_from_host(x_ptr, x_len)); } #[no_mangle] extern "C" fn _ffi_fn_get_test() -> *const u8 { Box::into_raw(Box::new(get_test())) as *const u8 } #[no_mangle] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[no_mangle] extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> *const _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(set_test(std::rc::Rc::new(_ffi_rs_Test(test_ptr)))); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); #[allow(non_camel_case_types)] struct _ffi_rs_Test(*const u8); impl Drop for _ffi_rs_Test { fn drop(&mut self) { extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Test for _ffi_rs_Test { fn get_string(&self) -> String { extern "C" { fn _ffi_js_Test__get_string(_: *const u8, _: *const _ffi_ret_ptr_usize); } unsafe { _ffi_js_Test__get_string(self.0, std::ptr::addr_of!(_FFI_RET_PTR_USIZE)) } let ret_ptr = unsafe { _FFI_RET_PTR_USIZE.0 }; let ret_len = unsafe { _FFI_RET_PTR_USIZE.1 }; _ffi_string_from_host(ret_ptr, ret_len) } fn set_string(&self, x: String) { extern "C" { fn _ffi_js_Test__set_string(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x); unsafe { _ffi_js_Test__set_string(self.0, x_ptr, x_len, x_cap) }; } fn set_str(&self, x: &str) { extern "C" { fn _ffi_js_Test__set_str(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x.into()); unsafe { _ffi_js_Test__set_str(self.0, x_ptr, x_len, x_cap) }; } } #[no_mangle] extern "C" fn _ffi_rs_drop_Rc_Test(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[no_mangle] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[no_mangle] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/snapshots/wasm_trait_string_2024/ffi.d.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }>; export interface Test { get_string(): string; set_string(x: string): void; set_str(x: string): void; } export function rust_mem_leaked(): number; export function get_test(): Test; export function set_test(test: Test): string; ================================================ FILE: src/tests/snapshots/wasm_trait_string_2024/ffi.mjs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source, imports) { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports; return { memory: _ffi_exports.memory }; } export function rust_mem_leaked() { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_test() { let ret_ptr = _ffi_exports._ffi_fn_get_test(); return new _ffi_Rc_Test(ret_ptr); } export function set_test(test) { let multi_ret = _ffi_exports._ffi_fn_set_test(_ffi_handle_alloc(test)); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_reg_Rc_Test = new FinalizationRegistry((ptr) => _ffi_exports._ffi_rs_drop_Rc_Test(ptr)); let _ffi_handles = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8; let _ffi_dv; const _ffi_Rc_Test = class Test { constructor(_) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Test.register(this, _); } get_string() { let multi_ret = _ffi_exports._ffi_Rc_Test__get_string(this._); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } set_string(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_string(this._, x_ptr, x_len); } set_str(x) { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_str(this._, x_ptr, x_len); } }; function _ffi_handle_alloc(obj) { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_string_from_rust(ptr, len, cap) { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str) { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv() { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports; const _ffi_imports = { _ffi_js_Test__get_string(self, _ffi_ret_ptr_usize) { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_string()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Test__set_str(self, x_ptr, x_len, x_cap) { _ffi_handles.get(self).set_str(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_Test__set_string(self, x_ptr, x_len, x_cap) { _ffi_handles.get(self).set_string(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_drop(handle) { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_string_2024/ffi.mts ================================================ // This file was generated by miniffi v0.1.0. Do not edit. export async function instantiate(bytes: BufferSource, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export async function instantiateStreaming(source: Response | PromiseLike, imports?: WebAssembly.ModuleImports): Promise<{ memory: WebAssembly.Memory }> { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports as any; return { memory: _ffi_exports.memory }; } export interface Test { get_string(): string; set_string(x: string): void; set_str(x: string): void; } export function rust_mem_leaked(): number { return _ffi_exports._ffi_fn_rust_mem_leaked(); } export function get_test(): Test { let ret_ptr = _ffi_exports._ffi_fn_get_test(); return new _ffi_Rc_Test(ret_ptr); } export function set_test(test: Test): string { let multi_ret = _ffi_exports._ffi_fn_set_test(_ffi_handle_alloc(test)); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } let _ffi_len = 0; let _ffi_reg_Rc_Test = new FinalizationRegistry((ptr: number) => _ffi_exports._ffi_rs_drop_Rc_Test(ptr)); let _ffi_handles: Map = /* @__PURE__ */ new Map; let _ffi_next_handle = 0; let _ffi_decoder = /* @__PURE__ */ new TextDecoder; let _ffi_encoder = /* @__PURE__ */ new TextEncoder; let _ffi_u8: Uint8Array; let _ffi_dv: DataView; const _ffi_Rc_Test = class Test implements Test { declare readonly _: number; constructor(_: number) { Object.defineProperty(this, "_", { value: _ }); _ffi_reg_Rc_Test.register(this, _); } get_string(): string { let multi_ret = _ffi_exports._ffi_Rc_Test__get_string(this._); let ret_ptr = _ffi_update_dv().getInt32(multi_ret, true); let ret_len = _ffi_dv.getUint32(multi_ret + 4, true); let ret_cap = _ffi_dv.getUint32(multi_ret + 8, true); return _ffi_string_from_rust(ret_ptr, ret_len, ret_cap); } set_string(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_string(this._, x_ptr, x_len); } set_str(x: string): void { let x_ptr = _ffi_string_to_rust(x), x_len = _ffi_len; _ffi_exports._ffi_Rc_Test__set_str(this._, x_ptr, x_len); } }; function _ffi_handle_alloc(obj: any): number { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } function _ffi_string_from_rust(ptr: number, len: number, cap: number): string { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } function _ffi_update_u8(): Uint8Array { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } function _ffi_string_to_rust(str: string): number { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } function _ffi_update_dv(): DataView { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } let _ffi_exports: { memory: WebAssembly.Memory, _ffi_Rc_Test__get_string: (_self: number) => number, _ffi_Rc_Test__set_str: (_self: number, x_ptr: number, x_len: number) => void, _ffi_Rc_Test__set_string: (_self: number, x_ptr: number, x_len: number) => void, _ffi_fn_get_test: () => number, _ffi_fn_rust_mem_leaked: () => number, _ffi_fn_set_test: (test_ptr: number) => number, _ffi_rs_drop_Rc_Test: (ptr: number) => void, _ffi_dealloc: (ptr: number, capacity: number) => void, _ffi_alloc: (len: number) => number, }; const _ffi_imports = { _ffi_js_Test__get_string(self: number, _ffi_ret_ptr_usize: number): void { let ret_ptr = _ffi_string_to_rust(_ffi_handles.get(self).get_string()), ret_len = _ffi_len; _ffi_update_dv().setInt32(_ffi_ret_ptr_usize, ret_ptr, true); _ffi_dv.setInt32(_ffi_ret_ptr_usize + 4, ret_len, true); }, _ffi_js_Test__set_str(self: number, x_ptr: number, x_len: number, x_cap: number): void { _ffi_handles.get(self).set_str(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_Test__set_string(self: number, x_ptr: number, x_len: number, x_cap: number): void { _ffi_handles.get(self).set_string(_ffi_string_from_rust(x_ptr, x_len, x_cap)); }, _ffi_js_drop(handle: number): void { _ffi_handles.delete(handle); }, }; ================================================ FILE: src/tests/snapshots/wasm_trait_string_2024/miniffi.rs ================================================ // This file was generated by miniffi v0.1.0. Do not edit. #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> *const _ffi_ret_ptr_2_usize { let _self = unsafe { &*(_self as *const std::rc::Rc) }; let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(_self.get_string()); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_str(&_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u8, x_len: usize) { let _self = unsafe { &*(_self as *const std::rc::Rc) }; _self.set_string(_ffi_string_from_host(x_ptr, x_len)); } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_get_test() -> *const u8 { Box::into_raw(Box::new(get_test())) as *const u8 } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_rust_mem_leaked() -> usize { rust_mem_leaked() } #[unsafe(no_mangle)] extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> *const _ffi_ret_ptr_2_usize { let (ret_ptr, ret_len, ret_cap) = _ffi_string_to_host(set_test(std::rc::Rc::new(_ffi_rs_Test(test_ptr)))); unsafe { _FFI_RET_PTR_2_USIZE = _ffi_ret_ptr_2_usize(ret_ptr, ret_len, ret_cap); std::ptr::addr_of!(_FFI_RET_PTR_2_USIZE) } } #[repr(C)] struct _ffi_ret_ptr_2_usize(*const u8, usize, usize); static mut _FFI_RET_PTR_2_USIZE: _ffi_ret_ptr_2_usize = _ffi_ret_ptr_2_usize(std::ptr::null(), 0, 0); #[repr(C)] struct _ffi_ret_ptr_usize(*const u8, usize); static mut _FFI_RET_PTR_USIZE: _ffi_ret_ptr_usize = _ffi_ret_ptr_usize(std::ptr::null(), 0); #[allow(non_camel_case_types)] struct _ffi_rs_Test(*const u8); impl Drop for _ffi_rs_Test { fn drop(&mut self) { unsafe extern "C" { fn _ffi_js_drop(_: *const u8); } unsafe { _ffi_js_drop(self.0) }; } } impl Test for _ffi_rs_Test { fn get_string(&self) -> String { unsafe extern "C" { fn _ffi_js_Test__get_string(_: *const u8, _: *const _ffi_ret_ptr_usize); } unsafe { _ffi_js_Test__get_string(self.0, std::ptr::addr_of!(_FFI_RET_PTR_USIZE)) } let ret_ptr = unsafe { _FFI_RET_PTR_USIZE.0 }; let ret_len = unsafe { _FFI_RET_PTR_USIZE.1 }; _ffi_string_from_host(ret_ptr, ret_len) } fn set_string(&self, x: String) { unsafe extern "C" { fn _ffi_js_Test__set_string(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x); unsafe { _ffi_js_Test__set_string(self.0, x_ptr, x_len, x_cap) }; } fn set_str(&self, x: &str) { unsafe extern "C" { fn _ffi_js_Test__set_str(_: *const u8, x_ptr: *const u8, x_len: usize, x_cap: usize); } let (x_ptr, x_len, x_cap) = _ffi_string_to_host(x.into()); unsafe { _ffi_js_Test__set_str(self.0, x_ptr, x_len, x_cap) }; } } #[unsafe(no_mangle)] extern "C" fn _ffi_rs_drop_Rc_Test(ptr: *const u8) { drop(unsafe { Box::from_raw(ptr as *mut std::rc::Rc) }); } #[unsafe(no_mangle)] extern "C" fn _ffi_alloc(len: usize) -> *const u8 { Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8 } fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String { unsafe { String::from_raw_parts(ptr as *mut u8, len, len) } } #[unsafe(no_mangle)] extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) { drop(unsafe { Vec::from_raw_parts(ptr, 0, capacity) }); } fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) { let buf = std::mem::ManuallyDrop::new(buf.into_bytes()); (buf.as_ptr(), buf.len(), buf.capacity()) } ================================================ FILE: src/tests/swift.rs ================================================ use super::*; use std::borrow::Cow; pub fn run_test(name: &str, case: &TestCase, edition: usize) { let name = Path::new(name).file_stem().unwrap(); let name = &format!("swift_{}_{edition}", name.to_string_lossy()); let test_dir = &Path::new(".temp").join(name); let src_dir = &test_dir.join("src"); std::fs::create_dir_all(src_dir).expect("failed to create directory `src`"); let TestCase { rust, swift_pre, swift_post, checks, .. } = case; let checks = checks.iter().map(to_str).collect::>().join("\n"); std::fs::write( src_dir.join("lib.rs"), format!( r#" #![deny(warnings)] {} {rust} include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); "#, rust_leak_check() ), ) .expect("failed to write file `src/lib.rs`"); std::fs::write( test_dir.join("build.rs"), format!( r#" fn main() {{ use miniffi::*; let mut result = SwiftTarget::new() .rust_edition({edition}) .write_swift_to("ffi.swift") .write_header_to("ffi.h") .build() .convert_warnings_to_errors(); result.finish(); for output in &result.output_files {{ if output.path.extension().unwrap() == "rs" {{ std::fs::copy(&output.path, "miniffi.rs").unwrap(); }} }} }} "# ), ) .expect("failed to write file `build.rs`"); std::fs::write( test_dir.join("Cargo.toml"), format!( r#" [package] name = "{name}" version = "0.1.0" edition = "{edition}" [lib] crate-type = ["staticlib"] [build-dependencies] miniffi = {{ path = "../.." }} "# ), ) .expect("failed to write file `Cargo.toml`"); std::fs::write( test_dir.join("main.swift"), format!( r#" extension DefaultStringInterpolation {{ mutating func appendInterpolation(_ x: T?) {{ appendInterpolation(String(describing: x)) }} }} {swift_pre} do {{ {checks} }} {swift_post} assert(rust_mem_leaked() == 0, "\(rust_mem_leaked()) bytes leaked") "# ), ) .expect("failed to write file `main.swift`"); cargo_build(test_dir, None); copy_snapshot(name, test_dir.join("miniffi.rs")); copy_snapshot(name, test_dir.join("ffi.swift")); copy_snapshot(name, test_dir.join("ffi.h")); check_output( Command::new("swiftc") .current_dir(test_dir) .arg("main.swift") .arg("ffi.swift") .args(["-import-objc-header", "ffi.h"]) .arg(format!("../target/debug/lib{name}.a")) .arg("-warnings-as-errors") .output() .expect("failed to run command `swiftc`"), ); check_output( Command::new("./main") .current_dir(test_dir) .env("RUST_BACKTRACE", "1") .output() .expect("failed to run command `./main`"), ); _ = std::fs::remove_dir_all(test_dir); } fn ty_to_str(ty: &ExprTy) -> String { match ty { TyBool => "Bool".to_string(), TyU8 => "UInt8".to_string(), TyU16 => "UInt16".to_string(), TyU32 => "UInt32".to_string(), TyUsize => "UInt".to_string(), TyU64 => "UInt64".to_string(), TyI8 => "Int8".to_string(), TyI16 => "Int16".to_string(), TyI32 => "Int32".to_string(), TyIsize => "Int".to_string(), TyI64 => "Int64".to_string(), TyF32 => "Float32".to_string(), TyF64 => "Float64".to_string(), TyString => "String".to_string(), TyTuple(x) => format!( "({})", x.iter().map(ty_to_str).collect::>().join(", ") ), TyOption(x) => format!("{}?", ty_to_str(x)), TyVec(x) => format!("[{}]", ty_to_str(x)), TyBox(x) => ty_to_str(x), TyName(x) => format!("{x}"), } } fn key_to_str(x: &'static str) -> Cow<'static, str> { match starts_with_digit(x) { false => Cow::Borrowed(x), true => Cow::Owned(format!("_{x}")), } } fn many_to_str(x: &[Expr]) -> String { x.iter().map(to_str).collect::>().join(", ") } fn to_str(expr: &Expr) -> String { match expr { Bool(x) => format!("{x}"), U8(x) => format!("UInt8({x})"), U16(x) => format!("UInt16({x})"), U32(x) => format!("UInt32({x})"), Usize(x) => format!("UInt({x})"), U64(x) => format!("UInt64({x})"), I8(x) => format!("Int8({x})"), I16(x) => format!("Int16({x})"), I32(x) => format!("Int32({x})"), Isize(x) => format!("Int({x})"), I64(x) => format!("Int64({x})"), F32(x) => format!("Float32({x:?})"), F64(x) => format!("Float64({x:?})"), Str(x) => format!("{x:?}"), Export(x) => format!("{x}"), Enum(x, y) => format!("{x}.{y}"), EnumPayload(x, y, z) if z.is_empty() => format!("{x}.{y}"), EnumPayload(x, y, z) => format!( "{x}.{y}({})", z.iter() .map(|(k, v)| match starts_with_digit(k) { false => format!("{}: {}", key_to_str(k), to_str(v)), true => to_str(v), }) .collect::>() .join(", ") ), DeclareMutableLocal(x, y) => format!("var {x} = {}", to_str(y)), DeclareImmutableLocal(x, y) => format!("let {x} = {}", to_str(y)), LoadLocal(x) => format!("{x}"), StoreLocal(x, y) => format!("{x} = {}", to_str(y)), NewBox(_, x, y) | NewRc(_, x, y) => format!("{x}({})", many_to_str(y)), Tuple(x) => format!("({})", many_to_str(x)), Vector(x) => format!("[{}]", many_to_str(x)), EmptyVector(_) => "[]".to_string(), Struct(x, y) => format!( "{x}({})", y.iter() .map(|(k, v)| format!("{}: {}", key_to_str(k), to_str(v))) .collect::>() .join(", ") ), AssertEqual(x, y) => match &**y { F32(y) if *y == 0.0 => { let sign = if y.is_sign_negative() { "minus" } else { "plus" }; format!( r#"do {{ let left = {} assert(left == 0.0 && left.sign == .{sign}, "\(left) == {y:?}") }}"#, to_str(x) ) } F64(y) if *y == 0.0 => { let sign = if y.is_sign_negative() { "minus" } else { "plus" }; format!( r#"do {{ let left = {} assert(left == 0.0 && left.sign == .{sign}, "\(left) == {y:?}") }}"#, to_str(x) ) } _ => { let ty = match (&**x, &**y) { // Avoid "constant inferred to have type '()', which may be unexpected" (Tuple(z), _) | (_, Tuple(z)) if z.is_empty() => ": ()", _ => "", }; format!( r#"do {{ let left{ty} = {} let right{ty} = {} assert(left == right, "\(left) == \(right)") }}"#, to_str(x), to_str(y) ) } }, AssertNotEqual(x, y) => match &**y { F32(y) if *y == 0.0 => { let sign = if y.is_sign_negative() { "minus" } else { "plus" }; format!( r#"do {{ let left = {} assert(left != 0.0 || left.sign != .{sign}, "\(left) != {y:?}") }}"#, to_str(x) ) } F64(y) if *y == 0.0 => { let sign = if y.is_sign_negative() { "minus" } else { "plus" }; format!( r#"do {{ let left = {} assert(left != 0.0 || left.sign == .{sign}, "\(left) != {y:?}") }}"#, to_str(x) ) } _ => { let ty = match (&**x, &**y) { // Avoid "constant inferred to have type '()', which may be unexpected" (Tuple(z), _) | (_, Tuple(z)) if z.is_empty() => ": ()", _ => "", }; format!( r#"do {{ let left{ty} = {} let right{ty} = {} assert(left != right, "\(left) != \(right)") }}"#, to_str(x), to_str(y) ) } }, StrConcat(x, y) => format!("({}) + ({})", to_str(x), to_str(y)), Call(x, y) => format!("{}({})", to_str(x), many_to_str(y)), CallMethod(x, y, z) => format!("({}).{y}({})", to_str(x), many_to_str(z)), TupleMember(x, y) => format!("({}).{y}", to_str(x)), StructMember(x, y) => format!("({}).{y}", to_str(x)), VectorMember(x, y) => format!("({})[{y}]", to_str(x)), VectorLen(x) => format!("UInt(({}).count)", to_str(x)), AfterGC(x) => to_str(x), OptNone(x) => format!("Optional<{}>.none", ty_to_str(x)), OptSome(x) => format!("Optional.some({})", to_str(x)), Boxed(_, x) => to_str(x), } } ================================================ FILE: src/tests/warnings.rs ================================================ use super::*; #[test] fn syntax_error() { check_warnings( " fn main() { this is a syntax error } ", &["{MESSAGE} --> src/lib.rs:3:18 | 3 | this is a syntax error | ^^ "], ); } #[test] fn unsupported_variant_discriminant() { check_warnings( r#" pub enum Foo { A, B = 123, C = include!("./foo.txt"), } "#, &[ r#"unsupported discriminant `include!("./foo.txt")` for variant `C` in enum `Foo` --> src/lib.rs:5:17 | 5 | C = include!("./foo.txt"), | ^^^^^^^^^^^^^^^^^^^^^ must be an integer literal "#, ], ); } #[test] fn unsupported_constant_type() { check_warnings( " pub const FOO: i128 = 0; ", &["unsupported type `i128` for constant `FOO` --> src/lib.rs:2:24 | 2 | pub const FOO: i128 = 0; | ^^^^ "], ); } #[test] fn unsupported_constant_value() { check_warnings( " pub const FOO: bool = cfg!(unix); ", &["unsupported value `cfg!(unix)` for constant `FOO` --> src/lib.rs:2:31 | 2 | pub const FOO: bool = cfg!(unix); | ^^^^^^^^^^ only literals are supported "], ); } #[test] fn unsupported_trait_item() { check_warnings( r" pub trait Foo { type Bar = Foo; } ", &[r"unsupported item `type Bar = Foo;` for trait `Foo` --> src/lib.rs:3:13 | 3 | type Bar = Foo; | ^^^^^^^^^^^^^^^ only functions are supported "], ); } #[test] fn unsupported_field_type() { check_warnings( " pub struct Foo(i128); pub struct Bar { x: i128 } pub enum A { Foo(i128) } pub enum B { Bar { x: i128 } } ", &[ "unsupported type `i128` for field `0` in struct `Foo` --> src/lib.rs:2:24 | 2 | pub struct Foo(i128); | ^^^^ ", "unsupported type `i128` for field `x` in struct `Bar` --> src/lib.rs:3:29 | 3 | pub struct Bar { x: i128 } | ^^^^ ", "unsupported type `i128` for field `0` in variant `A::Foo` --> src/lib.rs:4:26 | 4 | pub enum A { Foo(i128) } | ^^^^ ", "unsupported type `i128` for field `x` in variant `B::Bar` --> src/lib.rs:5:31 | 5 | pub enum B { Bar { x: i128 } } | ^^^^ ", ], ); } #[test] fn unsupported_fn_arg_pattern() { check_warnings( " pub fn foo((x, y): (i32, i32)) {} ", &["unsupported pattern `(x, y)` for function `foo` --> src/lib.rs:2:20 | 2 | pub fn foo((x, y): (i32, i32)) {} | ^^^^^^ only identifiers are supported "], ); } #[test] fn unsupported_fn_arg_type() { check_warnings( " pub fn foo(x: i128) {} ", &["unsupported type `i128` for argument `x` --> src/lib.rs:2:23 | 2 | pub fn foo(x: i128) {} | ^^^^ "], ); } #[test] fn unsupported_fn_return_type() { check_warnings( " pub fn foo() -> i128 { 0 } ", &["unsupported return type `i128` for function `foo` --> src/lib.rs:2:25 | 2 | pub fn foo() -> i128 { 0 } | ^^^^ "], ); } #[test] fn unsupported_fn_receiver() { check_warnings( " pub trait ByVal { fn foo(self, x: i32); } pub trait ByMutRef { fn foo(&mut self, x: i32); } pub trait ByBox { fn foo(self: &Box, x: i32); } pub trait NoReceiver { fn foo(x: i32); } pub fn foo(&self, x: i32) {} ", &[ "unsupported receiver `self` for argument `foo` in trait `ByVal` --> src/lib.rs:3:20 | 3 | fn foo(self, x: i32); | ^^^^ use `&self` instead ", "unsupported receiver `&mut self` for argument `foo` in trait `ByMutRef` --> src/lib.rs:6:20 | 6 | fn foo(&mut self, x: i32); | ^^^^^^^^^ use `&self` instead ", "unsupported receiver `self: &Box` for argument `foo` in trait `ByBox` --> src/lib.rs:9:20 | 9 | fn foo(self: &Box, x: i32); | ^^^^^^^^^^^^^^^^ use `&self` instead ", "unsupported function `foo` for trait `NoReceiver` --> src/lib.rs:12:16 | 12 | fn foo(x: i32); | ^^^ methods on public traits must use `&self` ", "unsupported argument `self` for function `foo` --> src/lib.rs:14:21 | 14 | pub fn foo(&self, x: i32) {} | ^^^^ ", ], ); } fn check_warnings(contents: &str, expected_warnings: &[&str]) { #[derive(Eq, PartialEq)] struct Wrapper(String); impl std::fmt::Debug for Wrapper { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("\n{}", self.0)) } } let suffix = r#"include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));"#; let input_file = FileData { path: "src/lib.rs".parse().unwrap(), contents: format!("{contents}{suffix}"), }; let result = NullTarget::new().build_custom(input_file, "miniffi.rs".parse().unwrap()); assert_eq!(result.errors, Vec::::new()); assert_eq!( result .warnings .iter() .map(|w| Wrapper(w.to_human_string())) .collect::>(), expected_warnings .iter() .enumerate() .map(|(i, w)| { // Be robust to different versions of the "syn" crate returning different errors if w.contains("{MESSAGE}") && result.warnings.len() == expected_warnings.len() { Wrapper(w.replace("{MESSAGE}", &result.warnings[i].message)) } else { Wrapper(w.to_string()) } }) .collect::>() ); } ================================================ FILE: src/tests/wasm.rs ================================================ use super::*; pub fn run_test(name: &str, case: &TestCase, edition: usize) { let name = Path::new(name).file_stem().unwrap(); let name = &format!("wasm_{}_{edition}", name.to_string_lossy()); let test_dir = &std::env::current_dir().unwrap().join(".temp").join(name); let src_dir = &test_dir.join("src"); let pkg_json_dir = &test_dir.join(".."); let tsc_path = &pkg_json_dir .join("node_modules") .join("typescript") .join("lib") .join("tsc.js"); std::fs::create_dir_all(src_dir).expect("failed to create directory `src`"); let TestCase { rust, js_pre, js_post, checks, .. } = case; let checks = checks.iter().map(to_str).collect::>().join(";\n"); // Install TypeScript for type checking if !tsc_path.exists() { std::fs::write(pkg_json_dir.join("package.json"), "{}") .expect("failed to write file `package.json`"); check_output( Command::new("npm") .current_dir(pkg_json_dir) .arg("i") .arg("typescript@5.9.2") .output() .expect("failed to run command `npm`"), ); } std::fs::write( src_dir.join("lib.rs"), format!( r#" #![deny(warnings)] {} {rust} include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); "#, rust_leak_check() ), ) .expect("failed to create file `src/lib.rs`"); std::fs::write( test_dir.join("build.rs"), format!( r#" fn main() {{ use miniffi::*; let mut result = WasmTarget::new() .rust_edition({edition}) .write_js_to("ffi.mjs") .write_ts_to("ffi.mts") .write_d_ts_to("ffi.d.mts") .build() .convert_warnings_to_errors(); result.finish(); for output in &result.output_files {{ if output.path.extension().unwrap() == "rs" {{ std::fs::copy(&output.path, "miniffi.rs").unwrap(); }} }} }} "# ), ) .expect("failed to create file `build.rs`"); std::fs::write( test_dir.join("Cargo.toml"), format!( r#" [package] name = "{name}" version = "0.1.0" edition = "{edition}" [lib] crate-type = ["cdylib"] [build-dependencies] miniffi = {{ path = "../.." }} "# ), ) .expect("failed to create file `Cargo.toml`"); std::fs::write( test_dir.join("test.mjs"), format!( r#" import * as assert from "assert"; import * as fs from "fs"; import * as ffi from "./ffi.mjs"; Error.stackTraceLimit = Infinity; await ffi.instantiate(fs.readFileSync( "../target/wasm32-unknown-unknown/debug/{name}.wasm")); {js_pre} // Use a function wrapper to allow for garbage collection async function __TEST_MAIN__() {{ {checks} }} await __TEST_MAIN__(); {js_post} if (globalThis.gc) {{ globalThis.gc() await new Promise(r => setTimeout(r, 100)) // Try to run finalizers assert.deepStrictEqual(ffi.rust_mem_leaked(), 0, ffi.rust_mem_leaked() + " bytes leaked"); }} "# ), ) .expect("failed to create file `test.mjs`"); std::fs::write( test_dir.join("tsconfig.json"), r#"{ "compilerOptions": { "target": "ESNext", "module": "ESNext", "strict": true, }, }"#, ) .expect("failed to create file `tsconfig.json`"); cargo_build(test_dir, Some("wasm32-unknown-unknown")); copy_snapshot(name, test_dir.join("miniffi.rs")); copy_snapshot(name, test_dir.join("ffi.mjs")); copy_snapshot(name, test_dir.join("ffi.mts")); copy_snapshot(name, test_dir.join("ffi.d.mts")); // Run the JavaScript code check_output( Command::new("node") .current_dir(test_dir) .env("FORCE_COLOR", "1") .arg("--expose-gc") .arg("test.mjs") .output() .unwrap(), ); // Check for TypeScript errors check_output( Command::new("node") .current_dir(test_dir) .arg(tsc_path) .arg("-noEmit") .args(["-p", "tsconfig.json"]) .output() .unwrap(), ); _ = std::fs::remove_dir_all(test_dir); } fn to_str(expr: &Expr) -> String { fn many_to_str(x: &[Expr]) -> String { x.iter().map(to_str).collect::>().join(", ") } match expr { Bool(x) => format!("{x}"), U8(x) => format!("{x}"), U16(x) => format!("{x}"), U32(x) => format!("{x}"), Usize(x) => format!("{x}"), U64(x) => format!("{x}n"), I8(x) => format!("{x}"), I16(x) => format!("{x}"), I32(x) => format!("{x}"), Isize(x) => format!("{x}"), I64(x) => format!("{x}n"), F32(x) => format!("{}", *x as f64), F64(x) => format!("{x}"), Str(x) => format!("{x:?}"), Export(x) => format!("ffi.{x}"), Enum(x, y) => format!("ffi.{x}.{y}"), EnumPayload(_, x, y) => format!( "{{ $: {x:?}{} }}", y.iter() .map(|(k, v)| format!(", {k}: {}", to_str(v))) .collect::>() .join("") ), DeclareMutableLocal(x, y) => format!("let {x} = {}", to_str(y)), DeclareImmutableLocal(x, y) => format!("const {x} = {}", to_str(y)), LoadLocal(x) => format!("{x}"), StoreLocal(x, y) => format!("{x} = {}", to_str(y)), NewBox(_, x, y) | NewRc(_, x, y) => format!("new {x}({})", many_to_str(y)), Tuple(x) if x.is_empty() => "undefined".to_string(), Tuple(x) | Vector(x) => format!("[{}]", many_to_str(x)), EmptyVector(_) => "[]".to_string(), Struct(_, x) => format!( "{{{}}}", x.iter() .map(|(k, v)| format!("{k}: {}", to_str(v))) .collect::>() .join(", ") ), AssertEqual(x, y) => match &**y { F32(y) if *y == 0.0 => { format!("assert.default(Object.is({}, {y}))", to_str(x)) } F64(y) if *y == 0.0 => { format!("assert.default(Object.is({}, {y}))", to_str(x)) } _ => { format!("assert.deepStrictEqual({}, {})", to_str(x), to_str(y)) } }, AssertNotEqual(x, y) => match &**y { F32(y) if *y == 0.0 => { format!("assert.default(!Object.is({}, {y}))", to_str(x)) } F64(y) if *y == 0.0 => { format!("assert.default(!Object.is({}, {y}))", to_str(x)) } _ => { format!("assert.notDeepStrictEqual({}, {})", to_str(x), to_str(y)) } }, StrConcat(x, y) => format!("({}) + ({})", to_str(x), to_str(y)), Call(x, y) => format!("{}({})", to_str(x), many_to_str(y)), CallMethod(x, y, z) => { format!("({}).{y}({})", to_str(x), many_to_str(z)) } TupleMember(x, y) => format!("({})[{y}]", to_str(x)), StructMember(x, y) => format!("({}).{y}", to_str(x)), VectorMember(x, y) => format!("({})[{y}]", to_str(x)), VectorLen(x) => format!("({}).length", to_str(x)), AfterGC(x) => format!( " if (globalThis.gc) {{ globalThis.gc() await new Promise(r => setTimeout(r, 100)) // Try to run finalizers {} }} ", to_str(x) ), OptNone(_) => "null".into(), OptSome(x) => to_str(x), Boxed(_, x) => to_str(x), } } ================================================ FILE: src/util.rs ================================================ use super::*; use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::hash::Hash; use std::path::{Path, PathBuf}; use std::rc::Rc; #[derive(Clone, Default)] pub struct NameSet { used: HashSet, } impl NameSet { pub fn contains(&self, name: &str) -> bool { self.used.contains(name) } pub fn find(&self, base: &str) -> String { let mut name = base.to_string(); let mut tries = match name.as_str() { "_" => 0, _ => 1, }; while self.used.contains(&name) { tries += 1; name = format!("{base}{tries}"); } name } pub fn add(&mut self, name: String) { self.used.insert(name); } pub fn create(&mut self, base: &str) -> String { let name = self.find(base); self.add(name.clone()); name } } #[derive(Default)] struct HelperFlags { is_used: bool, is_forward_decl: bool, } pub struct Helper { code: T, deps: Vec<(G, String)>, forward_decls: Vec<(G, String)>, flags: RefCell, } impl Helper { pub fn add_dep_group(&mut self, group: G, name: &str) -> &mut Self { self.deps.push((group, name.into())); self } pub fn add_deps_group(&mut self, deps: HashSet<(G, String)>) -> &mut Self { let mut deps: Vec<_> = deps.into_iter().collect(); deps.sort(); self.deps.extend(deps.into_iter()); self } pub fn add_forward_decl_group(&mut self, group: G, name: &str) -> &mut Self { self.forward_decls.push((group, name.into())); self } pub fn mark_used(&self) { self.flags.borrow_mut().is_used = true; } pub fn set_is_forward_decl(&self) { self.flags.borrow_mut().is_forward_decl = true; } } impl Helper<(), T> { pub fn add_dep(&mut self, name: &str) -> &mut Self { self.deps.push(((), name.into())); self } } pub struct HelperSet { map: HashMap<(G, String), Helper>, } impl Default for HelperSet { fn default() -> HelperSet { HelperSet { map: HashMap::new(), } } } impl HelperSet { pub fn was_added(&self, group: G, key: &str) -> bool { self.map.contains_key(&(group, key.into())) } pub fn add_group>(&mut self, group: G, name: &str, code: I) -> &mut Helper { let key = (group, name.to_string()); debug_assert!( !self.map.contains_key(&key), "{name:?} was added to group \"{group:?}\" more than once" ); self.map.entry(key).or_insert(Helper { code: code.into(), deps: Vec::new(), forward_decls: Vec::new(), flags: HelperFlags::default().into(), }) } pub fn mark_used_group(&mut self, group: G, name: &str) { get_key_in_map(&(group, name.into()), &self.map).mark_used(); } pub fn mark_all_used_group(&mut self, all: HashSet<(G, String)>) { for key in all { get_key_in_map(&key, &self.map).mark_used(); } } pub fn code_by_group_in_order(&self) -> HashMap> { enum VisitStatus { Visiting, Visited, } // Sort dependencies before dependents in case that matters fn visit<'a, G: Copy + Debug + Eq + Hash + Ord, T>( key: &'a (G, String), map: &'a HashMap<(G, String), Helper>, result: &mut HashMap>, visits: &mut HashMap<&'a (G, String), VisitStatus>, ) { let helper = get_key_in_map(key, map); match visits.get(key) { Some(VisitStatus::Visited) => {} Some(VisitStatus::Visiting) => { // Insert forward declarations as needed for C++ for dep in &helper.forward_decls { visit(dep, map, result, visits); } } None => { visits.insert(key, VisitStatus::Visiting); for dep in &helper.deps { visit(dep, map, result, visits); } result .entry(key.0) .or_default() .push(&map.get(key).unwrap().code); visits.insert(key, VisitStatus::Visited); } } } let mut result = HashMap::new(); let mut visits = HashMap::new(); let mut keys: Vec<_> = self.map.keys().collect(); keys.sort(); for key in keys { if self.map.get(key).unwrap().flags.borrow().is_used { visit(key, &self.map, &mut result, &mut visits); } } result } } impl HelperSet<(), T> { pub fn add>(&mut self, name: &str, code: I) -> &mut Helper<(), T> { self.add_group((), name, code) } pub fn mark_used(&mut self, name: &str) { self.mark_used_group((), name); } pub fn code_in_order(&self) -> Vec<&T> { self.code_by_group_in_order() .into_iter() .next() .unwrap_or_else(|| ((), Vec::new())) .1 } } fn get_key_in_map<'a, G: Copy + Debug + Eq + Hash + Ord, T>( key: &(G, String), map: &'a HashMap<(G, String), Helper>, ) -> &'a Helper { debug_assert!( map.contains_key(key), "missing helper named {:?} in group \"{:?}\"", key.1, key.0 ); map.get(&key).unwrap() } // This is sort of like a language-agnostic AST (Abstract Syntax Tree). It lets // us emit variable declarations in the "FnBuilder" and then optionally inline // them into one or more of the following lines later on. For example, consider // the following code: // // let x = 1; // let y = 2; // let z = foo(x, y); // return z; // // That would be represented like this: // // Decl("x", "1"), // Decl("y", "2"), // Decl("z", "foo(x, y)"), // Line("return z;"), // // When the code constructing each "Line" uses "RefInline", the result will // become this (which is more concise and often easier to read): // // return foo(1, 2); // // However, if some other code inserts something in the middle, then the sub- // expressions will naturally be broken out into separate variable declarations. // Consider something that needs to call "cleanup()" before returning: // // Decl("x", "1"), // Decl("y", "2"), // Decl("z", "foo(x, y)"), // Line("cleanup();"), // Line("return z;"), // // Then when the code constructing each "Line" uses "RefInline", the result // will become this instead: // // let z = foo(1, 2); // cleanup(); // return z; // #[derive(Eq, PartialEq)] pub enum Line { Plain(String), // Two alternative lines (first when false, second when true) PlainAlt(String, String, Rc>), // Local declaration with an optional type annotation Decl(String, Option, String), } pub struct Decl { pub code: String, pub pure: bool, } pub use RefKind::*; #[derive(Clone, Copy, Eq, PartialEq)] pub enum RefKind { // This should always be safe. Use this when a value may be used multiple // times. We can't inline the value into every use because that may have // side effects. RefMany, // Only use this when values are guaranteed to be used once in declaration // order. For example, this should not be used in C++ when there are // multiple sibling sub-expressions because C++ doesn't specify the // evaluation order of sub-expressions in a function call. RefInline, // C++ needs "std::move()" to handle non-copyable lvalues such as a local // variable holding a "std::unique_ptr". RefStdMove, } #[derive(Default)] pub struct FnBuilder { lines: Vec, deferred_lines: Vec, // Deferred lines go at the end of the function pure: HashMap, } impl FnBuilder { pub fn is_empty(&self) -> bool { self.lines.is_empty() && self.deferred_lines.is_empty() } pub fn take_lines(&mut self) -> Vec { self.lines.append(&mut self.deferred_lines); self.lines.drain(..).collect() } pub fn extend(&mut self, other: FnBuilder) { self.lines.extend(other.lines); self.deferred_lines.extend(other.deferred_lines); self.pure.extend(other.pure); } pub fn insert_deferred_lines_here(&mut self) { self.lines.append(&mut self.deferred_lines); } // Here "pure" means "can be duplicated, reordered, and/or removed" (e.g. a field access) pub fn mark_pure(&mut self, name: &str) { self.pure.insert(name.to_string(), name.to_string()); } pub fn line(&mut self, text: String) { self.lines.push(Line::Plain(text)); } pub fn line_alt(&mut self, when_false: String, when_true: String, flag: Rc>) { self.lines.push(Line::PlainAlt(when_false, when_true, flag)); } pub fn decl>(&mut self, name: T, text: String) { self.lines.push(Line::Decl(name.into(), None, text)); } pub fn decl_ty>(&mut self, name: T, ty: RustType, text: String) { self.lines.push(Line::Decl(name.into(), Some(ty), text)); } pub fn pure_decl>(&mut self, name: T, text: String) { self.pure.insert(name.into(), text); } pub fn maybe_pure_decl>(&mut self, pure: bool, name: T, text: String) { if pure { self.pure_decl(name, text); } else { self.decl(name, text); } } pub fn defer_line(&mut self, text: String) { self.deferred_lines.push(Line::Plain(text)); } pub fn defer_decl>(&mut self, name: T, text: String) { self.deferred_lines .push(Line::Decl(name.into(), None, text)); } pub fn pop_line_if bool>(&mut self, predicate: F) -> Option { if predicate(self.lines.last_mut()?) { self.lines.pop() } else { None } } pub fn find(&mut self, name: &str, ty: &RustType, kind: RefKind) -> Decl { if let Some(code) = self.pure.get(name) { // This is an lvalue let code = if kind == RefStdMove && needs_std_move(ty) { format!("std::move({code})") } else { code.clone() }; return Decl { code, pure: true }; } if kind == RefInline { if let Some(Line::Decl(last_name, _, last_code)) = self.lines.last() { if last_name == name { // This is an rvalue let code = last_code.to_string(); self.lines.pop(); return Decl { code, pure: false }; } } } // This is an lvalue let code = if kind == RefStdMove && needs_std_move(ty) { format!("std::move({name})") } else { name.to_string() }; Decl { code, pure: false } } pub fn find_args(&mut self, args: &Vec, kind: RefKind) -> String { // Inline is ok if there's only one sub-expression let kind = if kind == RefMany && args.len() == 1 { RefInline } else { kind }; // Inline in reverse so we pop the stack of args that were pushed earlier let mut parts = Vec::new(); for arg in args.iter().rev() { parts.push(self.find(&arg.name, &arg.ty, kind).code); } parts.reverse(); // Split up long multi-argument lists across multiple lines if parts.len() > 1 { maybe_split_across_lines(&parts, "", "") } else { parts.join(", ") } } pub fn find_fields( &mut self, fields: &Vec, names: Vec>, kind: RefKind, open: &str, close: &str, ) -> String { debug_assert_eq!(fields.len(), names.len()); // Inline is ok if there's only one sub-expression let kind = if kind == RefMany && names.len() == 1 { RefInline } else { kind }; // Inline in reverse so we pop the stack of args that were pushed earlier let mut parts = Vec::new(); for (f, name) in fields.iter().rev().zip(names.iter().rev()) { let code = self.find(name, &f.ty, kind).code; parts.push(match f.name.as_str() { "" => code, _ => format!("{}: {}", f.name, code), }); } parts.reverse(); // Split up long lists of fields across multiple lines maybe_split_across_lines(&parts, open, close) } } fn maybe_split_across_lines(parts: &[String], mut open: &str, mut close: &str) -> String { let is_multi_line = parts.iter().any(|x| x.contains('\n')) || parts.iter().map(|x| x.len()).sum::() > 100; if is_multi_line { open = open.trim_end(); close = close.trim_start(); } let mut result: String = open.into(); for (i, part) in parts.iter().enumerate() { result.push_str(match (is_multi_line, i > 0) { (false, false) => "", (false, true) => ", ", (true, false) => "\n", (true, true) => ",\n", }); result.push_str(part); } if is_multi_line { result.push_str("\n"); } result.push_str(close); result } fn needs_std_move(ty: &RustType) -> bool { use RustType::*; match ty { Pair { other, .. } => needs_std_move(other), Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => false, _ => true, } } // This is a copy of an old "Path" method in the Rust standard library that was // never stabilized. It's copied here because there still isn't a way in Rust's // standard library to compute the relative path between two paths. pub fn path_relative_from(path: &Path, base: &Path) -> Option { use std::path::Component; if path.is_absolute() != base.is_absolute() { if path.is_absolute() { Some(PathBuf::from(path)) } else { None } } else { let mut ita = path.components(); let mut itb = base.components(); let mut comps: Vec = vec![]; loop { match (ita.next(), itb.next()) { (None, None) => break, (Some(a), None) => { comps.push(a); comps.extend(ita.by_ref()); break; } (None, _) => comps.push(Component::ParentDir), (Some(a), Some(b)) if comps.is_empty() && a == b => (), (Some(a), Some(b)) if b == Component::CurDir => comps.push(a), (Some(_), Some(b)) if b == Component::ParentDir => return None, (Some(a), Some(_)) => { comps.push(Component::ParentDir); for _ in itb { comps.push(Component::ParentDir); } comps.push(a); comps.extend(ita.by_ref()); break; } } } Some(comps.iter().map(|c| c.as_os_str()).collect()) } } pub struct SharedBuf { buf_name: String, end_name: String, is_buf_name_used: Rc>, is_end_name_used: Rc>, } impl SharedBuf { pub fn new(buf_name: &str, end_name: &str) -> Rc { Rc::new(SharedBuf { buf_name: buf_name.to_string(), end_name: end_name.to_string(), is_buf_name_used: Rc::new(Cell::new(false)), is_end_name_used: Rc::new(Cell::new(false)), }) } pub fn buf_name(&self) -> &str { self.is_buf_name_used.set(true); &self.buf_name } pub fn end_name(&self) -> &str { self.is_end_name_used.set(true); &self.end_name } pub fn is_buf_name_used_flag(&self) -> Rc> { self.is_buf_name_used.clone() } pub fn is_end_name_used_flag(&self) -> Rc> { self.is_end_name_used.clone() } pub fn final_buf_name_for_rust(&self) -> &str { match self.is_buf_name_used.get() { false => "_", // Rust uses "_" to disable unused variable warnings true => &self.buf_name, } } pub fn final_end_name_for_rust(&self) -> &str { match self.is_end_name_used.get() { false => "_", // Rust uses "_" to disable unused variable warnings true => &self.end_name, } } } #[derive(Clone, Copy, Default, Eq, PartialEq)] pub enum BufStatus { #[default] Outside, Inside, } pub fn starts_with_digit(name: &str) -> bool { name.chars().next().unwrap().is_ascii_digit() } pub fn with_digit_prefix(name: &str) -> Cow<'_, str> { if starts_with_digit(name) { Cow::Owned(format!("_{name}")) } else { Cow::Borrowed(name) } } pub fn name_for_match(name: &str, count: usize) -> Cow<'_, str> { match starts_with_digit(name) { false => Cow::Borrowed(name), true if count == 1 => Cow::Borrowed("x"), true => Cow::Owned(format!("x{}", name)), } } ================================================ FILE: src/wasm.rs ================================================ use super::*; use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::rc::Rc; /// Use this target when the host language is JavaScript or TypeScript. /// /// This can either generate a `.js` file or a `.ts` file depending on how you /// want to import the API. If you're using a `.js` file, you may also want to /// generate a `.d.ts` file to improve type checking in your IDE. If no file is /// explicitly requested, a file named `miniffi.js` will be written to the /// directory containing your `Cargo.toml` file. You can customize these paths /// before calling [`build`](Target::build): /// /// ```no_run /// use miniffi::*; /// /// fn main() { /// if true { /// // You probably either want both `.js` and `.d.ts`: /// WasmTarget::new() /// .write_js_to("../app/rust.js") /// .write_d_ts_to("../app/rust.d.ts") /// .build(); /// } else { /// // Or just a `.ts`: /// WasmTarget::new() /// .write_ts_to("../app/rust.ts") /// .build(); /// } /// } /// ``` /// /// If your `src/lib.rs` looks like this: /// /// ```no_run /// pub fn add(left: u32, right: u32) -> u32 { /// left + right /// } /// /// # macro_rules! env { ($a:expr) => { $a } } /// # macro_rules! include { ($a:expr) => { $a } } /// include!(concat!(env!("OUT_DIR"), "/miniffi.rs")); /// ``` /// /// You can call that from JavaScript like this: /// /// ```text /// import * as rust from "./miniffi.js" /// /// // First instantiate the WASM module /// await rust.instantiate(...) // See below /// /// // Then call your Rust code /// console.log("1 + 2 =", rust.add(1, 2)) /// ``` /// /// One way to build your Rust code into a `.wasm` module is to use the /// `cdylib` crate type and the `wasm32-unknown-unknown` cargo target. That can /// be done from the command line like this: /// /// ```text /// cargo rustc --crate-type=cdylib --target=wasm32-unknown-unknown /// ``` /// /// Instantiating a `.wasm` module may need to work differently depending on /// the JavaScript environment, so miniffi doesn't attempt to do it for you. /// How you do it depends on whether you are using node or the browser. /// /// ## Using from node /// /// If you're using JavaScript in node, you'll have to load the `.wasm` module /// using node's file system APIs and call `instantiate`. That might look /// like this: /// /// ```js /// import * as rust from "./miniffi.js" /// import fs from "fs" /// /// // First instantiate the WASM module /// await rust.instantiate(fs.readFileSync( /// "./target/wasm32-unknown-unknown/debug/example.wasm")) /// /// // Then call your Rust code /// console.log("1 + 2 =", rust.add(1, 2)) /// ``` /// /// The `instantiate` function exported by the FFI bindings deliberately /// mirrors the standard [`WebAssembly.instantiate`][WASM_instantiate] API. /// However, it's important to use the exported `instantiate` function as it /// imports additional JavaScript helper code related to the FFI bindings. /// /// [WASM_instantiate]: https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/instantiate_static /// /// ## Using from the browser /// /// If you're using JavaScript in the browser, you'll have to download the /// `.wasm` module from the server and call `instantiateStreaming`. That /// might look like this: /// /// ```html /// /// ``` /// /// The `instantiateStreaming` function exported by the FFI bindings /// deliberately mirrors the standard /// [`WebAssembly.instantiateStreaming`][WASM_instantiateStreaming] API. /// However, it's important to use the exported `instantiateStreaming` function /// as it imports additional JavaScript helper code related to the FFI bindings. /// /// Also note that the `.wasm` file must be served using a MIME type of /// `application/wasm` by the server or the browser won't compile it. /// /// [WASM_instantiateStreaming]: https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/instantiateStreaming_static /// /// ## Additional notes /// /// The generated WebAssembly code is written assuming a single-threaded /// environment, which is normally the case when using WebAssembly. Specifically /// mutable global variables may be used to pass data across the FFI boundary to /// avoid allocation overhead. This is different than miniffi's other targets, /// which allocate temporary buffers for this instead since they need to work in /// a multi-threaded environment. pub struct WasmTarget { common_options: CommonOptions, js_path: Option, ts_path: Option, d_ts_path: Option, set_panic_hook: bool, } impl WasmTarget { pub fn new() -> WasmTarget { WasmTarget { common_options: CommonOptions::default(), js_path: None, ts_path: None, d_ts_path: None, set_panic_hook: false, } } pub fn write_js_to>(mut self, path: T) -> Self { self.js_path = Some(path.into()); self } pub fn write_ts_to>(mut self, path: T) -> Self { self.ts_path = Some(path.into()); self } pub fn write_d_ts_to>(mut self, path: T) -> Self { self.d_ts_path = Some(path.into()); self } /// Unfortunately Rust's standard library unconditionally deletes all code /// that writes to stdout and stderr when building for `wasm32`, which can /// make debugging difficult. One difficulty is that panics in Rust will no /// longer print any useful error message. Luckily Rust's panic feature can /// be customized with [`std::panic::set_hook`], so panic support can be /// added back. /// /// Call this to generate an appropriate panic hook and automatically /// register it when the WASM module is instantiated. /// /// Note that this will throw a JavaScript `Error` object, which will unwind /// the stack without Rust being able to catch it using /// [`std::panic::catch_unwind`]. However, Rust compiles `panic!()` to /// abort when building for `wasm32` anyway, so `catch_unwind` already /// doesn't work regardless of whatever this custom panic hook does. pub fn set_panic_hook(mut self) -> Self { self.set_panic_hook = true; self } } pub const JS_KEYWORDS: &[&str] = &[ "abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "undefined", "var", "void", "volatile", "while", "with", "yield", ]; #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] enum JsGroup { Let, Imports, Exports, Other, } impl Compile for WasmTarget { fn common_options(&mut self) -> &mut CommonOptions { &mut self.common_options } fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec { let syntax = RustSyntax::with_edition(self.common_options.edition); let mut js_helpers = HelperSet::::default(); let mut rust_helpers = HelperSet::<(), String>::default(); add_common_rust_helpers(&syntax, &mut rust_helpers); ast.rename_keywords(JS_KEYWORDS); js_helpers.add_group( JsGroup::Exports, "_ffi_alloc", JsString::from_template("« _ffi_alloc: (len: number) => number,\n»"), ); js_helpers.add_group( JsGroup::Exports, "_ffi_dealloc", JsString::from_template( "« _ffi_dealloc: (ptr: number, capacity: number) => void,\n»", ), ); js_helpers.add_group( JsGroup::Exports, "_ffi_set_panic_hook", JsString::from_template("« _ffi_set_panic_hook: () => void,\n»"), ); js_helpers.add_group( JsGroup::Imports, "_ffi_js_drop", JsString::from_template( " _ffi_js_drop(handle«: number»)«: void» { _ffi_handles.delete(handle); }, ", ), ); js_helpers.add_group( JsGroup::Other, "_ffi_WriteBuf", JsString::from_template( "« interface _ffi_WriteBuf { u8: Uint8Array, dv: DataView | null, off: number, } »", ), ); js_helpers.add_group( JsGroup::Other, "_ffi_ReadBuf", JsString::from_template( "« interface _ffi_ReadBuf { dv: DataView, off: number, } »", ), ); js_helpers .add_group( JsGroup::Let, "_ffi_new_WriteBuf", JsString::from_template( "let _ffi_new_WriteBuf = ()«: _ffi_WriteBuf» => \ ({ u8: new Uint8Array(16), dv: null, off: 0 });\n", ), ) .add_dep_group(JsGroup::Other, "_ffi_WriteBuf"); js_helpers .add_group( JsGroup::Let, "_ffi_new_ReadBuf", JsString::from_template( "let _ffi_new_ReadBuf = (off«: number»)«: _ffi_ReadBuf» => \ ({ dv: _ffi_update_dv(), off });\n", ), ) .add_dep_group(JsGroup::Other, "_ffi_ReadBuf") .add_dep_group(JsGroup::Other, "_ffi_update_dv"); js_helpers.add_group( JsGroup::Other, "_ffi_grow", JsString::from_template( " function _ffi_grow(buf«: _ffi_WriteBuf», n«: number»)«: number» { let off = buf.off; let u8 = buf.u8; if (off + n > u8.length) { (buf.u8 = new Uint8Array((off + n) << 1)).set(u8); buf.dv = null; } buf.off += n; if (!buf.dv) buf.dv = new DataView(buf.u8.buffer); return off; } ", ), ); js_helpers .add_group( JsGroup::Other, "_ffi_buf_to_rust", JsString::from_template( " function _ffi_buf_to_rust({ u8, off }«: _ffi_WriteBuf»)«: number» { let ptr = _ffi_exports._ffi_alloc(off); _ffi_update_u8().set(u8.length > off ? u8.subarray(0, off) : u8, ptr); return ptr; } ", ), ) .add_dep_group(JsGroup::Exports, "_ffi_alloc") .add_dep_group(JsGroup::Other, "_ffi_update_u8"); js_helpers.add_group( JsGroup::Let, "_ffi_next_handle", "let _ffi_next_handle = 0;\n", ); js_helpers.add_group( JsGroup::Let, "_ffi_handles", JsString::from_template( "let _ffi_handles«: Map» = /* @__PURE__ */ new Map;\n", ), ); js_helpers.add_group( JsGroup::Let, "_ffi_encoder", "let _ffi_encoder = /* @__PURE__ */ new TextEncoder;\n", ); js_helpers.add_group( JsGroup::Let, "_ffi_decoder", "let _ffi_decoder = /* @__PURE__ */ new TextDecoder;\n", ); js_helpers.add_group( JsGroup::Let, "_ffi_u8", JsString::from_template("let _ffi_u8«: Uint8Array»;\n"), ); js_helpers.add_group( JsGroup::Let, "_ffi_dv", JsString::from_template("let _ffi_dv«: DataView»;\n"), ); js_helpers.add_group(JsGroup::Let, "_ffi_len", "let _ffi_len = 0;\n"); js_helpers .add_group( JsGroup::Other, "_ffi_handle_alloc", JsString::from_template( " function _ffi_handle_alloc(obj«: any»)«: number» { _ffi_handles.set(++_ffi_next_handle, obj); return _ffi_next_handle; } ", ), ) .add_dep_group(JsGroup::Let, "_ffi_handles") .add_dep_group(JsGroup::Let, "_ffi_next_handle"); js_helpers .add_group( JsGroup::Other, "_ffi_string_to_rust", JsString::from_template( " function _ffi_string_to_rust(str«: string»)«: number» { let buf = _ffi_encoder.encode(str); let ptr = _ffi_exports._ffi_alloc(_ffi_len = buf.length); _ffi_update_u8().set(buf, ptr); return ptr; } ", ), ) .add_dep_group(JsGroup::Let, "_ffi_len") .add_dep_group(JsGroup::Let, "_ffi_encoder") .add_dep_group(JsGroup::Exports, "_ffi_alloc") .add_dep_group(JsGroup::Other, "_ffi_update_u8"); js_helpers .add_group( JsGroup::Other, "_ffi_string_from_rust", JsString::from_template( " function _ffi_string_from_rust(ptr«: number», len«: number», cap«: number»)«: string» { let str = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)); _ffi_exports._ffi_dealloc(ptr, cap); return str; } ", ), ) .add_dep_group(JsGroup::Let, "_ffi_decoder") .add_dep_group(JsGroup::Exports, "_ffi_dealloc"); js_helpers .add_group( JsGroup::Other, "_ffi_update_u8", JsString::from_template( " function _ffi_update_u8()«: Uint8Array» { let buffer = _ffi_exports.memory.buffer; if (!_ffi_u8 || _ffi_u8.buffer !== buffer) _ffi_u8 = new Uint8Array(buffer); return _ffi_u8; } ", ), ) .add_dep_group(JsGroup::Let, "_ffi_u8"); js_helpers .add_group( JsGroup::Other, "_ffi_update_dv", JsString::from_template( " function _ffi_update_dv()«: DataView» { let buffer = _ffi_exports.memory.buffer; if (!_ffi_dv || _ffi_dv.buffer !== buffer) _ffi_dv = new DataView(buffer); return _ffi_dv; } ", ), ) .add_dep_group(JsGroup::Let, "_ffi_dv"); js_helpers .add_group( JsGroup::Imports, "_ffi_throw_panic", JsString::from_template( r#" _ffi_throw_panic(ptr«: number», len«: number»)«: void» { let legacy_demangle = (_«: string», t«: string») => { let e«: any» = { SP: "@", BP: "*", RF: "&", LT: "<", GT: ">", LP: "(", RP: ")", C: "," }, p«: string[]» = [], i = 3; for (let n«: any»; n = /^\d+/.exec(t.slice(i)); ) p.push(t.slice(i += n[0].length, i += +n[0]).replace(/^_\$/, "$").replace(/\.\./g, "::").replace(/\$(\w|\w\w|u[0-9a-f]+)\$/g, (a, b) => b[0] == "u" ? String.fromCodePoint(parseInt(b.slice(1), 16)) : e[b] || a)); if (/^h[0-9a-f]+$/.test(p[p.length - 1])) p.pop(); return p.join("::") + (t[i] == "E" ? t.slice(i + 1).replace(/^\.llvm\.[0-9A-F@]+$/, "") : ""); }; let msg = _ffi_decoder.decode(new Uint8Array(_ffi_exports.memory.buffer, ptr, len)), Err«: any» = Error, old = Err.stackTraceLimit; Err.stackTraceLimit = 99; let err = Err(msg); Err.stackTraceLimit = old; let stack = (err.stack || "").replace(/\b(?:[\w\-]+[\.\[])*(_ZN[^ @\]]+)/g, legacy_demangle); if (stack.startsWith("Error: ")) err.stack = stack; else err = Err(msg + "\nstack backtrace:\n" + stack); throw err; }, "#, ), ) .add_dep_group(JsGroup::Let, "_ffi_decoder"); rust_helpers.add( "_ffi_set_panic_hook", format!( r#" {} extern "C" fn _ffi_set_panic_hook() {{ #[cfg(target_arch = "wasm32")] std::panic::set_hook(Box::new(|info| {{ let location = info.location().unwrap(); let thread = std::thread::current(); let name = thread.name().unwrap_or(""); let payload = info.payload(); let payload = if let Some(&s) = payload.downcast_ref::<&'static str>() {{ s }} else if let Some(s) = payload.downcast_ref::() {{ s.as_str() }} else {{ "Box" }}; let text = format!("thread '{{name}}' panicked at {{location}}:\n{{payload}}"); unsafe extern "C" {{ fn _ffi_throw_panic(ptr: *const u8, len: usize); }} unsafe {{ _ffi_throw_panic(text.as_ptr(), text.len()) }} }})); }} "#, syntax.unsafe_no_mangle() ), ); let js_path = if self.js_path.is_none() && self.ts_path.is_none() && self.d_ts_path.is_none() { Some("miniffi.js".into()) } else { self.js_path.clone() }; if self.set_panic_hook { js_helpers.mark_used_group(JsGroup::Imports, "_ffi_throw_panic"); rust_helpers.mark_used("_ffi_set_panic_hook"); } let mut rust = format!("// {DO_NOT_EDIT_COMMENT}\n"); let mut dts = format!("// {DO_NOT_EDIT_COMMENT}\n"); let mut js = JsString::default(); _ = write!(js, "// {DO_NOT_EDIT_COMMENT}\n"); // "instantiate" helper dts.push_str( "\nexport function instantiate(\ bytes: BufferSource, \ imports?: WebAssembly.ModuleImports\ ): Promise<{ memory: WebAssembly.Memory }>;\n", ); js.push_template( " export async function instantiate(\ bytes«: BufferSource», \ imports«?: WebAssembly.ModuleImports»\ )«: Promise<{ memory: WebAssembly.Memory }>» { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiate(bytes, { env }); _ffi_exports = (await promise).instance.exports« as any»; ", ); if self.set_panic_hook { js.push_both(" _ffi_exports._ffi_set_panic_hook();\n"); js_helpers.mark_used_group(JsGroup::Exports, "_ffi_set_panic_hook"); } js.push_both(" return { memory: _ffi_exports.memory };\n}\n"); // "instantiateStreaming" helper dts.push_str( "export function instantiateStreaming(\ source: Response | PromiseLike, \ imports?: WebAssembly.ModuleImports\ ): Promise<{ memory: WebAssembly.Memory }>;\n", ); js.push_template( " export async function instantiateStreaming(\ source«: Response | PromiseLike», \ imports«?: WebAssembly.ModuleImports»\ )«: Promise<{ memory: WebAssembly.Memory }>» { let env = Object.assign({}, imports, _ffi_imports); let promise = WebAssembly.instantiateStreaming(source, { env }); _ffi_exports = (await promise).instance.exports« as any»; ", ); if self.set_panic_hook { js.push_both(" _ffi_exports._ffi_set_panic_hook();\n"); } js.push_both(" return { memory: _ffi_exports.memory };\n}\n"); // Traits for t in &ast.traits { let mut ts = JsString::default(); ts.push_ts(&format!("\nexport interface {} {{\n", t.name)); for f in &t.fns { ts.push_ts(" "); ts.push_ts(&f.name); ts.push_ts("("); for (i, arg) in f.args.iter().enumerate() { if i > 0 { ts.push_ts(", "); } ts.push_ts(&arg.name); ts.push_ts(": "); append_ts_type(&mut ts, &ast, &arg.ty); } ts.push_ts(")"); if let Some(returns) = &f.returns { ts.push_ts(": "); append_ts_type(&mut ts, &ast, &returns.ty); } else { ts.push_ts(": void"); } ts.push_ts(";\n"); } ts.push_ts("}\n"); js.extend_from(&ts); dts.push_str(&ts.with_types); } // Enums for e in &ast.enums { let mut ts = JsString::default(); if !e.has_fields() { // Enums without fields just map to TypeScript enums (i.e. integers) let mut discriminant = 0; ts.push_js(&format!("\nexport const {} = {{\n", e.name)); ts.push_ts(&format!("\nexport const enum {} {{\n", e.name)); for v in &e.variants { ts.push_js(&format!(" {}: {},\n", v.name, v.discriminant)); if v.discriminant == discriminant { ts.push_ts(&format!(" {},\n", v.name)); } else { ts.push_ts(&format!(" {} = {},\n", v.name, v.discriminant)); } discriminant = v.discriminant.wrapping_add(1); } ts.push_js("};\n"); ts.push_ts("}\n"); } else { // Enums with fields map to objects with a special "$" field ts.push_ts(&format!("\nexport type {} =\n", e.name)); for v in &e.variants { ts.push_ts(&format!(" | {{ readonly $: {:?}", v.name)); for f in &v.fields { ts.push_ts(&format!(", {}: ", f.name)); append_ts_type(&mut ts, &ast, &f.ty); } ts.push_ts(" }\n"); } } js.extend_from(&ts); dts.push_str(&ts.with_types); } // Structs for s in &ast.structs { let mut ts = JsString::default(); ts.push_ts(&format!("\nexport interface {} {{\n", s.name)); for f in &s.fields { ts.push_ts(" "); ts.push_ts(&f.name); ts.push_ts(": "); append_ts_type(&mut ts, &ast, &f.ty); ts.push_ts(",\n"); } ts.push_ts("}\n"); js.extend_from(&ts); dts.push_str(&ts.with_types); } // Constants if !ast.consts.is_empty() { js.push_both("\n"); dts.push('\n'); for c in &ast.consts { let mut ts_type = JsString::default(); append_ts_type(&mut ts_type, &ast, &c.ty); _ = write!(dts, "export const {}: {};\n", c.name, ts_type.with_types); js.push_both("export const "); js.push_both(&c.name); js.push_ts(": "); js.extend_from(&ts_type); js.push_both(" = "); append_js_val(&mut js, &c.val); js.push_both(";\n"); } } let mut ctx = WasmCtx { syntax, js_helpers, rust_helpers, ..WasmCtx::default() }; // Functions for (i, f) in ast.fns.iter().enumerate() { generate_js_to_rust_fn(&ast, &mut ctx, f, &mut js, None); // Also generate a type declaration for the function let mut ts = JsString::default(); if i == 0 { ts.push_both("\n"); } _ = write!(ts, "export function {}(", f.name); for (j, arg) in f.args.iter().enumerate() { if j > 0 { ts.push_ts(", "); } ts.push_both(&arg.name); ts.push_ts(": "); append_ts_type(&mut ts, &ast, &arg.ty); } ts.push_both(")"); if let Some(returns) = &f.returns { ts.push_ts(": "); append_ts_type(&mut ts, &ast, &returns.ty); } else { ts.push_ts(": void"); } ts.push_both(";\n"); dts.push_str(&ts.with_types); } for it in ctx.rust_helpers.code_in_order() { rust.push_str(it); } let js_code = ctx.js_helpers.code_by_group_in_order(); for group in [JsGroup::Let, JsGroup::Other] { if let Some(code) = js_code.get(&group) { if group == JsGroup::Let || group == JsGroup::Let { js.push_both("\n"); } for it in code { js.extend_from(&it); } } } // Export object js.push_both("\nlet _ffi_exports"); js.push_ts(": {\n"); js.push_ts(" memory: WebAssembly.Memory,\n"); if let Some(code) = js_code.get(&JsGroup::Exports) { for it in code { js.extend_from(&it); } } js.push_ts("}"); js.push_both(";\n"); // Import object js.push_both("\nconst _ffi_imports = {"); if let Some(code) = js_code.get(&JsGroup::Imports) { for it in code { js.extend_from(&it); } } js.push_both("};\n"); let mut output_files = vec![FileData { path: rust_path, contents: rust, }]; if let Some(path) = js_path { output_files.push(FileData { path, contents: js.without_types, }); } if let Some(path) = &self.ts_path { output_files.push(FileData { path: path.clone(), contents: js.with_types, }); } if let Some(path) = &self.d_ts_path { output_files.push(FileData { path: path.clone(), contents: dts, }); } output_files } } #[derive(Default)] struct WasmCtx { syntax: RustSyntax, helper_names: NameSet, js_helpers: HelperSet, rust_helpers: HelperSet<(), String>, multi_ret_helpers: HashMap, (String, String)>, trait_to_rust_helpers: HashMap, trait_to_js_helpers: HashMap<(RustPtr, usize), String>, vec_to_rust_helpers: HashMap, vec_to_js_helpers: HashMap, box_to_rust_helpers: HashMap, box_to_js_helpers: HashMap, enum_to_rust_helpers: HashMap, enum_to_js_helpers: HashMap, } #[derive(Default)] struct Transform { js: FnBuilder, rust: FnBuilder, ffi_args: Vec, buf: Option>, buf_status: BufStatus, buf_ref: &'static str, } #[derive(Default)] struct JsString { without_types: String, with_types: String, } impl JsString { fn extend_from(&mut self, it: &JsString) { self.without_types.push_str(&it.without_types); self.with_types.push_str(&it.with_types); } fn push_js(&mut self, text: &str) { self.without_types.push_str(text); } fn push_ts(&mut self, text: &str) { self.with_types.push_str(text); } fn push_both(&mut self, text: &str) { self.without_types.push_str(text); self.with_types.push_str(text); } fn push_template(&mut self, text: &str) { for (i, part) in text.split(&['«', '»']).enumerate() { if i % 2 == 0 { self.without_types.push_str(part); } self.with_types.push_str(part); } } fn from_template(text: &str) -> JsString { let mut js = JsString::default(); js.push_template(text); js } } impl From<&str> for JsString { fn from(value: &str) -> JsString { JsString { without_types: value.to_string(), with_types: value.to_string(), } } } impl std::fmt::Write for JsString { fn write_str(&mut self, text: &str) -> Result<(), std::fmt::Error> { self.push_both(text); Ok(()) } } struct TraitInfo<'a> { t: &'a RustTrait, kind: RustPtr, } fn generate_js_to_rust_fn( ast: &AST, ctx: &mut WasmCtx, f: &RustFn, js: &mut JsString, trait_info: Option, ) { let ffi_name = ctx.helper_names.create(&match &trait_info { None => format!("_ffi_fn_{}", f.name), Some(info) => format!("_ffi_{:?}_{}__{}", info.kind, info.t.name, f.name), }); let mut names = NameSet::default(); for arg in &f.args { names.add(arg.name.clone()); } if let Some(ret) = &f.returns { names.add(ret.name.clone()); } // Transform the arguments let mut arg_tfm = Transform::default(); if let Some(info) = &trait_info { arg_tfm.rust.line(format!( "let _self = unsafe {{ &*(_self as *const {}) }};", info.kind.path(), info.t.name )); } for arg in &f.args { arg_tfm.js.mark_pure(&arg.name); transform_to_rust(ast, ctx, &mut names, &mut arg_tfm, &arg.name, &arg.ty); } arg_tfm.js.insert_deferred_lines_here(); // Generate the Rust call to the API function let mut rust_call = String::new(); if trait_info.is_some() { rust_call.push_str("_self."); } _ = write!(rust_call, "{}(", f.name); rust_call.push_str(&arg_tfm.rust.find_args(&f.args, RefInline)); rust_call.push(')'); // Transform the result let mut ret_tfm = Transform::default(); if let Some(ret) = &f.returns { ret_tfm.rust.decl(&ret.name, rust_call); transform_to_js(ast, ctx, &mut names, &mut ret_tfm, &ret.name, &ret.ty); } else { rust_call.push(';'); ret_tfm.rust.line(rust_call); } // Generate the JavaScript call to the FFI function let mut js_call = String::new(); _ = write!(js_call, "_ffi_exports.{ffi_name}("); if trait_info.is_some() { js_call.push_str("this._"); if !arg_tfm.ffi_args.is_empty() { js_call.push_str(", "); } } js_call.push_str(&arg_tfm.js.find_args(&arg_tfm.ffi_args, RefInline)); js_call.push(')'); // JavaScript { // Handle the return values let mut fb = arg_tfm.js; match &ret_tfm.ffi_args[..] { [] => { js_call.push(';'); fb.line(js_call) } [arg] => fb.decl(&arg.name, js_call), _ => { let ret = names.create("multi_ret"); let mut view = "_ffi_update_dv()"; let mut offset = 0; fb.decl(&ret, js_call); for arg in &ret_tfm.ffi_args { fb.decl( &arg.name, js_multi_ret_load(view, &ret, &arg.ty, &mut offset), ); view = "_ffi_dv"; ctx.js_helpers .mark_used_group(JsGroup::Other, "_ffi_update_dv"); } } }; // Return from the function fb.extend(ret_tfm.js); fb.insert_deferred_lines_here(); if let Some(ret) = &f.returns { let code = fb.find(&ret.name, &ret.ty, RefInline).code; fb.line(format!("return {code};")); } // Write out the final function let (_, indent) = match &trait_info { None => (write!(js, "\nexport function {}(", f.name), " "), Some(_) => (write!(js, "\n {}(", f.name), " "), }; for (i, arg) in f.args.iter().enumerate() { if i > 0 { js.push_both(", "); } js.push_both(&arg.name); js.push_ts(": "); append_ts_type(js, ast, &arg.ty); } js.push_both(")"); if let Some(returns) = &f.returns { js.push_ts(": "); append_ts_type(js, ast, &returns.ty); } else { js.push_ts(": void"); } js.push_both(" {\n"); fb.write_to_js(ast, js, indent); _ = write!(js, "{}}}\n", &indent[4..]); } // TypeScript (export) { let mut js = JsString::default(); js.push_ts(&format!(" {ffi_name}: (")); if trait_info.is_some() { js.push_ts("_self: number"); } for (i, arg) in arg_tfm.ffi_args.iter().enumerate() { if trait_info.is_some() || i > 0 { js.push_ts(", "); } js.push_ts(&arg.name); js.push_ts(": "); append_ts_type(&mut js, ast, &arg.ty); } js.push_ts(") => "); match &ret_tfm.ffi_args[..] { [] => js.push_ts("void"), [arg] => append_ts_type(&mut js, ast, &arg.ty), _ => js.push_ts("number"), } js.push_ts(",\n"); ctx.js_helpers .add_group(JsGroup::Exports, &ffi_name, js) .mark_used(); } // Rust { // Return from the function let mut fb = arg_tfm.rust; fb.extend(ret_tfm.rust); fb.insert_deferred_lines_here(); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { let code = fb.find(&arg.name, &arg.ty, RefInline).code; fb.line(code); } _ => { let (ty_name, static_name) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); let args = fb.find_args(&ret_tfm.ffi_args, RefInline); // Note: This must be formatted this way (both lines in one // unsafe block) to work correctly across different versions // of Rust. Older versions of Rust give an error if "unsafe" // is missing and newer versions of Rust give an error if // "unsafe" is present. fb.line("unsafe {".into()); fb.line(format!("{static_name} = {ty_name}({args});")); fb.line(format!("std::ptr::addr_of!({static_name})")); fb.line("}".into()); } } // Write out the final function let mut rust = String::new(); _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle()); _ = write!(rust, "extern \"C\" fn {ffi_name}("); if trait_info.is_some() { rust.push_str("_self: *const u8"); } for (i, arg) in arg_tfm.ffi_args.iter().enumerate() { if trait_info.is_some() || i > 0 { rust.push_str(", "); } _ = write!(rust, "{}: ", arg.name); append_rust_type(&mut rust, ast, &arg.ty); } rust.push(')'); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { rust.push_str(" -> "); append_rust_type(&mut rust, ast, &arg.ty); } _ => { let (ty_name, _) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust, " -> *const {ty_name}"); } } rust.push_str(" {\n"); fb.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&ffi_name, rust).mark_used(); } } fn generate_rust_to_js_fn( ast: &AST, ctx: &mut WasmCtx, t: &RustTrait, f: &RustFn, rust: &mut String, ) { let ffi_name = ctx .helper_names .create(&format!("_ffi_js_{}__{}", t.name, f.name)); let mut names = NameSet::default(); for arg in &f.args { names.add(arg.name.clone()); } if let Some(ret) = &f.returns { names.add(ret.name.clone()); } // Transform the arguments let mut arg_tfm = Transform::default(); for arg in &f.args { arg_tfm.rust.mark_pure(&arg.name); transform_to_js(ast, ctx, &mut names, &mut arg_tfm, &arg.name, &arg.ty); } arg_tfm.rust.insert_deferred_lines_here(); // Generate the JavaScript call to the API function let mut js_call = format!("_ffi_handles.get(self).{}(", f.name); js_call.push_str(&arg_tfm.js.find_args(&f.args, RefInline)); js_call.push(')'); // Transform the result let mut ret_tfm = Transform::default(); if let Some(ret) = &f.returns { ret_tfm.js.decl(&ret.name, js_call); transform_to_rust(ast, ctx, &mut names, &mut ret_tfm, &ret.name, &ret.ty); } else { js_call.push(';'); ret_tfm.js.line(js_call); } // Generate the Rust call to the FFI function let mut rust_call = format!("unsafe {{ {ffi_name}(self.0"); if !arg_tfm.ffi_args.is_empty() { rust_call.push_str(", "); } rust_call.push_str(&arg_tfm.rust.find_args(&arg_tfm.ffi_args, RefInline)); if ret_tfm.ffi_args.len() > 1 { let (_, static_name) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust_call, ", std::ptr::addr_of!({static_name})"); } rust_call.push_str(") }"); // Rust { // Handle the return values let mut fb = arg_tfm.rust; match &ret_tfm.ffi_args[..] { [] => { rust_call.push(';'); fb.line(rust_call); } [arg] => fb.decl(&arg.name, rust_call), _ => { let (_, static_name) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); fb.line(rust_call); for (i, arg) in ret_tfm.ffi_args.iter().enumerate() { fb.decl(&arg.name, format!("unsafe {{ {static_name}.{i} }}")); } } }; // Return from the function fb.extend(ret_tfm.rust); fb.insert_deferred_lines_here(); if let Some(ret) = &f.returns { let code = fb.find(&ret.name, &ret.ty, RefInline).code; fb.line(code); } // Write out the final function _ = write!(rust, "\n fn {}(&self", f.name); for arg in &f.args { _ = write!(rust, ", {}: ", arg.name); append_rust_type(rust, ast, &arg.ty); } rust.push(')'); if let Some(returns) = &f.returns { rust.push_str(" -> "); append_rust_type(rust, ast, &returns.ty); } rust.push_str(" {\n"); _ = write!( rust, " {} \"C\" {{ fn {ffi_name}(_: *const u8", ctx.syntax.unsafe_extern() ); for arg in &arg_tfm.ffi_args { _ = write!(rust, ", {}: ", arg.name); append_rust_type(rust, ast, &arg.ty); } match &ret_tfm.ffi_args[..] { [] => rust.push(')'), [arg] => { rust.push_str(") -> "); append_rust_type(rust, ast, &arg.ty); } _ => { let (ty_name, _) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); _ = write!(rust, ", _: *const {ty_name})"); } } rust.push_str("; }\n"); fb.write_to_rust(ast, rust, " "); rust.push_str(" }\n"); } // JavaScript { // Return from the function let mut fb = arg_tfm.js; fb.extend(ret_tfm.js); fb.insert_deferred_lines_here(); match &ret_tfm.ffi_args[..] { [] => {} [arg] => { let code = fb.find(&arg.name, &arg.ty, RefInline).code; fb.line(format!("return {code};")); } _ => { let (ty_name, _) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); let mut offset = 0; let mut offsets = Vec::new(); for arg in &ret_tfm.ffi_args { let size = js_multi_ret_size(&arg.ty); offset = (offset + (size - 1)) & !(size - 1); offsets.push(offset); offset += size; } let mut stores = Vec::new(); for (offset, arg) in offsets.iter().zip(ret_tfm.ffi_args.iter()).rev() { let code = fb.find(&arg.name, &arg.ty, RefInline).code; stores.push(js_multi_ret_store( match offset { 0 => "_ffi_update_dv()", _ => "_ffi_dv", }, &ty_name, &code, &arg.ty, *offset, )); } for store in stores.into_iter().rev() { fb.line(store); } ctx.js_helpers .mark_used_group(JsGroup::Other, "_ffi_update_dv"); } } // Write out the final function let mut js = JsString::default(); _ = write!(js, "\n {ffi_name}(self"); js.push_ts(": number"); for arg in &arg_tfm.ffi_args { js.push_both(", "); js.push_both(&arg.name); js.push_ts(": "); append_ts_type(&mut js, ast, &arg.ty); } if ret_tfm.ffi_args.len() > 1 { let (ty_name, _) = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args); js.push_both(", "); js.push_both(&ty_name); js.push_ts(": number"); } js.push_both(")"); match &ret_tfm.ffi_args[..] { [arg] => { js.push_ts(": "); append_ts_type(&mut js, ast, &arg.ty); } _ => js.push_ts(": void"), } js.push_both(" {\n"); fb.write_to_js(ast, &mut js, " "); js.push_both(" },\n"); ctx.js_helpers .add_group(JsGroup::Imports, &ffi_name, js) .mark_used(); } } fn transform_to_rust( ast: &AST, ctx: &mut WasmCtx, names: &mut NameSet, tfm: &mut Transform, name: &str, ty: &RustType, ) { use RustType::*; fn add_ffi_arg(ast: &AST, ctx: &mut WasmCtx, tfm: &mut Transform, name: &str, ty: &RustType) { match tfm.buf_status { BufStatus::Outside => tfm.ffi_args.push(RustArg { name: name.to_string(), ty: ty.clone(), }), BufStatus::Inside => { let buf = tfm.buf.as_ref().unwrap(); // JavaScript (write) let code = tfm.js.find(name, ty, RefInline).code; tfm.js.line(js_write(ctx, buf.buf_name(), &code, ty)); // Rust (read) let mut rust = "_ffi_read::<".to_string(); append_rust_type(&mut rust, ast, ty); _ = write!(rust, ">({}{})", tfm.buf_ref, buf.end_name()); tfm.rust.decl(name, rust); ctx.rust_helpers.mark_used("_ffi_read"); } } } match ty { Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => add_ffi_arg(ast, ctx, tfm, name, ty), RefStr | OwnStr => { let js_code = tfm.js.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let len_name = names.create(&format!("{name}_len")); let opt_ref = match ty { RefStr => "&", _ => "", }; tfm.js.line(format!( "let {ptr_name} = _ffi_string_to_rust({js_code}), {len_name} = _ffi_len;" )); ctx.js_helpers.mark_used_group(JsGroup::Let, "_ffi_len"); ctx.js_helpers .mark_used_group(JsGroup::Other, "_ffi_string_to_rust"); add_ffi_arg(ast, ctx, tfm, &ptr_name, &ForeignHandle); add_ffi_arg(ast, ctx, tfm, &len_name, &Usize); let len_code = tfm.rust.find(&len_name, &Usize, RefInline).code; let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.rust.decl( name, format!("{opt_ref}_ffi_string_from_host({ptr_code}, {len_code})"), ); ctx.rust_helpers.mark_used("_ffi_string_from_host"); } Enum(enum_index) => { let js = tfm.js.find(name, ty, RefInline); let e = &ast.enums[*enum_index]; let (js_helper, rust_helper) = enum_to_rust_helper(ast, ctx, *enum_index); if !e.has_fields() { let raw_name = names.create(&format!("{name}_raw")); tfm.js.maybe_pure_decl(js.pure, &raw_name, js.code); add_ffi_arg(ast, ctx, tfm, &raw_name, &I32); tfm.rust.decl(name, format!("{rust_helper}({raw_name})")); } else { let buf = ensure_js_buf(ctx, names, tfm); tfm.js .line(format!("{js_helper}({}, {});", js.code, buf.buf_name())); tfm.rust.decl( name, format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()), ); } } Struct(struct_index) => { let js = tfm.js.find(name, ty, RefMany); let s = &ast.structs[*struct_index]; let mut item_names = Vec::new(); for f in &s.fields { let item_name = names.create(&format!("{name}_{}", f.name)); tfm.js .maybe_pure_decl(js.pure, &item_name, member_access(&js.code, &f.name)); transform_to_rust(ast, ctx, names, tfm, &item_name, &f.ty); item_names.push(item_name.into()); } rust_decl_ctor(&mut tfm.rust, name, &s.name, &s.fields, item_names); } Tuple(types) => { let js = tfm.js.find(name, ty, RefMany); let mut item_args = Vec::new(); for (i, item_ty) in types.iter().enumerate() { let item_name = names.create(&format!("{name}_{i}")); tfm.js .maybe_pure_decl(js.pure, &item_name, format!("{}[{i}]", js.code)); transform_to_rust(ast, ctx, names, tfm, &item_name, &item_ty); item_args.push(RustArg { name: item_name, ty: item_ty.clone(), }); } let mut rust_code = tfm.rust.find_args(&item_args, RefInline); if types.len() == 1 { rust_code.push(','); } tfm.rust.decl(name, format!("({rust_code})")); } Ptr(kind, inner_ty) => { if let DynTrait(trait_index) = &**inner_ty { let js_code = tfm.js.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let rust_helper = trait_to_rust_helper(ast, ctx, *trait_index); let js_code = format!("_ffi_handle_alloc({js_code})"); ctx.js_helpers .mark_used_group(JsGroup::Other, "_ffi_handle_alloc"); tfm.js.decl(&ptr_name, js_code); add_ffi_arg(ast, ctx, tfm, &ptr_name, &ForeignHandle); let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.rust.decl( name, format!("{}::new({rust_helper}({ptr_code}))", kind.path()), ); } else if *kind == RustPtr::Box { let js_code = tfm.js.find(name, ty, RefMany).code; let (js_helper, rust_helper) = box_to_rust_helper(ast, ctx, inner_ty); let buf = ensure_js_buf(ctx, names, tfm); tfm.js .line(format!("{js_helper}({js_code}, {});", buf.buf_name())); tfm.rust.decl( name, format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()), ); } else { unreachable!() } } Vector(inner_ty) => { let js_code = tfm.js.find(name, ty, RefMany).code; let len_name = names.create(&format!("{name}_len")); let (js_helper, rust_helper) = vec_to_rust_helper(ast, ctx, inner_ty); let buf = ensure_js_buf(ctx, names, tfm); tfm.js.decl(&len_name, format!("{js_code}.length")); add_ffi_arg(ast, ctx, tfm, &len_name, &Usize); tfm.js .line(format!("{js_helper}({js_code}, {});", buf.buf_name())); let len_code = tfm.rust.find(&len_name, ty, RefInline).code; tfm.rust.decl( name, format!( "{rust_helper}({len_code}, {}{})", tfm.buf_ref, buf.end_name() ), ); } Optional(inner_ty) => { let js_code = tfm.js.find(name, ty, RefMany).code; let has_name = names.create(&format!("has_{name}")); let val_name = names.create(&format!("{name}_val")); ensure_js_buf(ctx, names, tfm); tfm.js.decl(&has_name, format!("{js_code} !== null")); add_ffi_arg(ast, ctx, tfm, &has_name, &Bool); let mut rust = FnBuilder::default(); tfm.js.line(format!("if ({js_code} !== null) {{")); tfm.js.decl(&val_name, format!("{js_code}")); { let old = tfm.buf_status; tfm.buf_status = BufStatus::Inside; std::mem::swap(&mut tfm.rust, &mut rust); transform_to_rust(ast, ctx, names, tfm, &val_name, inner_ty); std::mem::swap(&mut tfm.rust, &mut rust); tfm.buf_status = old; } tfm.js.line("}".into()); let has_code = tfm.rust.find(&has_name, ty, RefInline).code; let val_code = rust.find(&val_name, ty, RefInline).code; if rust.is_empty() { tfm.rust .decl(name, format!("{has_code}.then(|| {val_code})")); } else { rust.insert_deferred_lines_here(); rust.line(val_code); tfm.rust.line(format!("let {name} = {has_code}.then(|| {{")); tfm.rust.extend(rust); tfm.rust.line("});".to_string()); } } Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(), } } fn transform_to_js( ast: &AST, ctx: &mut WasmCtx, names: &mut NameSet, tfm: &mut Transform, name: &str, ty: &RustType, ) { use RustType::*; fn add_ffi_arg(ctx: &mut WasmCtx, tfm: &mut Transform, name: &str, ty: &RustType) { match tfm.buf_status { BufStatus::Outside => { tfm.ffi_args.push(RustArg { name: name.to_string(), ty: ty.clone(), }); if let Bool = ty { // This comes over the FFI as an integer and needs a cast tfm.js.pure_decl(name, format!("!!{name}")); } } BufStatus::Inside => { let buf_name = tfm.buf.as_ref().unwrap().buf_name(); // Rust (write) let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust .line(format!("_ffi_write({code}, {}{buf_name});", tfm.buf_ref)); ctx.rust_helpers.mark_used("_ffi_write"); // JavaScript (read) tfm.js.decl(name, js_read(ctx, buf_name, ty)); } } } match ty { Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64 | ForeignHandle => { add_ffi_arg(ctx, tfm, name, ty); } RefStr | OwnStr => { let mut rust_code = tfm.rust.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let len_name = names.create(&format!("{name}_len")); let cap_name = names.create(&format!("{name}_cap")); if let RefStr = ty { rust_code.push_str(".into()"); } tfm.rust.line(format!( "let ({ptr_name}, {len_name}, {cap_name}) = _ffi_string_to_host({rust_code});" )); ctx.rust_helpers.mark_used("_ffi_string_to_host"); add_ffi_arg(ctx, tfm, &ptr_name, &ForeignHandle); add_ffi_arg(ctx, tfm, &len_name, &Usize); add_ffi_arg(ctx, tfm, &cap_name, &Usize); let cap_code = tfm.js.find(&cap_name, &Usize, RefInline).code; let len_code = tfm.js.find(&len_name, &Usize, RefInline).code; let ptr_code = tfm.js.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.js.decl( name, format!("_ffi_string_from_rust({ptr_code}, {len_code}, {cap_code})"), ); ctx.js_helpers .mark_used_group(JsGroup::Other, "_ffi_string_from_rust"); } Enum(enum_index) => { let rust = tfm.rust.find(name, ty, RefInline); let e = &ast.enums[*enum_index]; if !e.has_fields() { tfm.rust .maybe_pure_decl(rust.pure, name, format!("{} as i32", rust.code)); add_ffi_arg(ctx, tfm, name, &I32); } else { let (js_helper, rust_helper) = enum_to_js_helper(ast, ctx, *enum_index); let buf = ensure_rust_buf(ctx, names, tfm); tfm.rust.line(format!( "{rust_helper}({}, {}{});", rust.code, tfm.buf_ref, buf.buf_name() )); tfm.js .decl_ty(name, ty.clone(), format!("{js_helper}({})", buf.buf_name())); } } Struct(struct_index) => { let rust = tfm.rust.find(name, ty, RefMany); let s = &ast.structs[*struct_index]; let mut item_names = Vec::new(); for f in &s.fields { let item_name = names.create(&format!("{name}_{}", f.name)); tfm.rust.maybe_pure_decl( rust.pure, &item_name, format!("{}.{}", rust.code, f.name), ); transform_to_js(ast, ctx, names, tfm, &item_name, &f.ty); item_names.push(item_name.into()); } if s.fields.is_empty() { tfm.js.decl_ty(name, ty.clone(), "{}".to_string()); // Avoid an unused variable warning in Rust let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!("_ = {code};")); } else { let fields = tfm .js .find_fields(&s.fields, item_names, RefInline, "{ ", " }"); tfm.js.decl_ty(name, ty.clone(), fields); } } Tuple(types) => { let rust = tfm.rust.find(name, ty, RefMany); let mut item_args = Vec::new(); for (i, item_ty) in types.iter().enumerate() { let item_name = names.create(&format!("{name}_{i}")); tfm.rust .maybe_pure_decl(rust.pure, &item_name, format!("{}.{i}", rust.code)); transform_to_js(ast, ctx, names, tfm, &item_name, &item_ty); item_args.push(RustArg { name: item_name, ty: item_ty.clone(), }); } if types.is_empty() { tfm.js.pure_decl(name, "undefined".to_string()); // Avoid an unused variable warning in Rust let code = tfm.rust.find(name, ty, RefInline).code; tfm.rust.line(format!("_ = {code};")); } else { let js_code = tfm.js.find_args(&item_args, RefInline); tfm.js.decl_ty(name, ty.clone(), format!("[{js_code}]")); } } Ptr(kind, inner_ty) => { if let DynTrait(trait_index) = &**inner_ty { let rust_code = tfm.rust.find(name, ty, RefInline).code; let ptr_name = names.create(&format!("{name}_ptr")); let js_helper = trait_to_js_helper(ast, ctx, *trait_index, *kind); tfm.rust.decl( &ptr_name, format!("Box::into_raw(Box::new({rust_code})) as *const u8"), ); add_ffi_arg(ctx, tfm, &ptr_name, &ForeignHandle); let ptr_code = tfm.js.find(&ptr_name, &ForeignHandle, RefInline).code; tfm.js .decl_ty(name, ty.clone(), format!("new {js_helper}({ptr_code})")); } else if *kind == RustPtr::Box { let rust_code = tfm.rust.find(name, ty, RefInline).code; let (js_helper, rust_helper) = box_to_js_helper(ast, ctx, inner_ty); let buf = ensure_rust_buf(ctx, names, tfm); tfm.rust.line(format!( "{rust_helper}(*{rust_code}, {}{});", tfm.buf_ref, buf.buf_name() )); tfm.js .decl(name, format!("{js_helper}({})", buf.buf_name())); } else { unreachable!() } } Vector(inner_ty) => { let rust_code = tfm.rust.find(name, ty, RefMany).code; let len_name = names.create(&format!("{name}_len")); let (js_helper, rust_helper) = vec_to_js_helper(ast, ctx, inner_ty); let buf = ensure_rust_buf(ctx, names, tfm); tfm.rust.decl(&len_name, format!("{rust_code}.len()")); add_ffi_arg(ctx, tfm, &len_name, &Usize); tfm.rust.line(format!( "{rust_helper}({rust_code}, {}{});", tfm.buf_ref, buf.buf_name() )); let len_code = tfm.js.find(&len_name, ty, RefInline).code; tfm.js .decl(name, format!("{js_helper}({len_code}, {})", buf.buf_name())); } Optional(inner_ty) => { let rust_code = tfm.rust.find(name, ty, RefMany).code; let has_name = names.create(&format!("has_{name}")); let val_name = names.create(&format!("{name}_val")); ensure_rust_buf(ctx, names, tfm); tfm.rust.decl(&has_name, format!("{rust_code}.is_some()")); add_ffi_arg(ctx, tfm, &has_name, &Bool); let mut js = FnBuilder::default(); tfm.rust .line(format!("if let Some({val_name}) = {rust_code} {{")); { let old = tfm.buf_status; tfm.buf_status = BufStatus::Inside; std::mem::swap(&mut tfm.js, &mut js); transform_to_js(ast, ctx, names, tfm, &val_name, inner_ty); std::mem::swap(&mut tfm.js, &mut js); tfm.buf_status = old; } tfm.rust.line("}".into()); let has_code = tfm.js.find(&has_name, ty, RefInline).code; let has_code = has_code.strip_prefix("!!").unwrap_or(&has_code); let val_code = js.find(&val_name, ty, RefInline).code; if js.is_empty() { tfm.js .decl_ty(name, ty.clone(), format!("{has_code} ? {val_code} : null")); } else { js.insert_deferred_lines_here(); js.line(format!("{name} = {val_code};")); tfm.js.decl_ty(name, ty.clone(), "null".into()); tfm.js.line(format!("if ({has_code}) {{")); tfm.js.extend(js); tfm.js.line("}".to_string()); } } Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(), } } fn ensure_js_buf(ctx: &mut WasmCtx, names: &mut NameSet, tfm: &mut Transform) -> Rc { if let Some(buf) = &tfm.buf { return buf.clone(); } let buf_name = names.create("buf"); let ptr_name = names.create("buf_ptr"); let end_name = names.create("buf_end"); let buf = SharedBuf::new(&buf_name, &end_name); // JavaScript (write) tfm.js .line(format!("let {buf_name} = _ffi_new_WriteBuf();")); tfm.js .defer_decl(&ptr_name, format!("_ffi_buf_to_rust({buf_name})")); ctx.js_helpers .mark_used_group(JsGroup::Let, "_ffi_new_WriteBuf"); ctx.js_helpers .mark_used_group(JsGroup::Other, "_ffi_buf_to_rust"); // Rust (read) tfm.rust.line_alt( // Avoid a warning about an unnecessarily mutable variable format!("let {end_name} = {ptr_name};"), format!("let mut {end_name} = {ptr_name};"), buf.is_buf_name_used_flag(), ); tfm.rust .defer_line(format!("_ffi_buf_from_host({ptr_name}, {end_name});")); ctx.rust_helpers.mark_used("_ffi_buf_from_host"); // FFI tfm.buf = Some(buf.clone()); tfm.buf_ref = "&mut "; tfm.ffi_args.push(RustArg { name: ptr_name, ty: RustType::ForeignHandle, }); buf } fn ensure_rust_buf(ctx: &mut WasmCtx, names: &mut NameSet, tfm: &mut Transform) -> Rc { if let Some(buf) = &tfm.buf { return buf.clone(); } let buf_name = names.create("buf"); let ptr_name = names.create("buf_ptr"); let cap_name = names.create("buf_cap"); let buf = SharedBuf::new(&buf_name, ""); // Rust (write) tfm.rust.line_alt( // Avoid a warning about an unnecessarily mutable variable format!("let {buf_name} = Vec::::new();"), format!("let mut {buf_name} = Vec::::new();"), buf.is_buf_name_used_flag(), ); tfm.rust.defer_line(format!( "let ({ptr_name}, {cap_name}) = _ffi_buf_to_host({buf_name});" )); ctx.rust_helpers.mark_used("_ffi_buf_to_host"); // JavaScript (read) tfm.js .line(format!("let {buf_name} = _ffi_new_ReadBuf({ptr_name});")); tfm.js.defer_line(format!( "_ffi_exports._ffi_dealloc({ptr_name}, {cap_name});" )); ctx.js_helpers .mark_used_group(JsGroup::Let, "_ffi_new_ReadBuf"); ctx.js_helpers .mark_used_group(JsGroup::Exports, "_ffi_dealloc"); // FFI tfm.buf = Some(buf.clone()); tfm.buf_ref = "&mut "; tfm.ffi_args.push(RustArg { name: ptr_name, ty: RustType::ForeignHandle, }); tfm.ffi_args.push(RustArg { name: cap_name, ty: RustType::Usize, }); buf } fn vec_to_rust_helper(ast: &AST, ctx: &mut WasmCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.vec_to_rust_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_vec_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let js_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_js")); // This must be done first to avoid a stack overflow ctx.vec_to_rust_helpers .insert(inner_ty.clone(), (js_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let vec_name = locals.create("items"); let item_name = locals.create("item"); let end_name = locals.create("end"); let len_name = locals.create("len"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.js.mark_pure(&item_name); transform_to_rust(ast, ctx, &mut locals, &mut tfm, &item_name, &inner_ty); let item_code = tfm.rust.find(&item_name, inner_ty, RefInline).code; tfm.rust.line(format!("{vec_name}.push({item_code});")); // JavaScript { let mut js = JsString::default(); _ = write!(js, "\nfunction {js_name}({vec_name}"); js.push_ts(": "); append_ts_type(&mut js, ast, &RustType::Vector(inner_ty.clone().into())); _ = write!(js, ", {buf_name}"); js.push_ts(": _ffi_WriteBuf"); js.push_both(")"); js.push_ts(": void"); js.push_both(" {\n"); if !tfm.js.is_empty() { _ = write!(js, " for (const {item_name} of {vec_name}) {{\n"); tfm.js.write_to_js(ast, &mut js, " "); js.push_both(" }\n"); } js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Other, "_ffi_WriteBuf") .mark_used(); } // Rust { let mut rust = String::new(); let mut item_ty = String::new(); let end_name = buf.final_end_name_for_rust(); append_rust_type(&mut item_ty, ast, inner_ty); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({len_name}: usize, {end_name}: &mut *const u8) -> Vec<{item_ty}> {{\n" ); _ = write!( rust, " let mut {vec_name} = Vec::<{item_ty}>::with_capacity({len_name});\n" ); _ = write!(rust, " for _ in 0..{len_name} {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); _ = write!(rust, " {vec_name}\n"); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } (js_name, rust_name) } fn vec_to_js_helper(ast: &AST, ctx: &mut WasmCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.vec_to_js_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_vec_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let js_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_js")); // This must be done first to avoid a stack overflow ctx.vec_to_js_helpers .insert(inner_ty.clone(), (js_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let vec_name = locals.create("items"); let item_name = locals.create("item"); let len_name = locals.create("len"); let buf_name = locals.create("buf"); // Transform the items let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, ""); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.rust.mark_pure(&item_name); transform_to_js(ast, ctx, &mut locals, &mut tfm, &item_name, &inner_ty); let item_code = tfm.js.find(&item_name, inner_ty, RefInline).code; tfm.js.line(format!("{vec_name}.push({item_code});")); // Rust { let mut rust = String::new(); let buf_name = buf.final_buf_name_for_rust(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({vec_name}: Vec<"); append_rust_type(&mut rust, ast, inner_ty); _ = write!(rust, ">, {buf_name}: &mut Vec) {{\n"); if !tfm.rust.is_empty() { _ = write!(rust, " for {item_name} in {vec_name} {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } // JavaScript { let mut js = JsString::default(); let array_ty = RustType::Vector(inner_ty.clone().into()); _ = write!(js, "\nfunction {js_name}({len_name}"); js.push_ts(": number"); _ = write!(js, ", {buf_name}"); js.push_ts(": _ffi_ReadBuf"); js.push_both(")"); js.push_ts(": "); append_ts_type(&mut js, ast, &array_ty); js.push_both(" {\n"); _ = write!(js, " let {vec_name}"); js.push_ts(": "); append_ts_type(&mut js, ast, &array_ty); js.push_both(" = [];\n"); _ = write!(js, " while ({vec_name}.length < {len_name}) {{\n"); tfm.js.write_to_js(ast, &mut js, " "); js.push_both(" }\n"); _ = write!(js, " return {vec_name};\n"); js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Other, "_ffi_ReadBuf") .mark_used(); } (js_name, rust_name) } fn trait_to_rust_helper(ast: &AST, ctx: &mut WasmCtx, trait_index: usize) -> String { if let Some(result) = ctx.trait_to_rust_helpers.get(&trait_index) { return result.clone(); } let t = &ast.traits[trait_index]; let rust_name = format!("_ffi_rs_{}", t.name); // This must be done first to avoid a stack overflow ctx.trait_to_rust_helpers .insert(trait_index, rust_name.clone()); // Rust { let mut rust = String::new(); allow_non_camel_case_types(&mut rust, &rust_name); _ = write!(rust, "\nstruct {rust_name}(*const u8);\n"); _ = write!(rust, "\nimpl Drop for {rust_name} {{\n"); rust.push_str(" fn drop(&mut self) {\n"); _ = write!( rust, " {} \"C\" {{ fn _ffi_js_drop(_: *const u8); }}\n", ctx.syntax.unsafe_extern() ); _ = write!(rust, " unsafe {{ _ffi_js_drop(self.0) }};\n"); rust.push_str(" }\n"); rust.push_str("}\n"); _ = write!(rust, "\nimpl {} for {rust_name} {{", t.name); for f in &t.fns { generate_rust_to_js_fn(ast, ctx, t, f, &mut rust); } rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); ctx.js_helpers .mark_used_group(JsGroup::Imports, "_ffi_js_drop"); } rust_name } fn trait_to_js_helper(ast: &AST, ctx: &mut WasmCtx, trait_index: usize, kind: RustPtr) -> String { if let Some(result) = ctx.trait_to_js_helpers.get(&(kind, trait_index)) { return result.clone(); } let t = &ast.traits[trait_index]; let drop_name = format!("_ffi_rs_drop_{kind:?}_{}", t.name); let reg_name = format!("_ffi_reg_{kind:?}_{}", t.name); let js_name = format!("_ffi_{kind:?}_{}", t.name); // This must be done first to avoid a stack overflow ctx.trait_to_js_helpers .insert((kind, trait_index), js_name.clone()); // JavaScript { let reg_js = JsString::from_template(&format!( "let {reg_name} = new FinalizationRegistry((ptr«: number») => _ffi_exports.{drop_name}(ptr));\n" )); let mut js = JsString::from_template(&format!( r#" const {js_name} = class {}« implements {}» {{ « declare readonly _: number; » constructor(_«: number») {{ Object.defineProperty(this, "_", {{ value: _ }}); {reg_name}.register(this, _); }} "#, t.name, t.name )); for f in &t.fns { let info = Some(TraitInfo { t, kind }); generate_js_to_rust_fn(ast, ctx, f, &mut js, info); } js.push_both("};\n"); ctx.js_helpers.add_group(JsGroup::Let, ®_name, reg_js); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Let, ®_name) .mark_used(); } // TypeScript (export) { ctx.js_helpers .add_group( JsGroup::Exports, &drop_name, JsString::from_template(&format!("« {drop_name}: (ptr: number) => void,\n»")), ) .mark_used(); } // Rust { let mut rust = String::new(); _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle()); _ = write!(rust, "extern \"C\" fn {drop_name}(ptr: *const u8) {{\n"); _ = write!( rust, " drop(unsafe {{ Box::from_raw(ptr as *mut {}) }});\n", kind.path(), t.name ); rust.push_str("}\n"); ctx.rust_helpers.add(&drop_name, rust).mark_used(); } js_name } fn box_to_rust_helper(ast: &AST, ctx: &mut WasmCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.box_to_rust_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_box_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let js_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_js")); // This must be done first to avoid a stack overflow ctx.box_to_rust_helpers .insert(inner_ty.clone(), (js_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let end_name = locals.create("end"); let buf_name = locals.create("buf"); // Transform the value let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.js.mark_pure(&val_name); transform_to_rust(ast, ctx, &mut locals, &mut tfm, &val_name, &inner_ty); let val_code = tfm.rust.find(&val_name, inner_ty, RefInline).code; tfm.rust.line(format!("Box::new({val_code})")); // JavaScript { let mut js = JsString::default(); _ = write!(js, "\nfunction {js_name}({val_name}"); js.push_ts(": "); append_ts_type(&mut js, ast, &inner_ty); _ = write!(js, ", {buf_name}"); js.push_ts(": _ffi_WriteBuf"); js.push_both(")"); js.push_ts(": void"); js.push_both(" {\n"); tfm.js.write_to_js(ast, &mut js, " "); js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Other, "_ffi_WriteBuf") .mark_used(); } // Rust { let mut rust = String::new(); let mut item_ty = String::new(); let end_name = buf.final_end_name_for_rust(); append_rust_type(&mut item_ty, ast, inner_ty); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({end_name}: &mut *const u8) -> Box<{item_ty}> {{\n" ); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } (js_name, rust_name) } fn box_to_js_helper(ast: &AST, ctx: &mut WasmCtx, inner_ty: &RustType) -> (String, String) { if let Some(result) = ctx.box_to_js_helpers.get(inner_ty) { return result.clone(); } let mut base_name = "_ffi_box_".to_string(); append_type_name_hint(&mut base_name, ast, inner_ty); let js_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_js")); // This must be done first to avoid a stack overflow ctx.box_to_js_helpers .insert(inner_ty.clone(), (js_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); // Transform the value let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, ""); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; tfm.rust.mark_pure(&val_name); transform_to_js(ast, ctx, &mut locals, &mut tfm, &val_name, &inner_ty); let val_code = tfm.js.find(&val_name, inner_ty, RefInline).code; tfm.js.line(format!("return {val_code};")); // Rust { let mut rust = String::new(); let buf_name = buf.final_buf_name_for_rust(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({val_name}: "); append_rust_type(&mut rust, ast, inner_ty); _ = write!(rust, ", {buf_name}: &mut Vec) {{\n"); tfm.rust.write_to_rust(ast, &mut rust, " "); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); } // JavaScript { let mut js = JsString::default(); _ = write!(js, "\nfunction {js_name}({buf_name}"); js.push_ts(": _ffi_ReadBuf"); js.push_both(")"); js.push_ts(": "); append_ts_type(&mut js, ast, &inner_ty); js.push_both(" {\n"); tfm.js.write_to_js(ast, &mut js, " "); js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Other, "_ffi_ReadBuf") .mark_used(); } (js_name, rust_name) } fn enum_to_rust_helper(ast: &AST, ctx: &mut WasmCtx, enum_index: usize) -> (String, String) { if let Some(result) = ctx.enum_to_rust_helpers.get(&enum_index) { return result.clone(); } let e = &ast.enums[enum_index]; let base_name = format!("_ffi_enum_{}", e.name); let rust_name = ctx.helper_names.create(&format!("{base_name}_from_js")); let js_name = ctx.helper_names.create(&format!("{base_name}_to_rust")); // This must be done first to avoid a stack overflow ctx.enum_to_rust_helpers .insert(enum_index, (js_name.clone(), rust_name.clone())); let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); let end_name = locals.create("end"); let mut branches = Vec::new(); // Enums without fields are just integers if !e.has_fields() { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!(rust, "\nfn {rust_name}({val_name}: i32) -> {} {{\n", e.name); _ = write!(rust, " match {val_name} {{\n"); for v in &e.variants { _ = write!( rust, " {} => {}::{},\n", v.discriminant, e.name, v.name ); } rust.push_str(" _ => panic!(),\n"); rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers.add(&rust_name, rust).mark_used(); return (js_name, rust_name); } struct Branch { tfm: Transform, } // Transform all fields for each variant in a separate branch for v in &e.variants { let mut branch_locals = locals.clone(); let mut fields = Vec::new(); let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, &end_name); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; for f in &v.fields { let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len())); tfm.js .pure_decl(field_name.clone(), member_access(&val_name, &f.name)); transform_to_rust(ast, ctx, &mut branch_locals, &mut tfm, &field_name, &f.ty); fields.push(field_name); } rust_decl_ctor( &mut tfm.rust, &val_name, &format!("{}::{}", e.name, v.name), &v.fields, fields.iter().map(|x| Cow::Borrowed(x.as_str())).collect(), ); branches.push(Branch { tfm }); } // JavaScript { let mut js = JsString::from_template(&format!( "\nfunction {js_name}({val_name}«: {}», {buf_name}«: _ffi_WriteBuf»)«: void» {{\n", e.name )); _ = write!(js, " switch ({val_name}.$) {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { let write = js_write( ctx, &buf_name, &format!("{}", v.discriminant), &RustType::I32, ); _ = write!(js, " case {:?}:\n", v.name); _ = write!(js, " {}\n", write); branch.tfm.js.write_to_js(ast, &mut js, " "); js.push_both(" break;\n"); } js.push_both(" default:\n"); _ = write!( js, " throw TypeError({:?});\n", format!("Invalid value for enum {:?}", e.name) ); js.push_both(" }\n"); js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Other, "_ffi_WriteBuf") .mark_used(); } // Rust { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({end_name}: &mut *const u8) -> {} {{\n", e.name ); _ = write!(rust, " match _ffi_read::({end_name}) {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { let val_code = branch .tfm .rust .find(&val_name, &RustType::Enum(enum_index), RefInline) .code; if branch.tfm.rust.is_empty() { let val_code = format!("{} => {val_code},", v.discriminant); branch.tfm.rust.line(val_code); branch.tfm.rust.write_to_rust(ast, &mut rust, " "); } else { _ = write!(rust, " {} => {{", v.discriminant); branch.tfm.rust.line(val_code); branch .tfm .rust .write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } } rust.push_str(" _ => panic!(),\n"); rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers .add(&rust_name, rust) .add_dep("_ffi_read") .mark_used(); } (js_name, rust_name) } fn enum_to_js_helper(ast: &AST, ctx: &mut WasmCtx, enum_index: usize) -> (String, String) { if let Some(result) = ctx.enum_to_js_helpers.get(&enum_index) { return result.clone(); } let e = &ast.enums[enum_index]; let base_name = format!("_ffi_enum_{}", e.name); let js_name = ctx.helper_names.create(&format!("{base_name}_from_rust")); let rust_name = ctx.helper_names.create(&format!("{base_name}_to_js")); // This must be done first to avoid a stack overflow ctx.enum_to_js_helpers .insert(enum_index, (js_name.clone(), rust_name.clone())); struct Branch { tfm: Transform, fields: Vec, } let mut locals = NameSet::default(); let val_name = locals.create("val"); let buf_name = locals.create("buf"); let mut branches = Vec::new(); let mut js_deps = HashSet::new(); // Transform all fields for each variant in a separate branch for v in &e.variants { let mut branch_locals = locals.clone(); let mut fields = Vec::new(); let mut tfm = Transform::default(); let buf = SharedBuf::new(&buf_name, ""); tfm.buf = Some(buf.clone()); tfm.buf_status = BufStatus::Inside; for f in &v.fields { let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len())); tfm.rust.mark_pure(&field_name); transform_to_js(ast, ctx, &mut branch_locals, &mut tfm, &field_name, &f.ty); fields.push(field_name); } let mut val_fields = vec![RustField { name: "$".to_string(), ty: RustType::ForeignHandle, }]; let mut val_names = vec![Cow::Owned(format!("{:?}", v.name))]; val_fields.extend_from_slice(&v.fields); for name in &fields { val_names.push(Cow::Borrowed(name.as_str())); } let val_code = tfm .js .find_fields(&val_fields, val_names, RefInline, "{ ", " }"); if v.fields.is_empty() { // Turn enums without fields into singletons to reduce garbage generation let singleton_name = ctx .helper_names .create(&format!("_ffi_enum_{}__{}", e.name, v.name)); let mut js = JsString::from_template(&format!("let {}«: {}» = ", singleton_name, e.name)); js.push_both(&val_code); js.push_both(";\n"); ctx.js_helpers.add_group(JsGroup::Let, &singleton_name, js); tfm.js.pure_decl(&val_name, singleton_name.clone()); js_deps.insert((JsGroup::Let, singleton_name)); } else { tfm.js.decl(&val_name, val_code); } branches.push(Branch { tfm, fields }); } // Rust { let mut rust = String::new(); allow_non_snake_case(&mut rust, &rust_name); _ = write!( rust, "\nfn {rust_name}({val_name}: {}, {buf_name}: &mut Vec) {{\n", e.name ); _ = write!(rust, " match {val_name} {{\n"); for (v, branch) in e.variants.iter().zip(&mut branches) { _ = write!(rust, " {}::{}", e.name, v.name); if v.fields.iter().any(|f| starts_with_digit(&f.name)) { rust.push_str("("); for (i, name) in branch.fields.iter().enumerate() { rust.push_str(if i > 0 { ", " } else { "" }); rust.push_str(name); } rust.push_str(")"); } else if !v.fields.is_empty() { rust.push_str(" {"); for (i, (f, name)) in v.fields.iter().zip(&branch.fields).enumerate() { rust.push_str(if i > 0 { ", " } else { " " }); if f.name != *name { _ = write!(rust, "{}: ", f.name); } rust.push_str(name); } rust.push_str(" }"); } if branch.tfm.rust.is_empty() { _ = write!( rust, " => _ffi_write({} as i32, {buf_name}),\n", v.discriminant ); } else { rust.push_str(" => {\n"); _ = write!( rust, " _ffi_write({} as i32, {buf_name});\n", v.discriminant ); branch .tfm .rust .write_to_rust(ast, &mut rust, " "); rust.push_str(" }\n"); } } rust.push_str(" }\n"); rust.push_str("}\n"); ctx.rust_helpers .add(&rust_name, rust) .add_dep("_ffi_write") .mark_used(); } // JavaScript { let mut js = JsString::from_template(&format!( "\nfunction {js_name}({buf_name}«: _ffi_ReadBuf»)«: {}» {{\n", e.name )); let read = js_read(ctx, &buf_name, &RustType::I32); _ = write!(js, " switch ({read}) {{\n",); for (v, branch) in e.variants.iter().zip(&mut branches) { let val_code = branch .tfm .js .find(&val_name, &RustType::Enum(enum_index), RefInline) .code; if branch.tfm.js.is_empty() { let val_code = format!("case {}: return {val_code};", v.discriminant); branch.tfm.js.line(val_code); branch.tfm.js.write_to_js(ast, &mut js, " "); } else { _ = write!(js, " case {}: {{\n", v.discriminant); branch.tfm.js.line(format!("return {val_code};")); branch.tfm.js.write_to_js(ast, &mut js, " "); js.push_both(" }\n"); } } js.push_both(" default: throw Error();\n"); js.push_both(" }\n"); js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, &js_name, js) .add_dep_group(JsGroup::Other, "_ffi_ReadBuf") .add_deps_group(js_deps) .mark_used(); } (js_name, rust_name) } fn multi_ret_helper(ast: &AST, ctx: &mut WasmCtx, args: &[RustArg]) -> (String, String) { let types: Vec<_> = args.iter().map(|arg| arg.ty.clone()).collect(); if let Some(result) = ctx.multi_ret_helpers.get(&types) { return result.clone(); } let mut ty_name = "_ffi_ret_".to_string(); append_type_name_hints(&mut ty_name, ast, &types); let ty_name = ctx.helper_names.create(&ty_name); let static_name = ty_name.to_uppercase(); // Rust { let mut rust = String::new(); _ = write!(rust, "\n#[repr(C)]\nstruct {ty_name}("); for (i, ty) in types.iter().enumerate() { if i > 0 { rust.push_str(", "); } append_rust_type(&mut rust, ast, ty); } rust.push_str(");\n"); _ = write!(rust, "static mut {static_name}: {ty_name} = {ty_name}("); for (i, ty) in types.iter().enumerate() { if i > 0 { rust.push_str(", "); } append_rust_default_val(&mut rust, ast, ty); } rust.push_str(");\n"); ctx.rust_helpers.add(&ty_name, rust).mark_used(); } ctx.multi_ret_helpers .insert(types, (ty_name.clone(), static_name.clone())); (ty_name, static_name) } fn js_multi_ret_load(view: &str, ptr: &str, ty: &RustType, offset: &mut usize) -> String { use RustType::*; let (size, method) = match ty { Bool | U8 => (1, "getUint8"), // Note: the "!!" int-to-bool cast is added elsewhere I8 => (1, "getInt8"), U16 => (2, "getUint16"), I16 => (2, "getInt16"), U32 | Usize => (4, "getUint32"), I32 | Isize | ForeignHandle => (4, "getInt32"), U64 => (8, "setBigUint64"), I64 => (8, "setBigInt64"), F32 => (4, "getFloat32"), F64 => (8, "getFloat64"), _ => unreachable!(), }; *offset = (*offset + (size - 1)) & !(size - 1); let load = match (*offset, size) { (0, 1) => format!("{view}.{method}({ptr})"), (0, _) => format!("{view}.{method}({ptr}, true)"), (_, 1) => format!("{view}.{method}({ptr} + {offset})"), (_, _) => format!("{view}.{method}({ptr} + {offset}, true)"), }; *offset += size; load } fn js_multi_ret_size(ty: &RustType) -> u32 { use RustType::*; match ty { Bool | U8 | I8 => 1, U16 | I16 => 2, U32 | Usize | I32 | Isize | ForeignHandle => 4, U64 | I64 => 8, F32 => 4, F64 => 8, _ => unreachable!(), } } fn js_multi_ret_store(view: &str, ptr: &str, val: &str, ty: &RustType, offset: u32) -> String { use RustType::*; let method = match ty { Bool | U8 | I8 => "setInt8", U16 | I16 => "setInt16", U32 | Usize | I32 | Isize | ForeignHandle => "setInt32", U64 | I64 => "setBigInt64", F32 => "setFloat32", F64 => "setFloat64", _ => unreachable!(), }; match (offset, method != "setInt8") { (0, false) => format!("{view}.{method}({ptr}, {val});"), (0, true) => format!("{view}.{method}({ptr}, {val}, true);"), (_, false) => format!("{view}.{method}({ptr} + {offset}, {val});"), (_, true) => format!("{view}.{method}({ptr} + {offset}, {val}, true);"), } } fn js_write(ctx: &mut WasmCtx, buf: &str, val: &str, ty: &RustType) -> String { use RustType::*; let mut cast = ""; let (size, method, helper) = match ty { Pair { other, .. } => return js_write(ctx, buf, val, other), Bool => { cast = "+"; (1, "setInt8", "_ffi_write_i8") } U8 | I8 => (1, "setInt8", "_ffi_write_i8"), U16 | I16 => (2, "setInt16", "_ffi_write_i16"), U32 | Usize | I32 | Isize | ForeignHandle => (4, "setInt32", "_ffi_write_i32"), U64 | I64 => (8, "setBigInt64", "_ffi_write_i64"), F32 => (4, "setFloat32", "_ffi_write_f32"), F64 => (8, "setFloat64", "_ffi_write_f64"), _ => unreachable!(), }; let result = if !cast.is_empty() && val.chars().any(|c| !c.is_alphanumeric()) { format!("{helper}({buf}, {cast}({val}));") } else { format!("{helper}({buf}, {cast}{val});") }; if ctx.js_helpers.was_added(JsGroup::Other, helper) { return result; } let val_ty = match ty { U64 | I64 => "bigint", _ => "number", }; let is_le = if size == 1 { "" } else { ", true" }; let js = JsString::from_template(&format!( " function {helper}(buf«: _ffi_WriteBuf», val«: {val_ty}»)«: void» {{ let ptr = _ffi_grow(buf, {size}); buf.dv«!».{method}(ptr, val{is_le}); }} " )); ctx.js_helpers .add_group(JsGroup::Other, helper, js) .add_dep_group(JsGroup::Other, "_ffi_WriteBuf") .add_dep_group(JsGroup::Other, "_ffi_grow") .mark_used(); result } fn js_read(ctx: &mut WasmCtx, buf: &str, ty: &RustType) -> String { use RustType::*; let mut prefix = ""; let (size, method, helper) = match ty { Pair { other, .. } => return js_read(ctx, buf, other), Bool => { prefix = "!!"; (1, "getUint8", "_ffi_read_u8") } U8 => (1, "getUint8", "_ffi_read_u8"), I8 => (1, "getInt8", "_ffi_read_i8"), U16 => (2, "getUint16", "_ffi_read_u16"), I16 => (2, "getInt16", "_ffi_read_i16"), U32 | Usize => (4, "getUint32", "_ffi_read_u32"), I32 | Isize | ForeignHandle => (4, "getInt32", "_ffi_read_i32"), U64 => (8, "setBigUint64", "_ffi_read_u64"), I64 => (8, "setBigInt64", "_ffi_read_i64"), F32 => (4, "getFloat32", "_ffi_read_f32"), F64 => (8, "getFloat64", "_ffi_read_f64"), _ => unreachable!(), }; let result = format!("{prefix}{helper}({buf})"); if ctx.js_helpers.was_added(JsGroup::Other, helper) { return result; } let val_ty = match ty { U64 | I64 => "bigint", _ => "number", }; let mut js = JsString::from_template(&format!( "\nfunction {helper}(buf«: _ffi_ReadBuf»)«: {val_ty}» {{\n" )); if size == 1 { _ = write!(js, " return buf.dv.{method}({buf}.off++);\n"); } else { let is_le = if size == 1 { "" } else { ", true" }; _ = write!(js, " let val = buf.dv.{method}({buf}.off{is_le});\n"); _ = write!(js, " buf.off += {size};\n"); js.push_both(" return val;\n"); } js.push_both("}\n"); ctx.js_helpers .add_group(JsGroup::Other, helper, js) .add_dep_group(JsGroup::Other, "_ffi_ReadBuf") .mark_used(); result } fn append_ts_type(ts: &mut JsString, ast: &AST, ty: &RustType) { use RustType::*; #[derive(Eq, PartialEq)] enum Parent { Top, Vector, Optional, } fn append(ts: &mut JsString, ast: &AST, ty: &RustType, parent: Parent) { match ty { Pair { other, .. } => append(ts, ast, other, parent), Verbatim(text) => ts.push_ts(text), Bool => ts.push_ts("boolean"), U8 | U16 | U32 | Usize => ts.push_ts("number"), I8 | I16 | I32 | Isize => ts.push_ts("number"), F32 | F64 | ForeignHandle => ts.push_ts("number"), U64 | I64 => ts.push_ts("bigint"), RefStr | OwnStr => ts.push_ts("string"), Struct(index) => ts.push_ts(&ast.structs[*index].name), Enum(index) => ts.push_ts(&ast.enums[*index].name), DynTrait(index) => ts.push_ts(&ast.traits[*index].name), Ptr(_, inner) => append(ts, ast, inner, parent), Vector(inner) => { append(ts, ast, &inner, Parent::Vector); ts.push_ts("[]"); } Tuple(types) if types.is_empty() => ts.push_ts("undefined"), Tuple(types) => { ts.push_ts("["); for (i, ty) in types.iter().enumerate() { if i > 0 { ts.push_ts(", "); } append(ts, ast, ty, Parent::Top); } ts.push_ts("]"); } Optional(inner) if parent == Parent::Optional => append(ts, ast, inner, parent), Optional(inner) => { let wrap = parent == Parent::Vector; if wrap { ts.push_ts("("); } append(ts, ast, &inner, Parent::Optional); ts.push_ts(" | null"); if wrap { ts.push_ts(")"); } } } } append(ts, ast, ty, Parent::Top) } fn append_js_val(js: &mut JsString, val: &RustVal) { use RustVal::*; match val { Bool(x) => _ = write!(js, "{x}"), U8(x) => _ = write!(js, "{x}"), U16(x) => _ = write!(js, "{x}"), U32(x) => _ = write!(js, "{x}"), U64(x) => _ = write!(js, "{x}n"), I8(x) => _ = write!(js, "{x}"), I16(x) => _ = write!(js, "{x}"), I32(x) => _ = write!(js, "{x}"), I64(x) => _ = write!(js, "{x}n"), F32(x) => _ = write!(js, "{}", *x as f64), F64(x) => _ = write!(js, "{x}"), Str(x) => append_js_quoted(js, x), } } fn append_js_quoted(js: &mut JsString, text: &str) { js.push_both("\""); for c in text.chars() { match c { '\t' => js.push_both("\\t"), '\n' => js.push_both("\\n"), '\r' => js.push_both("\\r"), '\\' => js.push_both("\\\\"), '\"' => js.push_both("\\\""), c if (c as u32) < 0x20 => _ = write!(js, "\\x{:02x}", c as u32), _ => _ = write!(js, "{c}"), } } js.push_both("\""); } fn member_access(object: &str, member: &str) -> String { match starts_with_digit(member) { false => format!("{object}.{member}"), true => format!("{object}[{member}]"), } } impl FnBuilder { fn write_to_js(&mut self, ast: &AST, out: &mut JsString, base_indent: &str) { let callback = |line: &str, out: &mut String, indent: &mut usize| { if line.starts_with(&['}', ']', ')']) { *indent -= 1; } _ = write!(out, "{base_indent}{}{line}\n", " ".repeat(*indent)); if line.ends_with(&['{', '[', '(']) { *indent += 1; } }; let mut js_indent = 0; let mut ts_indent = 0; for line in self.take_lines() { match line { Line::Plain(text) => { for line in text.split('\n') { callback(line, &mut out.without_types, &mut js_indent); callback(line, &mut out.with_types, &mut ts_indent); } } Line::PlainAlt(when_false, when_true, flag) => { let text = match flag.get() { false if when_false.is_empty() => continue, false => when_false, true => when_true, }; for line in text.split('\n') { callback(line, &mut out.without_types, &mut js_indent); callback(line, &mut out.with_types, &mut ts_indent); } } Line::Decl(name, ty, text) => { for line in format!("let {name} = {text};").split('\n') { callback(line, &mut out.without_types, &mut js_indent); if ty.is_none() { callback(line, &mut out.with_types, &mut ts_indent); } } // Handle optional type annotations separately if let Some(ty) = ty { let mut decl_ty = JsString::default(); append_ts_type(&mut decl_ty, ast, &ty); let text = format!("let {name}: {} = {text};", decl_ty.with_types); for line in text.split('\n') { callback(line, &mut out.with_types, &mut js_indent); } } } } } } }