Skip to content

Commit

Permalink
Allow the assembler argument to dynasm to be an expression instead of…
Browse files Browse the repository at this point in the history
… an ident. Allow full statements to be inserted into dynasm! statements following a double semicolon to reduce code noise around macros
  • Loading branch information
CensoredUsername committed Sep 25, 2016
1 parent 8d63448 commit 7241c57
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 14 deletions.
7 changes: 6 additions & 1 deletion plugin/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ pub enum Stmt {
GlobalJumpTarget(Ident, Size),
ForwardJumpTarget(Ident, Size),
BackwardJumpTarget(Ident, Size),
DynamicJumpTarget(P<ast::Expr>, Size)
DynamicJumpTarget(P<ast::Expr>, Size),

Stmt(ast::Stmt),
}

/*
Expand Down Expand Up @@ -121,6 +123,9 @@ pub fn compile(ecx: &ExtCtxt, nodes: Vec<parser::Item>) -> Result<StmtBuffer, ()
}
}
}
},
Item::Stmt(stmt) => {
stmts.push(Stmt::Stmt(stmt));
}
}
}
Expand Down
16 changes: 12 additions & 4 deletions plugin/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ pub type Ident = Spanned<ast::Ident>;
pub enum Item {
Instruction(Vec<Ident>, Vec<Arg>, Span),
Label(LabelType),
Directive(Ident, Vec<Arg>, Span)
Directive(Ident, Vec<Arg>, Span),
Stmt(ast::Stmt),
}

#[derive(Debug)]
Expand Down Expand Up @@ -301,9 +302,8 @@ impl Size {
// this means we don't have to figure out nesting via []'s by ourselves.
// syntax for a single op: PREFIX* ident (SIZE? expr ("," SIZE? expr)*)? ";"

pub fn parse<'a>(ecx: &ExtCtxt, parser: &mut Parser<'a>) -> PResult<'a, (Ident, Vec<Item>)> {
let span = parser.span;
let name = Spanned {node: try!(parser.parse_ident()), span: span};
pub fn parse<'a>(ecx: &ExtCtxt, parser: &mut Parser<'a>) -> PResult<'a, (P<ast::Expr>, Vec<Item>)> {
let name = try!(parser.parse_expr());

let mut ins = Vec::new();

Expand All @@ -313,6 +313,14 @@ pub fn parse<'a>(ecx: &ExtCtxt, parser: &mut Parser<'a>) -> PResult<'a, (Ident,

let startspan = parser.span;

if parser.eat(&token::Semi) {
let stmt = try!(parser.parse_stmt());
if let Some(stmt) = stmt {
ins.push(Item::Stmt(stmt));
}
continue;
}

// possible prefix symbols: => (dynamic label), -> (global label), . (directive)

if parser.eat(&token::FatArrow) {
Expand Down
16 changes: 10 additions & 6 deletions plugin/src/serialize.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::rc::Rc;

use compiler;
use parser::{Ident, Size};
use parser::{Size};

use syntax::ext::build::AstBuilder;
use syntax::ext::base::ExtCtxt;
Expand All @@ -11,7 +11,7 @@ use syntax::parse::token::intern;
use syntax::codemap::{Span, Spanned};


pub fn serialize(ecx: &mut ExtCtxt, name: Ident, stmts: compiler::StmtBuffer) -> Vec<ast::Stmt> {
pub fn serialize(ecx: &mut ExtCtxt, name: P<ast::Expr>, stmts: compiler::StmtBuffer) -> Vec<ast::Stmt> {
let mut buffer = Vec::new();

// construction for `op.push(expr)` is as follows
Expand Down Expand Up @@ -54,7 +54,7 @@ pub fn serialize(ecx: &mut ExtCtxt, name: Ident, stmts: compiler::StmtBuffer) ->

DynScale(scale, rest) => {
let temp = ast::Ident::with_empty_ctxt(intern("temp"));
buffer.push(ecx.stmt_let(ecx.call_site(), false, temp, encoded_size(ecx, name, scale)));
buffer.push(ecx.stmt_let(ecx.call_site(), false, temp, encoded_size(ecx, &name, scale)));
("push", vec![or_mask_shift_expr(ecx, rest, ecx.expr_ident(ecx.call_site(), temp), 3, 6)])
},

Expand Down Expand Up @@ -85,10 +85,14 @@ pub fn serialize(ecx: &mut ExtCtxt, name: Ident, stmts: compiler::StmtBuffer) ->
DynamicJumpTarget(expr, size) => {
let span = expr.span;
("dynamic_reloc", vec![expr, ecx.expr_u8(span, size.in_bytes())])
},
Stmt(stmt) => {
buffer.push(stmt);
continue;
}
};

let op = ecx.expr_path(ast::Path::from_ident(name.span, name.node));
let op = name.clone();
let method = ast::Ident::with_empty_ctxt(intern(method));
let expr = ecx.expr_method_call(ecx.call_site(), op, method, args);

Expand Down Expand Up @@ -233,7 +237,7 @@ pub fn size_of(ecx: &ExtCtxt, path: ast::Path) -> P<ast::Expr> {
ecx.expr_call(span, ecx.expr_path(size_of), Vec::new())
}

pub fn encoded_size(ecx: &ExtCtxt, name: Ident, size: P<ast::Expr>) -> P<ast::Expr> {
pub fn encoded_size(ecx: &ExtCtxt, name: &P<ast::Expr>, size: P<ast::Expr>) -> P<ast::Expr> {
let span = size.span;

ecx.expr_match(span, size, vec![
Expand All @@ -242,7 +246,7 @@ pub fn encoded_size(ecx: &ExtCtxt, name: Ident, size: P<ast::Expr>) -> P<ast::Ex
ecx.arm(span, vec![ecx.pat_lit(span, ecx.expr_usize(span, 2))], ecx.expr_u8(span, 1)),
ecx.arm(span, vec![ecx.pat_lit(span, ecx.expr_usize(span, 1))], ecx.expr_u8(span, 0)),
ecx.arm(span, vec![ecx.pat_wild(span)], ecx.expr_method_call(span,
ecx.expr_ident(name.span, name.node),
name.clone(),
ast::Ident::with_empty_ctxt(intern("runtime_error")),
vec![ecx.expr_str(span,
intern("Type size not representable as scale").as_str()
Expand Down
5 changes: 3 additions & 2 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl ExecutableBuffer {
&self[offset.0] as *const u8
}

fn as_mut_slice(&mut self) -> &mut[u8] {
fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe {&mut self.buffer.as_mut_slice()[..self.length] }
}
}
Expand All @@ -85,6 +85,7 @@ impl Executor {
/// is alive, it can be used to read and execute from the `ExecutableBuffer`.
/// Any pointers created to the `Executablebuffer` should no longer be used when
/// the guard is dropped.
#[inline]
pub fn lock(&self) -> RwLockReadGuard<ExecutableBuffer> {
self.execbuffer.read().unwrap()
}
Expand Down Expand Up @@ -701,4 +702,4 @@ impl<'a, 'b> Extend<&'b u8> for UncommittedModifier<'a> {
fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item=&'b u8> {
self.extend(iter.into_iter().cloned())
}
}
}
2 changes: 1 addition & 1 deletion testing/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ fn main() {

// fixups
let start = ops.offset();
dynasm!(ops
dynasm!( (ops)
; inc rbx
);
let end = ops.offset();
Expand Down

0 comments on commit 7241c57

Please sign in to comment.