Fix metadata serialization of foreign functions. Properly take the value of foreign functions from other crates to fix #1840.
This commit is contained in:
parent
f3b50ae348
commit
a7f6e00944
5 changed files with 45 additions and 6 deletions
|
@ -288,6 +288,7 @@ fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num)
|
||||||
'u' { dl_def(ast::def_fn(did, ast::unsafe_fn)) }
|
'u' { dl_def(ast::def_fn(did, ast::unsafe_fn)) }
|
||||||
'f' { dl_def(ast::def_fn(did, ast::impure_fn)) }
|
'f' { dl_def(ast::def_fn(did, ast::impure_fn)) }
|
||||||
'p' { dl_def(ast::def_fn(did, ast::pure_fn)) }
|
'p' { dl_def(ast::def_fn(did, ast::pure_fn)) }
|
||||||
|
'F' { dl_def(ast::def_fn(did, ast::extern_fn)) }
|
||||||
'y' { dl_def(ast::def_ty(did)) }
|
'y' { dl_def(ast::def_ty(did)) }
|
||||||
't' { dl_def(ast::def_ty(did)) }
|
't' { dl_def(ast::def_ty(did)) }
|
||||||
'm' { dl_def(ast::def_mod(did)) }
|
'm' { dl_def(ast::def_mod(did)) }
|
||||||
|
|
|
@ -527,7 +527,7 @@ fn purity_fn_family(p: purity) -> char {
|
||||||
unsafe_fn { 'u' }
|
unsafe_fn { 'u' }
|
||||||
pure_fn { 'p' }
|
pure_fn { 'p' }
|
||||||
impure_fn { 'f' }
|
impure_fn { 'f' }
|
||||||
extern_fn { 'c' }
|
extern_fn { 'F' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2392,16 +2392,18 @@ fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id,
|
||||||
ccx, node_id_type(bcx, id))));
|
ccx, node_id_type(bcx, id))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Need to support extern-ABI functions (#1840)
|
alt ty::get(tpt.ty).struct {
|
||||||
if fn_id.crate == ast::local_crate {
|
ty::ty_fn(fn_ty) {
|
||||||
alt bcx.tcx().def_map.find(id) {
|
alt fn_ty.purity {
|
||||||
some(ast::def_fn(_, ast::extern_fn)) {
|
ast::extern_fn {
|
||||||
// Extern functions are just opaque pointers
|
// Extern functions are just opaque pointers
|
||||||
let val = PointerCast(bcx, val, T_ptr(T_i8()));
|
let val = PointerCast(bcx, val, T_ptr(T_i8()));
|
||||||
ret lval_no_env(bcx, val, owned_imm);
|
ret lval_no_env(bcx, val, owned_imm);
|
||||||
}
|
}
|
||||||
_ { }
|
_ { /* fall through */ }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_ { /* fall through */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
ret {bcx: bcx, val: val, kind: owned, env: null_env};
|
ret {bcx: bcx, val: val, kind: owned, env: null_env};
|
||||||
|
|
22
src/test/auxiliary/extern-crosscrate-source.rs
Normal file
22
src/test/auxiliary/extern-crosscrate-source.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#[link(name = "externcallback",
|
||||||
|
vers = "0.1")];
|
||||||
|
|
||||||
|
#[crate_type = "lib"];
|
||||||
|
|
||||||
|
extern mod rustrt {
|
||||||
|
fn rust_dbg_call(cb: *u8,
|
||||||
|
data: libc::uintptr_t) -> libc::uintptr_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fact(n: uint) -> uint {
|
||||||
|
#debug("n = %?", n);
|
||||||
|
rustrt::rust_dbg_call(cb, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||||
|
if data == 1u {
|
||||||
|
data
|
||||||
|
} else {
|
||||||
|
fact(data - 1u) * data
|
||||||
|
}
|
||||||
|
}
|
14
src/test/run-pass/extern-crosscrate.rs
Normal file
14
src/test/run-pass/extern-crosscrate.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//aux-build:extern-crosscrate-source.rs
|
||||||
|
|
||||||
|
use externcallback(vers = "0.1");
|
||||||
|
|
||||||
|
fn fact(n: uint) -> uint {
|
||||||
|
#debug("n = %?", n);
|
||||||
|
externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let result = fact(10u);
|
||||||
|
#debug("result = %?", result);
|
||||||
|
assert result == 3628800u;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue