///|
/// How a hidden safepoint describes GC roots already present in its arguments.
pub(all) enum StackMapArgumentRoots {
Fixed(Int)
I32ConstantOperand(Int)
AllocationOperands
} derive(Debug, Eq)
///|
pub struct HiddenSafepointAbi {
priv symbol : @native.ExternalSymbol
priv argument_roots : StackMapArgumentRoots
}
///|
pub fn HiddenSafepointAbi::new(
symbol : @native.ExternalSymbol,
argument_roots : StackMapArgumentRoots,
) -> HiddenSafepointAbi {
{ symbol, argument_roots, }
}
///|
pub struct CallerRootScopeAbi {
priv push_symbol : @native.ExternalSymbol
priv pop_symbol : @native.ExternalSymbol
}
///|
pub fn CallerRootScopeAbi::new(
push_symbol : @native.ExternalSymbol,
pop_symbol : @native.ExternalSymbol,
) -> CallerRootScopeAbi {
{ push_symbol, pop_symbol, }
}
///|
pub struct CallAbiElaboration {
priv root_scope : CallerRootScopeAbi?
priv hidden_safepoints : Array[HiddenSafepointAbi]
}
///|
pub fn CallAbiElaboration::new(
root_scope? : CallerRootScopeAbi,
hidden_safepoints? : Array[HiddenSafepointAbi] = [],
) -> CallAbiElaboration {
{ root_scope, hidden_safepoints: hidden_safepoints.copy(), }
}
///|
fn CallAbiElaboration::hidden_safepoint(
self : CallAbiElaboration,
call : @native.NativeCall,
) -> HiddenSafepointAbi? {
guard call.callee is External(symbol) else { return None }
for hidden in self.hidden_safepoints {
if hidden.symbol == symbol {
return Some(hidden)
}
}
None
}
///|
fn root_scope_push_call(symbol : @native.ExternalSymbol) -> @native.NativeCall {
@native.NativeCall::new(
External(symbol),
@native.Signature::new([Ptr64, Ptr64, I32], []),
Platform,
@native.CallBehavior::new(ReadWrite, true, false, false, false),
)
}
///|
fn root_scope_pop_call(symbol : @native.ExternalSymbol) -> @native.NativeCall {
@native.NativeCall::new(
External(symbol),
@native.Signature::new([Ptr64], []),
Platform,
@native.CallBehavior::new(ReadWrite, true, false, false, false),
)
}
///|
pub suberror DirectLoweringError {
InvalidCallAbi(message~ : String)
} derive(Debug, Eq)
///|
pub impl Show for DirectLoweringError with fn output(self, logger) {
logger.write_string(Repr(self).to_string())
}