我正在寻找Rust内置函数的实现,特别是具有一个参数的“transmute”内置函数。
我在cast.rs中看到了以下代码,但正如您所看到的,它只是将其委托给其他transmute的实现。
#[inline]
pub unsafe fn transmute<L, G>(thing: L) -> G {
intrinsics::transmute(thing)
}
实现intrinsic函数的代码在哪里,特别是transmute intrinsic函数的实现?
我正在寻找Rust内置函数的实现,特别是具有一个参数的“transmute”内置函数。
我在cast.rs中看到了以下代码,但正如您所看到的,它只是将其委托给其他transmute的实现。
#[inline]
pub unsafe fn transmute<L, G>(thing: L) -> G {
intrinsics::transmute(thing)
}
cast::transmute
委托给 intrinsics::transmute
。有一个名为 intrinsics
(现在位于 libcore
中)的模块,其中包含了对几个函数的extern
绑定,其中就包括transmute
。从该模块文档中可以看出,内置函数的实现位于librustc/middle/trans/foreign.rs
中。
不过,据我所见,内置函数的实际实现位于librustc/middle/trans/intrinsic.rs
中。你可以搜索transmute
,然后在一个非常大的 match
语句中找到一段代码,它看起来像这样:
"transmute" => {
let (in_type, out_type) = (*substs.substs.tps.get(0),
*substs.substs.tps.get(1));
let llintype = type_of::type_of(ccx, in_type);
let llouttype = type_of::type_of(ccx, out_type);
let in_type_size = machine::llbitsize_of_real(ccx, llintype);
let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
if in_type_size != out_type_size {
let sp = match ccx.tcx.map.get(ref_id.unwrap()) {
ast_map::NodeExpr(e) => e.span,
_ => fail!("transmute has non-expr arg"),
};
ccx.sess().span_fatal(sp,
format!("transmute called on types with different sizes: \
{intype} ({insize, plural, =1{# bit} other{# bits}}) to \
{outtype} ({outsize, plural, =1{# bit} other{# bits}})",
intype = ty_to_str(ccx.tcx(), in_type),
insize = in_type_size as uint,
outtype = ty_to_str(ccx.tcx(), out_type),
outsize = out_type_size as uint));
}
if !return_type_is_void(ccx, out_type) {
let llsrcval = get_param(decl, first_real_arg);
if type_is_immediate(ccx, in_type) {
match fcx.llretptr.get() {
Some(llretptr) => {
Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
RetVoid(bcx);
}
None => match (llintype.kind(), llouttype.kind()) {
(Pointer, other) | (other, Pointer) if other != Pointer => {
let tmp = Alloca(bcx, llouttype, "");
Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
Ret(bcx, Load(bcx, tmp));
}
(Array, _) | (_, Array) | (Struct, _) | (_, Struct) => {
let tmp = Alloca(bcx, llouttype, "");
Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
Ret(bcx, Load(bcx, tmp));
}
_ => {
let llbitcast = BitCast(bcx, llsrcval, llouttype);
Ret(bcx, llbitcast)
}
}
}
} else if type_is_immediate(ccx, out_type) {
let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
let ll_load = Load(bcx, llsrcptr);
Ret(bcx, ll_load);
} else {
// NB: Do not use a Load and Store here. This causes massive
// code bloat when `transmute` is used on large structural
// types.
let lldestptr = fcx.llretptr.get().unwrap();
let lldestptr = PointerCast(bcx, lldestptr, Type::i8p(ccx));
let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p(ccx));
let llsize = llsize_of(ccx, llintype);
call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1);
RetVoid(bcx);
};
} else {
RetVoid(bcx);
}
}
看起来这是一个生成代码的代码,这个代码将被插入到 transmute
的调用位置。我不是编译器专家,如果我说错了,请有经验的人纠正我。