@@ -1147,6 +1147,60 @@ std::string emit_asm_wrapper(
11471147
11481148 emit_prologue (aw, caller_pkey, target_pkey, arch);
11491149
1150+ // Check types that have (both) {con,de}structors.
1151+ // Check types in the type registry.
1152+ // If the function is itself a constructor or destructor,
1153+ // call `ia2_type_registry_{con,de}struct`.
1154+ // Otherwise, go through all of the args,
1155+ // and if they have (both) {con,de}structors
1156+ // and are one of the 6 x86 register args,
1157+ // call `ia2_type_registry_check`.
1158+ // TODO make x86 only
1159+ std::string_view ia2_type_registry_fn_kind;
1160+ std::string ia2_type_registry_fn_name;
1161+ std::vector<size_t > arg_indices_to_check;
1162+ if (target_name) {
1163+ if (ctx.constructors .find (*target_name) != ctx.constructors .end ()) {
1164+ ia2_type_registry_fn_kind = " construct" ;
1165+ arg_indices_to_check.emplace_back (0 );
1166+ } else if (ctx.destructors .find (*target_name) != ctx.destructors .end ()) {
1167+ ia2_type_registry_fn_kind = " destruct" ;
1168+ arg_indices_to_check.emplace_back (0 );
1169+ } else {
1170+ ia2_type_registry_fn_kind = " check" ;
1171+ for (auto i = 0 ; i < sig.api .args .size (); i++) {
1172+ const auto &arg = sig.api .args [i];
1173+ const auto &type = ctx.types .get (arg.type );
1174+ if (!type.has_structors ()) {
1175+ continue ;
1176+ }
1177+ if (i >= x86_int_param_reg_order.size ()) {
1178+ llvm::errs () << " skipping checking type " << type.canonical_name << " type ID " << type.id << " for arg #" << i << " of function " << *target_name << " \n " ;
1179+ continue ;
1180+ }
1181+ arg_indices_to_check.emplace_back (i);
1182+ }
1183+ }
1184+ ia2_type_registry_fn_name = llvm::formatv (" ia2_type_registry_{0}" , ia2_type_registry_fn_kind);
1185+ }
1186+
1187+ if (!arg_indices_to_check.empty ()) {
1188+ emit_save_args (aw, arch);
1189+ emit_align_stack (aw, arch);
1190+ for (const auto i : arg_indices_to_check) {
1191+ const auto &arg = sig.api .args [i];
1192+ const auto &type = ctx.types .get (arg.type );
1193+ add_comment_line (aw, llvm::formatv (" {0}ing type {1}, type ID {2}, arg #{3}" , ia2_type_registry_fn_kind, type.canonical_name , type.id , i));
1194+ // `ia2_type_registry_*` arg 0 is a ptr of type `T*` from arg i.
1195+ add_asm_line (aw, llvm::formatv (" movq {0}(%rsp), %{1}" , 8 + 8 * (x86_int_param_reg_order.size () - 1 - i), x86_int_param_reg_order[0 ]));
1196+ // `ia2_type_registry_*` arg 1 is the `TypeId`.
1197+ add_asm_line (aw, llvm::formatv (" movq ${0}, %{1}" , type.id , x86_int_param_reg_order[1 ]));
1198+ emit_direct_call (aw, arch, ia2_type_registry_fn_name);
1199+ }
1200+ emit_revert_align_stack (aw, arch);
1201+ emit_restore_args (aw, arch, /* pop */ true );
1202+ }
1203+
11501204 // Call the pre-condition functions for this target function.
11511205 // The calls happens in the caller's compartment.
11521206 // If there are any post-condition functions, save the args for that, too.
0 commit comments