Parsing stack_limit

This commit is contained in:
Sergey Pepyakin
2018-05-31 00:12:13 +02:00
committed by Dan Gohman
parent effe770c5f
commit 73b6468d25
3 changed files with 48 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
test cat
; Verify parsing of stack_limit.
function %minimal(i64 vmctx) {
gv0 = vmctx
; Stack limit
stack_limit = gv0
ebb0:
trap user0
}
; sameln: function %minimal(i64 vmctx) fast {
; nextln: gv0 = vmctx
; nextln: stack_limit = gv0
; nextln:
; nextln: ebb0:
; nextln: trap user0
; nextln: }

View File

@@ -126,6 +126,15 @@ impl Function {
self.stack_slots.push(data) 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<GlobalVar>) -> Option<GlobalVar> {
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. /// Adds a signature which can later be used to declare an external function import.
pub fn import_signature(&mut self, signature: Signature) -> SigRef { pub fn import_signature(&mut self, signature: Signature) -> SigRef {
self.dfg.signatures.push(signature) self.dfg.signatures.push(signature)

View File

@@ -244,6 +244,15 @@ impl<'a> Context<'a> {
} }
} }
// Assign the global for the stack limit.
fn set_stack_limit(&mut self, gv: GlobalVar, loc: &Location) -> Result<()> {
if let Some(_) = self.function.set_stack_limit(Some(gv)) {
err!(loc, "multiple stack_limit declarations")
} else {
Ok(())
}
}
// Allocate a new EBB. // Allocate a new EBB.
fn add_ebb(&mut self, ebb: Ebb, loc: &Location) -> Result<Ebb> { fn add_ebb(&mut self, ebb: Ebb, loc: &Location) -> Result<Ebb> {
while self.function.dfg.num_ebbs() <= ebb.index() { while self.function.dfg.num_ebbs() <= ebb.index() {
@@ -973,6 +982,7 @@ impl<'a> Parser<'a> {
// * function-decl // * function-decl
// * signature-decl // * signature-decl
// * jump-table-decl // * jump-table-decl
// * stack-limit-decl
// //
// The parsed decls are added to `ctx` rather than returned. // The parsed decls are added to `ctx` rather than returned.
fn parse_preamble(&mut self, ctx: &mut Context) -> Result<()> { fn parse_preamble(&mut self, ctx: &mut Context) -> Result<()> {
@@ -1009,6 +1019,8 @@ impl<'a> Parser<'a> {
self.parse_jump_table_decl() self.parse_jump_table_decl()
.and_then(|(jt, dat)| ctx.add_jt(jt, dat, &self.loc)) .and_then(|(jt, dat)| ctx.add_jt(jt, dat, &self.loc))
} }
Some(Token::Identifier("stack_limit")) => self.parse_stack_limit_decl()
.and_then(|gv| ctx.set_stack_limit(gv, &self.loc)),
// More to come.. // More to come..
_ => return Ok(()), _ => return Ok(()),
}?; }?;
@@ -1291,6 +1303,15 @@ impl<'a> Parser<'a> {
} }
} }
/// stack-limit-decl ::= "stack_limit" "=" GlobalVar(gv)
fn parse_stack_limit_decl(&mut self) -> Result<GlobalVar> {
self.consume();
self.match_token(Token::Equal, "expected '=' in stack limit declaration")?;
let gv = self.match_gv("expected global variable")?;
Ok(gv)
}
// Parse a function body, add contents to `ctx`. // Parse a function body, add contents to `ctx`.
// //
// function-body ::= * { extended-basic-block } // function-body ::= * { extended-basic-block }