RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core) {
	RzListIter *it;
	RzAnalysisFunction *fcn;
	ut64 seek;
	if (rz_config_get_b(core->config, "cfg.debug")) {
		eprintf("TOFIX: aaft can't run in debugger mode.\n");
		return false;
	}
	RzConfigHold *hold = rz_config_hold_new(core->config);
	rz_config_hold_i(hold, "io.va", "io.pcache.write", NULL);
	bool io_cache = rz_config_get_b(core->config, "io.pcache.write");
	if (!io_cache) {
		// XXX. we shouldnt need this, but it breaks 'rizin -c aaa -w ls'
		rz_config_set_b(core->config, "io.pcache.write", true);
	}
	const bool delete_regs = !rz_flag_space_count(core->flags, RZ_FLAGS_FS_REGISTERS);
	seek = core->offset;
	rz_reg_arena_push(core->analysis->reg);
	rz_reg_arena_zero(core->analysis->reg);
	rz_core_analysis_esil_init(core);
	rz_core_analysis_esil_init_mem(core, NULL, UT64_MAX, UT32_MAX);
	ut8 *saved_arena = rz_reg_arena_peek(core->analysis->reg);

	// loop count of rz_core_analysis_type_match
	// TODO : figure out the reason to hold a `LOOP COUNT` in type_match
	// HtUU <addr->loop_count>
	HtUU *loop_table = ht_uu_new0();

	// Iterating Reverse so that we get function in top-bottom call order
	rz_list_foreach_prev(core->analysis->fcns, it, fcn) {
		int ret = rz_core_seek(core, fcn->addr, true);
		if (!ret) {
			continue;
		}
		rz_reg_arena_poke(core->analysis->reg, saved_arena);
		rz_analysis_esil_set_pc(core->analysis->esil, fcn->addr);
		rz_core_analysis_type_match(core, fcn, loop_table);
		if (rz_cons_is_breaked()) {
			break;
		}
		rz_analysis_fcn_vars_add_types(core->analysis, fcn);
	}
	if (delete_regs) {
		rz_core_debug_clear_register_flags(core);
	}
	rz_core_seek(core, seek, true);
	rz_reg_arena_pop(core->analysis->reg);
	rz_config_hold_restore(hold);
	rz_config_hold_free(hold);
	free(saved_arena);
	ht_uu_free(loop_table);
	return true;
}
RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core) {
	RzListIter *it;
	RzAnalysisFunction *fcn;
	ut64 seek;
	if (rz_config_get_b(core->config, "cfg.debug")) {
		eprintf("TOFIX: aaft can't run in debugger mode.\n");
		return false;
	}
	RzConfigHold *hold = rz_config_hold_new(core->config);
	rz_config_hold_i(hold, "io.va", "io.pcache.write", NULL);
	bool io_cache = rz_config_get_b(core->config, "io.pcache.write");
	if (!io_cache) {
		 
		rz_config_set_b(core->config, "io.pcache.write", true);
	}
	const bool delete_regs = !rz_flag_space_count(core->flags, RZ_FLAGS_FS_REGISTERS);
	seek = core->offset;
	rz_reg_arena_push(core->analysis->reg);
	rz_reg_arena_zero(core->analysis->reg);
	rz_core_analysis_esil_init(core);
	rz_core_analysis_esil_init_mem(core, NULL, UT64_MAX, UT32_MAX);
	ut8 *saved_arena = rz_reg_arena_peek(core->analysis->reg);

	 
	 
	 
	HtUU *loop_table = ht_uu_new0();

	 
	rz_list_foreach_prev(core->analysis->fcns, it, fcn) {
		int ret = rz_core_seek(core, fcn->addr, true);
		if (!ret) {
			continue;
		}
		rz_reg_arena_poke(core->analysis->reg, saved_arena);
		rz_analysis_esil_set_pc(core->analysis->esil, fcn->addr);
		rz_core_analysis_type_match(core, fcn, loop_table);
		if (rz_cons_is_breaked()) {
			break;
		}
		rz_analysis_fcn_vars_add_types(core->analysis, fcn);
	}
	if (delete_regs) {
		rz_core_debug_clear_register_flags(core);
	}
	rz_core_seek(core, seek, true);
	rz_reg_arena_pop(core->analysis->reg);
	rz_config_hold_restore(hold);
	rz_config_hold_free(hold);
	free(saved_arena);
	ht_uu_free(loop_table);
	return true;
}