From 8aac784da5b1f9ffcd8a6d7b984dd9926ca88725 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Thu, 31 May 2018 00:12:13 +0200 Subject: [PATCH] Parsing stack_limit --- filetests/parser/preamble.cton | 18 ++++++++++++++++++ lib/codegen/src/ir/function.rs | 9 +++++++++ lib/reader/src/parser.rs | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 filetests/parser/preamble.cton diff --git a/filetests/parser/preamble.cton b/filetests/parser/preamble.cton new file mode 100644 index 000000000..00841c0fa --- /dev/null +++ b/filetests/parser/preamble.cton @@ -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: } diff --git a/lib/codegen/src/ir/function.rs b/lib/codegen/src/ir/function.rs index c59c3ffde..f7773f225 100644 --- a/lib/codegen/src/ir/function.rs +++ b/lib/codegen/src/ir/function.rs @@ -126,6 +126,15 @@ 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) -> Option { + 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) diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index 0f6488514..a6586fea7 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -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. fn add_ebb(&mut self, ebb: Ebb, loc: &Location) -> Result { while self.function.dfg.num_ebbs() <= ebb.index() { @@ -973,6 +982,7 @@ impl<'a> Parser<'a> { // * function-decl // * signature-decl // * jump-table-decl + // * stack-limit-decl // // The parsed decls are added to `ctx` rather than returned. fn parse_preamble(&mut self, ctx: &mut Context) -> Result<()> { @@ -1009,6 +1019,8 @@ impl<'a> Parser<'a> { self.parse_jump_table_decl() .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.. _ => 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 { + 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`. // // function-body ::= * { extended-basic-block }