1// Mangled symbol arrangements: 2// 3// (a) One-off internal symbol. 4// pattern: {CXXBRIDGE} $ {NAME} 5// examples: 6// - cxxbridge1$exception 7// defining characteristics: 8// - 2 segments 9// - starts with cxxbridge 10// 11// (b) Behavior on a builtin binding without generic parameter. 12// pattern: {CXXBRIDGE} $ {TYPE} $ {NAME} 13// examples: 14// - cxxbridge1$string$len 15// defining characteristics: 16// - 3 segments 17// - starts with cxxbridge 18// 19// (c) Behavior on a builtin binding with generic parameter. 20// pattern: {CXXBRIDGE} $ {TYPE} $ {PARAM...} $ {NAME} 21// examples: 22// - cxxbridge1$box$org$rust$Struct$alloc 23// - cxxbridge1$unique_ptr$std$vector$u8$drop 24// defining characteristics: 25// - 4+ segments 26// - starts with cxxbridge 27// 28// (d) User-defined extern function. 29// pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {NAME} 30// examples: 31// - cxxbridge1$new_client 32// - org$rust$cxxbridge1$new_client 33// defining characteristics: 34// - cxxbridge is second from end 35// FIXME: conflict with (a) if they collide with one of our one-off symbol names in the global namespace 36// 37// (e) User-defined extern member function. 38// pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE} $ {NAME} 39// examples: 40// - org$cxxbridge1$Struct$get 41// defining characteristics: 42// - cxxbridge is third from end 43// FIXME: conflict with (b) if e.g. user binds a type in global namespace that collides with our builtin type names 44// 45// (f) Operator overload. 46// pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE} $ operator $ {NAME} 47// examples: 48// - org$rust$cxxbridge1$Struct$operator$eq 49// defining characteristics: 50// - second segment from end is `operator` (not possible in type or namespace names) 51// 52// (g) Closure trampoline. 53// pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE?} $ {NAME} $ {ARGUMENT} $ {DIRECTION} 54// examples: 55// - org$rust$cxxbridge1$Struct$invoke$f$0 56// defining characteristics: 57// - last symbol is `0` (C half) or `1` (Rust half) which are not legal identifiers on their own 58// 59// 60// Mangled preprocessor variable arrangements: 61// 62// (A) One-off internal variable. 63// pattern: {CXXBRIDGE} _ {NAME} 64// examples: 65// - CXXBRIDGE1_PANIC 66// - CXXBRIDGE1_RUST_STRING 67// defining characteristics: 68// - NAME does not begin with STRUCT or ENUM 69// 70// (B) Guard around user-defined type. 71// pattern: {CXXBRIDGE} _ {STRUCT or ENUM} _ {NAMESPACE...} $ {TYPE} 72// examples: 73// - CXXBRIDGE1_STRUCT_org$rust$Struct 74// - CXXBRIDGE1_ENUM_Enabled 75 76use crate::syntax::symbol::{self, Symbol}; 77use crate::syntax::{ExternFn, Pair, Types}; 78 79const CXXBRIDGE: &str = "cxxbridge1"; 80 81macro_rules! join { 82 ($($segment:expr),+ $(,)?) => { 83 symbol::join(&[$(&$segment),+]) 84 }; 85} 86 87pub fn extern_fn(efn: &ExternFn, types: &Types) -> Symbol { 88 match &efn.receiver { 89 Some(receiver) => { 90 let receiver_ident = types.resolve(&receiver.ty); 91 join!( 92 efn.name.namespace, 93 CXXBRIDGE, 94 receiver_ident.name.cxx, 95 efn.name.rust, 96 ) 97 } 98 None => join!(efn.name.namespace, CXXBRIDGE, efn.name.rust), 99 } 100} 101 102pub fn operator(receiver: &Pair, operator: &'static str) -> Symbol { 103 join!( 104 receiver.namespace, 105 CXXBRIDGE, 106 receiver.cxx, 107 "operator", 108 operator, 109 ) 110} 111 112// The C half of a function pointer trampoline. 113pub fn c_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol { 114 join!(extern_fn(efn, types), var.rust, 0) 115} 116 117// The Rust half of a function pointer trampoline. 118pub fn r_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol { 119 join!(extern_fn(efn, types), var.rust, 1) 120} 121