Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
81cf72c2
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
81cf72c2
编写于
6月 16, 2013
作者:
J
James Miller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Finish up Type refactoring
上级
57a75374
变更
30
隐藏空白更改
内联
并排
Showing
30 changed file
with
517 addition
and
886 deletion
+517
-886
src/librustc/back/upcall.rs
src/librustc/back/upcall.rs
+4
-4
src/librustc/lib/llvm.rs
src/librustc/lib/llvm.rs
+12
-35
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/_match.rs
+1
-1
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/adt.rs
+6
-6
src/librustc/middle/trans/asm.rs
src/librustc/middle/trans/asm.rs
+2
-0
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/base.rs
+43
-49
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/build.rs
+32
-23
src/librustc/middle/trans/cabi.rs
src/librustc/middle/trans/cabi.rs
+19
-38
src/librustc/middle/trans/cabi_arm.rs
src/librustc/middle/trans/cabi_arm.rs
+45
-44
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/cabi_mips.rs
+51
-50
src/librustc/middle/trans/cabi_x86.rs
src/librustc/middle/trans/cabi_x86.rs
+2
-0
src/librustc/middle/trans/cabi_x86_64.rs
src/librustc/middle/trans/cabi_x86_64.rs
+94
-84
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/callee.rs
+5
-3
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/closure.rs
+2
-0
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/common.rs
+19
-373
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/consts.rs
+28
-26
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/context.rs
+7
-9
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/controlflow.rs
+3
-1
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/expr.rs
+7
-7
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/foreign.rs
+9
-10
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/glue.rs
+25
-53
src/librustc/middle/trans/machine.rs
src/librustc/middle/trans/machine.rs
+3
-1
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/meth.rs
+4
-2
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/reflect.rs
+3
-1
src/librustc/middle/trans/shape.rs
src/librustc/middle/trans/shape.rs
+4
-2
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/tvec.rs
+2
-0
src/librustc/middle/trans/type_.rs
src/librustc/middle/trans/type_.rs
+46
-18
src/librustc/middle/trans/type_of.rs
src/librustc/middle/trans/type_of.rs
+32
-41
src/librustc/middle/trans/write_guard.rs
src/librustc/middle/trans/write_guard.rs
+2
-0
src/libstd/unstable/intrinsics.rs
src/libstd/unstable/intrinsics.rs
+5
-5
未找到文件。
src/librustc/back/upcall.rs
浏览文件 @
81cf72c2
...
...
@@ -24,17 +24,17 @@ pub struct Upcalls {
macro_rules!
upcall
(
(
fn
$name:ident
(
$
(
$arg:expr
),
+
)
->
$ret:expr
)
=>
({
let
fn_ty
=
Type
::
func
([
$
(
$arg
),
*
],
$ret
);
let
fn_ty
=
Type
::
func
([
$
(
$arg
),
*
],
&
$ret
);
base
::
decl_cdecl_fn
(
llmod
,
~
"upcall_"
+
stringify!
(
$name
),
fn_ty
)
});
(
nothrow
fn
$name:ident
(
$
(
$arg:expr
),
+
)
->
$ret:expr
)
=>
({
let
fn_ty
=
Type
::
func
([
$
(
$arg
),
*
],
$ret
);
let
fn_ty
=
Type
::
func
([
$
(
$arg
),
*
],
&
$ret
);
let
decl
=
base
::
decl_cdecl_fn
(
llmod
,
~
"upcall_"
+
stringify!
(
$name
),
fn_ty
);
base
::
set_no_unwind
(
decl
);
decl
});
(
nothrow
fn
$name:ident
->
$ret:expr
)
=>
({
let
fn_ty
=
Type
::
func
([],
$ret
);
let
fn_ty
=
Type
::
func
([],
&
$ret
);
let
decl
=
base
::
decl_cdecl_fn
(
llmod
,
~
"upcall_"
+
stringify!
(
$name
),
fn_ty
);
base
::
set_no_unwind
(
decl
);
decl
...
...
@@ -42,7 +42,7 @@ pub struct Upcalls {
)
pub
fn
declare_upcalls
(
targ_cfg
:
@
session
::
config
,
llmod
:
ModuleRef
)
->
@
Upcalls
{
let
opaque_ptr
=
Type
::
i8
()
.
to_ptr
();
let
opaque_ptr
=
Type
::
i8
()
.
ptr_to
();
let
int_ty
=
Type
::
int
(
targ_cfg
.arch
);
@
Upcalls
{
...
...
src/librustc/lib/llvm.rs
浏览文件 @
81cf72c2
...
...
@@ -2141,7 +2141,7 @@ pub fn associate_type(&mut self, s: &str, t: &Type) {
}
pub
fn
find_name
<
'r
>
(
&
'r
self
,
ty
:
&
Type
)
->
Option
<&
'r
str
>
{
match
self
.type_names
.find
(
ty
.to_ref
())
{
match
self
.type_names
.find
(
&
ty
.to_ref
())
{
Some
(
a
)
=>
Some
(
a
.slice
(
0
,
a
.len
())),
None
=>
None
}
...
...
@@ -2151,14 +2151,14 @@ pub fn find_type(&self, s: &str) -> Option<Type> {
self
.named_types
.find_equiv
(
&
s
)
.map_consume
(|
x
|
Type
::
from_ref
(
*
x
))
}
pub
fn
type_to_str
(
&
self
,
ty
:
Type
Ref
)
->
~
str
{
pub
fn
type_to_str
(
&
self
,
ty
:
Type
)
->
~
str
{
match
self
.find_name
(
&
ty
)
{
option
::
Some
(
name
)
=>
return
name
.to_owned
(),
None
=>
()
}
unsafe
{
let
kind
=
llvm
::
LLVMGetTypeKind
(
ty
);
let
kind
=
ty
.kind
(
);
match
kind
{
Void
=>
~
"Void"
,
...
...
@@ -2172,31 +2172,28 @@ pub fn type_to_str(&self, ty: TypeRef) -> ~str {
Metadata
=>
~
"Metadata"
,
X86_MMX
=>
~
"X86_MMAX"
,
Integer
=>
{
fmt!
(
"i%d"
,
llvm
::
LLVMGetIntTypeWidth
(
ty
)
as
int
)
fmt!
(
"i%d"
,
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
()
)
as
int
)
}
Function
=>
{
let
out_ty
=
llvm
::
LLVMGetReturnType
(
ty
);
let
n_args
=
llvm
::
LLVMCountParamTypes
(
ty
)
as
uint
;
let
args
=
vec
::
from_elem
(
n_args
,
0
as
TypeRef
);
llvm
::
LLVMGetParamTypes
(
ty
,
vec
::
raw
::
to_ptr
(
args
));
let
out_ty
=
ty
.return_type
();
let
args
=
ty
.func_params
();
let
args
=
args
.map
(|
&
ty
|
self
.type_to_str
(
ty
))
.connect
(
", "
);
let
out_ty
=
self
.type_to_str
(
out_ty
);
fmt!
(
"fn(%s) -> %s"
,
args
,
out_ty
)
}
Struct
=>
{
let
tys
=
struct_tys
(
ty
);
let
tys
=
ty
.field_types
(
);
let
tys
=
tys
.map
(|
&
ty
|
self
.type_to_str
(
ty
))
.connect
(
", "
);
fmt!
(
"{%s}"
,
tys
)
}
Array
=>
{
let
el_ty
=
llvm
::
LLVMGetElementType
(
ty
);
let
el_ty
=
ty
.element_type
(
);
let
el_ty
=
self
.type_to_str
(
el_ty
);
let
len
=
llvm
::
LLVMGetArrayLength
(
ty
)
as
uint
;
let
len
=
ty
.array_length
()
;
fmt!
(
"[%s x %u]"
,
el_ty
,
len
)
}
Pointer
=>
{
let
el_ty
=
llvm
::
LLVMGetElementType
(
ty
);
let
el_ty
=
ty
.element_type
(
);
let
el_ty
=
self
.type_to_str
(
el_ty
);
fmt!
(
"*%s"
,
el_ty
)
}
...
...
@@ -2207,32 +2204,12 @@ pub fn type_to_str(&self, ty: TypeRef) -> ~str {
pub
fn
val_to_str
(
&
self
,
val
:
ValueRef
)
->
~
str
{
unsafe
{
self
.type_to_str
(
llvm
::
LLVMTypeOf
(
val
))
let
ty
=
Type
::
from_ref
(
llvm
::
LLVMTypeOf
(
val
));
self
.type_to_str
(
ty
)
}
}
}
pub
fn
float_width
(
llt
:
TypeRef
)
->
uint
{
unsafe
{
return
match
llvm
::
LLVMGetTypeKind
(
llt
)
as
int
{
1
=>
32u
,
2
=>
64u
,
3
=>
80u
,
4
|
5
=>
128u
,
_
=>
fail
!
(
"llvm_float_width called on a non-float type"
)
};
}
}
pub
fn
fn_ty_param_tys
(
fn_ty
:
TypeRef
)
->
~
[
TypeRef
]
{
unsafe
{
let
args
=
vec
::
from_elem
(
llvm
::
LLVMCountParamTypes
(
fn_ty
)
as
uint
,
0
as
TypeRef
);
llvm
::
LLVMGetParamTypes
(
fn_ty
,
vec
::
raw
::
to_ptr
(
args
));
return
args
;
}
}
/* Memory-managed interface to target data. */
...
...
src/librustc/middle/trans/_match.rs
浏览文件 @
81cf72c2
...
...
@@ -911,7 +911,7 @@ pub fn extract_vec_elems(bcx: block,
Sub
(
bcx
,
count
,
C_int
(
bcx
.ccx
(),
(
elem_count
-
i
)
as
int
))])
}
_
=>
unsafe
{
llvm
::
LLVMGetUndef
(
vt
.llunit_ty
)
}
_
=>
unsafe
{
llvm
::
LLVMGetUndef
(
vt
.llunit_ty
.to_ref
()
)
}
}
};
if
slice
.is_some
()
{
...
...
src/librustc/middle/trans/adt.rs
浏览文件 @
81cf72c2
...
...
@@ -59,6 +59,8 @@
use
syntax
::
ast
;
use
util
::
ppaux
::
ty_to_str
;
use
middle
::
trans
::
type_
::
Type
;
/// Representations.
pub
enum
Repr
{
...
...
@@ -260,10 +262,8 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] {
let
most_aligned
=
most_aligned
.get
();
let
padding
=
largest_size
-
most_aligned
.size
;
assert
!
(
padding
>=
0
);
struct_llfields
(
cx
,
most_aligned
,
sizing
)
+
[
Type
::
array
(
Type
::
i8
(),
padding
/*bad*/
as
uint
)]
+
[
Type
::
array
(
&
Type
::
i8
(),
padding
)]
}
}
}
...
...
@@ -439,7 +439,7 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
// The unit-like case might have a nonzero number of unit-like fields.
// (e.g., Result or Either with () as one side.)
let
ty
=
type_of
::
type_of
(
bcx
.ccx
(),
nullfields
[
ix
]);
assert_eq!
(
machine
::
llsize_of_alloc
(
bcx
.ccx
(),
ll
ty
),
0
);
assert_eq!
(
machine
::
llsize_of_alloc
(
bcx
.ccx
(),
ty
),
0
);
// The contents of memory at this pointer can't matter, but use
// the value that's "reasonable" in case of pointer comparison.
PointerCast
(
bcx
,
val
,
ty
.ptr_to
())
...
...
@@ -457,7 +457,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint,
type_of
::
type_of
(
ccx
,
ty
)
};
let
real_ty
=
Type
::
struct_
(
fields
,
st
.packed
);
PointerCast
(
bcx
,
val
,
real_
llty
.to_ptr
()
.to_ref
())
PointerCast
(
bcx
,
val
,
real_
ty
.ptr_to
())
}
else
{
val
};
...
...
@@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef])
}
fn
padding
(
size
:
u64
)
->
ValueRef
{
C_undef
(
Type
::
array
(
Type
::
i8
(),
size
)
.to_ref
(
))
C_undef
(
Type
::
array
(
&
Type
::
i8
(),
size
))
}
// XXX this utility routine should be somewhere more general
...
...
src/librustc/middle/trans/asm.rs
浏览文件 @
81cf72c2
...
...
@@ -20,6 +20,8 @@
use
middle
::
trans
::
common
::
*
;
use
middle
::
ty
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
str
;
use
syntax
::
ast
;
...
...
src/librustc/middle/trans/base.rs
浏览文件 @
81cf72c2
...
...
@@ -63,6 +63,8 @@
use
util
::
common
::
indenter
;
use
util
::
ppaux
::{
Repr
,
ty_to_str
};
use
middle
::
trans
::
type_
::
Type
;
use
core
::
hash
;
use
core
::
hashmap
::{
HashMap
};
use
core
::
int
;
...
...
@@ -150,7 +152,7 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type)
}
pub
fn
decl_cdecl_fn
(
llmod
:
ModuleRef
,
name
:
&
str
,
ty
:
Type
)
->
ValueRef
{
return
decl_fn
(
llmod
,
name
,
lib
::
llvm
::
CCallConv
,
ll
ty
);
return
decl_fn
(
llmod
,
name
,
lib
::
llvm
::
CCallConv
,
ty
);
}
// Only use this if you are going to actually define the function. It's
...
...
@@ -229,7 +231,7 @@ pub fn opaque_box_body(bcx: block,
let
_
icx
=
bcx
.insn_ctxt
(
"opaque_box_body"
);
let
ccx
=
bcx
.ccx
();
let
ty
=
type_of
(
ccx
,
body_t
);
let
ty
=
Type
::
box
(
ccx
,
ty
);
let
ty
=
Type
::
box
(
ccx
,
&
ty
);
let
boxptr
=
PointerCast
(
bcx
,
boxptr
,
ty
.ptr_to
());
GEPi
(
bcx
,
boxptr
,
[
0u
,
abi
::
box_field_body
])
}
...
...
@@ -281,15 +283,8 @@ pub fn malloc_raw_dyn(bcx: block,
* address space 0. Otherwise the resulting (non-box) pointer will be in the
* wrong address space and thus be the wrong type.
*/
pub
fn
non_gc_box_cast
(
bcx
:
block
,
val
:
ValueRef
)
->
ValueRef
{
unsafe
{
debug!
(
"non_gc_box_cast"
);
add_comment
(
bcx
,
"non_gc_box_cast"
);
assert
!
(
llvm
::
LLVMGetPointerAddressSpace
(
val_ty
(
val
))
==
gc_box_addrspace
||
bcx
.unreachable
);
let
non_gc_t
=
llvm
::
LLVMGetElementType
(
val_ty
(
val
))
.ptr_to
();
PointerCast
(
bcx
,
val
,
non_gc_t
)
}
pub
fn
non_gc_box_cast
(
_
:
block
,
val
:
ValueRef
)
->
ValueRef
{
val
}
// malloc_raw: expects an unboxed type and returns a pointer to
...
...
@@ -721,8 +716,8 @@ pub fn cast_shift_expr_rhs(cx: block, op: ast::binop,
pub
fn
cast_shift_const_rhs
(
op
:
ast
::
binop
,
lhs
:
ValueRef
,
rhs
:
ValueRef
)
->
ValueRef
{
cast_shift_rhs
(
op
,
lhs
,
rhs
,
|
a
,
b
|
unsafe
{
llvm
::
LLVMConstTrunc
(
a
,
b
)
},
|
a
,
b
|
unsafe
{
llvm
::
LLVMConstZExt
(
a
,
b
)
})
|
a
,
b
|
unsafe
{
llvm
::
LLVMConstTrunc
(
a
,
b
.to_ref
()
)
},
|
a
,
b
|
unsafe
{
llvm
::
LLVMConstZExt
(
a
,
b
.to_ref
()
)
})
}
pub
fn
cast_shift_rhs
(
op
:
ast
::
binop
,
...
...
@@ -735,8 +730,8 @@ pub fn cast_shift_rhs(op: ast::binop,
if
ast_util
::
is_shift_binop
(
op
)
{
let
rhs_llty
=
val_ty
(
rhs
);
let
lhs_llty
=
val_ty
(
lhs
);
let
rhs_sz
=
llvm
::
LLVMGetIntTypeWidth
(
rhs_llty
);
let
lhs_sz
=
llvm
::
LLVMGetIntTypeWidth
(
lhs_llty
);
let
rhs_sz
=
llvm
::
LLVMGetIntTypeWidth
(
rhs_llty
.to_ref
()
);
let
lhs_sz
=
llvm
::
LLVMGetIntTypeWidth
(
lhs_llty
.to_ref
()
);
if
lhs_sz
<
rhs_sz
{
trunc
(
rhs
,
lhs_llty
)
}
else
if
lhs_sz
>
rhs_sz
{
...
...
@@ -761,11 +756,11 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop,
};
let
is_zero
=
match
ty
::
get
(
rhs_t
)
.sty
{
ty
::
ty_int
(
t
)
=>
{
let
zero
=
C_integral
(
Type
::
int_from_ty
(
cx
.ccx
(),
t
),
0u64
,
F
alse
);
let
zero
=
C_integral
(
Type
::
int_from_ty
(
cx
.ccx
(),
t
),
0u64
,
f
alse
);
ICmp
(
cx
,
lib
::
llvm
::
IntEQ
,
rhs
,
zero
)
}
ty
::
ty_uint
(
t
)
=>
{
let
zero
=
C_integral
(
Type
::
uint_from_ty
(
cx
.ccx
(),
t
),
0u64
,
F
alse
);
let
zero
=
C_integral
(
Type
::
uint_from_ty
(
cx
.ccx
(),
t
),
0u64
,
f
alse
);
ICmp
(
cx
,
lib
::
llvm
::
IntEQ
,
rhs
,
zero
)
}
_
=>
{
...
...
@@ -779,7 +774,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop,
}
pub
fn
null_env_ptr
(
bcx
:
block
)
->
ValueRef
{
C_null
(
Type
::
opaque_box
(
bcx
.ccx
())
.
to_ptr
())
C_null
(
Type
::
opaque_box
(
bcx
.ccx
())
.
ptr_to
())
}
pub
fn
trans_external_path
(
ccx
:
&
mut
CrateContext
,
did
:
ast
::
def_id
,
t
:
ty
::
t
)
...
...
@@ -1479,7 +1474,7 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) {
let
llintrinsicfn
=
ccx
.intrinsics
.get_copy
(
&
intrinsic_key
);
let
llptr
=
PointerCast
(
cx
,
llptr
,
Type
::
i8
()
.ptr_to
());
let
llzeroval
=
C_u8
(
0
);
let
size
=
IntCast
(
cx
,
machine
::
llsize_of
(
ccx
,
ty
),
ccx
.int_type
.to_ref
()
);
let
size
=
IntCast
(
cx
,
machine
::
llsize_of
(
ccx
,
ty
),
ccx
.int_type
);
let
align
=
C_i32
(
llalign_of_min
(
ccx
,
ty
)
as
i32
);
let
volatile
=
C_i1
(
false
);
Call
(
cx
,
llintrinsicfn
,
[
llptr
,
llzeroval
,
size
,
align
,
volatile
]);
...
...
@@ -1506,7 +1501,7 @@ pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef {
}
}
let
initcx
=
base
::
raw_block
(
cx
.fcx
,
false
,
cx
.fcx.llstaticallocas
);
let
p
=
Alloca
(
initcx
,
ty
.to_ref
()
);
let
p
=
Alloca
(
initcx
,
ty
);
if
zero
{
memzero
(
initcx
,
p
,
ty
);
}
p
}
...
...
@@ -1515,10 +1510,10 @@ pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef {
let
_
icx
=
cx
.insn_ctxt
(
"arrayalloca"
);
if
cx
.unreachable
{
unsafe
{
return
llvm
::
LLVMGetUndef
(
ty
);
return
llvm
::
LLVMGetUndef
(
ty
.to_ref
()
);
}
}
return
ArrayAlloca
(
base
::
raw_block
(
cx
.fcx
,
false
,
cx
.fcx.llstaticallocas
),
ty
.to_ref
()
,
v
);
return
ArrayAlloca
(
base
::
raw_block
(
cx
.fcx
,
false
,
cx
.fcx.llstaticallocas
),
ty
,
v
);
}
pub
struct
BasicBlocks
{
...
...
@@ -1588,7 +1583,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
let
fcx
=
@
mut
fn_ctxt_
{
llfn
:
llfndecl
,
llenv
:
unsafe
{
llvm
::
LLVMGetUndef
(
Type
::
i8p
())
llvm
::
LLVMGetUndef
(
Type
::
i8p
()
.to_ref
()
)
},
llretptr
:
None
,
llstaticallocas
:
llbbs
.sa
,
...
...
@@ -2309,7 +2304,7 @@ fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
fn
create_entry_fn
(
ccx
:
@
mut
CrateContext
,
rust_main
:
ValueRef
,
use_start_lang_item
:
bool
)
{
let
llfty
=
Type
::
func
([
ccx
.int_type
,
Type
::
i8
()
.ptr_to
()
.ptr_to
()],
ccx
.int_type
);
let
llfty
=
Type
::
func
([
ccx
.int_type
,
Type
::
i8
()
.ptr_to
()
.ptr_to
()],
&
ccx
.int_type
);
// FIXME #4404 android JNI hacks
let
llfn
=
if
*
ccx
.sess.building_library
{
...
...
@@ -2338,10 +2333,9 @@ fn create_entry_fn(ccx: @mut CrateContext,
}
let
crate_map
=
ccx
.crate_map
;
let
opaque_crate_map
=
llvm
::
LLVMBuildPointerCast
(
bld
,
crate_map
,
Type
::
i8p
(),
noname
());
let
opaque_crate_map
=
do
"crate_map"
.as_c_str
|
buf
|
{
llvm
::
LLVMBuildPointerCast
(
bld
,
crate_map
,
Type
::
i8p
()
.to_ref
(),
buf
)
};
let
(
start_fn
,
args
)
=
if
use_start_lang_item
{
let
start_def_id
=
ccx
.tcx.lang_items
.start_fn
();
...
...
@@ -2354,8 +2348,9 @@ fn create_entry_fn(ccx: @mut CrateContext,
};
let
args
=
{
let
opaque_rust_main
=
llvm
::
LLVMBuildPointerCast
(
bld
,
rust_main
,
Type
::
i8p
(),
noname
());
let
opaque_rust_main
=
do
"rust_main"
.as_c_str
|
buf
|
{
llvm
::
LLVMBuildPointerCast
(
bld
,
rust_main
,
Type
::
i8p
()
.to_ref
(),
buf
)
};
~
[
C_null
(
Type
::
opaque_box
(
ccx
)
.ptr_to
()),
...
...
@@ -2487,7 +2482,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
let
g
=
do
str
::
as_c_str
(
ident
)
|
buf
|
{
unsafe
{
let
ty
=
type_of
(
ccx
,
typ
);
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ty
,
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ty
.to_ref
()
,
buf
)
}
};
g
...
...
@@ -2583,7 +2578,7 @@ pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) {
note_unique_llvm_symbol
(
ccx
,
s
);
let
discrim_gvar
=
str
::
as_c_str
(
s
,
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ccx
.int_type
,
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ccx
.int_type
.to_ref
()
,
buf
)
}
});
unsafe
{
...
...
@@ -2616,14 +2611,14 @@ pub fn vp2i(cx: block, v: ValueRef) -> ValueRef {
pub
fn
p2i
(
ccx
:
&
CrateContext
,
v
:
ValueRef
)
->
ValueRef
{
unsafe
{
return
llvm
::
LLVMConstPtrToInt
(
v
,
ccx
.int_type
);
return
llvm
::
LLVMConstPtrToInt
(
v
,
ccx
.int_type
.to_ref
()
);
}
}
macro_rules!
ifn
(
(
$name:expr
,
$args:expr
,
$ret:expr
)
=>
({
let
name
=
$name
;
let
f
=
decl_cdecl_fn
(
llmod
,
name
,
Type
::
func
(
$args
,
$ret
));
let
f
=
decl_cdecl_fn
(
llmod
,
name
,
Type
::
func
(
$args
,
&
$ret
));
intrinsics
.insert
(
name
,
f
);
})
)
...
...
@@ -2642,7 +2637,7 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> {
[
i8p
,
i8p
,
Type
::
i64
(),
Type
::
i32
(),
Type
::
i1
()],
Type
::
void
());
ifn!
(
"llvm.memset.p0i8.i32"
,
[
i8p
,
Type
::
i8
(),
Type
::
i32
(),
Type
::
i32
(),
Type
::
i1
()],
Type
::
void
());
ifn!
(
"llvm.mem
cpy
.p0i8.i64"
,
ifn!
(
"llvm.mem
set
.p0i8.i64"
,
[
i8p
,
Type
::
i8
(),
Type
::
i64
(),
Type
::
i32
(),
Type
::
i1
()],
Type
::
void
());
ifn!
(
"llvm.trap"
,
[],
Type
::
void
());
...
...
@@ -2710,7 +2705,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati
}
pub
fn
trap
(
bcx
:
block
)
{
match
bcx
.ccx
()
.intrinsics
.find_equiv
(
"llvm.trap"
)
{
match
bcx
.ccx
()
.intrinsics
.find_equiv
(
&
&
"llvm.trap"
)
{
Some
(
&
x
)
=>
{
Call
(
bcx
,
x
,
[]);
},
_
=>
bcx
.sess
()
.bug
(
"unbound llvm.trap in trap"
)
}
...
...
@@ -2724,7 +2719,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
let
gc_metadata_name
=
~
"_gc_module_metadata_"
+
llmod_id
;
let
gc_metadata
=
do
str
::
as_c_str
(
gc_metadata_name
)
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
Type
::
i32
(),
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
Type
::
i32
()
.to_ref
()
,
buf
)
}
};
unsafe
{
...
...
@@ -2736,12 +2731,12 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
pub
fn
create_module_map
(
ccx
:
&
mut
CrateContext
)
->
ValueRef
{
let
elttype
=
Type
::
struct_
([
ccx
.int_type
,
ccx
.int_type
],
false
);
let
maptype
=
Type
::
array
(
elttype
,
ccx
.module_data
.len
()
+
1
);
let
map
=
str
::
as_c_str
(
"_rust_mod_map"
,
|
buf
|
{
let
maptype
=
Type
::
array
(
&
elttype
,
(
ccx
.module_data
.len
()
+
1
)
as
u64
);
let
map
=
do
"_rust_mod_map"
.as_c_str
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
maptype
,
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
maptype
.to_ref
()
,
buf
)
}
}
)
;
};
lib
::
llvm
::
SetLinkage
(
map
,
lib
::
llvm
::
InternalLinkage
);
let
mut
elts
:
~
[
ValueRef
]
=
~
[];
...
...
@@ -2783,11 +2778,11 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
~
"toplevel"
};
let
sym_name
=
~
"_rust_crate_map_"
+
mapname
;
let
arrtype
=
Type
::
array
(
int_type
,
n_subcrates
as
u64
);
let
arrtype
=
Type
::
array
(
&
int_type
,
n_subcrates
as
u64
);
let
maptype
=
Type
::
struct_
([
Type
::
i32
(),
Type
::
i8p
(),
int_type
,
arrtype
],
false
);
let
map
=
str
::
as_c_str
(
sym_name
,
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
llmod
,
maptype
,
buf
)
llvm
::
LLVMAddGlobal
(
llmod
,
maptype
.to_ref
()
,
buf
)
}
});
lib
::
llvm
::
SetLinkage
(
map
,
lib
::
llvm
::
ExternalLinkage
);
...
...
@@ -2806,7 +2801,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
cstore
::
get_crate_hash
(
cstore
,
i
));
let
cr
=
str
::
as_c_str
(
nm
,
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ccx
.int_type
,
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ccx
.int_type
.to_ref
()
,
buf
)
}
});
subcrates
.push
(
p2i
(
ccx
,
cr
));
...
...
@@ -2830,8 +2825,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
let
mod_map
=
create_module_map
(
ccx
);
llvm
::
LLVMSetInitializer
(
map
,
C_struct
(
[
C_i32
(
1
),
lib
::
llvm
::
llvm
::
LLVMConstPointerCast
(
llannihilatefn
,
Type
::
i8p
()),
lib
::
llvm
::
llvm
::
LLVMConstPointerCast
(
llannihilatefn
,
Type
::
i8p
()
.to_ref
()),
p2i
(
ccx
,
mod_map
),
C_array
(
ccx
.int_type
,
subcrates
)]));
}
...
...
@@ -2869,7 +2863,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) {
let
llconst
=
C_struct
([
llmeta
]);
let
mut
llglobal
=
str
::
as_c_str
(
"rust_metadata"
,
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
val_ty
(
llconst
),
buf
)
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
val_ty
(
llconst
)
.to_ref
()
,
buf
)
}
});
unsafe
{
...
...
@@ -2880,9 +2874,9 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) {
lib
::
llvm
::
SetLinkage
(
llglobal
,
lib
::
llvm
::
InternalLinkage
);
let
t_ptr_i8
=
Type
::
i8p
();
llglobal
=
llvm
::
LLVMConstBitCast
(
llglobal
,
t_ptr_i8
);
llglobal
=
llvm
::
LLVMConstBitCast
(
llglobal
,
t_ptr_i8
.to_ref
()
);
let
llvm_used
=
do
"llvm.used"
.as_c_str
|
buf
|
{
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
Type
::
array
(
t_ptr_i8
,
1u
),
buf
)
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
Type
::
array
(
&
t_ptr_i8
,
1
)
.to_ref
(
),
buf
)
};
lib
::
llvm
::
SetLinkage
(
llvm_used
,
lib
::
llvm
::
AppendingLinkage
);
llvm
::
LLVMSetInitializer
(
llvm_used
,
C_array
(
t_ptr_i8
,
[
llglobal
]));
...
...
src/librustc/middle/trans/build.rs
浏览文件 @
81cf72c2
...
...
@@ -13,12 +13,14 @@
use
lib
::
llvm
::
llvm
;
use
lib
::
llvm
::{
CallConv
,
AtomicBinOp
,
AtomicOrdering
,
AsmDialect
};
use
lib
::
llvm
::{
Opcode
,
IntPredicate
,
RealPredicate
,
False
};
use
lib
::
llvm
::{
ValueRef
,
Type
,
BasicBlockRef
,
BuilderRef
,
ModuleRef
};
use
lib
::
llvm
::{
ValueRef
,
BasicBlockRef
,
BuilderRef
,
ModuleRef
};
use
lib
;
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
::
machine
::
llalign_of_min
;
use
syntax
::
codemap
::
span
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
cast
;
use
core
::
hashmap
::
HashMap
;
use
core
::
libc
::{
c_uint
,
c_ulonglong
,
c_char
};
...
...
@@ -232,7 +234,7 @@ pub fn Unreachable(cx: block) {
pub
fn
_
Undef
(
val
:
ValueRef
)
->
ValueRef
{
unsafe
{
return
llvm
::
LLVMGetUndef
(
val_ty
(
val
));
return
llvm
::
LLVMGetUndef
(
val_ty
(
val
)
.to_ref
()
);
}
}
...
...
@@ -504,7 +506,7 @@ pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
pub
fn
Alloca
(
cx
:
block
,
Ty
:
Type
)
->
ValueRef
{
unsafe
{
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Ty
.
to_ptr
()
.to_ref
());
}
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Ty
.
ptr_to
()
.to_ref
());
}
count_insn
(
cx
,
"alloca"
);
return
llvm
::
LLVMBuildAlloca
(
B
(
cx
),
Ty
.to_ref
(),
noname
());
}
...
...
@@ -512,7 +514,7 @@ pub fn Alloca(cx: block, Ty: Type) -> ValueRef {
pub
fn
ArrayAlloca
(
cx
:
block
,
Ty
:
Type
,
Val
:
ValueRef
)
->
ValueRef
{
unsafe
{
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Ty
.
to_ptr
()
.to_ref
());
}
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Ty
.
ptr_to
()
.to_ref
());
}
count_insn
(
cx
,
"arrayalloca"
);
return
llvm
::
LLVMBuildArrayAlloca
(
B
(
cx
),
Ty
.to_ref
(),
Val
,
noname
());
}
...
...
@@ -531,9 +533,12 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
let
ccx
=
cx
.fcx.ccx
;
if
cx
.unreachable
{
let
ty
=
val_ty
(
PointerVal
);
let
eltty
=
if
llvm
::
LLVMGetTypeKind
(
ty
)
==
lib
::
llvm
::
Array
{
llvm
::
LLVMGetElementType
(
ty
)
}
else
{
ccx
.int_type
};
return
llvm
::
LLVMGetUndef
(
eltty
);
let
eltty
=
if
ty
.kind
()
==
lib
::
llvm
::
Array
{
ty
.element_type
()
}
else
{
ccx
.int_type
};
return
llvm
::
LLVMGetUndef
(
eltty
.to_ref
());
}
count_insn
(
cx
,
"load"
);
return
llvm
::
LLVMBuildLoad
(
B
(
cx
),
PointerVal
,
noname
());
...
...
@@ -544,7 +549,7 @@ pub fn AtomicLoad(cx: block, PointerVal: ValueRef, order: AtomicOrdering) -> Val
unsafe
{
let
ccx
=
cx
.fcx.ccx
;
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
ccx
.int_type
);
return
llvm
::
LLVMGetUndef
(
ccx
.int_type
.to_ref
()
);
}
count_insn
(
cx
,
"load.atomic"
);
let
align
=
llalign_of_min
(
ccx
,
ccx
.int_type
);
...
...
@@ -639,7 +644,7 @@ pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
pub
fn
GlobalString
(
cx
:
block
,
_
Str
:
*
c_char
)
->
ValueRef
{
unsafe
{
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Type
::
i8p
());
}
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Type
::
i8p
()
.to_ref
()
);
}
count_insn
(
cx
,
"globalstring"
);
return
llvm
::
LLVMBuildGlobalString
(
B
(
cx
),
_
Str
,
noname
());
}
...
...
@@ -647,7 +652,7 @@ pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef {
pub
fn
GlobalStringPtr
(
cx
:
block
,
_
Str
:
*
c_char
)
->
ValueRef
{
unsafe
{
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Type
::
i8p
());
}
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Type
::
i8p
()
.to_ref
()
);
}
count_insn
(
cx
,
"globalstringptr"
);
return
llvm
::
LLVMBuildGlobalStringPtr
(
B
(
cx
),
_
Str
,
noname
());
}
...
...
@@ -841,7 +846,7 @@ pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef])
unsafe
{
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
Ty
.to_ref
());
}
assert_eq!
(
vals
.len
(),
bbs
.len
());
let
phi
=
EmptyPhi
(
cx
,
Ty
.to_ref
()
);
let
phi
=
EmptyPhi
(
cx
,
Ty
);
count_insn
(
cx
,
"addincoming"
);
llvm
::
LLVMAddIncoming
(
phi
,
vec
::
raw
::
to_ptr
(
vals
),
vec
::
raw
::
to_ptr
(
bbs
),
...
...
@@ -863,10 +868,13 @@ pub fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
unsafe
{
let
ccx
=
cx
.fcx.ccx
;
let
ty
=
val_ty
(
Fn
);
let
retty
=
if
llvm
::
LLVMGetTypeKind
(
ty
)
==
lib
::
llvm
::
Integer
{
llvm
::
LLVMGetReturnType
(
ty
)
}
else
{
ccx
.int_type
};
count_insn
(
cx
,
""
);
return
llvm
::
LLVMGetUndef
(
retty
);
let
retty
=
if
ty
.kind
()
==
lib
::
llvm
::
Integer
{
ty
.return_type
()
}
else
{
ccx
.int_type
};
count_insn
(
cx
,
"ret_undef"
);
return
llvm
::
LLVMGetUndef
(
retty
.to_ref
());
}
}
...
...
@@ -887,9 +895,10 @@ pub fn add_comment(bcx: block, text: &str) {
let
comment_text
=
~
"# "
+
sanitized
.replace
(
"
\n
"
,
"
\n\t
# "
);
count_insn
(
bcx
,
"inlineasm"
);
let
asm
=
str
::
as_c_str
(
comment_text
,
|
c
|
{
llvm
::
LLVMConstInlineAsm
(
Type
::
func
([],
Type
::
void
()),
c
,
noname
(),
False
,
False
)
});
let
asm
=
do
comment_text
.as_c_str
|
c
|
{
llvm
::
LLVMConstInlineAsm
(
Type
::
func
([],
&
Type
::
void
())
.to_ref
(),
c
,
noname
(),
False
,
False
)
};
Call
(
bcx
,
asm
,
[]);
}
}
...
...
@@ -913,8 +922,8 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
};
debug!
(
"Asm Output Type: %?"
,
cx
.ccx
()
.tn
.type_to_str
(
output
));
let
fty
=
Type
::
func
(
argtys
,
output
);
let
v
=
llvm
::
LLVMInlineAsm
(
ll
fty
.to_ref
(),
asm
,
cons
,
volatile
,
alignstack
,
dia
as
c_uint
);
let
fty
=
Type
::
func
(
argtys
,
&
output
);
let
v
=
llvm
::
LLVMInlineAsm
(
fty
.to_ref
(),
asm
,
cons
,
volatile
,
alignstack
,
dia
as
c_uint
);
Call
(
cx
,
v
,
inputs
)
}
...
...
@@ -1005,9 +1014,9 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
pub
fn
VectorSplat
(
cx
:
block
,
NumElts
:
uint
,
EltVal
:
ValueRef
)
->
ValueRef
{
unsafe
{
let
elt_ty
=
val_ty
(
EltVal
);
let
Undef
=
llvm
::
LLVMGetUndef
(
Type
::
vector
(
elt_ty
,
NumElts
)
.to_ref
());
let
Undef
=
llvm
::
LLVMGetUndef
(
Type
::
vector
(
&
elt_ty
,
NumElts
as
u64
)
.to_ref
());
let
VecVal
=
InsertElement
(
cx
,
Undef
,
EltVal
,
C_i32
(
0
));
ShuffleVector
(
cx
,
VecVal
,
Undef
,
C_null
(
Type
::
vector
(
Type
::
i32
()
.to_ref
(),
NumElts
)))
ShuffleVector
(
cx
,
VecVal
,
Undef
,
C_null
(
Type
::
vector
(
&
Type
::
i32
(),
NumElts
as
u64
)))
}
}
...
...
@@ -1049,7 +1058,7 @@ pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
pub
fn
PtrDiff
(
cx
:
block
,
LHS
:
ValueRef
,
RHS
:
ValueRef
)
->
ValueRef
{
unsafe
{
let
ccx
=
cx
.fcx.ccx
;
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
ccx
.int_type
);
}
if
cx
.unreachable
{
return
llvm
::
LLVMGetUndef
(
ccx
.int_type
.to_ref
()
);
}
count_insn
(
cx
,
"ptrdiff"
);
return
llvm
::
LLVMBuildPtrDiff
(
B
(
cx
),
LHS
,
RHS
,
noname
());
}
...
...
src/librustc/middle/trans/cabi.rs
浏览文件 @
81cf72c2
...
...
@@ -8,20 +8,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
lib
::
llvm
::{
llvm
,
TypeRef
,
ValueRef
,
Attribute
,
Void
};
use
lib
::
llvm
::{
llvm
,
ValueRef
,
Attribute
,
Void
};
use
middle
::
trans
::
base
::
*
;
use
middle
::
trans
::
build
::
*
;
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
libc
::
c_uint
;
use
core
::
option
;
use
core
::
vec
;
pub
trait
ABIInfo
{
fn
compute_info
(
&
self
,
atys
:
&
[
TypeRef
],
rty
:
TypeRef
,
ret_def
:
bool
)
->
FnType
;
fn
compute_info
(
&
self
,
atys
:
&
[
Type
],
rty
:
Type
,
ret_def
:
bool
)
->
FnType
;
}
pub
struct
LLVMType
{
...
...
@@ -40,7 +39,7 @@ impl FnType {
pub
fn
decl_fn
(
&
self
,
decl
:
&
fn
(
fnty
:
Type
)
->
ValueRef
)
->
ValueRef
{
let
atys
=
vec
::
map
(
self
.arg_tys
,
|
t
|
t
.ty
);
let
rty
=
self
.ret_ty.ty
;
let
fnty
=
Type
::
func
(
atys
,
rty
);
let
fnty
=
Type
::
func
(
atys
,
&
rty
);
let
llfn
=
decl
(
fnty
);
for
self
.attrs
.iter
()
.enumerate
()
.advance
|(
i
,
a
)|
{
...
...
@@ -57,10 +56,7 @@ pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef {
return
llfn
;
}
pub
fn
build_shim_args
(
&
self
,
bcx
:
block
,
arg_tys
:
&
[
Type
],
llargbundle
:
ValueRef
)
pub
fn
build_shim_args
(
&
self
,
bcx
:
block
,
arg_tys
:
&
[
Type
],
llargbundle
:
ValueRef
)
->
~
[
ValueRef
]
{
let
mut
atys
:
&
[
LLVMType
]
=
self
.arg_tys
;
let
mut
attrs
:
&
[
option
::
Option
<
Attribute
>
]
=
self
.attrs
;
...
...
@@ -80,7 +76,7 @@ pub fn build_shim_args(&self,
while
i
<
n
{
let
llargval
=
if
atys
[
i
]
.cast
{
let
arg_ptr
=
GEPi
(
bcx
,
llargbundle
,
[
0u
,
i
]);
let
arg_ptr
=
BitCast
(
bcx
,
arg_ptr
,
T_ptr
(
atys
[
i
]
.ty
));
let
arg_ptr
=
BitCast
(
bcx
,
arg_ptr
,
atys
[
i
]
.ty
.ptr_to
(
));
Load
(
bcx
,
arg_ptr
)
}
else
if
attrs
[
i
]
.is_some
()
{
GEPi
(
bcx
,
llargbundle
,
[
0u
,
i
])
...
...
@@ -94,19 +90,14 @@ pub fn build_shim_args(&self,
return
llargvals
;
}
pub
fn
build_shim_ret
(
&
self
,
bcx
:
block
,
arg_tys
:
&
[
Type
],
ret_def
:
bool
,
llargbundle
:
ValueRef
,
llretval
:
ValueRef
)
{
pub
fn
build_shim_ret
(
&
self
,
bcx
:
block
,
arg_tys
:
&
[
Type
],
ret_def
:
bool
,
llargbundle
:
ValueRef
,
llretval
:
ValueRef
)
{
for
vec
::
eachi
(
self
.attrs
)
|
i
,
a
|
{
for
self
.attrs
.iter
()
.enumerate
()
.advance
|(
i
,
a
)|
{
match
*
a
{
option
::
Some
(
attr
)
=>
{
unsafe
{
llvm
::
LLVMAddInstrAttribute
(
llretval
,
(
i
+
1u
)
as
c_uint
,
attr
as
c_uint
);
llvm
::
LLVMAddInstrAttribute
(
llretval
,
(
i
+
1u
)
as
c_uint
,
attr
as
c_uint
);
}
}
_
=>
()
...
...
@@ -121,7 +112,7 @@ pub fn build_shim_ret(&self,
// R* llretloc = *llretptr; /* (args->r) */
let
llretloc
=
Load
(
bcx
,
llretptr
);
if
self
.ret_ty.cast
{
let
tmp_ptr
=
BitCast
(
bcx
,
llretloc
,
T_ptr
(
self
.ret_ty.ty
));
let
tmp_ptr
=
BitCast
(
bcx
,
llretloc
,
self
.ret_ty.ty
.ptr_to
(
));
// *args->r = r;
Store
(
bcx
,
llretval
,
tmp_ptr
);
}
else
{
...
...
@@ -130,11 +121,8 @@ pub fn build_shim_ret(&self,
};
}
pub
fn
build_wrap_args
(
&
self
,
bcx
:
block
,
ret_ty
:
Type
,
llwrapfn
:
ValueRef
,
llargbundle
:
ValueRef
)
{
pub
fn
build_wrap_args
(
&
self
,
bcx
:
block
,
ret_ty
:
Type
,
llwrapfn
:
ValueRef
,
llargbundle
:
ValueRef
)
{
let
mut
atys
:
&
[
LLVMType
]
=
self
.arg_tys
;
let
mut
attrs
:
&
[
option
::
Option
<
Attribute
>
]
=
self
.attrs
;
let
mut
j
=
0u
;
...
...
@@ -159,7 +147,7 @@ pub fn build_wrap_args(&self,
store_inbounds
(
bcx
,
argval
,
llargbundle
,
[
0u
,
i
]);
}
else
if
atys
[
i
]
.cast
{
let
argptr
=
GEPi
(
bcx
,
llargbundle
,
[
0u
,
i
]);
let
argptr
=
BitCast
(
bcx
,
argptr
,
T_ptr
(
atys
[
i
]
.ty
));
let
argptr
=
BitCast
(
bcx
,
argptr
,
atys
[
i
]
.ty
.ptr_to
(
));
Store
(
bcx
,
argval
,
argptr
);
}
else
{
store_inbounds
(
bcx
,
argval
,
llargbundle
,
[
0u
,
i
]);
...
...
@@ -169,14 +157,9 @@ pub fn build_wrap_args(&self,
store_inbounds
(
bcx
,
llretptr
,
llargbundle
,
[
0u
,
n
]);
}
pub
fn
build_wrap_ret
(
&
self
,
bcx
:
block
,
arg_tys
:
&
[
TypeRef
],
llargbundle
:
ValueRef
)
{
unsafe
{
if
llvm
::
LLVMGetTypeKind
(
self
.ret_ty.ty
)
==
Void
{
return
;
}
pub
fn
build_wrap_ret
(
&
self
,
bcx
:
block
,
arg_tys
:
&
[
Type
],
llargbundle
:
ValueRef
)
{
if
self
.ret_ty.ty
.kind
()
==
Void
{
return
;
}
if
bcx
.fcx.llretptr
.is_some
()
{
...
...
@@ -187,9 +170,7 @@ pub fn build_wrap_ret(&self,
}
else
{
Load
(
bcx
,
llretval
)
};
let
llretptr
=
BitCast
(
bcx
,
bcx
.fcx.llretptr
.get
(),
self
.ret_ty.ty
.ptr_to
());
let
llretptr
=
BitCast
(
bcx
,
bcx
.fcx.llretptr
.get
(),
self
.ret_ty.ty
.ptr_to
());
Store
(
bcx
,
llretval
,
llretptr
);
}
}
...
...
src/librustc/middle/trans/cabi_arm.rs
浏览文件 @
81cf72c2
...
...
@@ -9,11 +9,12 @@
// except according to those terms.
use
lib
::
llvm
::{
llvm
,
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
};
use
lib
::
llvm
::
struct_tys
;
use
lib
::
llvm
::{
Attribute
,
StructRetAttribute
};
use
lib
::
llvm
::
True
;
use
middle
::
trans
::
cabi
::{
ABIInfo
,
FnType
,
LLVMType
};
use
middle
::
trans
::
type_
::
Type
;
use
core
::
option
::{
Option
,
None
,
Some
};
use
core
::
uint
;
...
...
@@ -27,58 +28,58 @@ fn align(off: uint, ty: Type) -> uint {
}
fn
ty_align
(
ty
:
Type
)
->
uint
{
unsafe
{
match
ty
.kind
()
{
Integer
=>
{
match
ty
.kind
()
{
Integer
=>
{
unsafe
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
())
as
uint
)
+
7
)
/
8
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
1
}
else
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
1
,
|
a
,
t
|
uint
::
max
(
a
,
ty_align
(
*
t
)))
}
}
Array
=>
{
let
elt
=
ty
.element_type
();
ty_align
(
elt
)
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
1
}
else
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
1
,
|
a
,
t
|
uint
::
max
(
a
,
ty_align
(
*
t
)))
}
_
=>
fail
!
(
"ty_align: unhandled type"
)
}
Array
=>
{
let
elt
=
ty
.element_type
();
ty_align
(
elt
)
}
_
=>
fail
!
(
"ty_align: unhandled type"
)
}
}
fn
ty_size
(
ty
:
Type
)
->
uint
{
unsafe
{
match
ty
.kind
()
{
Integer
=>
{
match
ty
.kind
()
{
Integer
=>
{
unsafe
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
())
as
uint
)
+
7
)
/
8
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
s
+
ty_size
(
*
t
))
}
else
{
let
str_tys
=
ty
.field_types
();
let
size
=
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
align
(
s
,
*
t
)
+
ty_size
(
*
t
));
align
(
size
,
ty
)
}
}
Array
=>
{
let
len
=
ty
.array_length
();
let
elt
=
ty
.element_type
();
let
eltsz
=
ty_size
(
elt
);
len
*
eltsz
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
s
+
ty_size
(
*
t
))
}
else
{
let
str_tys
=
ty
.field_types
();
let
size
=
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
align
(
s
,
*
t
)
+
ty_size
(
*
t
));
align
(
size
,
ty
)
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
Array
=>
{
let
len
=
ty
.array_length
();
let
elt
=
ty
.element_type
();
let
eltsz
=
ty_size
(
elt
);
len
*
eltsz
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
}
...
...
@@ -107,9 +108,9 @@ fn classify_arg_ty(ty: Type) -> (LLVMType, Option<Attribute>) {
let
align
=
ty_align
(
ty
);
let
size
=
ty_size
(
ty
);
let
llty
=
if
align
<=
4
{
Type
::
array
(
Type
::
i32
(),
(
size
+
3
)
/
4
)
Type
::
array
(
&
Type
::
i32
(),
(
size
+
3
)
/
4
as
u6
4
)
}
else
{
Type
::
array
(
Type
::
i64
(),
(
size
+
7
)
/
8
)
Type
::
array
(
&
Type
::
i64
(),
(
size
+
7
)
/
8
as
u64
)
};
(
LLVMType
{
cast
:
true
,
ty
:
llty
},
None
)
}
...
...
@@ -122,7 +123,7 @@ fn is_reg_ty(ty: Type) -> bool {
|
Float
|
Double
=>
true
,
_
=>
false
}
;
}
}
}
...
...
src/librustc/middle/trans/cabi_mips.rs
浏览文件 @
81cf72c2
...
...
@@ -15,13 +15,14 @@
use
core
::
uint
;
use
core
::
vec
;
use
lib
::
llvm
::{
llvm
,
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
};
use
lib
::
llvm
::
struct_tys
;
use
lib
::
llvm
::{
Attribute
,
StructRetAttribute
};
use
lib
::
llvm
::
True
;
use
middle
::
trans
::
context
::
task_llcx
;
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
::
cabi
::
*
;
use
middle
::
trans
::
type_
::
Type
;
fn
align_up_to
(
off
:
uint
,
a
:
uint
)
->
uint
{
return
(
off
+
a
-
1u
)
/
a
*
a
;
}
...
...
@@ -32,58 +33,58 @@ fn align(off: uint, ty: Type) -> uint {
}
fn
ty_align
(
ty
:
Type
)
->
uint
{
unsafe
{
return
match
llvm
::
LLVMGetTypeKind
(
ty
)
{
Integer
=>
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
)
as
uint
)
+
7
)
/
8
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
1
}
else
{
let
str_tys
=
struct_tys
(
ty
);
str_tys
.iter
()
.fold
(
1
,
|
a
,
t
|
uint
::
max
(
a
,
ty_align
(
*
t
)))
}
}
Array
=>
{
let
elt
=
llvm
::
LLVMGetElementType
(
ty
);
ty_align
(
elt
)
match
ty
.kind
()
{
Integer
=>
{
unsafe
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
())
as
uint
)
+
7
)
/
8
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
};
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
1
}
else
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
1
,
|
a
,
t
|
uint
::
max
(
a
,
ty_align
(
*
t
)))
}
}
Array
=>
{
let
elt
=
ty
.element_type
();
ty_align
(
elt
)
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
}
fn
ty_size
(
ty
:
Type
Ref
)
->
uint
{
unsafe
{
return
match
llvm
::
LLVMGetTypeKind
(
ty
)
{
Integer
=>
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
)
as
uint
)
+
7
)
/
8
fn
ty_size
(
ty
:
Type
)
->
uint
{
match
ty
.kind
()
{
Integer
=>
{
unsafe
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
()
)
as
uint
)
+
7
)
/
8
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
llvm
::
LLVMIsPackedStruct
(
ty
)
==
True
{
let
str_tys
=
struct_tys
(
ty
);
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
s
+
ty_size
(
*
t
))
}
else
{
let
str_tys
=
ty
.field_types
();
let
size
=
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
align
(
s
,
*
t
)
+
ty_size
(
*
t
));
align
(
size
,
ty
)
}
}
Array
=>
{
let
len
=
ty
.array_length
();
let
elt
=
ty
.element_type
();
let
eltsz
=
ty_size
(
elt
);
len
*
eltsz
}
Pointer
=>
4
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
s
+
ty_size
(
*
t
))
}
else
{
let
str_tys
=
ty
.field_types
();
let
size
=
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
align
(
s
,
*
t
)
+
ty_size
(
*
t
));
align
(
size
,
ty
)
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
};
}
Array
=>
{
let
len
=
ty
.array_length
();
let
elt
=
ty
.element_type
();
let
eltsz
=
ty_size
(
elt
);
len
*
eltsz
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
}
...
...
@@ -120,7 +121,7 @@ fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option<Attribute>)
};
}
fn
is_reg_ty
(
ty
:
Type
Ref
)
->
bool
{
fn
is_reg_ty
(
ty
:
Type
)
->
bool
{
unsafe
{
return
match
ty
.kind
()
{
Integer
...
...
@@ -153,11 +154,11 @@ fn coerce_to_int(size: uint) -> ~[Type] {
let
r
=
size
%
32
;
if
r
>
0
{
unsafe
{
Type
::
from_ref
(
args
.push
(
llvm
::
LLVMIntTypeInContext
(
task_llcx
(),
r
as
c_uint
)))
args
.push
(
Type
::
from_ref
(
llvm
::
LLVMIntTypeInContext
(
task_llcx
(),
r
as
c_uint
)));
}
}
return
args
;
args
}
fn
struct_ty
(
ty
:
Type
,
...
...
src/librustc/middle/trans/cabi_x86.rs
浏览文件 @
81cf72c2
...
...
@@ -17,6 +17,8 @@
use
super
::
common
::
*
;
use
super
::
machine
::
*
;
use
middle
::
trans
::
type_
::
Type
;
struct
X86_ABIInfo
{
ccx
:
@
mut
CrateContext
}
...
...
src/librustc/middle/trans/cabi_x86_64.rs
浏览文件 @
81cf72c2
...
...
@@ -11,14 +11,15 @@
// The classification code for the x86_64 ABI is taken from the clay language
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
use
lib
::
llvm
::{
llvm
,
TypeRef
,
Integer
,
Pointer
,
Float
,
Double
};
use
lib
::
llvm
::{
llvm
,
Integer
,
Pointer
,
Float
,
Double
};
use
lib
::
llvm
::{
Struct
,
Array
,
Attribute
};
use
lib
::
llvm
::{
StructRetAttribute
,
ByValAttribute
};
use
lib
::
llvm
::
struct_tys
;
use
lib
::
llvm
::
True
;
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
::
cabi
::
*
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
libc
::
c_uint
;
use
core
::
option
;
use
core
::
option
::
Option
;
...
...
@@ -28,7 +29,7 @@
#[deriving(Eq)]
enum
RegClass
{
NoClass
,
Int
eger
,
Int
,
SSEFs
,
SSEFv
,
SSEDs
,
...
...
@@ -43,7 +44,7 @@ enum RegClass {
impl
Type
{
fn
is_reg_ty
(
&
self
)
->
bool
{
match
ty
.kind
()
{
match
self
.kind
()
{
Integer
|
Pointer
|
Float
|
Double
=>
true
,
_
=>
false
}
...
...
@@ -59,6 +60,11 @@ fn is_sse(&self) -> bool {
}
}
trait
ClassList
{
fn
is_pass_byval
(
&
self
)
->
bool
;
fn
is_ret_bysret
(
&
self
)
->
bool
;
}
impl
<
'self
>
ClassList
for
&
'self
[
RegClass
]
{
fn
is_pass_byval
(
&
self
)
->
bool
{
if
self
.len
()
==
0
{
return
false
;
}
...
...
@@ -83,64 +89,64 @@ fn align(off: uint, ty: Type) -> uint {
}
fn
ty_align
(
ty
:
Type
)
->
uint
{
unsafe
{
match
ty
.kind
()
{
Integer
=>
{
match
ty
.kind
()
{
Integer
=>
{
unsafe
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
())
as
uint
)
+
7
)
/
8
}
Pointer
=>
8
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
1
}
else
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
1
,
|
a
,
t
|
uint
::
max
(
a
,
ty_align
(
*
t
)))
}
}
Array
=>
{
let
elt
=
ty
.element_type
();
ty_align
(
elt
)
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
};
}
Pointer
=>
8
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
1
}
else
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
1
,
|
a
,
t
|
uint
::
max
(
a
,
ty_align
(
*
t
)))
}
}
Array
=>
{
let
elt
=
ty
.element_type
();
ty_align
(
elt
)
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
}
fn
ty_size
(
ty
:
TypeRef
)
->
uint
{
unsafe
{
match
ty
.kind
()
{
Integer
=>
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
)
as
uint
)
+
7
)
/
8
}
Pointer
=>
8
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
s
+
ty_size
(
*
t
))
}
else
{
let
str_tys
=
ty
.field_types
();
let
size
=
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
align
(
s
,
*
t
)
+
ty_size
(
*
t
));
align
(
size
,
ty
)
}
fn
ty_size
(
ty
:
Type
)
->
uint
{
match
ty
.kind
()
{
Integer
=>
{
unsafe
{
((
llvm
::
LLVMGetIntTypeWidth
(
ty
.to_ref
())
as
uint
)
+
7
)
/
8
}
Array
=>
{
let
len
=
ty
.array_length
();
let
elt
=
ty
.element_type
();
let
eltsz
=
ty_size
(
elt
);
len
*
eltsz
}
Pointer
=>
8
,
Float
=>
4
,
Double
=>
8
,
Struct
=>
{
if
ty
.is_packed
()
{
let
str_tys
=
ty
.field_types
();
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
s
+
ty_size
(
*
t
))
}
else
{
let
str_tys
=
ty
.field_types
();
let
size
=
str_tys
.iter
()
.fold
(
0
,
|
s
,
t
|
align
(
s
,
*
t
)
+
ty_size
(
*
t
));
align
(
size
,
ty
)
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
Array
=>
{
let
len
=
ty
.array_length
();
let
elt
=
ty
.element_type
();
let
eltsz
=
ty_size
(
elt
);
len
*
eltsz
}
_
=>
fail
!
(
"ty_size: unhandled type"
)
}
}
fn
all_mem
(
cls
:
&
mut
[
RegClass
])
{
for
uint
::
range
(
0
,
cls
.len
())
|
i
|
{
cls
[
i
]
=
memory_class
;
cls
[
i
]
=
Memory
;
}
}
...
...
@@ -149,21 +155,21 @@ fn unify(cls: &mut [RegClass],
newv
:
RegClass
)
{
if
cls
[
i
]
==
newv
{
return
;
}
else
if
cls
[
i
]
==
no_c
lass
{
}
else
if
cls
[
i
]
==
NoC
lass
{
cls
[
i
]
=
newv
;
}
else
if
newv
==
no_c
lass
{
}
else
if
newv
==
NoC
lass
{
return
;
}
else
if
cls
[
i
]
==
memory_class
||
newv
==
memory_class
{
cls
[
i
]
=
memory_class
;
}
else
if
cls
[
i
]
==
integer_class
||
newv
==
integer_class
{
cls
[
i
]
=
integer_class
;
}
else
if
cls
[
i
]
==
x87_class
||
cls
[
i
]
==
x87up_class
||
cls
[
i
]
==
complex_x87_class
||
newv
==
x87_class
||
newv
==
x87up_class
||
newv
==
complex_x87_class
{
cls
[
i
]
=
memory_class
;
}
else
if
cls
[
i
]
==
Memory
||
newv
==
Memory
{
cls
[
i
]
=
Memory
;
}
else
if
cls
[
i
]
==
Int
||
newv
==
Int
{
cls
[
i
]
=
Int
;
}
else
if
cls
[
i
]
==
X87
||
cls
[
i
]
==
X87Up
||
cls
[
i
]
==
ComplexX87
||
newv
==
X87
||
newv
==
X87Up
||
newv
==
ComplexX87
{
cls
[
i
]
=
Memory
;
}
else
{
cls
[
i
]
=
newv
;
}
...
...
@@ -192,7 +198,7 @@ fn classify(ty: Type,
let
mut
i
=
off
/
8u
;
let
e
=
(
off
+
t_size
+
7u
)
/
8u
;
while
i
<
e
{
unify
(
cls
,
ix
+
i
,
memory_class
);
unify
(
cls
,
ix
+
i
,
Memory
);
i
+=
1u
;
}
return
;
...
...
@@ -201,17 +207,17 @@ fn classify(ty: Type,
match
ty
.kind
()
{
Integer
|
Pointer
=>
{
unify
(
cls
,
ix
+
off
/
8u
,
integer_class
);
unify
(
cls
,
ix
+
off
/
8u
,
Int
);
}
Float
=>
{
if
off
%
8u
==
4u
{
unify
(
cls
,
ix
+
off
/
8u
,
sse_fv_class
);
unify
(
cls
,
ix
+
off
/
8u
,
SSEFv
);
}
else
{
unify
(
cls
,
ix
+
off
/
8u
,
sse_fs_clas
s
);
unify
(
cls
,
ix
+
off
/
8u
,
SSEF
s
);
}
}
Double
=>
{
unify
(
cls
,
ix
+
off
/
8u
,
sse_ds_clas
s
);
unify
(
cls
,
ix
+
off
/
8u
,
SSED
s
);
}
Struct
=>
{
classify_struct
(
ty
.field_types
(),
cls
,
ix
,
off
);
...
...
@@ -242,7 +248,7 @@ fn fixup(ty: Type, cls: &mut [RegClass]) {
if
cls
[
i
]
.is_sse
()
{
i
+=
1u
;
while
i
<
e
{
if
cls
[
i
]
!=
sseup_class
{
if
cls
[
i
]
!=
SSEUp
{
all_mem
(
cls
);
return
;
}
...
...
@@ -254,24 +260,24 @@ fn fixup(ty: Type, cls: &mut [RegClass]) {
}
}
else
{
while
i
<
e
{
if
cls
[
i
]
==
memory_class
{
if
cls
[
i
]
==
Memory
{
all_mem
(
cls
);
return
;
}
if
cls
[
i
]
==
x87up_class
{
if
cls
[
i
]
==
X87Up
{
// for darwin
// cls[i] =
sse_ds_clas
s;
// cls[i] =
SSED
s;
all_mem
(
cls
);
return
;
}
if
cls
[
i
]
==
sseup_class
{
cls
[
i
]
=
sse_int_class
;
if
cls
[
i
]
==
SSEUp
{
cls
[
i
]
=
SSEInt
;
}
else
if
cls
[
i
]
.is_sse
()
{
i
+=
1
;
while
i
!=
e
&&
cls
[
i
]
==
sseup_class
{
i
+=
1u
;
}
}
else
if
cls
[
i
]
==
x87_class
{
while
i
!=
e
&&
cls
[
i
]
==
SSEUp
{
i
+=
1u
;
}
}
else
if
cls
[
i
]
==
X87
{
i
+=
1
;
while
i
!=
e
&&
cls
[
i
]
==
x87up_class
{
i
+=
1u
;
}
while
i
!=
e
&&
cls
[
i
]
==
X87Up
{
i
+=
1u
;
}
}
else
{
i
+=
1
;
}
...
...
@@ -281,7 +287,7 @@ fn fixup(ty: Type, cls: &mut [RegClass]) {
}
let
words
=
(
ty_size
(
ty
)
+
7
)
/
8
;
let
mut
cls
=
vec
::
from_elem
(
words
,
no_c
lass
);
let
mut
cls
=
vec
::
from_elem
(
words
,
NoC
lass
);
if
words
>
4
{
all_mem
(
cls
);
let
cls
=
cls
;
...
...
@@ -296,7 +302,7 @@ fn llreg_ty(cls: &[RegClass]) -> Type {
fn
llvec_len
(
cls
:
&
[
RegClass
])
->
uint
{
let
mut
len
=
1u
;
for
cls
.each
|
c
|
{
if
*
c
!=
sseup_class
{
if
*
c
!=
SSEUp
{
break
;
}
len
+=
1u
;
...
...
@@ -310,20 +316,20 @@ fn llvec_len(cls: &[RegClass]) -> uint {
let
e
=
cls
.len
();
while
i
<
e
{
match
cls
[
i
]
{
integer_class
=>
{
Int
=>
{
tys
.push
(
Type
::
i64
());
}
sse_fv_class
=>
{
SSEFv
=>
{
let
vec_len
=
llvec_len
(
vec
::
tailn
(
cls
,
i
+
1u
))
*
2u
;
let
vec_ty
=
Type
::
vector
(
Type
::
f32
(),
vec_len
);
let
vec_ty
=
Type
::
vector
(
&
Type
::
f32
(),
vec_len
as
u64
);
tys
.push
(
vec_ty
);
i
+=
vec_len
;
loop
;
}
sse_fs_clas
s
=>
{
SSEF
s
=>
{
tys
.push
(
Type
::
f32
());
}
sse_ds_clas
s
=>
{
SSED
s
=>
{
tys
.push
(
Type
::
f64
());
}
_
=>
fail
!
(
"llregtype: unhandled class"
)
...
...
@@ -341,6 +347,7 @@ fn x86_64_tys(atys: &[Type],
fn
x86_64_ty
(
ty
:
Type
,
is_mem_cls
:
&
fn
(
cls
:
&
[
RegClass
])
->
bool
,
attr
:
Attribute
)
->
(
LLVMType
,
Option
<
Attribute
>
)
{
let
(
cast
,
attr
,
ty
)
=
if
!
ty
.is_reg_ty
()
{
let
cls
=
classify_ty
(
ty
);
if
is_mem_cls
(
cls
)
{
...
...
@@ -348,8 +355,11 @@ fn x86_64_ty(ty: Type,
}
else
{
(
true
,
option
::
None
,
llreg_ty
(
cls
))
}
}
else
{
(
false
,
option
::
None
,
ty
)
};
return
(
LLVMType
{
cast
:
cast
,
ty
:
ty
},
attr
);
(
LLVMType
{
cast
:
cast
,
ty
:
ty
},
attr
)
}
let
mut
arg_tys
=
~
[];
...
...
src/librustc/middle/trans/callee.rs
浏览文件 @
81cf72c2
...
...
@@ -45,6 +45,8 @@
use
middle
::
typeck
::
coherence
::
make_substs_for_receiver_types
;
use
util
::
ppaux
::
Repr
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
vec
;
use
syntax
::
ast
;
use
syntax
::
ast_map
;
...
...
@@ -526,7 +528,7 @@ pub fn trans_call_inner(in_cx: block,
let
(
llfn
,
llenv
)
=
unsafe
{
match
callee
.data
{
Fn
(
d
)
=>
{
(
d
.llfn
,
llvm
::
LLVMGetUndef
(
Type
::
opaque_box
(
ccx
)
.ptr_to
()))
(
d
.llfn
,
llvm
::
LLVMGetUndef
(
Type
::
opaque_box
(
ccx
)
.ptr_to
()
.to_ref
()
))
}
Method
(
d
)
=>
{
// Weird but true: we pass self in the *environment* slot!
...
...
@@ -653,7 +655,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest)
expr
::
Ignore
=>
{
if
ty
::
type_is_nil
(
retty
)
{
unsafe
{
llvm
::
LLVMGetUndef
(
Type
::
nil
()
.ptr_to
())
llvm
::
LLVMGetUndef
(
Type
::
nil
()
.ptr_to
()
.to_ref
()
)
}
}
else
{
alloc_ty
(
bcx
,
retty
)
...
...
@@ -777,7 +779,7 @@ pub fn trans_arg_expr(bcx: block,
// to have type lldestty (the callee's expected type).
let
llformal_arg_ty
=
type_of
::
type_of
(
ccx
,
formal_arg_ty
);
unsafe
{
val
=
llvm
::
LLVMGetUndef
(
llformal_arg_ty
);
val
=
llvm
::
LLVMGetUndef
(
llformal_arg_ty
.to_ref
()
);
}
}
else
{
// FIXME(#3548) use the adjustments table
...
...
src/librustc/middle/trans/closure.rs
浏览文件 @
81cf72c2
...
...
@@ -26,6 +26,8 @@
use
middle
::
ty
;
use
util
::
ppaux
::
ty_to_str
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
str
;
use
core
::
vec
;
use
syntax
::
ast
;
...
...
src/librustc/middle/trans/common.rs
浏览文件 @
81cf72c2
...
...
@@ -31,6 +31,8 @@
use
middle
::
borrowck
::
root_map_key
;
use
util
::
ppaux
::{
Repr
};
use
middle
::
trans
::
type_
::
Type
;
use
core
::
cast
::
transmute
;
use
core
::
cast
;
use
core
::
hashmap
::{
HashMap
};
...
...
@@ -58,29 +60,11 @@ pub fn new_namegen() -> namegen {
f
}
pub
type
addrspace
=
c_uint
;
// Address spaces communicate to LLVM which destructors need to run for
// specific types.
// 0 is ignored by the GC, and is used for all non-GC'd pointers.
// 1 is for opaque GC'd boxes.
// >= 2 are for specific types (e.g. resources).
pub
static
default_addrspace
:
addrspace
=
0
;
pub
static
gc_box_addrspace
:
addrspace
=
1
;
pub
type
addrspace_gen
=
@
fn
()
->
addrspace
;
pub
fn
new_addrspace_gen
()
->
addrspace_gen
{
let
i
=
@
mut
1
;
let
result
:
addrspace_gen
=
||
{
*
i
+=
1
;
*
i
};
result
}
pub
struct
tydesc_info
{
ty
:
ty
::
t
,
tydesc
:
ValueRef
,
size
:
ValueRef
,
align
:
ValueRef
,
addrspace
:
addrspace
,
take_glue
:
Option
<
ValueRef
>
,
drop_glue
:
Option
<
ValueRef
>
,
free_glue
:
Option
<
ValueRef
>
,
...
...
@@ -345,39 +329,14 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
}
}
// This is not the same as datum::Datum::root(), which is used to keep copies
// of @ values live for as long as a borrowed pointer to the interior exists.
// In the new GC, we can identify immediates on the stack without difficulty,
// but have trouble knowing where non-immediates are on the stack. For
// non-immediates, we must add an additional level of indirection, which
// allows us to alloca a pointer with the right addrspace.
pub
fn
root_for_cleanup
(
bcx
:
block
,
v
:
ValueRef
,
t
:
ty
::
t
)
->
(
ValueRef
,
bool
)
{
let
ccx
=
bcx
.ccx
();
let
addrspace
=
base
::
get_tydesc
(
ccx
,
t
)
.addrspace
;
if
addrspace
>
gc_box_addrspace
{
let
llty
=
type_of
::
type_of_rooted
(
ccx
,
t
);
let
root
=
base
::
alloca
(
bcx
,
llty
);
build
::
Store
(
bcx
,
build
::
PointerCast
(
bcx
,
v
,
llty
),
root
);
(
root
,
true
)
}
else
{
(
v
,
false
)
}
}
pub
fn
add_clean
(
bcx
:
block
,
val
:
ValueRef
,
t
:
ty
::
t
)
{
if
!
ty
::
type_needs_drop
(
bcx
.tcx
(),
t
)
{
return
;
}
debug!
(
"add_clean(%s, %s, %s)"
,
bcx
.to_str
(),
bcx
.val_to_str
(
val
),
t
.repr
(
bcx
.tcx
()));
let
(
root
,
rooted
)
=
root_for_cleanup
(
bcx
,
val
,
t
);
debug!
(
"add_clean(%s, %s, %s)"
,
bcx
.to_str
(),
bcx
.val_to_str
(
val
),
t
.repr
(
bcx
.tcx
()));
let
cleanup_type
=
cleanup_type
(
bcx
.tcx
(),
t
);
do
in_scope_cx
(
bcx
)
|
scope_info
|
{
scope_info
.cleanups
.push
(
clean
(|
a
|
glue
::
drop_ty_root
(
a
,
root
,
rooted
,
t
),
cleanup_type
));
scope_info
.cleanups
.push
(
clean
(|
a
|
glue
::
drop_ty
(
a
,
val
,
t
),
cleanup_type
));
grow_scope_clean
(
scope_info
);
}
}
...
...
@@ -400,12 +359,9 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) {
debug!
(
"add_clean_temp_mem(%s, %s, %s)"
,
bcx
.to_str
(),
bcx
.val_to_str
(
val
),
t
.repr
(
bcx
.tcx
()));
let
(
root
,
rooted
)
=
root_for_cleanup
(
bcx
,
val
,
t
);
let
cleanup_type
=
cleanup_type
(
bcx
.tcx
(),
t
);
do
in_scope_cx
(
bcx
)
|
scope_info
|
{
scope_info
.cleanups
.push
(
clean_temp
(
val
,
|
a
|
glue
::
drop_ty_root
(
a
,
root
,
rooted
,
t
),
cleanup_type
));
scope_info
.cleanups
.push
(
clean_temp
(
val
,
|
a
|
glue
::
drop_ty
(
a
,
val
,
t
),
cleanup_type
));
grow_scope_clean
(
scope_info
);
}
}
...
...
@@ -431,12 +387,8 @@ pub fn add_clean_return_to_mut(bcx: block,
scope_info
.cleanups
.push
(
clean_temp
(
frozen_val_ref
,
|
bcx
|
write_guard
::
return_to_mut
(
bcx
,
root_key
,
frozen_val_ref
,
bits_val_ref
,
filename_val
,
line_val
),
|
bcx
|
write_guard
::
return_to_mut
(
bcx
,
root_key
,
frozen_val_ref
,
bits_val_ref
,
filename_val
,
line_val
),
normal_exit_only
));
grow_scope_clean
(
scope_info
);
}
...
...
@@ -621,9 +573,9 @@ pub fn unpack(&self, bcx: &mut block) -> ValueRef {
}
}
pub
fn
val_ty
(
v
:
ValueRef
)
->
Type
Ref
{
pub
fn
val_ty
(
v
:
ValueRef
)
->
Type
{
unsafe
{
return
llvm
::
LLVMTypeOf
(
v
);
Type
::
from_ref
(
llvm
::
LLVMTypeOf
(
v
))
}
}
...
...
@@ -706,313 +658,6 @@ pub fn to_str(&self) -> ~str {
}
}
/*
// LLVM type constructors.
pub fn T_void() -> TypeRef {
unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); }
}
pub fn T_nil() -> TypeRef {
return T_struct([], false)
}
pub fn T_metadata() -> TypeRef {
unsafe { return llvm::LLVMMetadataTypeInContext(base::task_llcx()); }
}
pub fn T_i1() -> TypeRef {
unsafe { return llvm::LLVMInt1TypeInContext(base::task_llcx()); }
}
pub fn T_i8() -> TypeRef {
unsafe { return llvm::LLVMInt8TypeInContext(base::task_llcx()); }
}
pub fn T_i16() -> TypeRef {
unsafe { return llvm::LLVMInt16TypeInContext(base::task_llcx()); }
}
pub fn T_i32() -> TypeRef {
unsafe { return llvm::LLVMInt32TypeInContext(base::task_llcx()); }
}
pub fn T_i64() -> TypeRef {
unsafe { return llvm::LLVMInt64TypeInContext(base::task_llcx()); }
}
pub fn T_f32() -> TypeRef {
unsafe { return llvm::LLVMFloatTypeInContext(base::task_llcx()); }
}
pub fn T_f64() -> TypeRef {
unsafe { return llvm::LLVMDoubleTypeInContext(base::task_llcx()); }
}
pub fn T_bool() -> TypeRef { return T_i8(); }
pub fn T_int(targ_cfg: &session::config) -> TypeRef {
return match targ_cfg.arch {
X86 => T_i32(),
X86_64 => T_i64(),
Arm => T_i32(),
Mips => T_i32()
};
}
pub fn T_int_ty(cx: &CrateContext, t: ast::int_ty) -> TypeRef {
match t {
ast::ty_i => cx.int_type,
ast::ty_char => T_char(),
ast::ty_i8 => T_i8(),
ast::ty_i16 => T_i16(),
ast::ty_i32 => T_i32(),
ast::ty_i64 => T_i64()
}
}
pub fn T_uint_ty(cx: &CrateContext, t: ast::uint_ty) -> TypeRef {
match t {
ast::ty_u => cx.int_type,
ast::ty_u8 => T_i8(),
ast::ty_u16 => T_i16(),
ast::ty_u32 => T_i32(),
ast::ty_u64 => T_i64()
}
}
pub fn T_float_ty(cx: &CrateContext, t: ast::float_ty) -> TypeRef {
match t {
ast::ty_f => cx.float_type,
ast::ty_f32 => T_f32(),
ast::ty_f64 => T_f64()
}
}
pub fn T_float(targ_cfg: &session::config) -> TypeRef {
return match targ_cfg.arch {
X86 => T_f64(),
X86_64 => T_f64(),
Arm => T_f64(),
Mips => T_f64()
};
}
pub fn T_char() -> TypeRef { return T_i32(); }
pub fn T_size_t(targ_cfg: &session::config) -> TypeRef {
return T_int(targ_cfg);
}
pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef {
unsafe {
return llvm::LLVMFunctionType(output, to_ptr(inputs),
inputs.len() as c_uint,
False);
}
}
pub fn T_fn_pair(cx: &CrateContext, tfn: TypeRef) -> TypeRef {
return T_struct([T_ptr(tfn), T_opaque_cbox_ptr(cx)], false);
}
pub fn T_ptr(t: TypeRef) -> TypeRef {
unsafe {
return llvm::LLVMPointerType(t, default_addrspace);
}
}
pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
unsafe {
return llvm::LLVMPointerType(t, addrspace);
}
}
pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef {
unsafe {
return llvm::LLVMStructTypeInContext(base::task_llcx(),
to_ptr(elts),
elts.len() as c_uint,
packed as Bool);
}
}
pub fn T_named_struct(name: &str) -> TypeRef {
unsafe {
return str::as_c_str(name, |buf| {
llvm::LLVMStructCreateNamed(base::task_llcx(), buf)
});
}
}
pub fn set_struct_body(t: TypeRef, elts: &[TypeRef], packed: bool) {
unsafe {
llvm::LLVMStructSetBody(t,
to_ptr(elts),
elts.len() as c_uint,
packed as Bool);
}
}
pub fn T_empty_struct() -> TypeRef { return T_struct([], false); }
// A vtable is, in reality, a vtable pointer followed by zero or more pointers
// to tydescs and other vtables that it closes over. But the types and number
// of those are rarely known to the code that needs to manipulate them, so
// they are described by this opaque type.
pub fn T_vtable() -> TypeRef { T_array(T_ptr(T_i8()), 1u) }
pub fn T_tydesc_field(cx: &CrateContext, field: uint) -> TypeRef {
// Bit of a kludge: pick the fn typeref out of the tydesc..
unsafe {
let mut tydesc_elts: ~[TypeRef] =
vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
T_nil());
llvm::LLVMGetStructElementTypes(cx.tydesc_type, &mut tydesc_elts[0]);
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
return t;
}
}
pub fn T_generic_glue_fn(cx: &mut CrateContext) -> TypeRef {
let s = @"glue_fn";
match cx.tn.find_type(s) {
Some(t) => return t,
_ => ()
}
let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue);
cx.tn.associate_type(s, t);
return t;
}
pub fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
let tydesc = T_named_struct("tydesc");
let tydescpp = T_ptr(T_ptr(tydesc));
let pvoid = T_ptr(T_i8());
let glue_fn_ty =
T_ptr(T_fn([T_ptr(T_nil()), tydescpp, pvoid], T_void()));
let int_type = T_int(targ_cfg);
let elems =
~[int_type, int_type,
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty,
T_ptr(T_i8()), T_ptr(T_i8())];
set_struct_body(tydesc, elems, false);
return tydesc;
}
pub fn T_array(t: TypeRef, n: uint) -> TypeRef {
unsafe {
return llvm::LLVMArrayType(t, n as c_uint);
}
}
pub fn T_vector(t: TypeRef, n: uint) -> TypeRef {
unsafe {
return llvm::LLVMVectorType(t, n as c_uint);
}
}
// Interior vector.
pub fn T_vec2(targ_cfg: &session::config, t: TypeRef) -> TypeRef {
return T_struct([T_int(targ_cfg), // fill
T_int(targ_cfg), // alloc
T_array(t, 0u)], // elements
false);
}
pub fn T_vec(ccx: &CrateContext, t: TypeRef) -> TypeRef {
return T_vec2(ccx.sess.targ_cfg, t);
}
// Note that the size of this one is in bytes.
pub fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef {
return T_vec2(targ_cfg, T_i8());
}
pub fn T_box_header_fields(cx: &CrateContext) -> ~[TypeRef] {
let ptr = T_ptr(T_i8());
return ~[cx.int_type, T_ptr(cx.tydesc_type), ptr, ptr];
}
pub fn T_box_header(cx: &CrateContext) -> TypeRef {
return T_struct(T_box_header_fields(cx), false);
}
pub fn T_box(cx: &CrateContext, t: TypeRef) -> TypeRef {
return T_struct(vec::append(T_box_header_fields(cx), [t]), false);
}
pub fn T_box_ptr(t: TypeRef) -> TypeRef {
unsafe {
return llvm::LLVMPointerType(t, gc_box_addrspace);
}
}
pub fn T_opaque_box(cx: &CrateContext) -> TypeRef {
return T_box(cx, T_i8());
}
pub fn T_opaque_box_ptr(cx: &CrateContext) -> TypeRef {
return T_box_ptr(T_opaque_box(cx));
}
pub fn T_unique(cx: &CrateContext, t: TypeRef) -> TypeRef {
return T_struct(vec::append(T_box_header_fields(cx), [t]), false);
}
pub fn T_unique_ptr(t: TypeRef) -> TypeRef {
unsafe {
return llvm::LLVMPointerType(t, gc_box_addrspace);
}
}
pub fn T_port(cx: &CrateContext, _t: TypeRef) -> TypeRef {
return T_struct([cx.int_type], false); // Refcount
}
pub fn T_chan(cx: &CrateContext, _t: TypeRef) -> TypeRef {
return T_struct([cx.int_type], false); // Refcount
}
pub fn T_opaque_cbox_ptr(cx: &CrateContext) -> TypeRef {
// closures look like boxes (even when they are ~fn or &fn)
// see trans_closure.rs
return T_opaque_box_ptr(cx);
}
pub fn T_enum_discrim(cx: &CrateContext) -> TypeRef {
return cx.int_type;
}
pub fn T_captured_tydescs(cx: &CrateContext, n: uint) -> TypeRef {
return T_struct(vec::from_elem::<TypeRef>(n, T_ptr(cx.tydesc_type)), false);
}
pub fn T_opaque_trait(cx: &CrateContext, store: ty::TraitStore) -> TypeRef {
match store {
ty::BoxTraitStore => {
T_struct([T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)], false)
}
ty::UniqTraitStore => {
T_struct([T_ptr(cx.tydesc_type),
T_unique_ptr(T_unique(cx, T_i8()))],
false)
}
ty::RegionTraitStore(_) => {
T_struct([T_ptr(cx.tydesc_type), T_ptr(T_i8())], false)
}
}
}
pub fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); }
pub fn T_opaque_chan_ptr() -> TypeRef { return T_ptr(T_i8()); }
*/
// Let T be the content of a box @T. tuplify_box_ty(t) returns the
// representation of @T as a tuple (i.e., the ty::t version of what T_box()
// returns).
...
...
@@ -1101,7 +746,7 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
};
let
gsym
=
token
::
gensym
(
"str"
);
let
g
=
fmt!
(
"str%u"
,
gsym
)
.as_c_str
|
buf
|
{
let
g
=
do
fmt!
(
"str%u"
,
gsym
)
.as_c_str
|
buf
|
{
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
val_ty
(
sc
)
.to_ref
(),
buf
)
};
llvm
::
LLVMSetInitializer
(
g
,
sc
);
...
...
@@ -1138,7 +783,8 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef {
let
mut
i
=
0u
;
let
mut
elts
:
~
[
ValueRef
]
=
~
[];
while
i
<
size
{
elts
.push
(
C_u8
(
0u
));
i
+=
1u
;
}
return
llvm
::
LLVMConstArray
(
Type
::
i8
(),
vec
::
raw
::
to_ptr
(
elts
),
elts
.len
()
as
c_uint
);
return
llvm
::
LLVMConstArray
(
Type
::
i8
()
.to_ref
(),
vec
::
raw
::
to_ptr
(
elts
),
elts
.len
()
as
c_uint
);
}
}
...
...
@@ -1158,17 +804,17 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef {
}
}
pub
fn
C_named_struct
(
T
:
Type
Ref
,
elts
:
&
[
ValueRef
])
->
ValueRef
{
pub
fn
C_named_struct
(
T
:
Type
,
elts
:
&
[
ValueRef
])
->
ValueRef
{
unsafe
{
do
vec
::
as_imm_buf
(
elts
)
|
ptr
,
len
|
{
llvm
::
LLVMConstNamedStruct
(
T
,
ptr
,
len
as
c_uint
)
llvm
::
LLVMConstNamedStruct
(
T
.to_ref
()
,
ptr
,
len
as
c_uint
)
}
}
}
pub
fn
C_array
(
ty
:
Type
Ref
,
elts
:
&
[
ValueRef
])
->
ValueRef
{
pub
fn
C_array
(
ty
:
Type
,
elts
:
&
[
ValueRef
])
->
ValueRef
{
unsafe
{
return
llvm
::
LLVMConstArray
(
ty
,
vec
::
raw
::
to_ptr
(
elts
),
elts
.len
()
as
c_uint
);
return
llvm
::
LLVMConstArray
(
ty
.to_ref
()
,
vec
::
raw
::
to_ptr
(
elts
),
elts
.len
()
as
c_uint
);
}
}
...
...
@@ -1193,7 +839,7 @@ pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef {
let
llglobal
=
do
name
.as_c_str
|
buf
|
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
val_ty
(
llshape
)
.to_ref
(),
buf
)
};
llvm
::
LLVMSetInitializer
(
llglobal
,
llshape
.to_ref
()
);
llvm
::
LLVMSetInitializer
(
llglobal
,
llshape
);
llvm
::
LLVMSetGlobalConstant
(
llglobal
,
True
);
lib
::
llvm
::
SetLinkage
(
llglobal
,
lib
::
llvm
::
InternalLinkage
);
return
llvm
::
LLVMConstPointerCast
(
llglobal
,
Type
::
i8p
()
.to_ref
());
...
...
src/librustc/middle/trans/consts.rs
浏览文件 @
81cf72c2
...
...
@@ -11,7 +11,7 @@
use
core
::
prelude
::
*
;
use
back
::
abi
;
use
lib
::
llvm
::{
llvm
,
ConstFCmp
,
ConstICmp
,
SetLinkage
,
PrivateLinkage
,
ValueRef
,
TypeRef
,
Bool
,
use
lib
::
llvm
::{
llvm
,
ConstFCmp
,
ConstICmp
,
SetLinkage
,
PrivateLinkage
,
ValueRef
,
Bool
,
True
,
False
};
use
lib
::
llvm
::{
IntEQ
,
IntNE
,
IntUGT
,
IntUGE
,
IntULT
,
IntULE
,
IntSGT
,
IntSGE
,
IntSLT
,
IntSLE
,
RealOEQ
,
RealOGT
,
RealOGE
,
RealOLT
,
RealOLE
,
RealONE
};
...
...
@@ -30,6 +30,8 @@
use
middle
::
ty
;
use
util
::
ppaux
::{
Repr
,
ty_to_str
};
use
middle
::
trans
::
type_
::
Type
;
use
core
::
libc
::
c_uint
;
use
core
::
str
;
use
syntax
::{
ast
,
ast_util
,
ast_map
};
...
...
@@ -38,28 +40,28 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit)
->
ValueRef
{
let
_
icx
=
cx
.insn_ctxt
(
"trans_lit"
);
match
lit
.node
{
ast
::
lit_int
(
i
,
t
)
=>
C_integral
(
T
_int_ty
(
cx
,
t
),
i
as
u64
,
T
rue
),
ast
::
lit_uint
(
u
,
t
)
=>
C_integral
(
T
_uint_ty
(
cx
,
t
),
u
,
F
alse
),
ast
::
lit_int
(
i
,
t
)
=>
C_integral
(
T
ype
::
int_from_ty
(
cx
,
t
),
i
as
u64
,
t
rue
),
ast
::
lit_uint
(
u
,
t
)
=>
C_integral
(
T
ype
::
uint_from_ty
(
cx
,
t
),
u
,
f
alse
),
ast
::
lit_int_unsuffixed
(
i
)
=>
{
let
lit_int_ty
=
ty
::
node_id_to_type
(
cx
.tcx
,
e
.id
);
match
ty
::
get
(
lit_int_ty
)
.sty
{
ty
::
ty_int
(
t
)
=>
{
C_integral
(
T
_int_ty
(
cx
,
t
),
i
as
u64
,
T
rue
)
C_integral
(
T
ype
::
int_from_ty
(
cx
,
t
),
i
as
u64
,
t
rue
)
}
ty
::
ty_uint
(
t
)
=>
{
C_integral
(
T
_uint_ty
(
cx
,
t
),
i
as
u64
,
F
alse
)
C_integral
(
T
ype
::
uint_from_ty
(
cx
,
t
),
i
as
u64
,
f
alse
)
}
_
=>
cx
.sess
.span_bug
(
lit
.span
,
fmt!
(
"integer literal has type %s (expected int or uint)"
,
ty_to_str
(
cx
.tcx
,
lit_int_ty
)))
}
}
ast
::
lit_float
(
fs
,
t
)
=>
C_floating
(
fs
,
T
_float
_ty
(
cx
,
t
)),
ast
::
lit_float
(
fs
,
t
)
=>
C_floating
(
fs
,
T
ype
::
float_from
_ty
(
cx
,
t
)),
ast
::
lit_float_unsuffixed
(
fs
)
=>
{
let
lit_float_ty
=
ty
::
node_id_to_type
(
cx
.tcx
,
e
.id
);
match
ty
::
get
(
lit_float_ty
)
.sty
{
ty
::
ty_float
(
t
)
=>
{
C_floating
(
fs
,
T
_float
_ty
(
cx
,
t
))
C_floating
(
fs
,
T
ype
::
float_from
_ty
(
cx
,
t
))
}
_
=>
{
cx
.sess
.span_bug
(
lit
.span
,
...
...
@@ -73,16 +75,16 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit)
}
}
pub
fn
const_ptrcast
(
cx
:
&
mut
CrateContext
,
a
:
ValueRef
,
t
:
Type
Ref
)
->
ValueRef
{
pub
fn
const_ptrcast
(
cx
:
&
mut
CrateContext
,
a
:
ValueRef
,
t
:
Type
)
->
ValueRef
{
unsafe
{
let
b
=
llvm
::
LLVMConstPointerCast
(
a
,
T_ptr
(
t
));
let
b
=
llvm
::
LLVMConstPointerCast
(
a
,
t
.ptr_to
()
.to_ref
(
));
assert
!
(
cx
.const_globals
.insert
(
b
as
int
,
a
));
b
}
}
pub
fn
const_vec
(
cx
:
@
mut
CrateContext
,
e
:
@
ast
::
expr
,
es
:
&
[
@
ast
::
expr
])
->
(
ValueRef
,
ValueRef
,
Type
Ref
)
{
->
(
ValueRef
,
ValueRef
,
Type
)
{
unsafe
{
let
vec_ty
=
ty
::
expr_ty
(
cx
.tcx
,
e
);
let
unit_ty
=
ty
::
sequence_element_type
(
cx
.tcx
,
vec_ty
);
...
...
@@ -102,8 +104,8 @@ pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr])
fn
const_addr_of
(
cx
:
@
mut
CrateContext
,
cv
:
ValueRef
)
->
ValueRef
{
unsafe
{
let
gv
=
do
str
::
as_c_str
(
"const"
)
|
name
|
{
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
val_ty
(
cv
),
name
)
let
gv
=
do
"const"
.as_c_str
|
name
|
{
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
val_ty
(
cv
)
.to_ref
()
,
name
)
};
llvm
::
LLVMSetInitializer
(
gv
,
cv
);
llvm
::
LLVMSetGlobalConstant
(
gv
,
True
);
...
...
@@ -180,7 +182,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
match
adjustment
{
None
=>
{
}
Some
(
@
ty
::
AutoAddEnv
(
ty
::
re_static
,
ast
::
BorrowedSigil
))
=>
{
llconst
=
C_struct
([
llconst
,
C_null
(
T
_opaque_box_ptr
(
cx
))])
llconst
=
C_struct
([
llconst
,
C_null
(
T
ype
::
opaque_box
(
cx
)
.ptr_to
(
))])
}
Some
(
@
ty
::
AutoAddEnv
(
ref
r
,
ref
s
))
=>
{
cx
.sess
.span_bug
(
e
.span
,
fmt!
(
"unexpected static function:
\
...
...
@@ -349,9 +351,9 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
ty
::
ty_bool
=>
{
// Somewhat questionable, but I believe this is
// correct.
let
te
=
llvm
::
LLVMConstTrunc
(
te
,
T
_i1
());
let
te
=
llvm
::
LLVMConstTrunc
(
te
,
T
ype
::
i1
()
.to_ref
());
let
te
=
llvm
::
LLVMConstNot
(
te
);
llvm
::
LLVMConstZExt
(
te
,
T
_bool
())
llvm
::
LLVMConstZExt
(
te
,
T
ype
::
bool
()
.to_ref
())
}
_
=>
llvm
::
LLVMConstNot
(
te
),
}
...
...
@@ -426,21 +428,21 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
(
expr
::
cast_integral
,
expr
::
cast_integral
)
=>
{
let
s
=
ty
::
type_is_signed
(
basety
)
as
Bool
;
llvm
::
LLVMConstIntCast
(
v
,
llty
,
s
)
llvm
::
LLVMConstIntCast
(
v
,
llty
.to_ref
()
,
s
)
}
(
expr
::
cast_integral
,
expr
::
cast_float
)
=>
{
if
ty
::
type_is_signed
(
basety
)
{
llvm
::
LLVMConstSIToFP
(
v
,
llty
)
llvm
::
LLVMConstSIToFP
(
v
,
llty
.to_ref
()
)
}
else
{
llvm
::
LLVMConstUIToFP
(
v
,
llty
)
llvm
::
LLVMConstUIToFP
(
v
,
llty
.to_ref
()
)
}
}
(
expr
::
cast_float
,
expr
::
cast_float
)
=>
{
llvm
::
LLVMConstFPCast
(
v
,
llty
)
llvm
::
LLVMConstFPCast
(
v
,
llty
.to_ref
()
)
}
(
expr
::
cast_float
,
expr
::
cast_integral
)
=>
{
if
ty
::
type_is_signed
(
ety
)
{
llvm
::
LLVMConstFPToSI
(
v
,
llty
)
}
else
{
llvm
::
LLVMConstFPToUI
(
v
,
llty
)
}
if
ty
::
type_is_signed
(
ety
)
{
llvm
::
LLVMConstFPToSI
(
v
,
llty
.to_ref
()
)
}
else
{
llvm
::
LLVMConstFPToUI
(
v
,
llty
.to_ref
()
)
}
}
(
expr
::
cast_enum
,
expr
::
cast_integral
)
|
(
expr
::
cast_enum
,
expr
::
cast_float
)
=>
{
...
...
@@ -451,18 +453,18 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
match
ety_cast
{
expr
::
cast_integral
=>
{
let
s
=
ty
::
type_is_signed
(
ety
)
as
Bool
;
llvm
::
LLVMConstIntCast
(
iv
,
llty
,
s
)
llvm
::
LLVMConstIntCast
(
iv
,
llty
.to_ref
()
,
s
)
}
expr
::
cast_float
=>
llvm
::
LLVMConstUIToFP
(
iv
,
llty
),
expr
::
cast_float
=>
llvm
::
LLVMConstUIToFP
(
iv
,
llty
.to_ref
()
),
_
=>
cx
.sess
.bug
(
"enum cast destination is not
\
integral or float"
)
}
}
(
expr
::
cast_pointer
,
expr
::
cast_pointer
)
=>
{
llvm
::
LLVMConstPointerCast
(
v
,
llty
)
llvm
::
LLVMConstPointerCast
(
v
,
llty
.to_ref
()
)
}
(
expr
::
cast_integral
,
expr
::
cast_pointer
)
=>
{
llvm
::
LLVMConstIntToPtr
(
v
,
llty
)
llvm
::
LLVMConstIntToPtr
(
v
,
llty
.to_ref
()
)
}
_
=>
{
cx
.sess
.impossible_case
(
e
.span
,
...
...
@@ -513,7 +515,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
let
(
cv
,
sz
,
llunitty
)
=
const_vec
(
cx
,
e
,
*
es
);
let
llty
=
val_ty
(
cv
);
let
gv
=
do
str
::
as_c_str
(
"const"
)
|
name
|
{
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
llty
,
name
)
llvm
::
LLVMAddGlobal
(
cx
.llmod
,
llty
.to_ref
()
,
name
)
};
llvm
::
LLVMSetInitializer
(
gv
,
cv
);
llvm
::
LLVMSetGlobalConstant
(
gv
,
True
);
...
...
src/librustc/middle/trans/context.rs
浏览文件 @
81cf72c2
...
...
@@ -12,7 +12,7 @@
use
back
::{
upcall
};
use
driver
::
session
;
use
lib
::
llvm
::{
ContextRef
,
ModuleRef
,
ValueRef
,
TypeRef
};
use
lib
::
llvm
::{
ContextRef
,
ModuleRef
,
ValueRef
};
use
lib
::
llvm
::{
llvm
,
TargetData
,
TypeNames
};
use
lib
::
llvm
::{
mk_target_data
};
use
lib
;
...
...
@@ -36,8 +36,8 @@
use
extra
::
time
;
use
syntax
::
ast
;
use
middle
::
trans
::
common
::{
ExternMap
,
tydesc_info
,
BuilderRef_res
,
Stats
,
namegen
,
addrspace_gen
};
use
middle
::
trans
::
common
::{
mono_id
,
new_namegen
,
new_addrspace_gen
};
use
middle
::
trans
::
common
::{
ExternMap
,
tydesc_info
,
BuilderRef_res
,
Stats
,
namegen
};
use
middle
::
trans
::
common
::{
mono_id
,
new_namegen
};
use
middle
::
trans
::
base
::{
decl_crate_map
};
...
...
@@ -94,11 +94,10 @@ pub struct CrateContext {
impl_method_cache
:
HashMap
<
(
ast
::
def_id
,
ast
::
ident
),
ast
::
def_id
>
,
module_data
:
HashMap
<~
str
,
ValueRef
>
,
lltypes
:
HashMap
<
ty
::
t
,
Type
Ref
>
,
llsizingtypes
:
HashMap
<
ty
::
t
,
Type
Ref
>
,
lltypes
:
HashMap
<
ty
::
t
,
Type
>
,
llsizingtypes
:
HashMap
<
ty
::
t
,
Type
>
,
adt_reprs
:
HashMap
<
ty
::
t
,
@
adt
::
Repr
>
,
names
:
namegen
,
next_addrspace
:
addrspace_gen
,
symbol_hasher
:
hash
::
State
,
type_hashcodes
:
HashMap
<
ty
::
t
,
@
str
>
,
type_short_names
:
HashMap
<
ty
::
t
,
~
str
>
,
...
...
@@ -151,8 +150,8 @@ pub fn new(sess: session::Session, name: &str, tcx: ty::ctxt,
let
tydesc_type
=
Type
::
tydesc
(
targ_cfg
.arch
);
let
opaque_vec_type
=
Type
::
opaque_vec
(
targ_cfg
.arch
);
let
str_slice_ty
=
Type
::
named_struct
(
"str_slice"
);
str_slice_ty
.set_struct_body
([
Type
::
i8p
(),
int_type
]);
let
mut
str_slice_ty
=
Type
::
named_struct
(
"str_slice"
);
str_slice_ty
.set_struct_body
([
Type
::
i8p
(),
int_type
]
,
false
);
tn
.associate_type
(
"tydesc"
,
&
tydesc_type
);
tn
.associate_type
(
"str_slice"
,
&
str_slice_ty
);
...
...
@@ -197,7 +196,6 @@ pub fn new(sess: session::Session, name: &str, tcx: ty::ctxt,
llsizingtypes
:
HashMap
::
new
(),
adt_reprs
:
HashMap
::
new
(),
names
:
new_namegen
(),
next_addrspace
:
new_addrspace_gen
(),
symbol_hasher
:
symbol_hasher
,
type_hashcodes
:
HashMap
::
new
(),
type_short_names
:
HashMap
::
new
(),
...
...
src/librustc/middle/trans/controlflow.rs
浏览文件 @
81cf72c2
...
...
@@ -24,6 +24,8 @@
use
util
::
common
::
indenter
;
use
util
::
ppaux
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
str
;
use
core
::
vec
;
use
syntax
::
ast
;
...
...
@@ -204,7 +206,7 @@ pub fn trans_log(log_ex: @ast::expr,
let
global
;
unsafe
{
global
=
str
::
as_c_str
(
s
,
|
buf
|
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
Type
::
i32
(),
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
Type
::
i32
()
.to_ref
()
,
buf
)
});
llvm
::
LLVMSetGlobalConstant
(
global
,
False
);
llvm
::
LLVMSetInitializer
(
global
,
C_null
(
Type
::
i32
()));
...
...
src/librustc/middle/trans/expr.rs
浏览文件 @
81cf72c2
...
...
@@ -152,6 +152,8 @@
use
util
::
common
::
indenter
;
use
util
::
ppaux
::
Repr
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
cast
::
transmute
;
use
core
::
hashmap
::
HashMap
;
use
core
::
vec
;
...
...
@@ -981,9 +983,7 @@ fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
let
symbol
=
csearch
::
get_symbol
(
bcx
.ccx
()
.sess.cstore
,
did
);
let
llval
=
llvm
::
LLVMAddGlobal
(
bcx
.ccx
()
.llmod
,
llty
,
let
llval
=
llvm
::
LLVMAddGlobal
(
bcx
.ccx
()
.llmod
,
llty
.to_ref
(),
transmute
::
<&
u8
,
*
i8
>
(
&
symbol
[
0
]));
let
extern_const_values
=
&
mut
bcx
.ccx
()
.extern_const_values
;
extern_const_values
.insert
(
did
,
llval
);
...
...
@@ -1552,8 +1552,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
llsrc
:
ValueRef
,
signed
:
bool
)
->
ValueRef
{
let
_
icx
=
bcx
.insn_ctxt
(
"int_cast"
);
unsafe
{
let
srcsz
=
llvm
::
LLVMGetIntTypeWidth
(
llsrctype
);
let
dstsz
=
llvm
::
LLVMGetIntTypeWidth
(
lldsttype
);
let
srcsz
=
llvm
::
LLVMGetIntTypeWidth
(
llsrctype
.to_ref
()
);
let
dstsz
=
llvm
::
LLVMGetIntTypeWidth
(
lldsttype
.to_ref
()
);
return
if
dstsz
==
srcsz
{
BitCast
(
bcx
,
llsrc
,
lldsttype
)
}
else
if
srcsz
>
dstsz
{
...
...
@@ -1569,8 +1569,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
fn
float_cast
(
bcx
:
block
,
lldsttype
:
Type
,
llsrctype
:
Type
,
llsrc
:
ValueRef
)
->
ValueRef
{
let
_
icx
=
bcx
.insn_ctxt
(
"float_cast"
);
let
srcsz
=
l
ib
::
llvm
::
float_width
(
llsrctype
);
let
dstsz
=
l
ib
::
llvm
::
float_width
(
lldsttype
);
let
srcsz
=
l
lsrctype
.float_width
(
);
let
dstsz
=
l
ldsttype
.float_width
(
);
return
if
dstsz
>
srcsz
{
FPExt
(
bcx
,
llsrc
,
lldsttype
)
}
else
if
srcsz
>
dstsz
{
...
...
src/librustc/middle/trans/foreign.rs
浏览文件 @
81cf72c2
...
...
@@ -44,6 +44,7 @@
use
syntax
::
abi
::{
X86
,
X86_64
,
Arm
,
Mips
};
use
syntax
::
abi
::{
RustIntrinsic
,
Rust
,
Stdcall
,
Fastcall
,
Cdecl
,
Aapcs
,
C
};
use
middle
::
trans
::
type_
::
Type
;
fn
abi_info
(
ccx
:
@
mut
CrateContext
)
->
@
cabi
::
ABIInfo
{
return
match
ccx
.sess.targ_cfg.arch
{
...
...
@@ -122,7 +123,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes {
llsig
:
llsig
,
ret_def
:
ret_def
,
bundle_ty
:
bundle_ty
,
shim_fn_ty
:
Type
::
func
([
bundle_ty
.ptr_to
()],
Type
::
void
()),
shim_fn_ty
:
Type
::
func
([
bundle_ty
.ptr_to
()],
&
Type
::
void
()),
fn_ty
:
fn_ty
}
}
...
...
@@ -220,12 +221,9 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
let
return_context
=
raw_block
(
fcx
,
false
,
fcx
.llreturn
);
let
llfunctiontype
=
val_ty
(
llwrapfn
);
let
llfunctiontype
=
::
lib
::
llvm
::
llvm
::
LLVMGetElementType
(
llfunctiontype
);
let
llfunctionreturntype
=
::
lib
::
llvm
::
llvm
::
LLVMGetReturnType
(
llfunctiontype
);
if
::
lib
::
llvm
::
llvm
::
LLVMGetTypeKind
(
llfunctionreturntype
)
==
::
lib
::
llvm
::
Void
{
let
llfunctiontype
=
llfunctiontype
.element_type
();
let
return_type
=
llfunctiontype
.return_type
();
if
return_type
.kind
()
==
::
lib
::
llvm
::
Void
{
// XXX: This might be wrong if there are any functions for which
// the C ABI specifies a void output pointer and the Rust ABI
// does not.
...
...
@@ -233,9 +231,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
}
else
{
// Cast if we have to...
// XXX: This is ugly.
let
llretptr
=
BitCast
(
return_context
,
fcx
.llretptr
.get
(),
llfunctionreturntype
.ptr_to
());
let
llretptr
=
BitCast
(
return_context
,
fcx
.llretptr
.get
(),
return_type
.ptr_to
());
Ret
(
return_context
,
Load
(
return_context
,
llretptr
));
}
}
...
...
@@ -636,6 +632,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
}
}
build_return
(
bcx
);
finish_fn
(
fcx
,
lltop
);
return
;
}
...
...
src/librustc/middle/trans/glue.rs
浏览文件 @
81cf72c2
...
...
@@ -18,7 +18,7 @@
use
back
::
link
::
*
;
use
driver
::
session
;
use
lib
;
use
lib
::
llvm
::{
llvm
,
ValueRef
,
T
ype
,
T
rue
};
use
lib
::
llvm
::{
llvm
,
ValueRef
,
True
};
use
middle
::
trans
::
adt
;
use
middle
::
trans
::
base
::
*
;
use
middle
::
trans
::
callee
;
...
...
@@ -29,12 +29,14 @@
use
middle
::
trans
::
machine
::
*
;
use
middle
::
trans
::
reflect
;
use
middle
::
trans
::
tvec
;
use
middle
::
trans
::
type_of
::
{
type_of
,
type_of_glue_fn
}
;
use
middle
::
trans
::
type_of
::
type_of
;
use
middle
::
trans
::
uniq
;
use
middle
::
ty
;
use
util
::
ppaux
;
use
util
::
ppaux
::
ty_to_short_str
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
io
;
use
core
::
libc
::
c_uint
;
use
core
::
str
;
...
...
@@ -76,16 +78,6 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block {
return
cx
;
}
pub
fn
drop_ty_root
(
bcx
:
block
,
v
:
ValueRef
,
rooted
:
bool
,
t
:
ty
::
t
)
->
block
{
if
rooted
{
// NB: v is a raw ptr to an addrspace'd ptr to the value.
let
v
=
PointerCast
(
bcx
,
Load
(
bcx
,
v
),
type_of
(
bcx
.ccx
(),
t
)
.ptr_to
());
drop_ty
(
bcx
,
v
,
t
)
}
else
{
drop_ty
(
bcx
,
v
,
t
)
}
}
pub
fn
drop_ty_immediate
(
bcx
:
block
,
v
:
ValueRef
,
t
:
ty
::
t
)
->
block
{
let
_
icx
=
bcx
.insn_ctxt
(
"drop_ty_immediate"
);
match
ty
::
get
(
t
)
.sty
{
...
...
@@ -436,8 +428,8 @@ pub fn trans_struct_drop(bcx: block,
// The second argument is the "self" argument for drop
let
params
=
unsafe
{
l
ib
::
llvm
::
fn_ty_param_tys
(
llvm
::
LLVMGetElementType
(
llvm
::
LLVMTypeOf
(
dtor_addr
))
)
l
et
ty
=
Type
::
from_ref
(
llvm
::
LLVMTypeOf
(
dtor_addr
));
ty
.element_type
()
.func_params
(
)
};
// Class dtors have no explicit args, so the params should
...
...
@@ -617,20 +609,6 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
}
// Chooses the addrspace for newly declared types.
pub
fn
declare_tydesc_addrspace
(
ccx
:
&
CrateContext
,
t
:
ty
::
t
)
->
addrspace
{
if
!
ty
::
type_needs_drop
(
ccx
.tcx
,
t
)
{
return
default_addrspace
;
}
else
if
ty
::
type_is_immediate
(
t
)
{
// For immediate types, we don't actually need an addrspace, because
// e.g. boxed types include pointers to their contents which are
// already correctly tagged with addrspaces.
return
default_addrspace
;
}
else
{
return
(
ccx
.next_addrspace
)();
}
}
// Generates the declaration for (but doesn't emit) a type descriptor.
pub
fn
declare_tydesc
(
ccx
:
&
mut
CrateContext
,
t
:
ty
::
t
)
->
@
mut
tydesc_info
{
// If emit_tydescs already ran, then we shouldn't be creating any new
...
...
@@ -640,20 +618,18 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
let
llty
=
type_of
(
ccx
,
t
);
if
ccx
.sess
.count_type_sizes
()
{
io
::
println
(
fmt!
(
"%u
\t
%s"
,
llsize_of_real
(
ccx
,
llty
),
io
::
println
(
fmt!
(
"%u
\t
%s"
,
llsize_of_real
(
ccx
,
llty
),
ppaux
::
ty_to_str
(
ccx
.tcx
,
t
)));
}
let
llsize
=
llsize_of
(
ccx
,
llty
);
let
llalign
=
llalign_of
(
ccx
,
llty
);
let
addrspace
=
declare_tydesc_addrspace
(
ccx
,
t
);
let
name
=
mangle_internal_name_by_type_and_seq
(
ccx
,
t
,
"tydesc"
)
.to_managed
();
note_unique_llvm_symbol
(
ccx
,
name
);
debug!
(
"+++ declare_tydesc %s %s"
,
ppaux
::
ty_to_str
(
ccx
.tcx
,
t
),
name
);
let
gvar
=
str
::
as_c_str
(
name
,
|
buf
|
{
unsafe
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ccx
.tydesc_type
,
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
ccx
.tydesc_type
.to_ref
()
,
buf
)
}
});
let
inf
=
@
mut
tydesc_info
{
...
...
@@ -661,7 +637,6 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
tydesc
:
gvar
,
size
:
llsize
,
align
:
llalign
,
addrspace
:
addrspace
,
take_glue
:
None
,
drop_glue
:
None
,
free_glue
:
None
,
...
...
@@ -706,7 +681,11 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext,
let
llty
=
type_of
(
ccx
,
t
);
let
llrawptr0
=
PointerCast
(
bcx
,
llrawptr0
,
llty
.ptr_to
());
helper
(
bcx
,
llrawptr0
,
t
);
finish_fn
(
fcx
,
lltop
);
// This is from the general finish fn, but that emits a ret {} that we don't want
Br
(
raw_block
(
fcx
,
false
,
fcx
.llstaticallocas
),
lltop
);
RetVoid
(
raw_block
(
fcx
,
false
,
fcx
.llreturn
));
return
llfn
;
}
...
...
@@ -732,7 +711,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
//let _icx = ccx.insn_ctxt("emit_tydescs");
// As of this point, allow no more tydescs to be created.
ccx
.finished_tydescs
=
true
;
let
glue_fn_ty
=
T
_generic_glue_fn
(
ccx
)
.ptr_to
(
);
let
glue_fn_ty
=
T
ype
::
generic_glue_fn
(
ccx
);
let
tyds
=
&
mut
ccx
.tydescs
;
for
tyds
.each_value
|
&
val
|
{
let
ti
=
val
;
...
...
@@ -747,7 +726,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
Some
(
v
)
=>
{
unsafe
{
ccx
.stats.n_real_glues
+=
1u
;
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
)
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
.to_ref
()
)
}
}
};
...
...
@@ -757,7 +736,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
Some
(
v
)
=>
{
unsafe
{
ccx
.stats.n_real_glues
+=
1u
;
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
)
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
.to_ref
()
)
}
}
};
...
...
@@ -767,7 +746,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
Some
(
v
)
=>
{
unsafe
{
ccx
.stats.n_real_glues
+=
1u
;
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
)
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
.to_ref
()
)
}
}
};
...
...
@@ -777,16 +756,16 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
Some
(
v
)
=>
{
unsafe
{
ccx
.stats.n_real_glues
+=
1u
;
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
)
llvm
::
LLVMConstPointerCast
(
v
,
glue_fn_ty
.to_ref
()
)
}
}
};
let
shape
=
C_null
(
Type
::
i8p
());
let
shape_tables
=
C_null
(
Type
::
i8p
());
let
tydesc
=
C_named_struct
(
ccx
.tydesc_type
,
let
tydesc
=
C_named_struct
(
ccx
.tydesc_type
,
[
ti
.size
,
// size
ti
.align
,
// align
take_glue
,
// take_glue
...
...
@@ -802,18 +781,11 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
llvm
::
LLVMSetGlobalConstant
(
gvar
,
True
);
lib
::
llvm
::
SetLinkage
(
gvar
,
lib
::
llvm
::
InternalLinkage
);
// Index tydesc by addrspace.
if
ti
.addrspace
>
gc_box_addrspace
{
let
llty
=
ccx
.tydesc_type
.ptr_to
();
let
addrspace_name
=
fmt!
(
"_gc_addrspace_metadata_%u"
,
ti
.addrspace
as
uint
);
let
addrspace_gvar
=
str
::
as_c_str
(
addrspace_name
,
|
buf
|
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
llty
,
buf
)
});
lib
::
llvm
::
SetLinkage
(
addrspace_gvar
,
lib
::
llvm
::
InternalLinkage
);
llvm
::
LLVMSetInitializer
(
addrspace_gvar
,
gvar
);
}
}
};
}
fn
type_of_glue_fn
(
ccx
:
&
CrateContext
)
->
Type
{
let
tydescpp
=
ccx
.tydesc_type
.ptr_to
()
.ptr_to
();
Type
::
func
([
Type
::
nil
()
.ptr_to
(),
tydescpp
,
Type
::
i8p
()
],
&
Type
::
void
())
}
src/librustc/middle/trans/machine.rs
浏览文件 @
81cf72c2
...
...
@@ -18,6 +18,8 @@
use
middle
::
ty
;
use
util
::
ppaux
::
ty_to_str
;
use
middle
::
trans
::
type_
::
Type
;
// ______________________________________________________________________
// compute sizeof / alignof
...
...
@@ -140,7 +142,7 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint {
debug!
(
"static_size_of_enum: variant %s type %s"
,
cx
.tcx.sess
.str_of
(
variant
.name
),
cx
.tn
.type_to_str
(
T
_struct
(
lltypes
,
false
)));
cx
.tn
.type_to_str
(
T
ype
::
struct_
(
lltypes
,
false
)));
let
this_size
=
llsize_of_real
(
cx
,
Type
::
struct_
(
lltypes
,
false
));
if
max_size
<
this_size
{
...
...
src/librustc/middle/trans/meth.rs
浏览文件 @
81cf72c2
...
...
@@ -30,6 +30,8 @@
use
util
::
common
::
indenter
;
use
util
::
ppaux
::
Repr
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
str
;
use
core
::
vec
;
use
syntax
::
ast_map
::{
path
,
path_mod
,
path_name
};
...
...
@@ -463,7 +465,7 @@ pub fn trans_monomorphized_callee(bcx: block,
// create a llvalue that represents the fn ptr
let
fn_ty
=
node_id_type
(
bcx
,
callee_id
);
let
llfn_ty
=
type_of_fn_from_ty
(
ccx
,
fn_ty
)
.
to_ptr
();
let
llfn_ty
=
type_of_fn_from_ty
(
ccx
,
fn_ty
)
.
ptr_to
();
let
llfn_val
=
PointerCast
(
bcx
,
callee
.llfn
,
llfn_ty
);
// combine the self environment with the rest
...
...
@@ -778,7 +780,7 @@ pub fn make_vtable(ccx: @mut CrateContext,
let
tbl
=
C_struct
(
components
);
let
vtable
=
ccx
.sess
.str_of
((
ccx
.names
)(
"vtable"
));
let
vt_gvar
=
do
str
::
as_c_str
(
vtable
)
|
buf
|
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
val_ty
(
tbl
),
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
val_ty
(
tbl
)
.to_ref
()
,
buf
)
};
llvm
::
LLVMSetInitializer
(
vt_gvar
,
tbl
);
llvm
::
LLVMSetGlobalConstant
(
vt_gvar
,
lib
::
llvm
::
True
);
...
...
src/librustc/middle/trans/reflect.rs
浏览文件 @
81cf72c2
...
...
@@ -9,7 +9,7 @@
// except according to those terms.
use
back
::
link
::
mangle_internal_name_by_path_and_seq
;
use
lib
::
llvm
::{
Type
,
ValueRef
,
llvm
};
use
lib
::
llvm
::{
ValueRef
,
llvm
};
use
middle
::
trans
::
adt
;
use
middle
::
trans
::
base
::
*
;
use
middle
::
trans
::
build
::
*
;
...
...
@@ -33,6 +33,8 @@
use
syntax
::
ast_map
::
path_name
;
use
syntax
::
parse
::
token
::
special_idents
;
use
middle
::
trans
::
type_
::
Type
;
pub
struct
Reflector
{
visitor_val
:
ValueRef
,
visitor_methods
:
@~
[
@
ty
::
Method
],
...
...
src/librustc/middle/trans/shape.rs
浏览文件 @
81cf72c2
...
...
@@ -17,6 +17,8 @@
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
str
;
pub
struct
Ctxt
{
...
...
@@ -32,7 +34,7 @@ pub fn mk_global(ccx: &CrateContext,
->
ValueRef
{
unsafe
{
let
llglobal
=
do
str
::
as_c_str
(
name
)
|
buf
|
{
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
val_ty
(
llval
),
buf
)
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
val_ty
(
llval
)
.to_ref
()
,
buf
)
};
llvm
::
LLVMSetInitializer
(
llglobal
,
llval
);
llvm
::
LLVMSetGlobalConstant
(
llglobal
,
True
);
...
...
@@ -50,7 +52,7 @@ pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt {
unsafe
{
let
llshapetablesty
=
Type
::
named_struct
(
"shapes"
);
do
"shapes"
.as_c_str
|
buf
|
{
llvm
::
LLVMAddGlobal
(
llmod
,
llshapetablesty
,
buf
)
llvm
::
LLVMAddGlobal
(
llmod
,
llshapetablesty
.to_ref
()
,
buf
)
};
Ctxt
{
...
...
src/librustc/middle/trans/tvec.rs
浏览文件 @
81cf72c2
...
...
@@ -27,6 +27,8 @@
use
util
::
common
::
indenter
;
use
util
::
ppaux
::
ty_to_str
;
use
middle
::
trans
::
type_
::
Type
;
use
core
::
option
::
None
;
use
syntax
::
ast
;
use
syntax
::
codemap
;
...
...
src/librustc/middle/trans/type_.rs
浏览文件 @
81cf72c2
...
...
@@ -11,6 +11,7 @@
use
core
::
prelude
::
*
;
use
lib
::
llvm
::{
llvm
,
TypeRef
,
Bool
,
False
,
True
,
TypeKind
};
use
lib
::
llvm
::{
Float
,
Double
,
X86_FP80
,
PPC_FP128
,
FP128
};
use
middle
::
ty
;
...
...
@@ -26,6 +27,7 @@
use
core
::
libc
::{
c_uint
};
#[deriving(Eq)]
pub
struct
Type
{
priv
rf
:
TypeRef
}
...
...
@@ -38,12 +40,14 @@ pub struct Type {
* Wrapper for LLVM TypeRef
*/
impl
Type
{
#[inline(always)]
pub
fn
from_ref
(
r
:
TypeRef
)
->
Type
{
Type
{
rf
:
r
}
}
#[inline(always)]
// So it doesn't kill --opt-level=0 builds of the compiler
pub
fn
to_ref
(
&
self
)
->
TypeRef
{
self
.rf
}
...
...
@@ -136,7 +140,7 @@ pub fn uint_from_ty(ctx: &CrateContext, t: ast::uint_ty) -> Type {
pub
fn
float_from_ty
(
ctx
:
&
CrateContext
,
t
:
ast
::
float_ty
)
->
Type
{
match
t
{
ast
::
ty_f
=>
ctx
.float_ty
,
ast
::
ty_f
=>
ctx
.float_ty
pe
,
ast
::
ty_f32
=>
Type
::
f32
(),
ast
::
ty_f64
=>
Type
::
f64
()
}
...
...
@@ -147,7 +151,7 @@ pub fn size_t(arch: Architecture) -> Type {
}
pub
fn
func
(
args
:
&
[
Type
],
ret
:
&
Type
)
->
Type
{
let
vec
:
&
[
TypeRef
]
=
unsafe
{
cast
::
transmute
()
};
let
vec
:
&
[
TypeRef
]
=
unsafe
{
cast
::
transmute
(
args
)
};
ty!
(
llvm
::
LLVMFunctionType
(
ret
.to_ref
(),
vec
::
raw
::
to_ptr
(
vec
),
args
.len
()
as
c_uint
,
False
))
}
...
...
@@ -157,12 +161,13 @@ pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type {
}
pub
fn
ptr
(
ty
:
Type
)
->
Type
{
ty!
(
llvm
::
LLVMPointerType
(
ty
,
0
as
c_uint
))
ty!
(
llvm
::
LLVMPointerType
(
ty
.to_ref
()
,
0
as
c_uint
))
}
pub
fn
struct_
(
els
:
&
[
Type
],
packed
:
bool
)
->
Type
{
let
els
:
&
[
TypeRef
]
=
unsafe
{
cast
::
transmute
(
els
)
};
ty!
(
llvm
::
LLVMStructType
(
vec
::
raw
::
to_ptr
(
els
),
els
.len
()
as
c_uint
,
packed
as
Bool
))
ty!
(
llvm
::
LLVMStructTypeInContext
(
base
::
task_llcx
(),
vec
::
raw
::
to_ptr
(
els
),
els
.len
()
as
c_uint
,
packed
as
Bool
))
}
pub
fn
named_struct
(
name
:
&
str
)
->
Type
{
...
...
@@ -175,7 +180,7 @@ pub fn empty_struct() -> Type {
}
pub
fn
vtable
()
->
Type
{
Type
::
array
(
Type
::
i8
()
.ptr_to
(),
1
)
Type
::
array
(
&
Type
::
i8
()
.ptr_to
(),
1
)
}
pub
fn
generic_glue_fn
(
cx
:
&
mut
CrateContext
)
->
Type
{
...
...
@@ -185,7 +190,7 @@ pub fn generic_glue_fn(cx: &mut CrateContext) -> Type {
}
let
ty
=
cx
.tydesc_type
.get_field
(
abi
::
tydesc_field_drop_glue
);
cx
.tn
.associate_type
(
"glue_fn"
,
ty
);
cx
.tn
.associate_type
(
"glue_fn"
,
&
ty
);
return
ty
;
}
...
...
@@ -193,10 +198,9 @@ pub fn generic_glue_fn(cx: &mut CrateContext) -> Type {
pub
fn
tydesc
(
arch
:
Architecture
)
->
Type
{
let
mut
tydesc
=
Type
::
named_struct
(
"tydesc"
);
let
tydescpp
=
tydesc
.ptr_to
()
.ptr_to
();
let
pvoid
=
Type
::
i8
()
.ptr_to
();
let
glue_fn_ty
=
Type
::
func
(
[
Type
::
nil
.ptr_to
(),
tydescpp
,
pvoid
],
Type
::
void
())
.ptr_to
();
let
pvoid
=
Type
::
i8p
();
let
glue_fn_ty
=
Type
::
func
([
Type
::
nil
()
.ptr_to
(),
tydescpp
,
pvoid
],
&
Type
::
void
())
.ptr_to
();
let
int_ty
=
Type
::
int
(
arch
);
...
...
@@ -226,7 +230,7 @@ pub fn vec(arch: Architecture, ty: &Type) -> Type {
}
pub
fn
opaque_vec
(
arch
:
Architecture
)
->
Type
{
Type
::
vec
(
arch
,
Type
::
i8
())
Type
::
vec
(
arch
,
&
Type
::
i8
())
}
#[inline]
...
...
@@ -242,11 +246,11 @@ pub fn box_header(ctx: &CrateContext) -> Type {
}
pub
fn
box
(
ctx
:
&
CrateContext
,
ty
:
&
Type
)
->
Type
{
Type
::
struct_
(
Type
::
box_header_fields
(
ctx
)
+
[
ty
],
false
)
Type
::
struct_
(
Type
::
box_header_fields
(
ctx
)
+
[
*
ty
],
false
)
}
pub
fn
opaque_box
(
ctx
:
&
CrateContext
)
->
Type
{
Type
::
box
(
ctx
,
Type
::
i8
())
Type
::
box
(
ctx
,
&
Type
::
i8
())
}
pub
fn
unique
(
ctx
:
&
CrateContext
,
ty
:
&
Type
)
->
Type
{
...
...
@@ -254,7 +258,7 @@ pub fn unique(ctx: &CrateContext, ty: &Type) -> Type {
}
pub
fn
opaque_cbox_ptr
(
cx
:
&
CrateContext
)
->
Type
{
Type
::
opaque_box
()
.ptr_to
()
Type
::
opaque_box
(
cx
)
.ptr_to
()
}
pub
fn
enum_discrim
(
cx
:
&
CrateContext
)
->
Type
{
...
...
@@ -275,7 +279,7 @@ pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type {
}
ty
::
UniqTraitStore
=>
{
Type
::
struct_
(
[
tydesc_ptr
,
Type
::
unique
(
ctx
,
Type
::
i8
())
.ptr_to
()],
[
tydesc_ptr
,
Type
::
unique
(
ctx
,
&
Type
::
i8
())
.ptr_to
()],
false
)
}
ty
::
RegionTraitStore
(
*
)
=>
{
...
...
@@ -301,7 +305,7 @@ pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
}
pub
fn
ptr_to
(
&
self
)
->
Type
{
ty!
(
llvm
::
LLVMPointerType
(
self
.to_ref
()))
ty!
(
llvm
::
LLVMPointerType
(
self
.to_ref
()
,
0
))
}
pub
fn
get_field
(
&
self
,
idx
:
uint
)
->
Type
{
...
...
@@ -335,14 +339,38 @@ pub fn array_length(&self) -> uint {
pub
fn
field_types
(
&
self
)
->
~
[
Type
]
{
unsafe
{
let
n_elts
=
llvm
::
LLVMCountStructElementTypes
(
s
truct_ty
)
as
uint
;
let
n_elts
=
llvm
::
LLVMCountStructElementTypes
(
s
elf
.to_ref
()
)
as
uint
;
if
n_elts
==
0
{
return
~
[];
}
let
mut
elts
=
vec
::
from_elem
(
n_elts
,
0
as
TypeRef
);
llvm
::
LLVMGetStructElementTypes
(
s
truct_ty
,
&
mut
elts
[
0
]);
llvm
::
LLVMGetStructElementTypes
(
s
elf
.to_ref
()
,
&
mut
elts
[
0
]);
cast
::
transmute
(
elts
)
}
}
pub
fn
return_type
(
&
self
)
->
Type
{
unsafe
{
ty!
(
llvm
::
LLVMGetReturnType
(
self
.to_ref
()))
}
}
pub
fn
func_params
(
&
self
)
->
~
[
Type
]
{
unsafe
{
let
n_args
=
llvm
::
LLVMCountParamTypes
(
self
.to_ref
())
as
uint
;
let
args
=
vec
::
from_elem
(
n_args
,
0
as
TypeRef
);
llvm
::
LLVMGetParamTypes
(
self
.to_ref
(),
vec
::
raw
::
to_ptr
(
args
));
cast
::
transmute
(
args
)
}
}
pub
fn
float_width
(
&
self
)
->
uint
{
match
self
.kind
()
{
Float
=>
32
,
Double
=>
64
,
X86_FP80
=>
80
,
FP128
|
PPC_FP128
=>
128
,
_
=>
fail
!
(
"llvm_float_width called on a non-float type"
)
}
}
}
src/librustc/middle/trans/type_of.rs
浏览文件 @
81cf72c2
...
...
@@ -18,6 +18,8 @@
use
middle
::
ty
;
use
util
::
ppaux
;
use
middle
::
trans
::
type_
::
Type
;
use
syntax
::
ast
;
pub
fn
arg_is_indirect
(
_
:
&
CrateContext
,
arg_ty
:
&
ty
::
t
)
->
bool
{
...
...
@@ -58,10 +60,15 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t)
atys
.push_all
(
type_of_explicit_args
(
cx
,
inputs
));
// Use the output as the actual return value if it's immediate.
<<<<<<<
HEAD
if
output_is_immediate
&&
!
ty
::
type_is_nil
(
output
)
{
Type
::
func
(
atys
,
lloutputtype
)
=======
if
output_is_immediate
{
Type
::
func
(
atys
,
&
lloutputtype
)
>>>>>>>
Finish
up
Type
refactoring
}
else
{
Type
::
func
(
atys
,
Type
::
void
())
Type
::
func
(
atys
,
&
Type
::
void
())
}
}
}
...
...
@@ -87,11 +94,11 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type {
match
ty
::
get
(
t
)
.sty
{
ty
::
ty_box
(
mt
)
=>
{
let
ty
=
type_of
(
cx
,
mt
.ty
);
Type
::
box
(
cx
,
ty
)
.ptr_to
()
Type
::
box
(
cx
,
&
ty
)
.ptr_to
()
}
ty
::
ty_uniq
(
mt
)
=>
{
let
ty
=
type_of
(
cx
,
mt
.ty
);
Type
::
unique
(
cx
,
ty
)
.ptr_to
()
Type
::
unique
(
cx
,
&
ty
)
.ptr_to
()
}
_
=>
{
cx
.sess
.bug
(
"non-box in type_of_non_gc_box"
);
...
...
@@ -146,14 +153,14 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type {
ty
::
ty_closure
(
*
)
=>
Type
::
struct_
([
Type
::
i8p
(),
Type
::
i8p
()],
false
),
ty
::
ty_trait
(
_
,
_
,
store
,
_
)
=>
Type
::
opaque_trait
(
cx
,
store
),
ty
::
ty_estr
(
ty
::
vstore_fixed
(
size
))
=>
Type
::
array
(
Type
::
i8
(),
size
),
ty
::
ty_estr
(
ty
::
vstore_fixed
(
size
))
=>
Type
::
array
(
&
Type
::
i8
(),
size
as
u64
),
ty
::
ty_evec
(
mt
,
ty
::
vstore_fixed
(
size
))
=>
{
Type
::
array
(
sizing_type_of
(
cx
,
mt
.ty
),
size
)
Type
::
array
(
&
sizing_type_of
(
cx
,
mt
.ty
),
size
as
u64
)
}
ty
::
ty_unboxed_vec
(
mt
)
=>
{
let
sz_ty
=
sizing_type_of
(
cx
,
mt
.ty
);
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
sz_ty
)
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
&
sz_ty
)
}
ty
::
ty_tup
(
*
)
|
ty
::
ty_enum
(
*
)
=>
{
...
...
@@ -165,7 +172,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type {
if
ty
::
type_is_simd
(
cx
.tcx
,
t
)
{
let
et
=
ty
::
simd_type
(
cx
.tcx
,
t
);
let
n
=
ty
::
simd_size
(
cx
.tcx
,
t
);
Type
::
vector
(
type_of
(
cx
,
et
),
n
)
Type
::
vector
(
&
type_of
(
cx
,
et
),
n
as
u64
)
}
else
{
let
repr
=
adt
::
represent_type
(
cx
,
t
);
let
packed
=
ty
::
lookup_packed
(
cx
.tcx
,
did
);
...
...
@@ -205,14 +212,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
return
llty
;
}
let
llty
=
match
ty
::
get
(
t
)
.sty
{
let
mut
llty
=
match
ty
::
get
(
t
)
.sty
{
ty
::
ty_nil
|
ty
::
ty_bot
=>
Type
::
nil
(),
ty
::
ty_bool
=>
Type
::
bool
(),
ty
::
ty_int
(
t
)
=>
Type
::
int_from_ty
(
cx
,
t
),
ty
::
ty_uint
(
t
)
=>
Type
::
uint_from_ty
(
cx
,
t
),
ty
::
ty_float
(
t
)
=>
Type
::
float_from_ty
(
cx
,
t
),
ty
::
ty_estr
(
ty
::
vstore_uniq
)
=>
{
Type
::
unique
(
cx
,
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
Type
::
i8
()))
.ptr_to
()
Type
::
unique
(
cx
,
&
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
&
Type
::
i8
()))
.ptr_to
()
}
ty
::
ty_enum
(
did
,
ref
substs
)
=>
{
// Only create the named struct, but don't fill it in. We
...
...
@@ -223,30 +230,30 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
Type
::
named_struct
(
llvm_type_name
(
cx
,
an_enum
,
did
,
substs
.tps
))
}
ty
::
ty_estr
(
ty
::
vstore_box
)
=>
{
Type
::
box
(
cx
,
Type
::
vec
(
cx
,
Type
::
i8
()))
.ptr_to
()
Type
::
box
(
cx
,
&
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
&
Type
::
i8
()))
.ptr_to
()
}
ty
::
ty_evec
(
ref
mt
,
ty
::
vstore_box
)
=>
{
let
e_ty
=
type_of
(
cx
,
mt
.ty
);
let
v_ty
=
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
e_ty
);
Type
::
box
(
cx
,
v_ty
)
.ptr_to
()
let
v_ty
=
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
&
e_ty
);
Type
::
box
(
cx
,
&
v_ty
)
.ptr_to
()
}
ty
::
ty_box
(
ref
mt
)
=>
{
let
ty
=
type_of
(
cx
,
mt
.ty
);
Type
::
box
(
cx
,
ty
)
.ptr_to
()
Type
::
box
(
cx
,
&
ty
)
.ptr_to
()
}
ty
::
ty_opaque_box
=>
Type
::
opaque_box
(
cx
)
.ptr_to
(),
ty
::
ty_uniq
(
ref
mt
)
=>
{
let
ty
=
type_of
(
cx
,
mt
.ty
);
Type
::
unique
(
cx
,
ty
)
.ptr_to
()
Type
::
unique
(
cx
,
&
ty
)
.ptr_to
()
}
ty
::
ty_evec
(
ref
mt
,
ty
::
vstore_uniq
)
=>
{
let
ty
=
type_of
(
cx
,
mt
.ty
);
let
ty
=
Type
::
vec
(
cx
,
ty
);
Type
::
unique
(
cx
,
ty
)
.ptr_to
()
let
ty
=
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
&
ty
);
Type
::
unique
(
cx
,
&
ty
)
.ptr_to
()
}
ty
::
ty_unboxed_vec
(
ref
mt
)
=>
{
let
ty
=
type_of
(
cx
,
mt
.ty
);
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
ty
)
Type
::
vec
(
cx
.sess.targ_cfg.arch
,
&
ty
)
}
ty
::
ty_ptr
(
ref
mt
)
=>
type_of
(
cx
,
mt
.ty
)
.ptr_to
(),
ty
::
ty_rptr
(
_
,
ref
mt
)
=>
type_of
(
cx
,
mt
.ty
)
.ptr_to
(),
...
...
@@ -263,20 +270,20 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
}
ty
::
ty_estr
(
ty
::
vstore_fixed
(
n
))
=>
{
Type
::
array
(
Type
::
i8
(),
n
+
1u
/* +1 for trailing null */
)
Type
::
array
(
&
Type
::
i8
(),
(
n
+
1u
)
as
u64
)
}
ty
::
ty_evec
(
ref
mt
,
ty
::
vstore_fixed
(
n
))
=>
{
Type
::
array
(
type_of
(
cx
,
mt
.ty
),
n
)
Type
::
array
(
&
type_of
(
cx
,
mt
.ty
),
n
as
u64
)
}
ty
::
ty_bare_fn
(
_
)
=>
type_of_fn_from_ty
(
cx
,
t
)
.ptr_to
(),
ty
::
ty_closure
(
_
)
=>
{
let
ty
=
type_of_fn_from_ty
(
cx
,
t
);
Type
::
func_pair
(
cx
,
ty
)
Type
::
func_pair
(
cx
,
&
ty
)
}
ty
::
ty_trait
(
_
,
_
,
store
,
_
)
=>
Type
::
opaque_trait
(
cx
,
store
),
ty
::
ty_type
=>
cx
.tydesc_type
.
to_ptr
(),
ty
::
ty_type
=>
cx
.tydesc_type
.
ptr_to
(),
ty
::
ty_tup
(
*
)
=>
{
let
repr
=
adt
::
represent_type
(
cx
,
t
);
Type
::
struct_
(
adt
::
fields_of
(
cx
,
repr
),
false
)
...
...
@@ -286,7 +293,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
if
ty
::
type_is_simd
(
cx
.tcx
,
t
)
{
let
et
=
ty
::
simd_type
(
cx
.tcx
,
t
);
let
n
=
ty
::
simd_size
(
cx
.tcx
,
t
);
Type
::
vector
(
type_of
(
cx
,
et
),
n
)
Type
::
vector
(
&
type_of
(
cx
,
et
),
n
as
u64
)
}
else
{
// Only create the named struct, but don't fill it in. We fill it
// in *after* placing it into the type cache. This prevents
...
...
@@ -306,16 +313,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
match
ty
::
get
(
t
)
.sty
{
ty
::
ty_enum
(
*
)
=>
{
let
repr
=
adt
::
represent_type
(
cx
,
t
);
common
::
set_struct_body
(
llty
,
adt
::
fields_of
(
cx
,
repr
),
false
);
llty
.set_struct_body
(
adt
::
fields_of
(
cx
,
repr
),
false
);
}
ty
::
ty_struct
(
did
,
_
)
=>
{
if
!
ty
::
type_is_simd
(
cx
.tcx
,
t
)
{
let
repr
=
adt
::
represent_type
(
cx
,
t
);
let
packed
=
ty
::
lookup_packed
(
cx
.tcx
,
did
);
common
::
set_struct_body
(
llty
,
adt
::
fields_of
(
cx
,
repr
),
packed
);
llty
.set_struct_body
(
adt
::
fields_of
(
cx
,
repr
),
packed
);
}
}
_
=>
()
...
...
@@ -345,19 +350,5 @@ pub fn llvm_type_name(cx: &CrateContext,
pub
fn
type_of_dtor
(
ccx
:
&
mut
CrateContext
,
self_ty
:
ty
::
t
)
->
Type
{
let
self_ty
=
type_of
(
ccx
,
self_ty
)
.ptr_to
();
Type
::
func
([
self_ty
],
Type
::
viod
())
}
/*
pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> Type {
let addrspace = base::get_tydesc(ccx, t).addrspace;
debug!("type_of_rooted %s in addrspace %u",
ppaux::ty_to_str(ccx.tcx, t), addrspace as uint);
return T_root(type_of(ccx, t), addrspace);
}
pub fn type_of_glue_fn(ccx: &CrateContext) -> Type {
let tydescpp = T_ptr(T_ptr(ccx.tydesc_type));
return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void());
Type
::
func
([
self_ty
],
Type
::
void
())
}
*/
src/librustc/middle/trans/write_guard.rs
浏览文件 @
81cf72c2
...
...
@@ -28,6 +28,8 @@
use
syntax
::
codemap
::
span
;
use
syntax
::
ast
;
use
middle
::
trans
::
type_
::
Type
;
pub
fn
root_and_write_guard
(
datum
:
&
Datum
,
mut
bcx
:
block
,
span
:
span
,
...
...
src/libstd/unstable/intrinsics.rs
浏览文件 @
81cf72c2
...
...
@@ -175,15 +175,15 @@
pub
fn
atomic_umin_relaxed
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
#[cfg(not(stage0))]
pub
fn
atomic_um
in
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
pub
fn
atomic_um
ax
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
#[cfg(not(stage0))]
pub
fn
atomic_um
in
_acq
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
pub
fn
atomic_um
ax
_acq
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
#[cfg(not(stage0))]
pub
fn
atomic_um
in
_rel
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
pub
fn
atomic_um
ax
_rel
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
#[cfg(not(stage0))]
pub
fn
atomic_um
in
_acqrel
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
pub
fn
atomic_um
ax
_acqrel
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
#[cfg(not(stage0))]
pub
fn
atomic_um
in
_relaxed
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
pub
fn
atomic_um
ax
_relaxed
(
dst
:
&
mut
int
,
src
:
int
)
->
int
;
/// The size of a type in bytes.
///
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录