From 28ccc2bf658e8fbd7265703ce8d361c2a982fe03 Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Sun, 20 Mar 2016 18:41:39 -0600 Subject: [PATCH] Implement the __rust_allocate C ABI function. --- src/interpreter.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index e24489931886..e5a593239cf6 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -14,6 +14,7 @@ use std::iter; use std::ops::Deref; use std::rc::Rc; use syntax::ast; +use syntax::attr; use syntax::codemap::DUMMY_SP; use error::{EvalError, EvalResult}; @@ -248,6 +249,9 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> { } } + Abi::C => + try!(self.call_c_abi(def_id, args, return_ptr.unwrap())), + Abi::Rust | Abi::RustCall => { // TODO(tsion): Adjust the first argument when calling a Fn or // FnMut closure via FnOnce::call_once. @@ -295,7 +299,7 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> { TerminatorTarget::Call } - abi => panic!("can't handle function with ABI {:?}", abi), + abi => panic!("can't handle function with {:?} ABI", abi), } } @@ -397,6 +401,7 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> { try!(self.memory.copy(src, dest, dest_size)); } + // TODO(tsion): Mark bytes as undef. "uninit" => {} name => panic!("can't handle intrinsic: {}", name), @@ -408,6 +413,34 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> { Ok(TerminatorTarget::Call) } + fn call_c_abi(&mut self, def_id: DefId, args: &[mir::Operand<'tcx>], dest: Pointer) + -> EvalResult + { + let name = self.tcx.item_name(def_id); + let attrs = self.tcx.get_attrs(def_id); + let link_name = match attr::first_attr_value_str_by_name(&attrs, "link_name") { + Some(ln) => ln.clone(), + None => name.as_str(), + }; + + match &link_name[..] { + "__rust_allocate" => { + let size_arg = try!(self.eval_operand(&args[0])); + let _align_arg = try!(self.eval_operand(&args[1])); + let size = try!(self.memory.read_uint(size_arg, self.memory.pointer_size)); + let ptr = self.memory.allocate(size as usize); + try!(self.memory.write_ptr(dest, ptr)); + } + + _ => panic!("can't call C ABI function: {}", link_name), + } + + // Since we pushed no stack frame, the main loop will act + // as if the call just completed and it's returning to the + // current frame. + Ok(TerminatorTarget::Call) + } + fn assign_to_aggregate(&mut self, dest: Pointer, dest_repr: &Repr, variant: usize, operands: &[mir::Operand<'tcx>]) -> EvalResult<()> { match *dest_repr {