Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
721c5bbe
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,发现更多精彩内容 >>
提交
721c5bbe
编写于
6月 07, 2011
作者:
G
Graydon Hoare
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
More work on proper linkage name-mangling. Almost right, aside from version numbers.
上级
7034a282
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
381 addition
and
143 deletion
+381
-143
src/comp/back/link.rs
src/comp/back/link.rs
+244
-2
src/comp/driver/session.rs
src/comp/driver/session.rs
+28
-15
src/comp/front/ast.rs
src/comp/front/ast.rs
+6
-1
src/comp/front/eval.rs
src/comp/front/eval.rs
+7
-2
src/comp/front/parser.rs
src/comp/front/parser.rs
+5
-1
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+71
-118
src/comp/middle/walk.rs
src/comp/middle/walk.rs
+1
-1
src/lib/fs.rs
src/lib/fs.rs
+14
-0
src/lib/std.rc
src/lib/std.rc
+5
-3
未找到文件。
src/comp/back/link.rs
浏览文件 @
721c5bbe
import
driver
::
session
;
import
lib
::
llvm
::
llvm
;
import
middle
::
trans
;
import
middle
::
metadata
;
import
middle
::
ty
;
import
std
::
str
;
import
std
::
fs
;
import
std
::
vec
;
import
std
::
option
;
import
option
::
some
;
import
option
::
none
;
import
std
::
sha1
::
sha1
;
import
std
::
sort
;
import
trans
::
crate_ctxt
;
import
front
::
ast
;
import
lib
::
llvm
::
llvm
::
ModuleRef
;
import
lib
::
llvm
::
llvm
::
ValueRef
;
...
...
@@ -49,7 +59,7 @@ fn link_intrinsics(session::session sess, ModuleRef llmod) {
auto
linkres
=
llvm
::
LLVMLinkModules
(
llmod
,
llintrinsicsmod
);
llvm
::
LLVMDisposeModule
(
llintrinsicsmod
);
if
(
linkres
==
False
)
{
llvm_err
(
sess
,
"couldn't link the module with the intrinsics"
);
fail
;
...
...
@@ -58,7 +68,7 @@ fn link_intrinsics(session::session sess, ModuleRef llmod) {
mod
write
{
fn
is_object_or_assembly_or_exe
(
output_type
ot
)
->
bool
{
if
(
(
ot
==
output_type_assembly
)
||
if
(
(
ot
==
output_type_assembly
)
||
(
ot
==
output_type_object
)
||
(
ot
==
output_type_exe
)
)
{
ret
true
;
...
...
@@ -218,3 +228,235 @@ fn run_passes(session::session sess, ModuleRef llmod, str output) {
}
}
/*
* Name mangling and its relationship to metadata. This is complex. Read
* carefully.
*
* The semantic model of Rust linkage is, broadly, that "there's no global
* namespace" between crates. Our aim is to preserve the illusion of this
* model despite the fact that it's not *quite* possible to implement on
* modern linkers. We initially didn't use system linkers at all, but have
* been convinced of their utility.
*
* There are a few issues to handle:
*
* - Linkers operate on a flat namespace, so we have to flatten names.
* We do this using the C++ namespace-mangling technique. Foo::bar
* symbols and such.
*
* - Symbols with the same name but different types need to get different
* linkage-names. We do this by hashing a string-encoding of the type into
* a fixed-size (currently 16-byte hex) cryptographic hash function (CHF:
* we use SHA1) to "prevent collisions". This is not airtight but 16 hex
* digits on uniform probability means you're going to need 2**32 same-name
* symbols in the same process before you're even hitting birthday-paradox
* collision probability.
*
* - Symbols in dirrerent crates but with same names "within" the crate need
* to get different linkage-names.
*
* So here is what we do:
*
* - Separate the meta tags into two sets: exported and local. Only work with
* the exported ones when considering linkage.
*
* - Consider two exported tags as special (and madatory): name and vers.
* Every crate gets them; if it doesn't name them explicitly we infer them
* as basename(crate) and "0.1", respectively. Call these CNAME, CVERS.
*
* - Define CMETA as all the non-name, non-vers exported meta tags in the
* crate (in sorted order).
*
* - Define CMH as hash(CMETA).
*
* - Compile our crate to lib CNAME-CMH-CVERS.so
*
* - Define STH(sym) as hash(CNAME, CMH, type_str(sym))
*
* - Suffix a mangled sym with ::STH@CVERS, so that it is unique in the
* name, non-name metadata, and type sense, and versioned in the way
* system linkers understand.
*
*/
iter
crate_export_metas
(
ast
::
crate
c
)
->
@
ast
::
meta_item
{
for
(
@
ast
::
crate_directive
cdir
in
c
.node.directives
)
{
alt
(
cdir
.node
)
{
case
(
ast
::
cdir_meta
(
?
v
,
?
mis
))
{
if
(
v
==
ast
::
export_meta
)
{
for
(
@
ast
::
meta_item
mi
in
mis
)
{
put
mi
;
}
}
}
case
(
_
)
{}
}
}
}
fn
get_crate_meta
(
&
session
::
session
sess
,
&
ast
::
crate
c
,
str
k
,
str
default
,
bool
warn_default
)
->
str
{
let
vec
[
@
ast
::
meta_item
]
v
=
[];
for
each
(
@
ast
::
meta_item
mi
in
crate_export_metas
(
c
))
{
if
(
mi
.node.name
==
k
)
{
v
+=
[
mi
];
}
}
alt
(
vec
::
len
(
v
))
{
case
(
0u
)
{
if
(
warn_default
)
{
sess
.warn
(
#
fmt
(
"missing meta '%s', using '%s' as default"
,
k
,
default
));
}
ret
default
;
}
case
(
1u
)
{
ret
v
.
(
0
)
.node.value
;
}
case
(
_
)
{
sess
.span_err
(
v
.
(
1
)
.span
,
#
fmt
(
"duplicate meta '%s'"
,
k
));
}
}
}
// This calculates CMH as defined above
fn
crate_meta_extras_hash
(
sha1
sha
,
&
ast
::
crate
crate
)
->
str
{
fn
lteq
(
&@
ast
::
meta_item
ma
,
&@
ast
::
meta_item
mb
)
->
bool
{
ret
ma
.node.name
<=
mb
.node.name
;
}
fn
len_and_str
(
&
str
s
)
->
str
{
ret
#
fmt
(
"%u_%s"
,
str
::
byte_len
(
s
),
s
);
}
let
vec
[
mutable
@
ast
::
meta_item
]
v
=
[
mutable
];
for
each
(
@
ast
::
meta_item
mi
in
crate_export_metas
(
crate
))
{
if
(
mi
.node.name
!=
"name"
&&
mi
.node.name
!=
"vers"
)
{
v
+=
[
mutable
mi
];
}
}
sort
::
quick_sort
(
lteq
,
v
);
sha
.reset
();
for
(
@
ast
::
meta_item
m
in
v
)
{
sha
.input_str
(
len_and_str
(
m
.node.name
));
sha
.input_str
(
len_and_str
(
m
.node.value
));
}
ret
truncated_sha1_result
(
sha
);
}
fn
crate_meta_name
(
&
session
::
session
sess
,
&
ast
::
crate
crate
,
&
str
output
)
->
str
{
auto
os
=
str
::
split
(
fs
::
basename
(
output
),
'.'
as
u8
);
assert
vec
::
len
(
os
)
>=
2u
;
vec
::
pop
(
os
);
ret
get_crate_meta
(
sess
,
crate
,
"name"
,
str
::
connect
(
os
,
"."
),
sess
.get_opts
()
.shared
);
}
fn
crate_meta_vers
(
&
session
::
session
sess
,
&
ast
::
crate
crate
)
->
str
{
ret
get_crate_meta
(
sess
,
crate
,
"vers"
,
"0.0"
,
sess
.get_opts
()
.shared
);
}
fn
truncated_sha1_result
(
sha1
sha
)
->
str
{
ret
str
::
substr
(
sha
.result_str
(),
0u
,
16u
);
}
// This calculates STH for a symbol, as defined above
fn
symbol_hash
(
ty
::
ctxt
tcx
,
sha1
sha
,
&
ty
::
t
t
,
str
crate_meta_name
,
str
crate_meta_extras_hash
)
->
str
{
// NB: do *not* use abbrevs here as we want the symbol names
// to be independent of one another in the crate.
auto
cx
=
@
rec
(
ds
=
metadata
::
def_to_str
,
tcx
=
tcx
,
abbrevs
=
metadata
::
ac_no_abbrevs
);
sha
.reset
();
sha
.input_str
(
crate_meta_name
);
sha
.input_str
(
"-"
);
sha
.input_str
(
crate_meta_name
);
sha
.input_str
(
"-"
);
sha
.input_str
(
metadata
::
Encode
::
ty_str
(
cx
,
t
));
auto
hash
=
truncated_sha1_result
(
sha
);
// Prefix with _ so that it never blends into adjacent digits
ret
"_"
+
hash
;
}
fn
get_symbol_hash
(
&@
crate_ctxt
ccx
,
&
ty
::
t
t
)
->
str
{
auto
hash
=
""
;
alt
(
ccx
.type_sha1s
.find
(
t
))
{
case
(
some
(
?
h
))
{
hash
=
h
;
}
case
(
none
)
{
hash
=
symbol_hash
(
ccx
.tcx
,
ccx
.sha
,
t
,
ccx
.crate_meta_name
,
ccx
.crate_meta_extras_hash
);
ccx
.type_sha1s
.insert
(
t
,
hash
);
}
}
ret
hash
;
}
fn
mangle
(
&
vec
[
str
]
ss
)
->
str
{
// Follow C++ namespace-mangling style
auto
n
=
"_ZN"
;
// Begin name-sequence.
for
(
str
s
in
ss
)
{
n
+=
#
fmt
(
"%u%s"
,
str
::
byte_len
(
s
),
s
);
}
n
+=
"E"
;
// End name-sequence.
ret
n
;
}
fn
exported_name
(
&
vec
[
str
]
path
,
&
str
hash
,
&
str
vers
)
->
str
{
// FIXME: versioning isn't working yet
ret
mangle
(
path
+
[
hash
]);
// + "@" + vers;
}
fn
mangle_exported_name
(
&@
crate_ctxt
ccx
,
&
vec
[
str
]
path
,
&
ty
::
t
t
)
->
str
{
auto
hash
=
get_symbol_hash
(
ccx
,
t
);
ret
exported_name
(
path
,
hash
,
ccx
.crate_meta_vers
);
}
fn
mangle_internal_name_by_type_only
(
&@
crate_ctxt
ccx
,
&
ty
::
t
t
,
&
str
name
)
->
str
{
auto
f
=
metadata
::
def_to_str
;
auto
cx
=
@
rec
(
ds
=
f
,
tcx
=
ccx
.tcx
,
abbrevs
=
metadata
::
ac_no_abbrevs
);
auto
s
=
ty
::
ty_to_short_str
(
ccx
.tcx
,
t
);
auto
hash
=
get_symbol_hash
(
ccx
,
t
);
ret
mangle
([
name
,
s
,
hash
]);
}
fn
mangle_internal_name_by_path_and_seq
(
&@
crate_ctxt
ccx
,
&
vec
[
str
]
path
,
&
str
flav
)
->
str
{
ret
mangle
(
path
+
[
ccx
.names
.next
(
flav
)]);
}
fn
mangle_internal_name_by_path
(
&@
crate_ctxt
ccx
,
&
vec
[
str
]
path
)
->
str
{
ret
mangle
(
path
);
}
fn
mangle_internal_name_by_seq
(
&@
crate_ctxt
ccx
,
&
str
flav
)
->
str
{
ret
ccx
.names
.next
(
flav
);
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
src/comp/driver/session.rs
浏览文件 @
721c5bbe
...
...
@@ -6,6 +6,9 @@
import
std
::
term
;
import
std
::
io
;
import
std
::
map
;
import
std
::
option
;
import
std
::
option
::
some
;
import
std
::
option
::
none
;
tag
os
{
os_win32
;
...
...
@@ -48,9 +51,16 @@ fn span_to_str(span sp, codemap::codemap cm) -> str {
lo
.col
,
hi
.line
,
hi
.col
));
}
fn
emit_diagnostic
(
span
sp
,
str
msg
,
str
kind
,
u8
color
,
fn
emit_diagnostic
(
option
::
t
[
span
]
sp
,
str
msg
,
str
kind
,
u8
color
,
codemap
::
codemap
cm
)
{
io
::
stdout
()
.write_str
(
span_to_str
(
sp
,
cm
)
+
": "
);
auto
ss
=
"<input>:0:0:0:0"
;
alt
(
sp
)
{
case
(
some
(
?
ssp
))
{
ss
=
span_to_str
(
ssp
,
cm
);
}
case
(
none
)
{}
}
io
::
stdout
()
.write_str
(
ss
+
": "
);
if
(
term
::
color_supported
())
{
term
::
fg
(
io
::
stdout
()
.get_buf_writer
(),
color
);
...
...
@@ -85,12 +95,12 @@ fn get_targ_crate_num() -> ast::crate_num {
fn
span_err
(
span
sp
,
str
msg
)
->
!
{
// FIXME: Use constants, but rustboot doesn't know how to export them.
emit_diagnostic
(
s
p
,
msg
,
"error"
,
9u8
,
cm
);
emit_diagnostic
(
s
ome
(
sp
)
,
msg
,
"error"
,
9u8
,
cm
);
fail
;
}
fn
err
(
str
msg
)
->
!
{
log_err
#
fmt
(
"error: %s"
,
msg
);
emit_diagnostic
(
none
[
span
],
msg
,
"error"
,
9u8
,
cm
);
fail
;
}
...
...
@@ -103,29 +113,32 @@ fn get_metadata() -> vec[@ast::meta_item] {
fn
span_warn
(
span
sp
,
str
msg
)
{
// FIXME: Use constants, but rustboot doesn't know how to export them.
emit_diagnostic
(
sp
,
msg
,
"warning"
,
11u8
,
cm
);
emit_diagnostic
(
some
(
sp
),
msg
,
"warning"
,
11u8
,
cm
);
}
fn
warn
(
str
msg
)
{
emit_diagnostic
(
none
[
span
],
msg
,
"warning"
,
11u8
,
cm
);
}
fn
span_note
(
span
sp
,
str
msg
)
{
// FIXME: Use constants, but rustboot doesn't know how to export them.
emit_diagnostic
(
sp
,
msg
,
"note"
,
10u8
,
cm
);
emit_diagnostic
(
some
(
sp
),
msg
,
"note"
,
10u8
,
cm
);
}
fn
span_bug
(
span
sp
,
str
msg
)
->
!
{
self
.span_err
(
sp
,
#
fmt
(
"internal compiler error %s"
,
msg
));
}
fn
bug
(
str
msg
)
->
!
{
log_err
#
fmt
(
"error: internal compiler error %s"
,
msg
);
fail
;
self
.err
(
#
fmt
(
"internal compiler error %s"
,
msg
));
}
fn
span_unimpl
(
span
sp
,
str
msg
)
->
!
{
// FIXME: Use constants, but rustboot doesn't know how to export them.
emit_diagnostic
(
sp
,
"internal compiler error: unimplemented "
+
msg
,
"error"
,
9u8
,
cm
);
fail
;
self
.span_bug
(
sp
,
"unimplemented "
+
msg
);
}
fn
unimpl
(
str
msg
)
->
!
{
log_err
#
fmt
(
"error: unimplemented %s"
,
msg
);
fail
;
self
.bug
(
"unimplemented "
+
msg
);
}
fn
get_external_crate
(
int
num
)
->
crate_metadata
{
...
...
src/comp/front/ast.rs
浏览文件 @
721c5bbe
...
...
@@ -71,6 +71,11 @@ fn def_id_of_def(def d) -> def_id {
type
crate_
=
rec
(
vec
[
@
crate_directive
]
directives
,
_
mod
module
);
tag
meta_visibility
{
export_meta
;
local_meta
;
}
tag
crate_directive_
{
cdir_expr
(
@
expr
);
// FIXME: cdir_let should be eliminated
...
...
@@ -80,7 +85,7 @@ fn def_id_of_def(def d) -> def_id {
cdir_src_mod
(
ident
,
option
::
t
[
filename
]);
cdir_dir_mod
(
ident
,
option
::
t
[
filename
],
vec
[
@
crate_directive
]);
cdir_view_item
(
@
view_item
);
cdir_meta
(
vec
[
@
meta_item
]);
cdir_meta
(
meta_visibility
,
vec
[
@
meta_item
]);
cdir_syntax
(
path
);
cdir_auth
(
path
,
_
auth
);
}
...
...
src/comp/front/eval.rs
浏览文件 @
721c5bbe
...
...
@@ -418,8 +418,13 @@ fn eval_crate_directive(ctx cx,
vec
::
push
[
@
ast
::
view_item
](
view_items
,
vi
);
}
case
(
ast
::
cdir_meta
(
?
mi
))
{
cx
.sess
.add_metadata
(
mi
);
case
(
ast
::
cdir_meta
(
?
vi
,
?
mi
))
{
// FIXME: we should actually record, for documentation-sake,
// the metadata that's not exported. It would be nice to have
// compiled-in to the target crate, not just in theh AST.
if
(
vi
==
ast
::
export_meta
)
{
cx
.sess
.add_metadata
(
mi
);
}
}
case
(
ast
::
cdir_syntax
(
?
pth
))
{}
...
...
src/comp/front/parser.rs
浏览文件 @
721c5bbe
...
...
@@ -2362,10 +2362,14 @@ fn parse_crate_directive(&parser p) -> ast::crate_directive
expect
(
p
,
token
::
SEMI
);
ret
spanned
(
lo
,
hi
,
ast
::
cdir_auth
(
n
,
a
));
}
else
if
(
eat_word
(
p
,
"meta"
))
{
auto
mv
=
ast
::
local_meta
;
if
(
eat_word
(
p
,
"export"
))
{
mv
=
ast
::
export_meta
;
}
auto
mis
=
parse_meta
(
p
);
auto
hi
=
p
.get_hi_pos
();
expect
(
p
,
token
::
SEMI
);
ret
spanned
(
lo
,
hi
,
ast
::
cdir_meta
(
mis
));
ret
spanned
(
lo
,
hi
,
ast
::
cdir_meta
(
m
v
,
m
is
));
}
else
if
(
eat_word
(
p
,
"mod"
))
{
auto
id
=
parse_ident
(
p
);
auto
file_opt
=
none
[
filename
];
...
...
src/comp/middle/trans.rs
浏览文件 @
721c5bbe
...
...
@@ -6,7 +6,7 @@
// particular definition to the LLVM IR output we're producing.
//
// Hopefully useful general knowledge about trans:
//
//
// * There's no way to find out the ty::t type of a ValueRef. Doing so
// would be "trying to get the eggs out of an omelette" (credit:
// pcwalton). You can, instead, find out its TypeRef by calling val_ty,
...
...
@@ -24,6 +24,7 @@
import
std
::
option
;
import
std
::
option
::
some
;
import
std
::
option
::
none
;
import
std
::
fs
;
import
front
::
ast
;
import
front
::
creader
;
...
...
@@ -62,6 +63,15 @@
import
lib
::
llvm
::
True
;
import
lib
::
llvm
::
Bool
;
import
link
::
mangle_internal_name_by_type_only
;
import
link
::
mangle_internal_name_by_seq
;
import
link
::
mangle_internal_name_by_path
;
import
link
::
mangle_internal_name_by_path_and_seq
;
import
link
::
mangle_exported_name
;
import
link
::
crate_meta_name
;
import
link
::
crate_meta_vers
;
import
link
::
crate_meta_extras_hash
;
state
obj
namegen
(
mutable
int
i
)
{
fn
next
(
str
prefix
)
->
str
{
i
+=
1
;
...
...
@@ -119,6 +129,9 @@ fn next(str prefix) -> str {
@
ast
::
native_item
]
native_items
,
hashmap
[
ast
::
def_id
,
str
]
item_symbols
,
mutable
option
::
t
[
ValueRef
]
main_fn
,
str
crate_meta_name
,
str
crate_meta_vers
,
str
crate_meta_extras_hash
,
// TODO: hashmap[tup(tag_id,subtys), @tag_info]
hashmap
[
ty
::
t
,
uint
]
tag_sizes
,
hashmap
[
ast
::
def_id
,
ValueRef
]
discrims
,
...
...
@@ -166,14 +179,14 @@ fn next(str prefix) -> str {
ValueRef
lltaskptr
,
ValueRef
llenv
,
ValueRef
llretptr
,
// The next three elements: "hoisted basic blocks" containing
// administrative activities that have to happen in only one place in the
// function, due to LLVM's quirks.
// A block for all the function's allocas, so that LLVM will coalesce them
// into a single alloca call.
mutable
BasicBlockRef
llallocas
,
mutable
BasicBlockRef
llallocas
,
// A block containing code that copies incoming arguments to space already
// allocated by code in the llallocas block. (LLVM requires that
...
...
@@ -313,73 +326,6 @@ fn extend_path(@local_ctxt cx, &str name) -> @local_ctxt {
ret
@
rec
(
path
=
cx
.path
+
[
name
]
with
*
cx
);
}
fn
get_type_sha1
(
&@
crate_ctxt
ccx
,
&
ty
::
t
t
)
->
str
{
auto
hash
=
""
;
alt
(
ccx
.type_sha1s
.find
(
t
))
{
case
(
some
(
?
h
))
{
hash
=
h
;
}
case
(
none
)
{
ccx
.sha
.reset
();
auto
f
=
metadata
::
def_to_str
;
// NB: do *not* use abbrevs here as we want the symbol names
// to be independent of one another in the crate.
auto
cx
=
@
rec
(
ds
=
f
,
tcx
=
ccx
.tcx
,
abbrevs
=
metadata
::
ac_no_abbrevs
);
ccx
.sha
.input_str
(
metadata
::
Encode
::
ty_str
(
cx
,
t
));
hash
=
str
::
substr
(
ccx
.sha
.result_str
(),
0u
,
16u
);
// Prefix with _ so that it never blends into adjacent digits
hash
=
"_"
+
hash
;
ccx
.type_sha1s
.insert
(
t
,
hash
);
}
}
ret
hash
;
}
fn
mangle
(
&
vec
[
str
]
ss
)
->
str
{
if
(
vec
::
len
(
ss
)
>
0u
&&
str
::
eq
(
vec
::
top
(
ss
),
"main"
))
{
ret
"_rust_main"
;
}
// Follow C++ namespace-mangling style
auto
n
=
"_ZN"
;
// Begin name-sequence.
for
(
str
s
in
ss
)
{
n
+=
#
fmt
(
"%u%s"
,
str
::
byte_len
(
s
),
s
);
}
n
+=
"E"
;
// End name-sequence.
ret
n
;
}
fn
mangle_name_by_type
(
&@
crate_ctxt
ccx
,
&
vec
[
str
]
path
,
&
ty
::
t
t
)
->
str
{
auto
hash
=
get_type_sha1
(
ccx
,
t
);
ret
mangle
(
path
+
[
hash
]);
}
fn
mangle_name_by_type_only
(
&@
crate_ctxt
ccx
,
&
ty
::
t
t
,
&
str
name
)
->
str
{
auto
f
=
metadata
::
def_to_str
;
auto
cx
=
@
rec
(
ds
=
f
,
tcx
=
ccx
.tcx
,
abbrevs
=
metadata
::
ac_no_abbrevs
);
auto
s
=
ty
::
ty_to_short_str
(
ccx
.tcx
,
t
);
auto
hash
=
get_type_sha1
(
ccx
,
t
);
ret
mangle
([
name
,
s
,
hash
]);
}
fn
mangle_name_by_path_and_seq
(
&@
crate_ctxt
ccx
,
&
vec
[
str
]
path
,
&
str
flav
)
->
str
{
ret
mangle
(
path
+
[
ccx
.names
.next
(
flav
)]);
}
fn
mangle_name_by_path
(
&
vec
[
str
]
path
)
->
str
{
ret
mangle
(
path
);
}
fn
mangle_name_by_seq
(
&@
crate_ctxt
ccx
,
&
str
flav
)
->
str
{
ret
ccx
.names
.next
(
flav
);
}
fn
res
(
@
block_ctxt
bcx
,
ValueRef
val
)
->
result
{
ret
rec
(
bcx
=
bcx
,
val
=
val
);
...
...
@@ -1917,10 +1863,10 @@ fn declare_tydesc(&@local_ctxt cx, &span sp, &ty::t t,
auto
name
;
if
(
cx
.ccx.sess
.get_opts
()
.debuginfo
)
{
name
=
mangle_name_by_type_only
(
cx
.ccx
,
t
,
"tydesc"
);
name
=
mangle_
internal_
name_by_type_only
(
cx
.ccx
,
t
,
"tydesc"
);
name
=
sanitize
(
name
);
}
else
{
name
=
mangle_name_by_seq
(
cx
.ccx
,
"tydesc"
);
name
=
mangle_
internal_
name_by_seq
(
cx
.ccx
,
"tydesc"
);
}
auto
gvar
=
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
T_tydesc
(
ccx
.tn
),
...
...
@@ -1951,10 +1897,12 @@ fn declare_generic_glue(&@local_ctxt cx,
&
str
name
)
->
ValueRef
{
auto
fn_nm
;
if
(
cx
.ccx.sess
.get_opts
()
.debuginfo
)
{
fn_nm
=
mangle_name_by_type_only
(
cx
.ccx
,
t
,
"glue_"
+
name
);
fn_nm
=
mangle_internal_name_by_type_only
(
cx
.ccx
,
t
,
"glue_"
+
name
);
fn_nm
=
sanitize
(
fn_nm
);
}
else
{
fn_nm
=
mangle_name_by_seq
(
cx
.ccx
,
"glue_"
+
name
);
fn_nm
=
mangle_internal_name_by_seq
(
cx
.ccx
,
"glue_"
+
name
);
}
auto
llfn
=
decl_fastcall_fn
(
cx
.ccx.llmod
,
fn_nm
,
llfnty
);
set_glue_inlining
(
cx
,
llfn
,
t
);
...
...
@@ -4106,7 +4054,8 @@ fn trans_for_each(&@block_ctxt cx,
// Step 2: Declare foreach body function.
let
str
s
=
mangle_name_by_path_and_seq
(
lcx
.ccx
,
lcx
.path
,
"foreach"
);
let
str
s
=
mangle_internal_name_by_path_and_seq
(
lcx
.ccx
,
lcx
.path
,
"foreach"
);
// The 'env' arg entering the body function is a fake env member (as in
// the env-part of the normal rust calling convention) that actually
...
...
@@ -4805,7 +4754,8 @@ fn trans_bind_thunk(&@local_ctxt cx,
// Construct a thunk-call with signature incoming_fty, and that copies
// args forward into a call to outgoing_fty:
let
str
s
=
mangle_name_by_path_and_seq
(
cx
.ccx
,
cx
.path
,
"thunk"
);
let
str
s
=
mangle_internal_name_by_path_and_seq
(
cx
.ccx
,
cx
.path
,
"thunk"
);
let
TypeRef
llthunk_ty
=
get_pair_fn_ty
(
type_of
(
cx
.ccx
,
sp
,
incoming_fty
));
let
ValueRef
llthunk
=
decl_internal_fastcall_fn
(
cx
.ccx.llmod
,
...
...
@@ -5823,13 +5773,17 @@ fn load_if_immediate(&@block_ctxt cx, ValueRef v, &ty::t t) -> ValueRef {
fn
trans_log
(
int
lvl
,
&@
block_ctxt
cx
,
&@
ast
::
expr
e
)
->
result
{
auto
lcx
=
cx
.fcx.lcx
;
auto
modname
=
str
::
connect
(
lcx
.module_path
,
"::"
);
auto
modname
=
link
::
mangle_internal_name_by_path
(
lcx
.ccx
,
lcx
.module_path
);
auto
global
;
if
(
lcx
.ccx.module_data
.contains_key
(
modname
))
{
global
=
lcx
.ccx.module_data
.get
(
modname
);
}
else
{
global
=
llvm
::
LLVMAddGlobal
(
lcx
.ccx.llmod
,
T_int
(),
str
::
buf
(
"_rust_mod_log_"
+
modname
));
auto
s
=
link
::
mangle_internal_name_by_path_and_seq
(
lcx
.ccx
,
lcx
.module_path
,
"loglevel"
);
global
=
llvm
::
LLVMAddGlobal
(
lcx
.ccx.llmod
,
T_int
(),
str
::
buf
(
s
));
llvm
::
LLVMSetGlobalConstant
(
global
,
False
);
llvm
::
LLVMSetInitializer
(
global
,
C_null
(
T_int
()));
llvm
::
LLVMSetLinkage
(
global
,
lib
::
llvm
::
LLVMInternalLinkage
...
...
@@ -6225,8 +6179,8 @@ fn trans_spawn(&@block_ctxt cx,
ret
res
(
bcx
,
new_task
);
}
fn
mk_spawn_wrapper
(
&@
block_ctxt
cx
,
&@
ast
::
expr
func
,
fn
mk_spawn_wrapper
(
&@
block_ctxt
cx
,
&@
ast
::
expr
func
,
&
ty
::
t
args_ty
)
->
result
{
auto
llmod
=
cx
.fcx.lcx.ccx.llmod
;
let
TypeRef
args_ty_tref
=
type_of
(
cx
.fcx.lcx.ccx
,
cx
.sp
,
args_ty
);
...
...
@@ -6239,9 +6193,9 @@ fn mk_spawn_wrapper(&@block_ctxt cx,
// TODO: construct a name based on tname
let
str
wrap_name
=
mangle_name_by_path_and_seq
(
cx
.fcx.lcx.ccx
,
cx
.fcx.lcx.path
,
"spawn_wrapper"
);
mangle_
internal_
name_by_path_and_seq
(
cx
.fcx.lcx.ccx
,
cx
.fcx.lcx.path
,
"spawn_wrapper"
);
auto
llfndecl
=
decl_fastcall_fn
(
llmod
,
wrap_name
,
wrapper_fn_type
);
...
...
@@ -6252,7 +6206,7 @@ fn mk_spawn_wrapper(&@block_ctxt cx,
// 3u to skip the three implicit args
let
ValueRef
arg
=
llvm
::
LLVMGetParam
(
fcx
.llfn
,
3u
);
let
vec
[
ValueRef
]
child_args
=
let
vec
[
ValueRef
]
child_args
=
[
llvm
::
LLVMGetParam
(
fcx
.llfn
,
0u
),
llvm
::
LLVMGetParam
(
fcx
.llfn
,
1u
),
llvm
::
LLVMGetParam
(
fcx
.llfn
,
2u
)];
...
...
@@ -6271,19 +6225,19 @@ fn mk_spawn_wrapper(&@block_ctxt cx,
}
}
}
// Find the function
auto
fnptr
=
trans_lval
(
fbcx
,
func
)
.res
;
fbcx
=
fnptr
.bcx
;
auto
llfnptr
=
fbcx
.build
.GEP
(
fnptr
.val
,
[
C_int
(
0
),
C_int
(
0
)]);
auto
llfn
=
fbcx
.build
.Load
(
llfnptr
);
fbcx
.build
.FastCall
(
llfn
,
child_args
);
fbcx
.build
.RetVoid
();
finish_fn
(
fcx
,
fbcx
.llbb
);
// TODO: make sure we clean up everything we need to.
...
...
@@ -6719,7 +6673,7 @@ fn new_local_ctxt(&@crate_ctxt ccx) -> @local_ctxt {
let
vec
[
ast
::
ty_param
]
obj_typarams
=
[];
let
vec
[
ast
::
obj_field
]
obj_fields
=
[];
ret
@
rec
(
path
=
pth
,
module_path
=
[
c
rate_name
(
ccx
,
"main"
)
],
module_path
=
[
c
cx
.crate_meta_name
],
obj_typarams
=
obj_typarams
,
obj_fields
=
obj_fields
,
ccx
=
ccx
);
...
...
@@ -7094,7 +7048,7 @@ fn meth_lteq(&@ast::method a, &@ast::method b) -> bool {
let
@
local_ctxt
mcx
=
@
rec
(
path
=
cx
.path
+
[
"method"
,
m
.node.ident
]
with
*
cx
);
let
str
s
=
mangle_
name_by_path
(
mcx
.path
);
let
str
s
=
mangle_
internal_name_by_path
(
mcx
.ccx
,
mcx
.path
);
let
ValueRef
llfn
=
decl_internal_fastcall_fn
(
cx
.ccx.llmod
,
s
,
llfnty
);
cx
.ccx.item_ids
.insert
(
m
.node.id
,
llfn
);
...
...
@@ -7106,7 +7060,8 @@ fn meth_lteq(&@ast::method a, &@ast::method b) -> bool {
methods
+=
[
llfn
];
}
auto
vtbl
=
C_struct
(
methods
);
auto
vtbl_name
=
mangle_name_by_path
(
cx
.path
+
[
"vtbl"
]);
auto
vtbl_name
=
mangle_internal_name_by_path
(
cx
.ccx
,
cx
.path
+
[
"vtbl"
]);
auto
gvar
=
llvm
::
LLVMAddGlobal
(
cx
.ccx.llmod
,
val_ty
(
vtbl
),
str
::
buf
(
vtbl_name
));
llvm
::
LLVMSetInitializer
(
gvar
,
vtbl
);
...
...
@@ -7123,7 +7078,7 @@ fn trans_dtor(@local_ctxt cx,
&@
ast
::
method
dtor
)
->
ValueRef
{
auto
llfnty
=
T_dtor
(
cx
.ccx
,
dtor
.span
,
llself_ty
);
let
str
s
=
mangle_
name_by_path
(
cx
.path
+
[
"drop"
]);
let
str
s
=
mangle_
internal_name_by_path
(
cx
.ccx
,
cx
.path
+
[
"drop"
]);
let
ValueRef
llfn
=
decl_internal_fastcall_fn
(
cx
.ccx.llmod
,
s
,
llfnty
);
cx
.ccx.item_ids
.insert
(
dtor
.node.id
,
llfn
);
cx
.ccx.item_symbols
.insert
(
dtor
.node.id
,
s
);
...
...
@@ -7516,25 +7471,29 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
}
}
let
bool
is_main
=
(
str
::
eq
(
vec
::
top
(
path
),
"main"
)
&&
!
ccx
.sess
.get_opts
()
.shared
);
// Declare the function itself.
let
str
s
=
mangle_name_by_path
(
path
);
let
str
s
=
if
(
is_main
)
{
"_rust_main"
}
else
{
mangle_internal_name_by_path
(
ccx
,
path
)
};
let
ValueRef
llfn
=
decl_internal_fastcall_fn
(
ccx
.llmod
,
s
,
llfty
);
// Declare the global constant pair that points to it.
let
str
ps
=
mangle_name_by_type
(
ccx
,
path
,
node_ann_type
(
ccx
,
ann
));
let
str
ps
=
mangle_exported_name
(
ccx
,
path
,
node_ann_type
(
ccx
,
ann
));
register_fn_pair
(
ccx
,
ps
,
llpairty
,
llfn
,
id
);
if
(
str
::
eq
(
vec
::
top
(
path
),
"main"
)
&&
!
ccx
.sess
.get_opts
()
.shared
)
{
if
(
is_main
)
{
if
(
ccx
.main_fn
!=
none
[
ValueRef
])
{
ccx
.sess
.span_err
(
sp
,
"multiple 'main' functions"
);
}
log
#
fmt
(
"registering %s as main function for crate"
,
ps
);
llvm
::
LLVMSetLinkage
(
llfn
,
lib
::
llvm
::
LLVMExternalLinkage
as
llvm
::
Linkage
);
ccx
.main_fn
=
some
(
llfn
);
}
}
fn
register_fn_pair
(
&@
crate_ctxt
cx
,
str
ps
,
TypeRef
llpairty
,
ValueRef
llfn
,
...
...
@@ -7565,7 +7524,7 @@ fn native_fn_ty_param_count(&@crate_ctxt cx, &ast::def_id id) -> uint {
alt
(
native_item
.node
)
{
case
(
ast
::
native_item_ty
(
_
,
_
))
{
cx
.sess
.bug
(
"decl_native_fn_and_pair(): native fn isn't "
+
"actually a fn
?!
"
);
"actually a fn"
);
}
case
(
ast
::
native_item_fn
(
_
,
_
,
_
,
?
tps
,
_
,
_
))
{
count
=
vec
::
len
[
ast
::
ty_param
](
tps
);
...
...
@@ -7594,13 +7553,13 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx,
// Declare the wrapper.
auto
t
=
node_ann_type
(
ccx
,
ann
);
auto
wrapper_type
=
native_fn_wrapper_type
(
ccx
,
sp
,
num_ty_param
,
t
);
let
str
s
=
mangle_
name_by_path
(
path
);
let
str
s
=
mangle_
internal_name_by_path
(
ccx
,
path
);
let
ValueRef
wrapper_fn
=
decl_internal_fastcall_fn
(
ccx
.llmod
,
s
,
wrapper_type
);
// Declare the global constant pair that points to it.
auto
wrapper_pair_type
=
T_fn_pair
(
ccx
.tn
,
wrapper_type
);
let
str
ps
=
mangle_
name_by_typ
e
(
ccx
,
path
,
node_ann_type
(
ccx
,
ann
));
let
str
ps
=
mangle_
exported_nam
e
(
ccx
,
path
,
node_ann_type
(
ccx
,
ann
));
register_fn_pair
(
ccx
,
ps
,
wrapper_pair_type
,
wrapper_fn
,
id
);
...
...
@@ -7938,7 +7897,7 @@ fn trans_constant(&@crate_ctxt ccx, @walk_ctxt wcx, &@ast::item it) {
auto
discrim_val
=
C_int
(
i
as
int
);
auto
p
=
wcx
.path
+
[
ident
,
variant
.node.name
,
"discrim"
];
auto
s
=
mangle_
name_by_typ
e
(
ccx
,
p
,
ty
::
mk_int
(
ccx
.tcx
));
auto
s
=
mangle_
exported_nam
e
(
ccx
,
p
,
ty
::
mk_int
(
ccx
.tcx
));
auto
discrim_gvar
=
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
T_int
(),
str
::
buf
(
s
));
...
...
@@ -7957,8 +7916,8 @@ fn trans_constant(&@crate_ctxt ccx, @walk_ctxt wcx, &@ast::item it) {
// with consts.
auto
v
=
C_int
(
1
);
ccx
.item_ids
.insert
(
cid
,
v
);
auto
s
=
mangle_
name_by_typ
e
(
ccx
,
wcx
.path
+
[
name
],
node_ann_type
(
ccx
,
ann
));
auto
s
=
mangle_
exported_nam
e
(
ccx
,
wcx
.path
+
[
name
],
node_ann_type
(
ccx
,
ann
));
ccx
.item_symbols
.insert
(
cid
,
s
);
}
...
...
@@ -8178,15 +8137,6 @@ fn create_module_map(&@crate_ctxt ccx) -> ValueRef {
ret
map
;
}
fn
crate_name
(
&@
crate_ctxt
ccx
,
&
str
deflt
)
->
str
{
for
(
@
ast
::
meta_item
item
in
ccx
.sess
.get_metadata
())
{
if
(
str
::
eq
(
item
.node.name
,
"name"
))
{
ret
item
.node.value
;
}
}
ret
deflt
;
}
// FIXME use hashed metadata instead of crate names once we have that
fn
create_crate_map
(
&@
crate_ctxt
ccx
)
->
ValueRef
{
let
vec
[
ValueRef
]
subcrates
=
[];
...
...
@@ -8199,10 +8149,9 @@ fn create_crate_map(&@crate_ctxt ccx) -> ValueRef {
i
+=
1
;
}
vec
::
push
[
ValueRef
](
subcrates
,
C_int
(
0
));
auto
cname
=
crate_name
(
ccx
,
"__none__"
);
auto
mapname
;
if
(
ccx
.sess
.get_opts
()
.shared
)
{
mapname
=
cname
;
mapname
=
c
cx
.crate_meta_
name
;
}
else
{
mapname
=
"toplevel"
;
}
...
...
@@ -8240,7 +8189,7 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
auto
sha1s
=
map
::
mk_hashmap
[
ty
::
t
,
str
](
hasher
,
eqer
);
auto
abbrevs
=
map
::
mk_hashmap
[
ty
::
t
,
metadata
::
ty_abbrev
](
hasher
,
eqer
);
auto
short_names
=
map
::
mk_hashmap
[
ty
::
t
,
str
](
hasher
,
eqer
);
auto
sha
=
std
::
sha1
::
mk_sha1
();
auto
ccx
=
@
rec
(
sess
=
sess
,
llmod
=
llmod
,
td
=
td
,
...
...
@@ -8252,6 +8201,10 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
native_items
=
new_def_hash
[
@
ast
::
native_item
](),
item_symbols
=
new_def_hash
[
str
](),
mutable
main_fn
=
none
[
ValueRef
],
crate_meta_name
=
crate_meta_name
(
sess
,
*
crate
,
output
),
crate_meta_vers
=
crate_meta_vers
(
sess
,
*
crate
),
crate_meta_extras_hash
=
crate_meta_extras_hash
(
sha
,
*
crate
),
tag_sizes
=
tag_sizes
,
discrims
=
new_def_hash
[
ValueRef
](),
discrim_symbols
=
new_def_hash
[
str
](),
...
...
@@ -8263,7 +8216,7 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
lltypes
=
lltypes
,
glues
=
glues
,
names
=
namegen
(
0
),
sha
=
s
td
::
sha1
::
mk_sha1
()
,
sha
=
s
ha
,
type_sha1s
=
sha1s
,
type_abbrevs
=
abbrevs
,
type_short_names
=
short_names
,
...
...
src/comp/middle/walk.rs
浏览文件 @
721c5bbe
...
...
@@ -68,7 +68,7 @@ fn walk_crate_directive(&ast_visitor v, @ast::crate_directive cd) {
case
(
ast
::
cdir_view_item
(
?
vi
))
{
walk_view_item
(
v
,
vi
);
}
case
(
ast
::
cdir_meta
(
_
))
{}
case
(
ast
::
cdir_meta
(
_
,
_
))
{}
case
(
ast
::
cdir_syntax
(
_
))
{}
case
(
ast
::
cdir_auth
(
_
,
_
))
{}
}
...
...
src/lib/fs.rs
浏览文件 @
721c5bbe
...
...
@@ -19,6 +19,20 @@ fn dirname(path p) -> path {
ret
str
::
substr
(
p
,
0u
,
i
as
uint
);
}
fn
basename
(
path
p
)
->
path
{
let
int
i
=
str
::
rindex
(
p
,
os_fs
::
path_sep
as
u8
);
if
(
i
==
-
1
)
{
i
=
str
::
rindex
(
p
,
os_fs
::
alt_path_sep
as
u8
);
if
(
i
==
-
1
)
{
ret
p
;
}
}
auto
len
=
str
::
byte_len
(
p
);
if
((
i
+
1
)
as
uint
>=
len
)
{
ret
p
;
}
ret
str
::
slice
(
p
,
i
+
1
as
uint
,
len
);
}
// FIXME: Need some typestate to avoid bounds check when len(pre) == 0
fn
connect
(
path
pre
,
path
post
)
->
path
{
auto
len
=
str
::
byte_len
(
pre
);
...
...
src/lib/std.rc
浏览文件 @
721c5bbe
meta (name = "std",
desc = "Rust standard library
",
vers = "0.1
",
uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
url = "http://rust-lang.org/src/std",
ver = "0.0.1");
url = "http://rust-lang.org/src/std");
meta (comment = "Rust standard library",
license = "BSD");
// Built-in types support modules.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录