Use &'self str instead of raw char pointer in ModEntry

This commit is contained in:
Florian Hahn 2013-09-29 14:23:58 +02:00
parent 9ef4463b2a
commit 5dd1145c9b
3 changed files with 116 additions and 140 deletions

View file

@ -54,7 +54,7 @@ use middle::trans::glue;
use middle::trans::inline;
use middle::trans::llrepr::LlvmRepr;
use middle::trans::machine;
use middle::trans::machine::{llalign_of_min, llsize_of};
use middle::trans::machine::{llalign_of_min, llsize_of, llsize_of_alloc};
use middle::trans::meth;
use middle::trans::monomorphize;
use middle::trans::tvec;
@ -2911,8 +2911,9 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
}
}
pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) {
let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) {
let str_slice_type = Type::struct_([Type::i8p(), ccx.int_type], false);
let elttype = Type::struct_([str_slice_type, ccx.int_type], false);
let maptype = Type::array(&elttype, ccx.module_data.len() as u64);
let map = do "_rust_mod_map".with_c_str |buf| {
unsafe {
@ -2931,17 +2932,18 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) {
}
for key in keys.iter() {
let val = *ccx.module_data.find_equiv(key).unwrap();
let s_const = C_cstr(ccx, *key);
let s_ptr = p2i(ccx, s_const);
let v_ptr = p2i(ccx, val);
let elt = C_struct([s_ptr, v_ptr]);
elts.push(elt);
let val = *ccx.module_data.find_equiv(key).unwrap();
let v_ptr = p2i(ccx, val);
let elt = C_struct([
C_estr_slice(ccx, *key),
v_ptr
]);
elts.push(elt);
}
unsafe {
llvm::LLVMSetInitializer(map, C_array(elttype, elts));
}
return (map, keys.len());
return (map, keys.len(), llsize_of_alloc(ccx, elttype));
}
@ -3003,17 +3005,19 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage);
llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates));
let (mod_map, mod_count) = create_module_map(ccx);
let (mod_map, mod_count, mod_struct_size) = create_module_map(ccx);
llvm::LLVMSetInitializer(map, C_struct(
[C_i32(1),
C_struct([
p2i(ccx, mod_map),
C_int(ccx, (mod_count * 16) as int)
// byte size of the module map array, an entry consists of two integers
C_int(ccx, ((mod_count * mod_struct_size) as int))
]),
C_struct([
p2i(ccx, vec_elements),
C_int(ccx, (subcrates.len() * 8) as int)
// byte size of the subcrates array, an entry consists of an integer
C_int(ccx, (subcrates.len() * llsize_of_alloc(ccx, ccx.int_type)) as int)
])
]));
}

View file

@ -11,7 +11,6 @@
#[cfg(not(stage0))] use cast::transmute;
use container::MutableSet;
use hashmap::HashSet;
use libc::c_char;
use option::{Some, None};
use vec::ImmutableVector;
@ -29,19 +28,19 @@ extern {
static CRATE_MAP: CrateMap<'static>;
}
pub struct ModEntry {
name: *c_char,
pub struct ModEntry<'self> {
name: &'self str,
log_level: *mut u32
}
pub struct CrateMapV0<'self> {
entries: &'self [ModEntry],
entries: &'self [ModEntry<'self>],
children: &'self [&'self CrateMap<'self>]
}
pub struct CrateMap<'self> {
version: i32,
entries: &'self [ModEntry],
entries: &'self [ModEntry<'self>],
/// a dynamically sized struct, where all pointers to children are listed adjacent
/// to the struct, terminated with NULL
children: &'self [&'self CrateMap<'self>]
@ -79,7 +78,7 @@ fn version(crate_map: &CrateMap) -> i32 {
#[cfg(not(stage0))]
fn get_entries_and_children<'a>(crate_map: &'a CrateMap<'a>) ->
(&'a [ModEntry], &'a [&'a CrateMap<'a>]) {
(&'a [ModEntry<'a>], &'a [&'a CrateMap<'a>]) {
match version(crate_map) {
0 => {
unsafe {
@ -127,34 +126,31 @@ pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
#[cfg(test)]
mod tests {
use c_str::ToCStr;
use cast::transmute;
use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
#[test]
fn iter_crate_map_duplicates() {
let mut level3: u32 = 3;
let entries = [
ModEntry { name: "c::m1", log_level: &mut level3},
];
let child_crate = CrateMap {
version: 1,
entries: entries,
children: []
};
let root_crate = CrateMap {
version: 1,
entries: [],
children: [&child_crate, &child_crate]
};
let mut cnt = 0;
unsafe {
let mod_name1 = "c::m1".to_c_str();
let mut level3: u32 = 3;
let entries = [
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
];
let child_crate = CrateMap {
version: 1,
entries: entries,
children: []
};
let root_crate = CrateMap {
version: 1,
entries: [],
children: [&child_crate, &child_crate]
};
let mut cnt = 0;
do iter_crate_map(transmute(&root_crate)) |entry| {
do iter_crate_map(&root_crate) |entry| {
assert!(*entry.log_level == 3);
cnt += 1;
}
@ -164,38 +160,36 @@ mod tests {
#[test]
fn iter_crate_map_follow_children() {
let mut level2: u32 = 2;
let mut level3: u32 = 3;
let child_crate2 = CrateMap {
version: 1,
entries: [
ModEntry { name: "c::m1", log_level: &mut level2},
ModEntry { name: "c::m2", log_level: &mut level3},
],
children: []
};
let child_crate1 = CrateMap {
version: 1,
entries: [
ModEntry { name: "t::f1", log_level: &mut 1},
],
children: [&child_crate2]
};
let root_crate = CrateMap {
version: 1,
entries: [
ModEntry { name: "t::f2", log_level: &mut 0},
],
children: [&child_crate1]
};
let mut cnt = 0;
unsafe {
let mod_name1 = "c::m1".to_c_str();
let mod_name2 = "c::m2".to_c_str();
let mut level2: u32 = 2;
let mut level3: u32 = 3;
let child_crate2 = CrateMap {
version: 1,
entries: [
ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
ModEntry { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
],
children: []
};
let child_crate1 = CrateMap {
version: 1,
entries: [
ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 1},
],
children: [&child_crate2]
};
let root_crate = CrateMap {
version: 1,
entries: [
ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 0},
],
children: [&child_crate1]
};
let mut cnt = 0;
do iter_crate_map(transmute(&root_crate)) |entry| {
do iter_crate_map(&root_crate) |entry| {
assert!(*entry.log_level == cnt);
cnt += 1;
}

View file

@ -16,7 +16,6 @@ use rt;
use rt::util::dumb_println;
use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
use str::StrSlice;
use str::raw::from_c_str;
use u32;
use vec::ImmutableVector;
#[cfg(test)] use cast::transmute;
@ -112,28 +111,26 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
let mut longest_match = -1i;
unsafe {
for dir in dirs.iter() {
match dir.name {
None => {
if longest_match == -1 {
longest_match = 0;
new_lvl = dir.level;
}
for dir in dirs.iter() {
match dir.name {
None => {
if longest_match == -1 {
longest_match = 0;
new_lvl = dir.level;
}
Some(ref dir_name) => {
let name = from_c_str(entry.name);
let len = dir_name.len() as int;
if name.starts_with(*dir_name) &&
len >= longest_match {
longest_match = len;
new_lvl = dir.level;
}
}
Some(ref dir_name) => {
let name = entry.name;
let len = dir_name.len() as int;
if name.starts_with(*dir_name) &&
len >= longest_match {
longest_match = len;
new_lvl = dir.level;
}
};
}
*entry.log_level = new_lvl;
}
};
}
unsafe { *entry.log_level = new_lvl; }
if longest_match >= 0 { return 1; } else { return 0; }
}
@ -144,13 +141,11 @@ fn update_log_settings(crate_map: &CrateMap, settings: ~str) {
let mut dirs = ~[];
if settings.len() > 0 {
if settings == ~"::help" || settings == ~"?" {
dumb_println("\nCrate log map:\n");
unsafe {
do iter_crate_map(crate_map) |entry| {
dumb_println(" "+from_c_str(entry.name));
}
exit(1);
dumb_println("\nCrate log map:\n");
do iter_crate_map(crate_map) |entry| {
dumb_println(" "+entry.name);
}
unsafe { exit(1); }
}
dirs = parse_logging_spec(settings);
}
@ -288,88 +283,71 @@ fn parse_logging_spec_global() {
// Tests for update_entry
#[test]
fn update_entry_match_full_path() {
use c_str::ToCStr;
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
LogDirective {name: Some(~"crate2"), level: 3}];
let level = &mut 0;
unsafe {
do "crate1::mod1".with_c_str |ptr| {
let entry= &ModEntry {name: ptr, log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 2);
assert!(m == 1);
}
let entry= &ModEntry {name:"crate1::mod1", log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 2);
assert!(m == 1);
}
}
#[test]
fn update_entry_no_match() {
use c_str::ToCStr;
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
LogDirective {name: Some(~"crate2"), level: 3}];
let level = &mut 0;
unsafe {
do "crate3::mod1".with_c_str |ptr| {
let entry= &ModEntry {name: ptr, log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
assert!(m == 0);
}
let entry= &ModEntry {name: "crate3::mod1", log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
assert!(m == 0);
}
}
#[test]
fn update_entry_match_beginning() {
use c_str::ToCStr;
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
LogDirective {name: Some(~"crate2"), level: 3}];
let level = &mut 0;
unsafe {
do "crate2::mod1".with_c_str |ptr| {
let entry= &ModEntry {name: ptr, log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 3);
assert!(m == 1);
}
let entry= &ModEntry {name: "crate2::mod1", log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 3);
assert!(m == 1);
}
}
#[test]
fn update_entry_match_beginning_longest_match() {
use c_str::ToCStr;
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
LogDirective {name: Some(~"crate2"), level: 3},
LogDirective {name: Some(~"crate2::mod"), level: 4}];
let level = &mut 0;
unsafe {
do "crate2::mod1".with_c_str |ptr| {
let entry = &ModEntry {name: ptr, log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 4);
assert!(m == 1);
}
let entry = &ModEntry {name: "crate2::mod1", log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 4);
assert!(m == 1);
}
}
#[test]
fn update_entry_match_default() {
use c_str::ToCStr;
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
LogDirective {name: None, level: 3}
];
let level = &mut 0;
unsafe {
do "crate1::mod1".with_c_str |ptr| {
let entry= &ModEntry {name: ptr, log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 2);
assert!(m == 1);
}
do "crate2::mod2".with_c_str |ptr| {
let entry= &ModEntry {name: ptr, log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 3);
assert!(m == 1);
}
let entry= &ModEntry {name: "crate1::mod1", log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 2);
assert!(m == 1);
let entry= &ModEntry {name: "crate2::mod2", log_level: level};
let m = update_entry(dirs, transmute(entry));
assert!(*entry.log_level == 3);
assert!(m == 1);
}
}