1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use super::*;

/////////////////////////////////////

/// Functions used to test that the C abi is the same in both the library and the loader.
#[repr(C)]
#[derive(StableAbi)]
pub struct CAbiTestingFns{
    pub(crate) take_pair_a:extern "C" fn(Tuple2<u16,()>)->u32,
    pub(crate) take_pair_b:extern "C" fn(Tuple2<(),u16>)->u32,
    pub(crate) ret_pair_a:extern "C" fn(u32)->Tuple2<u16,()>,
    pub(crate) ret_pair_b:extern "C" fn(u32)->Tuple2<(),u16>,
    
    pub(crate) take_triple_a:extern "C" fn(Tuple3<(),u16,u16>)->u64,
    pub(crate) take_triple_b:extern "C" fn(Tuple3<u16,(),u16>)->u64,
    pub(crate) take_triple_c:extern "C" fn(Tuple3<u16,u16,()>)->u64,
    pub(crate) ret_triple_a:extern "C" fn(u64)->Tuple3<(),u16,u16>,
    pub(crate) ret_triple_b:extern "C" fn(u64)->Tuple3<u16,(),u16>,
    pub(crate) ret_triple_c:extern "C" fn(u64)->Tuple3<u16,u16,()>,
    
    pub(crate) take_2_pairs_a:extern "C" fn(Tuple2<(),u16>,Tuple2<(),u16>)->u64,
    pub(crate) take_2_pairs_b:extern "C" fn(Tuple2<u16,()>,Tuple2<u16,()>)->u64,
    pub(crate) ret_2_pairs_a:extern "C" fn(u64)->Tuple2<Tuple2<(),u16>,Tuple2<(),u16>>,
    pub(crate) ret_2_pairs_b:extern "C" fn(u64)->Tuple2<Tuple2<u16,()>,Tuple2<u16,()>>,

    pub(crate) mixed_units:extern "C" fn(u16,MyUnit,u16,MyUnit,u16,MyUnit,u16)->u64,
    
}

/////////////////////////////////////

/// Functions used to test that the C abi is the same in both the library and the loader.
pub const C_ABI_TESTING_FNS:&CAbiTestingFns=&CAbiTestingFns{
    take_pair_a,
    take_pair_b,
    ret_pair_a,
    ret_pair_b,
    take_triple_a,
    take_triple_b,
    take_triple_c,
    ret_triple_a,
    ret_triple_b,
    ret_triple_c,
    take_2_pairs_a,
    take_2_pairs_b,
    ret_2_pairs_a,
    ret_2_pairs_b,
    mixed_units,
};


pub(crate) extern "C" fn take_pair_a(pair:Tuple2<u16,()>)->u32{
    pair.0 as u32
}
pub(crate) extern "C" fn take_pair_b(pair:Tuple2<(),u16>)->u32{
    (pair.1 as u32)<<16
}
pub(crate) extern "C" fn ret_pair_a(n:u32)->Tuple2<u16,()>{
    Tuple2(n as u16,())
}
pub(crate) extern "C" fn ret_pair_b(n:u32)->Tuple2<(),u16>{
    Tuple2((),(n>>16)as u16)
}


pub(crate) extern "C" fn take_triple_a(triple:Tuple3<(),u16,u16>)->u64{
    ((triple.1 as u64)<<16)+
    ((triple.2 as u64)<<32)
}
pub(crate) extern "C" fn take_triple_b(triple:Tuple3<u16,(),u16>)->u64{
    (triple.0 as u64)+
    ((triple.2 as u64)<<32)
}
pub(crate) extern "C" fn take_triple_c(triple:Tuple3<u16,u16,()>)->u64{
    (triple.0 as u64)+
    ((triple.1 as u64)<<16)
}
pub(crate) extern "C" fn ret_triple_a(n:u64)->Tuple3<(),u16,u16>{
    Tuple3(
        (),
        (n>>16) as u16,
        (n>>32) as u16,
    )
}
pub(crate) extern "C" fn ret_triple_b(n:u64)->Tuple3<u16,(),u16>{
    Tuple3(
        n as u16,
        (),
        (n>>32) as u16,
    )
}
pub(crate) extern "C" fn ret_triple_c(n:u64)->Tuple3<u16,u16,()>{
    Tuple3(
        n as u16,
        (n>>16) as u16,
        (),
    )
}


pub(crate) extern "C" fn take_2_pairs_a(a:Tuple2<(),u16>,b:Tuple2<(),u16>)->u64{
    ((a.1 as u64)<<16)+
    ((b.1 as u64)<<48)
}
pub(crate) extern "C" fn take_2_pairs_b(a:Tuple2<u16,()>,b:Tuple2<u16,()>)->u64{
    (a.0 as u64)+
    ((b.0 as u64)<<32)
}
pub(crate) extern "C" fn ret_2_pairs_a(n:u64)->Tuple2<Tuple2<(),u16>,Tuple2<(),u16>>{
    Tuple2(
        Tuple2((),(n>>16)as u16),
        Tuple2((),(n>>48)as u16),
    )
}
pub(crate) extern "C" fn ret_2_pairs_b(n:u64)->Tuple2<Tuple2<u16,()>,Tuple2<u16,()>>{
    Tuple2(
        Tuple2(n as u16,()),
        Tuple2((n>>32)as u16,()),
    )
}


pub(crate) extern "C" fn mixed_units(
    a:u16,
    _:MyUnit,
    b:u16,
    _:MyUnit,
    c:u16,
    _:MyUnit,
    d:u16,
)->u64{
    (a as u64)|
    ((b as u64)<<16)|
    ((c as u64)<<32)|
    ((d as u64)<<48)
}