Skip to content

Commit

Permalink
Move atom methods onto the type now.
Browse files Browse the repository at this point in the history
  • Loading branch information
archseer committed Jun 16, 2019
1 parent 2944563 commit 6573343
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 61 deletions.
50 changes: 23 additions & 27 deletions enigma/src/atom.rs
Expand Up @@ -2,6 +2,11 @@ use hashbrown::HashMap;
use once_cell::sync::Lazy;
use parking_lot::RwLock;

#[inline]
pub fn cmp(a1: Atom, a2: Atom) -> std::cmp::Ordering {
ATOMS.read().cmp(a1.0, a2.0)
}

/// Maximum character length of an atom.
pub const MAX_ATOM_CHARS: usize = 255;

Expand All @@ -10,10 +15,16 @@ pub struct Atom(pub u32);

impl Atom {
/// Construct a new atom from a raw string.
#[inline]
pub fn new(val: &str) -> Self {
assert!(val.len() <= MAX_ATOM_CHARS);
ATOMS.write().from_str(val)
}

#[inline]
pub fn to_str(&self) -> Option<&'static str> {
ATOMS.read().to_str(self.0)
}
}

impl std::fmt::Display for Atom {
Expand All @@ -22,19 +33,19 @@ impl std::fmt::Display for Atom {
}
}

// impl From<&str> for Atom {
// #[inline]
// fn from(value: &str) -> Self {
// Atom::new(val)
// }
// }
impl From<&str> for Atom {
#[inline]
fn from(value: &str) -> Self {
Atom::new(value)
}
}

// impl From<String> for Atom {
// #[inline]
// fn from(value: String) -> Self {
// Atom::new(val)
// }
// }
impl From<String> for Atom {
#[inline]
fn from(value: String) -> Self {
Atom::new(value.as_str())
}
}

#[derive(Debug)]
pub struct AtomTable {
Expand Down Expand Up @@ -727,18 +738,3 @@ pub const TRIM: Atom = Atom(264);
pub const TRIM_ALL: Atom = Atom(265);
pub const GLOBAL: Atom = Atom(266);
pub const SCOPE: Atom = Atom(267);

#[inline]
pub fn cmp(a1: Atom, a2: Atom) -> std::cmp::Ordering {
ATOMS.read().cmp(a1.0, a2.0)
}
#[inline]
pub fn from_str(val: &str) -> Atom {
// unfortunately, cache hits need the write lock to avoid race conditions
ATOMS.write().from_str(val)
}

#[inline]
pub fn to_str(index: Atom) -> Option<&'static str> {
ATOMS.read().to_str(index.0)
}
19 changes: 9 additions & 10 deletions enigma/src/bif.rs
Expand Up @@ -48,8 +48,8 @@ macro_rules! bif_map {
{
let mut table: BifTable = HashMap::new();
$(
let module = atom::from_str($module);
$(table.insert(module::MFA(module, atom::from_str($fun), $arity), $rust_fn);)*
let module = Atom::from($module);
$(table.insert(module::MFA(module, Atom::from($fun), $arity), $rust_fn);)*
)*
table
}
Expand Down Expand Up @@ -404,9 +404,9 @@ macro_rules! nif_map {
{
let mut table: NifTable = HashMap::new();
$(
let module = atom::from_str($module);
let module = Atom::from($module);
table.insert(module, vec![
$((atom::from_str($fun), $arity, $rust_fn),)*
$((Atom::from($fun), $arity, $rust_fn),)*
]);
)*
table
Expand Down Expand Up @@ -1123,11 +1123,11 @@ pub fn bif_erlang_load_nif_2(vm: &vm::Machine, process: &RcProcess, args: &[Term

if let Ok(cons) = args[0].cast_into() {
let name = value::cons::unicode_list_to_buf(cons, 2048).unwrap();
let atom = atom::from_str(&name);
let atom = Atom::from(name);
let nifs = match NIFS.get(&atom) {
Some(nifs) => nifs,
None => {
println!("NIFS name: {}, atom {} not found", name, atom);
println!("NIFS name: {}, atom {} not found", args[0], atom);
return Ok(Term::atom(atom::OK));
}
};
Expand Down Expand Up @@ -1192,10 +1192,9 @@ pub fn bif_erlang_process_flag_2(_vm: &vm::Machine, process: &RcProcess, args: &
// TODO: unimplemented
Ok(atom!(ON_HEAP))
}
Variant::Atom(i) => unimplemented!(
"erlang:process_flag/2 not implemented for {:?}",
atom::to_str(i)
),
Variant::Atom(i) => {
unimplemented!("erlang:process_flag/2 not implemented for {:?}", i.to_str())
}
_ => unreachable!(),
}
}
Expand Down
10 changes: 5 additions & 5 deletions enigma/src/bif/erlang.rs
Expand Up @@ -164,7 +164,7 @@ pub fn list_to_atom_1(_vm: &vm::Machine, _process: &RcProcess, args: &[Term]) ->
// BIF_RET(res);
let list = Cons::cast_from(&args[0])?;
let string = value::cons::unicode_list_to_buf(list, atom::MAX_ATOM_CHARS)?;
let atom = atom::from_str(string.as_str());
let atom = atom::Atom::from(string);
Ok(Term::atom(atom))
}

Expand Down Expand Up @@ -586,7 +586,7 @@ pub fn binary_to_atom_2(_vm: &vm::Machine, _process: &RcProcess, args: &[Term])
if let Some(bytes) = args[0].to_bytes() {
return match std::str::from_utf8(bytes) {
Ok(string) => {
let atom = atom::from_str(string);
let atom = atom::Atom::from(string);
Ok(Term::atom(atom))
}
Err(_) => Err(Exception::new(Reason::EXC_BADARG)),
Expand All @@ -598,7 +598,7 @@ pub fn binary_to_atom_2(_vm: &vm::Machine, _process: &RcProcess, args: &[Term])
pub fn atom_to_list_1(_vm: &vm::Machine, process: &RcProcess, args: &[Term]) -> bif::Result {
match args[0].into_variant() {
Variant::Atom(i) => {
let string = atom::to_str(i).unwrap();
let string = i.to_str().unwrap();
let heap = &process.context_mut().heap;

Ok(bitstring!(heap, string))
Expand All @@ -617,7 +617,7 @@ pub fn atom_to_binary_2(_vm: &vm::Machine, process: &RcProcess, args: &[Term]) -

match args[0].into_variant() {
Variant::Atom(i) => {
let string = atom::to_str(i).unwrap();
let string = i.to_str().unwrap();
let heap = &process.context_mut().heap;

Ok(Term::binary(
Expand Down Expand Up @@ -1204,7 +1204,7 @@ mod tests {

macro_rules! str_to_atom {
($str:expr) => {
Term::atom(crate::atom::from_str($str))
Term::atom(crate::atom::Atom::from($str))
};
}

Expand Down
4 changes: 2 additions & 2 deletions enigma/src/bif/load.rs
@@ -1,4 +1,4 @@
use crate::atom;
use crate::atom::{self, Atom};
use crate::bif;
use crate::exception::{Exception, Reason};
use crate::loader::Loader;
Expand All @@ -12,7 +12,7 @@ pub fn pre_loaded_0(_vm: &vm::Machine, process: &RcProcess, _args: &[Term]) -> b

let iter = vm::PRE_LOADED_NAMES
.iter()
.map(|name| Term::atom(atom::from_str(name)));
.map(|name| Term::atom(Atom::from(*name))); // TODO: inefficient because of lookups

Ok(Cons::from_iter(iter, heap))
}
Expand Down
4 changes: 2 additions & 2 deletions enigma/src/bif/maps.rs
Expand Up @@ -190,7 +190,7 @@ mod tests {

macro_rules! str_to_atom {
($str:expr) => {
Term::atom(crate::atom::from_str($str))
Term::atom(crate::atom::Atom::from($str))
};
}

Expand Down Expand Up @@ -269,7 +269,7 @@ mod tests {
let module: *const module::Module = std::ptr::null();
let process = process::allocate(&vm, 0, 0, module).unwrap();
let bad_map = Term::int(3);
let args = vec![Term::atom(atom::from_str("test")), bad_map];
let args = vec![str_to_atom!("test"), bad_map];

if let Err(exception) = get_2(&vm, &process, &args) {
assert_eq!(exception.reason, Reason::EXC_BADMAP);
Expand Down
6 changes: 3 additions & 3 deletions enigma/src/etf.rs
@@ -1,4 +1,4 @@
use crate::atom;
use crate::atom::{self, Atom};
use crate::bitstring;
use crate::immix::Heap;
use crate::module;
Expand Down Expand Up @@ -140,7 +140,7 @@ pub fn decode_atom(rest: &[u8]) -> IResult<&[u8], Term> {
let (rest, string) = take_str!(rest, len)?;

// TODO: create atom &string
Ok((rest, Term::atom(atom::from_str(string))))
Ok((rest, Term::atom(Atom::from(string))))
}

pub fn decode_tuple<'a>(rest: &'a [u8], len: u32, heap: &Heap) -> IResult<&'a [u8], Term> {
Expand Down Expand Up @@ -342,7 +342,7 @@ pub fn encode_term(res: &mut Vec<u8>, term: Term) -> std::io::Result<()> {
res.write_u8(Tag::Nil as u8)?;
}
Variant::Atom(i) => {
let atom = atom::to_str(i).unwrap();
let atom = i.to_str().unwrap();
encode_atom(res, atom)?;
}
Variant::Float(value::Float(f)) => encode_float(res, f)?,
Expand Down
3 changes: 2 additions & 1 deletion enigma/src/ets/pam.rs
Expand Up @@ -267,7 +267,8 @@ pub fn is_variable(obj: Term) -> Option<usize> {
match obj.into_variant() {
// TODO original checked for < 2 as error but we use nil, true, false as 0,1,2
Variant::Atom(Atom(i)) if i > 2 => {
crate::atom::to_str(Atom(i))
Atom(i)
.to_str()
.and_then(|name| {
let name = name.as_bytes();
if name[0] == b'$' {
Expand Down
2 changes: 1 addition & 1 deletion enigma/src/loader.rs
Expand Up @@ -279,7 +279,7 @@ impl<'a> Loader<'a> {
self.atoms = atoms;

for (index, a) in self.atoms.iter().enumerate() {
let g_index = atom::from_str(a).0;
let g_index = Atom::from(*a).0;
// keep a mapping of these to patch the instrs
self.atom_map.insert(index as u32, g_index);
}
Expand Down
4 changes: 2 additions & 2 deletions enigma/src/module.rs
Expand Up @@ -17,8 +17,8 @@ impl std::fmt::Display for MFA {
write!(
f,
"{}:{}/{}",
atom::to_str(self.0).unwrap(),
atom::to_str(self.1).unwrap(),
self.0.to_str().unwrap(),
self.1.to_str().unwrap(),
self.2
)
}
Expand Down
2 changes: 1 addition & 1 deletion enigma/src/value.rs
Expand Up @@ -1246,7 +1246,7 @@ impl std::fmt::Display for Variant {
Variant::Nil(..) => write!(f, "[]"),
Variant::Integer(i) => write!(f, "{}", i),
Variant::Float(self::Float(i)) => write!(f, "{}", i),
Variant::Atom(i) => write!(f, ":{}", atom::to_str(*i).unwrap()),
Variant::Atom(i) => write!(f, ":{}", i.to_str().unwrap()),
Variant::Port(i) => write!(f, "#Port<{}>", i),
Variant::Pid(i) => write!(f, "#Pid<{}>", i),
Variant::Cons(c) => unsafe {
Expand Down
12 changes: 6 additions & 6 deletions enigma/src/vm.rs
@@ -1,4 +1,4 @@
use crate::atom;
use crate::atom::{self, Atom};
use crate::bitstring;
use crate::ets::{RcTableRegistry, TableRegistry};
use crate::exception::{self, Exception, Reason};
Expand Down Expand Up @@ -725,13 +725,13 @@ impl Machine {
let registry = self.modules.lock();

// start the actual book process
let module = registry.lookup(atom::from_str("erl_init")).unwrap();
let module = registry.lookup(Atom::from("erl_init")).unwrap();
let process = process::allocate(&self, 0 /* itself */, 0, module).unwrap();

let context = process.context_mut();
let fun = atom::from_str("start");
let fun = Atom::from("start");
let arity = 2;
context.x[0] = Term::atom(atom::from_str("init"));
context.x[0] = Term::atom(Atom::from("init"));
context.x[1] = value::Cons::from_iter(
args.into_iter()
.map(|arg| Term::binary(&context.heap, bitstring::Binary::from(arg.into_bytes()))),
Expand All @@ -747,10 +747,10 @@ impl Machine {

// start system processes
// TODO: start as a special process and panic if it halts
let module = registry.lookup(atom::from_str("erts_code_purger")).unwrap();
let module = registry.lookup(Atom::from("erts_code_purger")).unwrap();
let process = process::allocate(&self, 0 /* itself */, 0, module).unwrap();
let context = process.context_mut();
let fun = atom::from_str("start");
let fun = Atom::from("start");
let arity = 0;
op_jump!(context, module.funs[&(fun, arity)]);
let future = run_with_error_handling(process);
Expand Down
2 changes: 1 addition & 1 deletion instruction-codegen/src/lib.rs
Expand Up @@ -360,7 +360,7 @@ pub fn instruction(tokens: TokenStream) -> TokenStream {
// "proc pid={:?} reds={:?} mod={:?} offs={:?} ins={:?}",
// process.pid,
// context.reds,
// atom::to_str(unsafe { (*context.ip.module).name}).unwrap(),
// unsafe { (*context.ip.module).name}.to_str().unwrap(),
// context.ip.ptr,
// ins,
// );
Expand Down

0 comments on commit 6573343

Please sign in to comment.