Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
98971605
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
98971605
编写于
7月 04, 2014
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
auto merge of #15412 : dotdash/rust/builder, r=alexcrichton
上级
935da073
db44468d
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
23 addition
and
58 deletion
+23
-58
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/foreign.rs
+23
-58
未找到文件。
src/librustc/middle/trans/foreign.rs
浏览文件 @
98971605
...
...
@@ -17,7 +17,6 @@
use
middle
::
trans
::
base
::
push_ctxt
;
use
middle
::
trans
::
base
;
use
middle
::
trans
::
build
::
*
;
use
middle
::
trans
::
builder
::
noname
;
use
middle
::
trans
::
cabi
;
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
::
machine
;
...
...
@@ -625,8 +624,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
"the block"
.with_c_str
(
|
s
|
llvm
::
LLVMAppendBasicBlockInContext
(
ccx
.llcx
,
llwrapfn
,
s
));
let
builder
=
ccx
.builder
.b
;
llvm
::
LLVMPositionBuilderAtEnd
(
builder
,
the_block
);
let
builder
=
ccx
.builder
()
;
builder
.position_at_end
(
the_block
);
// Array for the arguments we will pass to the rust function.
let
mut
llrust_args
=
Vec
::
new
();
...
...
@@ -666,10 +665,7 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
debug!
(
"out pointer, foreign={}"
,
ccx
.tn
.val_to_str
(
llforeign_outptr
));
let
llrust_retptr
=
llvm
::
LLVMBuildBitCast
(
builder
,
llforeign_outptr
,
llrust_ret_ty
.ptr_to
()
.to_ref
(),
noname
());
builder
.bitcast
(
llforeign_outptr
,
llrust_ret_ty
.ptr_to
());
debug!
(
"out pointer, foreign={} (casted)"
,
ccx
.tn
.val_to_str
(
llrust_retptr
));
llrust_args
.push
(
llrust_retptr
);
...
...
@@ -677,12 +673,7 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
}
None
=>
{
let
slot
=
{
"return_alloca"
.with_c_str
(
|
s
|
llvm
::
LLVMBuildAlloca
(
builder
,
llrust_ret_ty
.to_ref
(),
s
))
};
let
slot
=
builder
.alloca
(
llrust_ret_ty
,
"return_alloca"
);
debug!
(
"out pointer,
\
allocad={},
\
llrust_ret_ty={},
\
...
...
@@ -724,11 +715,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
// pointer). It makes adapting types easier, since we can
// always just bitcast pointers.
if
!
foreign_indirect
{
let
lltemp
=
llvm
::
LLVMBuildAlloca
(
builder
,
val_ty
(
llforeign_arg
)
.to_ref
(),
noname
());
llvm
::
LLVMBuildStore
(
builder
,
llforeign_arg
,
lltemp
);
let
lltemp
=
builder
.alloca
(
val_ty
(
llforeign_arg
),
""
);
builder
.store
(
llforeign_arg
,
lltemp
);
llforeign_arg
=
lltemp
;
}
...
...
@@ -737,15 +725,13 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
// Rust expects.
if
llforeign_arg_ty
.cast
.is_some
()
{
assert
!
(
!
foreign_indirect
);
llforeign_arg
=
llvm
::
LLVMBuildBitCast
(
builder
,
llforeign_arg
,
llrust_ty
.ptr_to
()
.to_ref
(),
noname
());
llforeign_arg
=
builder
.bitcast
(
llforeign_arg
,
llrust_ty
.ptr_to
());
}
let
llrust_arg
=
if
rust_indirect
{
llforeign_arg
}
else
{
llvm
::
LLVMBuildLoad
(
builder
,
llforeign_arg
,
noname
()
)
builder
.load
(
llforeign_arg
)
};
debug!
(
"llrust_arg {}{}: {}"
,
"#"
,
...
...
@@ -755,13 +741,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
// Perform the call itself
debug!
(
"calling llrustfn = {}, t = {}"
,
ccx
.tn
.val_to_str
(
llrustfn
),
t
.repr
(
ccx
.tcx
()));
let
llrust_ret_val
=
llvm
::
LLVMBuildCall
(
builder
,
llrustfn
,
llrust_args
.as_ptr
(),
llrust_args
.len
()
as
c_uint
,
noname
());
let
attributes
=
base
::
get_fn_llvm_attributes
(
ccx
,
t
);
for
&
(
idx
,
attr
)
in
attributes
.iter
()
{
llvm
::
LLVMAddCallSiteAttribute
(
llrust_ret_val
,
idx
as
c_uint
,
attr
);
}
let
llrust_ret_val
=
builder
.call
(
llrustfn
,
llrust_args
.as_slice
(),
attributes
.as_slice
());
// Get the return value where the foreign fn expects it.
let
llforeign_ret_ty
=
match
tys
.fn_ty.ret_ty.cast
{
...
...
@@ -772,20 +753,16 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
None
if
!
tys
.ret_def
=>
{
// Function returns `()` or `bot`, which in Rust is the LLVM
// type "{}" but in foreign ABIs is "Void".
llvm
::
LLVMBuildRetVoid
(
builder
);
builder
.ret_void
(
);
}
None
if
rust_uses_outptr
=>
{
// Rust uses an outpointer, but the foreign ABI does not. Load.
let
llrust_outptr
=
return_alloca
.unwrap
();
let
llforeign_outptr_casted
=
llvm
::
LLVMBuildBitCast
(
builder
,
llrust_outptr
,
llforeign_ret_ty
.ptr_to
()
.to_ref
(),
noname
());
let
llforeign_retval
=
llvm
::
LLVMBuildLoad
(
builder
,
llforeign_outptr_casted
,
noname
());
llvm
::
LLVMBuildRet
(
builder
,
llforeign_retval
);
builder
.bitcast
(
llrust_outptr
,
llforeign_ret_ty
.ptr_to
());
let
llforeign_retval
=
builder
.load
(
llforeign_outptr_casted
);
builder
.ret
(
llforeign_retval
);
}
None
if
llforeign_ret_ty
!=
llrust_ret_ty
=>
{
...
...
@@ -795,43 +772,31 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
// right now we just use a temp memory location and
// bitcast the pointer, which is the same thing the
// old wrappers used to do.
let
lltemp
=
llvm
::
LLVMBuildAlloca
(
builder
,
llforeign_ret_ty
.to_ref
(),
noname
());
let
lltemp_casted
=
llvm
::
LLVMBuildBitCast
(
builder
,
lltemp
,
llrust_ret_ty
.ptr_to
()
.to_ref
(),
noname
());
llvm
::
LLVMBuildStore
(
builder
,
llrust_ret_val
,
lltemp_casted
);
let
llforeign_retval
=
llvm
::
LLVMBuildLoad
(
builder
,
lltemp
,
noname
());
llvm
::
LLVMBuildRet
(
builder
,
llforeign_retval
);
let
lltemp
=
builder
.alloca
(
llforeign_ret_ty
,
""
);
let
lltemp_casted
=
builder
.bitcast
(
lltemp
,
llrust_ret_ty
.ptr_to
());
builder
.store
(
llrust_ret_val
,
lltemp_casted
);
let
llforeign_retval
=
builder
.load
(
lltemp
);
builder
.ret
(
llforeign_retval
);
}
None
=>
{
// Neither ABI uses an outpointer, and the types
// match. Easy peasy.
llvm
::
LLVMBuildRet
(
builder
,
llrust_ret_val
);
builder
.ret
(
llrust_ret_val
);
}
Some
(
llforeign_outptr
)
if
!
rust_uses_outptr
=>
{
// Foreign ABI requires an out pointer, but Rust doesn't.
// Store Rust return value.
let
llforeign_outptr_casted
=
llvm
::
LLVMBuildBitCast
(
builder
,
llforeign_outptr
,
llrust_retptr_ty
.to_ref
(),
noname
());
llvm
::
LLVMBuildStore
(
builder
,
llrust_ret_val
,
llforeign_outptr_casted
);
llvm
::
LLVMBuildRetVoid
(
builder
);
builder
.bitcast
(
llforeign_outptr
,
llrust_retptr_ty
);
builder
.store
(
llrust_ret_val
,
llforeign_outptr_casted
);
builder
.ret_void
();
}
Some
(
_
)
=>
{
// Both ABIs use outpointers. Easy peasy.
llvm
::
LLVMBuildRetVoid
(
builder
);
builder
.ret_void
(
);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录