From f41c53667e3464ab324d4484e8601968f9eb313f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 25 Sep 2012 12:17:20 -0700 Subject: [PATCH] rustc: Fix calls to the logging function when the must_cast flag is true; stop using shape code for logging --- src/libcore/logging.rs | 20 +++++++++++-- src/rt/rust_builtin.cpp | 4 +-- src/rustc/middle/lang_items.rs | 7 +++-- src/rustc/middle/trans/base.rs | 6 ---- src/rustc/middle/trans/callee.rs | 43 +++++++++++++++++++++++++-- src/rustc/middle/trans/controlflow.rs | 6 ++-- 6 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/libcore/logging.rs b/src/libcore/logging.rs index 6086b2edd7e..a9f63b57fa5 100644 --- a/src/libcore/logging.rs +++ b/src/libcore/logging.rs @@ -4,13 +4,16 @@ #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -export console_on, console_off; +use cast::transmute; + +export console_on, console_off, log_type; #[nolink] extern mod rustrt { #[legacy_exports]; fn rust_log_console_on(); fn rust_log_console_off(); + fn rust_log_str(level: u32, string: *libc::c_char, size: libc::size_t); } /// Turns on logging to stdout globally @@ -27,4 +30,17 @@ fn console_on() { */ fn console_off() { rustrt::rust_log_console_off(); -} \ No newline at end of file +} + +#[cfg(notest)] +#[lang="log_type"] +pub fn log_type(level: u32, object: &T) { + let bytes = do io::with_bytes_writer() |writer| { + repr::write_repr(writer, object); + }; + unsafe { + let len = bytes.len() as libc::size_t; + rustrt::rust_log_str(level, transmute(vec::raw::to_ptr(bytes)), len); + } +} + diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 02bc86f88b6..91c5760d3e9 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -952,9 +952,9 @@ rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) { // Don't run on the Rust stack! extern "C" void -rust_log_str(uint32_t level, const char *str) { +rust_log_str(uint32_t level, const char *str, size_t size) { rust_task *task = rust_get_current_task(); - task->sched_loop->get_log().log(task, level, "%s", str); + task->sched_loop->get_log().log(task, level, "%.*s", (int)size, str); } // diff --git a/src/rustc/middle/lang_items.rs b/src/rustc/middle/lang_items.rs index 87201f5a4da..ea22e3a7809 100644 --- a/src/rustc/middle/lang_items.rs +++ b/src/rustc/middle/lang_items.rs @@ -46,7 +46,8 @@ struct LanguageItems { mut str_eq_fn: Option, mut uniq_str_eq_fn: Option, - mut annihilate_fn: Option + mut annihilate_fn: Option, + mut log_type_fn: Option } mod LanguageItems { @@ -76,7 +77,8 @@ mod LanguageItems { str_eq_fn: None, uniq_str_eq_fn: None, - annihilate_fn: None + annihilate_fn: None, + log_type_fn: None } } } @@ -111,6 +113,7 @@ fn LanguageItemCollector(crate: @crate, session: session, item_refs.insert(~"str_eq", &mut items.str_eq_fn); item_refs.insert(~"uniq_str_eq", &mut items.uniq_str_eq_fn); item_refs.insert(~"annihilate", &mut items.annihilate_fn); + item_refs.insert(~"log_type", &mut items.log_type_fn); LanguageItemCollector { crate: crate, diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 964b418b765..65a788991bf 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2005,12 +2005,6 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, } Call(bcx, main_llfn, args); - // Call the box annihilator. - // XXX: Crashes. - //let did = bcx.tcx().lang_items.annihilate_fn.get(); - //let bcx = callee::trans_rtcall_or_lang_call(bcx, did, ~[], - // expr::Ignore); - build_return(bcx); finish_fn(fcx, lltop); return llfdecl; diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs index 308ff75c82e..3050297b360 100644 --- a/src/rustc/middle/trans/callee.rs +++ b/src/rustc/middle/trans/callee.rs @@ -163,7 +163,9 @@ fn trans_fn_ref_with_vtables( // // - `bcx`: the current block where the reference to the fn occurs // - `def_id`: def id of the fn or method item being referenced - // - `ref_id`: node id of the reference to the fn/method + // - `ref_id`: node id of the reference to the fn/method, if applicable. + // This parameter may be zero; but, if so, the resulting value may not + // have the right type, so it must be cast before being used. // - `type_params`: values for each of the fn/method's type parameters // - `vtables`: values for each bound on each of the type parameters @@ -220,7 +222,7 @@ fn trans_fn_ref_with_vtables( let mut {val, must_cast} = monomorphize::monomorphic_fn(ccx, def_id, type_params, vtables, Some(ref_id)); - if must_cast { + if must_cast && ref_id != 0 { // Monotype of the REFERENCE to the function (type params // are subst'd) let ref_ty = common::node_id_type(bcx, ref_id); @@ -290,6 +292,43 @@ fn trans_rtcall_or_lang_call(bcx: block, did: ast::def_id, args: ~[ValueRef], ArgVals(args), dest, DontAutorefArg); } +fn trans_rtcall_or_lang_call_with_type_params(bcx: block, + did: ast::def_id, + args: ~[ValueRef], + type_params: ~[ty::t], + dest: expr::Dest) -> block { + let fty; + if did.crate == ast::local_crate { + fty = ty::node_id_to_type(bcx.tcx(), did.node); + } else { + fty = csearch::get_type(bcx.tcx(), did).ty; + } + + let rty = ty::ty_fn_ret(fty); + return callee::trans_call_inner( + bcx, None, fty, rty, + |bcx| { + let callee = + trans_fn_ref_with_vtables_to_callee(bcx, did, 0, type_params, + None); + + let new_llval; + match callee.data { + Fn(fn_data) => { + let substituted = ty::subst_tps(callee.bcx.tcx(), + type_params, fty); + let mut llfnty = type_of::type_of(callee.bcx.ccx(), + substituted); + llfnty = T_ptr(struct_elt(llfnty, 0)); + new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty); + } + _ => fail + } + Callee { bcx: callee.bcx, data: Fn(FnData { llfn: new_llval }) } + }, + ArgVals(args), dest, DontAutorefArg); +} + fn body_contains_ret(body: ast::blk) -> bool { let cx = {mut found: false}; visit::visit_block(body, cx, visit::mk_vt(@{ diff --git a/src/rustc/middle/trans/controlflow.rs b/src/rustc/middle/trans/controlflow.rs index 9570f37df75..5d8b0fbbbe1 100644 --- a/src/rustc/middle/trans/controlflow.rs +++ b/src/rustc/middle/trans/controlflow.rs @@ -190,12 +190,12 @@ fn trans_log(log_ex: @ast::expr, // Translate the value to be logged let val_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, e)); - let tydesc = get_tydesc_simple(ccx, val_datum.ty); // Call the polymorphic log function let val = val_datum.to_ref_llval(bcx); - let val = PointerCast(bcx, val, T_ptr(T_i8())); - Call(bcx, ccx.upcalls.log_type, [tydesc, val, level]); + let did = bcx.tcx().lang_items.log_type_fn.get(); + let bcx = callee::trans_rtcall_or_lang_call_with_type_params( + bcx, did, ~[level, val], ~[val_datum.ty], expr::Ignore); bcx } }