Stack Limit as an Argument Purpose (#372)

* Initial approach.

* Move stack_limit check before opening the frame

* Account for GPRs and frame pointer in stack check

* Check stack_limit example.

* Remove stack_limit attribute code.

Amends #359

* fmt
This commit is contained in:
Sergey Pepyakin
2018-08-04 16:16:21 +03:00
committed by Dan Gohman
parent 217786e969
commit 9dbfbbde10
10 changed files with 91 additions and 75 deletions

View File

@@ -293,10 +293,25 @@ pub enum ArgumentPurpose {
/// This is a special-purpose argument used to identify the calling convention expected by the
/// caller in an indirect call. The callee can verify that the expected signature ID matches.
SignatureId,
/// A stack limit pointer.
///
/// This is a pointer to a stack limit. It is used to check the current stack pointer
/// against. Can only appear once in a signature.
StackLimit,
}
/// Text format names of the `ArgumentPurpose` variants.
static PURPOSE_NAMES: [&str; 7] = ["normal", "sret", "link", "fp", "csr", "vmctx", "sigid"];
static PURPOSE_NAMES: [&str; 8] = [
"normal",
"sret",
"link",
"fp",
"csr",
"vmctx",
"sigid",
"stack_limit",
];
impl fmt::Display for ArgumentPurpose {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -315,6 +330,7 @@ impl FromStr for ArgumentPurpose {
"csr" => Ok(ArgumentPurpose::CalleeSaved),
"vmctx" => Ok(ArgumentPurpose::VMContext),
"sigid" => Ok(ArgumentPurpose::SignatureId),
"stack_limit" => Ok(ArgumentPurpose::StackLimit),
_ => Err(()),
}
}
@@ -370,6 +386,8 @@ mod tests {
ArgumentPurpose::FramePointer,
ArgumentPurpose::CalleeSaved,
ArgumentPurpose::VMContext,
ArgumentPurpose::SignatureId,
ArgumentPurpose::StackLimit,
];
for (&e, &n) in all_purpose.iter().zip(PURPOSE_NAMES.iter()) {
assert_eq!(e.to_string(), n);

View File

@@ -32,10 +32,6 @@ pub struct Function {
/// Stack slots allocated in this function.
pub stack_slots: StackSlots,
/// If not `None`, represents the address that the stack pointer should
/// be checked against.
pub stack_limit: Option<ir::GlobalValue>,
/// Global values referenced.
pub global_values: PrimaryMap<ir::GlobalValue, ir::GlobalValueData>,
@@ -82,7 +78,6 @@ impl Function {
name,
signature: sig,
stack_slots: StackSlots::new(),
stack_limit: None,
global_values: PrimaryMap::new(),
heaps: PrimaryMap::new(),
tables: PrimaryMap::new(),
@@ -133,15 +128,6 @@ impl Function {
self.stack_slots.push(data)
}
/// Sets the stack limit for the function.
///
/// Returns previous one if any.
pub fn set_stack_limit(&mut self, stack_limit: Option<GlobalValue>) -> Option<GlobalValue> {
let prev = self.stack_limit.take();
self.stack_limit = stack_limit;
prev
}
/// Adds a signature which can later be used to declare an external function import.
pub fn import_signature(&mut self, signature: Signature) -> SigRef {
self.dfg.signatures.push(signature)