Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
053b8bff
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
053b8bff
编写于
8月 12, 2011
作者:
B
Brian Anderson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Accept main(args: [str]) as main signature
上级
76aab80e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
221 addition
and
19 deletion
+221
-19
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+136
-11
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+8
-0
src/rt/main.ll.in
src/rt/main.ll.in
+29
-4
src/rt/rust.cpp
src/rt/rust.cpp
+44
-4
src/rt/rustrt.def.in
src/rt/rustrt.def.in
+1
-0
src/test/run-pass/main-ivec.rs
src/test/run-pass/main-ivec.rs
+3
-0
未找到文件。
src/comp/middle/trans.rs
浏览文件 @
053b8bff
...
...
@@ -6345,28 +6345,153 @@ fn decl_fn_and_pair_full(ccx: &@crate_ctxt, sp: &span, path: &[str],
}
_
{
ccx
.sess
.bug
(
"decl_fn_and_pair(): fn item doesn't have fn type!"
);
}
}
let
is_main
:
bool
=
is_main_name
(
path
)
&&
!
ccx
.sess
.get_opts
()
.library
;
// Declare the function itself.
let
s
:
str
=
if
is_main
{
"_rust_main"
}
else
{
mangle_internal_name_by_path
(
ccx
,
path
)
};
let
s
:
str
=
mangle_internal_name_by_path
(
ccx
,
path
);
let
llfn
:
ValueRef
=
decl_internal_fastcall_fn
(
ccx
.llmod
,
s
,
llfty
);
// Declare the global constant pair that points to it.
let
ps
:
str
=
mangle_exported_name
(
ccx
,
path
,
node_type
);
register_fn_pair
(
ccx
,
ps
,
llfty
,
llfn
,
node_id
);
let
is_main
:
bool
=
is_main_name
(
path
)
&&
!
ccx
.sess
.get_opts
()
.library
;
if
is_main
{
if
ccx
.main_fn
!=
none
[
ValueRef
]
{
ccx
.sess
.span_fatal
(
sp
,
"multiple 'main' functions"
);
create_main_wrapper
(
ccx
,
sp
,
llfn
,
node_type
);
}
}
fn
create_main_wrapper
(
ccx
:
&@
crate_ctxt
,
sp
:
&
span
,
main_llfn
:
ValueRef
,
main_node_type
:
ty
::
t
)
{
if
ccx
.main_fn
!=
none
[
ValueRef
]
{
ccx
.sess
.span_fatal
(
sp
,
"multiple 'main' functions"
);
}
tag
main_mode
{
mm_nil
;
mm_vec
;
mm_ivec
;
};
let
main_mode
=
alt
ty
::
struct
(
ccx
.tcx
,
main_node_type
)
{
ty
::
ty_fn
(
_
,
args
,
_
,
_
,
_
)
{
if
std
::
ivec
::
len
(
args
)
==
0u
{
mm_nil
}
else
{
alt
ty
::
struct
(
ccx
.tcx
,
args
.
(
0
)
.ty
)
{
ty
::
ty_ivec
(
_
)
{
mm_ivec
}
ty
::
ty_vec
(
_
)
{
mm_vec
}
}
}
llvm
::
LLVMSetLinkage
(
llfn
,
lib
::
llvm
::
LLVMExternalLinkage
as
llvm
::
Linkage
);
ccx
.main_fn
=
some
(
llfn
);
}
};
// Have to create two different main functions depending on whether
// main was declared to take vec or ivec
let
llfn_vec
=
create_main_wrapper_vec
(
ccx
,
sp
,
main_llfn
,
main_mode
);
let
llfn_ivec
=
create_main_wrapper_ivec
(
ccx
,
sp
,
main_llfn
,
main_mode
);
let
takes_ivec
=
main_mode
==
mm_ivec
;
// Create a global to tell main.ll which main we want to use
create_main_type_indicator
(
ccx
,
takes_ivec
);
ccx
.main_fn
=
takes_ivec
?
some
(
llfn_ivec
)
:
some
(
llfn_vec
);
fn
create_main_wrapper_vec
(
ccx
:
&@
crate_ctxt
,
sp
:
&
span
,
main_llfn
:
ValueRef
,
main_mode
:
main_mode
)
->
ValueRef
{
let
vecarg
=
{
mode
:
ty
::
mo_val
,
ty
:
ty
::
mk_vec
(
ccx
.tcx
,
{
ty
:
ty
::
mk_str
(
ccx
.tcx
),
mut
:
ast
::
imm
})
};
let
llfty
=
type_of_fn
(
ccx
,
sp
,
ast
::
proto_fn
,
~
[
vecarg
],
ty
::
mk_nil
(
ccx
.tcx
),
0u
);
let
llfdecl
=
decl_fastcall_fn
(
ccx
.llmod
,
"_rust_main"
,
llfty
);
let
fcx
=
new_fn_ctxt
(
new_local_ctxt
(
ccx
),
sp
,
llfdecl
);
let
bcx
=
new_top_block_ctxt
(
fcx
);
if
main_mode
!=
mm_ivec
{
let
lloutputarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
0u
);
let
lltaskarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
1u
);
let
llenvarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
2u
);
let
llargvarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
3u
);
let
args
=
alt
main_mode
{
mm_nil
.
{
~
[
lloutputarg
,
lltaskarg
,
llenvarg
]
}
mm_vec
.
{
~
[
lloutputarg
,
lltaskarg
,
llenvarg
,
llargvarg
]
}
};
bcx
.build
.FastCall
(
main_llfn
,
args
);
}
bcx
.build
.RetVoid
();
let
lltop
=
bcx
.llbb
;
finish_fn
(
fcx
,
lltop
);
ret
llfdecl
;
}
fn
create_main_wrapper_ivec
(
ccx
:
&@
crate_ctxt
,
sp
:
&
span
,
main_llfn
:
ValueRef
,
main_mode
:
main_mode
)
->
ValueRef
{
let
ivecarg
=
{
mode
:
ty
::
mo_val
,
ty
:
ty
::
mk_ivec
(
ccx
.tcx
,
{
ty
:
ty
::
mk_str
(
ccx
.tcx
),
mut
:
ast
::
imm
})
};
let
llfty
=
type_of_fn
(
ccx
,
sp
,
ast
::
proto_fn
,
~
[
ivecarg
],
ty
::
mk_nil
(
ccx
.tcx
),
0u
);
let
llfdecl
=
decl_fastcall_fn
(
ccx
.llmod
,
"_rust_main_ivec"
,
llfty
);
let
fcx
=
new_fn_ctxt
(
new_local_ctxt
(
ccx
),
sp
,
llfdecl
);
let
bcx
=
new_top_block_ctxt
(
fcx
);
if
main_mode
==
mm_ivec
{
let
lloutputarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
0u
);
let
lltaskarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
1u
);
let
llenvarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
2u
);
let
llargvarg
=
llvm
::
LLVMGetParam
(
llfdecl
,
3u
);
let
args
=
~
[
lloutputarg
,
lltaskarg
,
llenvarg
,
llargvarg
];
bcx
.build
.FastCall
(
main_llfn
,
args
);
}
bcx
.build
.RetVoid
();
let
lltop
=
bcx
.llbb
;
finish_fn
(
fcx
,
lltop
);
ret
llfdecl
;
}
// FIXME: Remove after main takes only ivec
// Sets a global value hinting to the runtime whether main takes
// a vec or an ivec
fn
create_main_type_indicator
(
ccx
:
&@
crate_ctxt
,
takes_ivec
:
bool
)
{
let
i
=
llvm
::
LLVMAddGlobal
(
ccx
.llmod
,
T_int
(),
str
::
buf
(
"_rust_main_is_ivec"
));
llvm
::
LLVMSetInitializer
(
i
,
C_int
(
takes_ivec
as
int
));
llvm
::
LLVMSetGlobalConstant
(
i
,
True
);
}
}
// Create a closure: a pair containing (1) a ValueRef, pointing to where the
// fn's definition is in the executable we're creating, and (2) a pointer to
// space for the function's environment.
...
...
src/comp/middle/typeck.rs
浏览文件 @
053b8bff
...
...
@@ -2715,6 +2715,7 @@ fn check_item(ccx: @crate_ctxt, it: &@ast::item) {
fn
arg_is_argv_ty
(
tcx
:
&
ty
::
ctxt
,
a
:
&
ty
::
arg
)
->
bool
{
alt
ty
::
struct
(
tcx
,
a
.ty
)
{
// FIXME: Remove after main takes only ivec
ty
::
ty_vec
(
mt
)
{
if
mt
.mut
!=
ast
::
imm
{
ret
false
;
}
alt
ty
::
struct
(
tcx
,
mt
.ty
)
{
...
...
@@ -2722,6 +2723,13 @@ fn arg_is_argv_ty(tcx: &ty::ctxt, a: &ty::arg) -> bool {
_
{
ret
false
;
}
}
}
ty
::
ty_ivec
(
mt
)
{
if
mt
.mut
!=
ast
::
imm
{
ret
false
;
}
alt
ty
::
struct
(
tcx
,
mt
.ty
)
{
ty
::
ty_str
.
{
ret
true
;
}
_
{
ret
false
;
}
}
}
_
{
ret
false
;
}
}
}
...
...
src/rt/main.ll.in
浏览文件 @
053b8bff
...
...
@@ -6,15 +6,20 @@
%5 = type { i32, i32, i32, i32, [0 x %6*] }
%6 = type { i32, i32, i32, i32, [0 x i8] }
%tydesc = type { %tydesc**, i32, i32, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*, i8*, i8)* }
%task = type { i32, i32, i32, i32, i32, i32, i32, i32 }
%ivec = type { i32, i32, [4 x { i32, i32, i32, i32, [0 x i8] }*] }
@_rust_crate_map_toplevel = external global %0
declare fastcc void @_rust_main(i1* nocapture, %task*, %2* nocapture, %5*);
declare i32 @rust_start(i32, i32, i32, i32)
; FIXME: Remove after main takes only ivec
@_rust_main_is_ivec = external global i32
%tydesc = type { %tydesc**, i32, i32, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*, i8*, i8)* }
declare i32 @rust_start(i32, i32, i32, i32)
%task = type { i32, i32, i32, i32, i32, i32, i32, i32 }
declare external fastcc void @_rust_main(i1* nocapture, %task*, %2* nocapture, %5*);
define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %5 *)
{
...
...
@@ -22,7 +27,27 @@ define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %5 *)
ret void
}
declare i32 @rust_start_ivec(i32, i32, i32, i32, i32)
declare external fastcc void @_rust_main_ivec(i1* nocapture, %task*, %2* nocapture, %ivec)
define void @_rust_main_wrap_ivec(i1* nocapture, %task *, %2* nocapture, %ivec *)
{
%ivec = load %ivec *%3
tail call fastcc void @_rust_main_ivec(i1* %0, %task *%1, %2* nocapture %2, %ivec %ivec)
ret void
}
define i32 @"MAIN"(i32, i32) {
%is_ivec = load i32 *@_rust_main_is_ivec
%is_ivec1 = trunc i32 %is_ivec to i1
br i1 %is_ivec1, label %ivec, label %evec
evec:
%3 = tail call i32 @rust_start(i32 ptrtoint (void (i1*, %task*, %2*, %5*)* @_rust_main_wrap to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32))
ret i32 %3
ivec:
%4 = tail call i32 @rust_start_ivec(i32 ptrtoint (void (i1*, %task*, %2*, %ivec*)* @_rust_main_wrap_ivec to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32), i32 %is_ivec)
ret i32 %4
}
src/rt/rust.cpp
浏览文件 @
053b8bff
...
...
@@ -10,10 +10,12 @@ command_line_args : public kernel_owned<command_line_args>
// vec[str] passed to rust_task::start.
rust_vec
*
args
;
rust_ivec
*
args_ivec
;
command_line_args
(
rust_task
*
task
,
int
sys_argc
,
char
**
sys_argv
)
char
**
sys_argv
,
bool
main_is_ivec
)
:
kernel
(
task
->
kernel
),
task
(
task
),
argc
(
sys_argc
),
...
...
@@ -49,15 +51,39 @@ command_line_args : public kernel_owned<command_line_args>
mem
=
kernel
->
malloc
(
str_alloc
,
"command line arg"
);
strs
[
i
]
=
new
(
mem
)
rust_str
(
str_alloc
,
str_fill
,
(
uint8_t
const
*
)
argv
[
i
]);
strs
[
i
]
->
ref_count
++
;
}
args
->
fill
=
vec_fill
;
// If the caller has a declared args array, they may drop; but
// we don't know if they have such an array. So we pin the args
// array here to ensure it survives to program-shutdown.
args
->
ref
();
if
(
main_is_ivec
)
{
size_t
ivec_interior_sz
=
sizeof
(
size_t
)
*
2
+
sizeof
(
rust_str
*
)
*
4
;
args_ivec
=
(
rust_ivec
*
)
kernel
->
malloc
(
ivec_interior_sz
,
"command line arg interior"
);
args_ivec
->
fill
=
0
;
size_t
ivec_exterior_sz
=
sizeof
(
rust_str
*
)
*
argc
;
args_ivec
->
alloc
=
ivec_exterior_sz
;
// NB: This is freed by some ivec machinery, probably the drop
// glue in main, so we don't free it ourselves
args_ivec
->
payload
.
ptr
=
(
rust_ivec_heap
*
)
kernel
->
malloc
(
ivec_exterior_sz
+
sizeof
(
size_t
),
"command line arg exterior"
);
args_ivec
->
payload
.
ptr
->
fill
=
ivec_exterior_sz
;
memcpy
(
&
args_ivec
->
payload
.
ptr
->
data
,
strs
,
ivec_exterior_sz
);
}
else
{
args_ivec
=
NULL
;
}
}
~
command_line_args
()
{
if
(
args_ivec
)
{
kernel
->
free
(
args_ivec
);
}
if
(
args
)
{
// Drop the args we've had pinned here.
rust_str
**
strs
=
(
rust_str
**
)
&
args
->
data
[
0
];
...
...
@@ -84,7 +110,8 @@ command_line_args : public kernel_owned<command_line_args>
int
check_claims
=
0
;
extern
"C"
CDECL
int
rust_start
(
uintptr_t
main_fn
,
int
argc
,
char
**
argv
,
void
*
crate_map
)
{
rust_start_ivec
(
uintptr_t
main_fn
,
int
argc
,
char
**
argv
,
void
*
crate_map
,
int
main_is_ivec
)
{
rust_env
*
env
=
load_env
();
...
...
@@ -99,7 +126,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
rust_scheduler
*
sched
=
root_task
->
sched
;
command_line_args
*
args
=
new
(
kernel
,
"main command line args"
)
command_line_args
(
root_task
,
argc
,
argv
);
command_line_args
(
root_task
,
argc
,
argv
,
main_is_ivec
);
DLOG
(
sched
,
dom
,
"startup: %d args in 0x%"
PRIxPTR
,
args
->
argc
,
(
uintptr_t
)
args
->
args
);
...
...
@@ -107,7 +134,13 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
DLOG
(
sched
,
dom
,
"startup: arg[%d] = '%s'"
,
i
,
args
->
argv
[
i
]);
}
root_task
->
start
(
main_fn
,
(
uintptr_t
)
args
->
args
);
if
(
main_is_ivec
)
{
DLOG
(
sched
,
dom
,
"main takes ivec"
);
root_task
->
start
(
main_fn
,
(
uintptr_t
)
args
->
args_ivec
);
}
else
{
DLOG
(
sched
,
dom
,
"main takes vec"
);
root_task
->
start
(
main_fn
,
(
uintptr_t
)
args
->
args
);
}
root_task
->
deref
();
root_task
=
NULL
;
...
...
@@ -127,6 +160,13 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
return
ret
;
}
extern
"C"
CDECL
int
rust_start
(
uintptr_t
main_fn
,
int
argc
,
char
**
argv
,
void
*
crate_map
)
{
return
rust_start_ivec
(
main_fn
,
argc
,
argv
,
crate_map
,
0
);
}
//
// Local Variables:
// mode: C++
...
...
src/rt/rustrt.def.in
浏览文件 @
053b8bff
...
...
@@ -62,6 +62,7 @@ rust_process_wait
rust_ptr_eq
rust_run_program
rust_start
rust_start_ivec
rust_getcwd
set_min_stack
sched_threads
...
...
src/test/run-pass/main-ivec.rs
0 → 100644
浏览文件 @
053b8bff
fn
main
(
args
:
[
str
])
{
for
s
in
args
{
log
s
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录