Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4cfc4250
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,发现更多精彩内容 >>
提交
4cfc4250
编写于
9月 24, 2010
作者:
G
Graydon Hoare
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
More work on trans, almost getting to the point of emitting an upcall.
上级
6b412be6
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
204 addition
and
37 deletion
+204
-37
src/comp/back/abi.rs
src/comp/back/abi.rs
+12
-0
src/comp/back/x86.rs
src/comp/back/x86.rs
+3
-3
src/comp/lib/llvm.rs
src/comp/lib/llvm.rs
+87
-2
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+101
-32
src/comp/rustc.rc
src/comp/rustc.rc
+1
-0
未找到文件。
src/comp/back/abi.rs
浏览文件 @
4cfc4250
...
...
@@ -36,6 +36,18 @@
const
int
n_upcall_glues
=
7
;
fn
upcall_glue_name
(
int
n
)
->
str
{
ret
"rust_upcall_"
+
util
.common
.istr
(
n
);
}
fn
activate_glue_name
()
->
str
{
ret
"rust_activate_glue"
;
}
fn
yield_glue_name
()
->
str
{
ret
"rust_yield_glue"
;
}
//
// Local Variables:
// mode: rust
...
...
src/comp/back/x86.rs
浏览文件 @
4cfc4250
...
...
@@ -121,7 +121,7 @@ fn decl_glue(int align, str prefix, str name, vec[str] insns) -> str {
fn
decl_upcall_glue
(
int
align
,
str
prefix
,
uint
n
)
->
str
{
let
int
i
=
n
as
int
;
ret
decl_glue
(
align
,
prefix
,
"rust_upcall_"
+
istr
(
i
),
abi
.upcall_glue_name
(
i
),
upcall_glue
(
i
));
}
...
...
@@ -131,11 +131,11 @@ fn get_module_asm() -> str {
auto
glues
=
vec
(
decl_glue
(
align
,
prefix
,
"rust_activate_glue"
,
abi
.activate_glue_name
()
,
rust_activate_glue
()),
decl_glue
(
align
,
prefix
,
"rust_yield_glue"
,
abi
.yield_glue_name
()
,
rust_yield_glue
()))
+
_
vec
.init_fn
[
str
](
bind
decl_upcall_glue
(
align
,
prefix
,
_
),
...
...
src/comp/lib/llvm.rs
浏览文件 @
4cfc4250
...
...
@@ -41,7 +41,6 @@
const
uint
LLVMX86StdcallCallConv
=
64u
;
const
uint
LLVMX86FastcallCallConv
=
65u
;
native
mod
llvm
=
llvm_lib
{
type
ModuleRef
;
...
...
@@ -96,6 +95,14 @@ fn LLVMModuleCreateWithNameInContext(sbuf ModuleID,
/** See Module::setModuleInlineAsm. */
fn
LLVMSetModuleInlineAsm
(
ModuleRef
M
,
sbuf
Asm
);
/** See llvm::LLVMTypeKind::getTypeID. */
// FIXME: returning int rather than TypeKind because
// we directly inspect the values, and casting from
// a native doesn't work yet (only *to* a native).
fn
LLVMGetTypeKind
(
TypeRef
Ty
)
->
int
;
/** See llvm::LLVMType::getContext. */
fn
LLVMGetTypeContext
(
TypeRef
Ty
)
->
ContextRef
;
...
...
@@ -213,7 +220,9 @@ fn LLVMUnionTypeInContext(ContextRef C, vbuf ElementTypes,
/* Operations on scalar constants */
fn
LLVMConstInt
(
TypeRef
IntTy
,
ULongLong
N
,
Bool
SignExtend
)
->
ValueRef
;
fn
LLVMConstIntOfString
(
TypeRef
IntTy
,
sbuf
Text
,
u8
Radix
)
->
ValueRef
;
// FIXME: radix is actually u8, but our native layer can't handle this
// yet. lucky for us we're little-endian. Small miracles.
fn
LLVMConstIntOfString
(
TypeRef
IntTy
,
sbuf
Text
,
int
Radix
)
->
ValueRef
;
fn
LLVMConstIntOfStringAndSize
(
TypeRef
IntTy
,
sbuf
Text
,
uint
SLen
,
u8
Radix
)
->
ValueRef
;
fn
LLVMConstReal
(
TypeRef
RealTy
,
f64
N
)
->
ValueRef
;
...
...
@@ -1041,6 +1050,82 @@ fn PtrDiff(ValueRef LHS, ValueRef RHS) -> ValueRef {
}
}
fn
type_to_str
(
TypeRef
ty
)
->
str
{
let
int
kind
=
llvm
.LLVMGetTypeKind
(
ty
);
fn
tys_str
(
vec
[
TypeRef
]
tys
)
->
str
{
let
str
s
=
""
;
let
bool
first
=
true
;
for
(
TypeRef
t
in
tys
)
{
if
(
first
)
{
first
=
false
;
}
else
{
s
+=
", "
;
}
s
+=
type_to_str
(
t
);
}
ret
s
;
}
alt
(
kind
)
{
// FIXME: more enum-as-int constants determined from Core.h;
// horrible, horrible. Complete as needed.
case
(
0
)
{
ret
"Void"
;
}
case
(
1
)
{
ret
"Float"
;
}
case
(
2
)
{
ret
"Double"
;
}
case
(
3
)
{
ret
"X86_FP80"
;
}
case
(
4
)
{
ret
"FP128"
;
}
case
(
5
)
{
ret
"PPC_FP128"
;
}
case
(
6
)
{
ret
"Label"
;
}
case
(
7
)
{
ret
"i"
+
util
.common
.istr
(
llvm
.LLVMGetIntTypeWidth
(
ty
)
as
int
);
}
case
(
8
)
{
auto
s
=
"fn("
;
let
TypeRef
out_ty
=
llvm
.LLVMGetReturnType
(
ty
);
let
uint
n_args
=
llvm
.LLVMCountParamTypes
(
ty
);
let
vec
[
TypeRef
]
args
=
_
vec
.init_elt
[
TypeRef
](
0
as
TypeRef
,
n_args
);
llvm
.LLVMGetParamTypes
(
ty
,
_
vec
.buf
[
TypeRef
](
args
));
s
+=
tys_str
(
args
);
s
+=
") -> "
;
s
+=
type_to_str
(
out_ty
);
ret
s
;
}
case
(
9
)
{
let
str
s
=
"{"
;
let
uint
n_elts
=
llvm
.LLVMCountStructElementTypes
(
ty
);
let
vec
[
TypeRef
]
elts
=
_
vec
.init_elt
[
TypeRef
](
0
as
TypeRef
,
n_elts
);
llvm
.LLVMGetStructElementTypes
(
ty
,
_
vec
.buf
[
TypeRef
](
elts
));
s
+=
tys_str
(
elts
);
s
+=
"}"
;
ret
s
;
}
case
(
10
)
{
ret
"Array"
;
}
case
(
11
)
{
ret
"*"
+
type_to_str
(
llvm
.LLVMGetElementType
(
ty
));
}
case
(
12
)
{
ret
"Opaque"
;
}
case
(
13
)
{
ret
"Vector"
;
}
case
(
14
)
{
ret
"Metadata"
;
}
case
(
15
)
{
ret
"Union"
;
}
case
(
_
)
{
log
"unknown TypeKind"
+
util
.common
.istr
(
kind
as
int
);
fail
;
}
}
}
//
// Local Variables:
// mode: rust
...
...
src/comp/middle/trans.rs
浏览文件 @
4cfc4250
...
...
@@ -33,6 +33,21 @@
@
glue_fns
glues
,
str
path
);
type
fn_ctxt
=
rec
(
ValueRef
llfn
,
ValueRef
lloutptr
,
ValueRef
lltaskptr
,
@
trans_ctxt
tcx
);
type
terminator
=
fn
(
@
fn_ctxt
cx
,
builder
build
);
type
block_ctxt
=
rec
(
BasicBlockRef
llbb
,
builder
build
,
terminator
term
,
@
fn_ctxt
fcx
);
// LLVM type constructors.
fn
T_nil
()
->
TypeRef
{
ret
llvm
.LLVMVoidType
();
}
...
...
@@ -67,9 +82,38 @@ fn T_task() -> TypeRef {
T_opaque
()));
// Rest is opaque for now
}
// LLVM constant constructors.
fn
C_null
(
TypeRef
t
)
->
ValueRef
{
ret
llvm
.LLVMConstNull
(
t
);
}
fn
C_int
(
int
i
)
->
ValueRef
{
// FIXME. We can't use LLVM.ULongLong with our existing minimal native
// API, which only knows word-sized args. Lucky for us LLVM has a "take a
// string encoding" version. Hilarious. Please fix to handle:
//
// ret llvm.LLVMConstInt(T_int(), t as LLVM.ULongLong, False);
//
ret
llvm
.LLVMConstIntOfString
(
T_int
(),
_
str
.buf
(
istr
(
i
)),
10
);
}
fn
C_str
(
str
s
)
->
ValueRef
{
ret
llvm
.LLVMConstString
(
_
str
.buf
(
s
),
_
str
.byte_len
(
s
),
False
);
}
fn
C_struct
(
vec
[
ValueRef
]
elts
)
->
ValueRef
{
ret
llvm
.LLVMConstStruct
(
_
vec
.buf
[
ValueRef
](
elts
),
_
vec
.len
[
ValueRef
](
elts
),
False
);
}
fn
decl_cdecl_fn
(
ModuleRef
llmod
,
str
name
,
vec
[
TypeRef
]
inputs
,
TypeRef
output
)
->
ValueRef
{
let
TypeRef
llty
=
T_fn
(
inputs
,
output
);
log
"declaring "
+
name
+
" with type "
+
lib
.llvm
.type_to_str
(
llty
);
let
ValueRef
llfn
=
llvm
.LLVMAddFunction
(
llmod
,
_
str
.buf
(
name
),
llty
);
llvm
.LLVMSetFunctionCallConv
(
llfn
,
lib
.llvm.LLVMCCallConv
);
...
...
@@ -82,7 +126,7 @@ fn decl_glue(ModuleRef llmod, str s) -> ValueRef {
fn
decl_upcall
(
ModuleRef
llmod
,
uint
_
n
)
->
ValueRef
{
let
int
n
=
_
n
as
int
;
let
str
s
=
"rust_upcall_"
+
istr
(
n
);
let
str
s
=
abi
.upcall_glue_name
(
n
);
let
vec
[
TypeRef
]
args
=
vec
(
T_ptr
(
T_task
()),
// taskptr
T_int
())
// callee
...
...
@@ -91,9 +135,7 @@ fn decl_upcall(ModuleRef llmod, uint _n) -> ValueRef {
ret
decl_cdecl_fn
(
llmod
,
s
,
args
,
T_int
());
}
type
terminator
=
fn
(
&
trans_ctxt
cx
,
builder
b
);
fn
get_upcall
(
&
trans_ctxt
cx
,
str
name
,
int
n_args
)
->
ValueRef
{
fn
get_upcall
(
@
trans_ctxt
cx
,
str
name
,
int
n_args
)
->
ValueRef
{
if
(
cx
.upcalls
.contains_key
(
name
))
{
ret
cx
.upcalls
.get
(
name
);
}
...
...
@@ -105,61 +147,87 @@ fn get_upcall(&trans_ctxt cx, str name, int n_args) -> ValueRef {
ret
f
;
}
fn
trans_log
(
&
trans_ctxt
cx
,
builder
b
,
&
ast
.atom
a
)
{
fn
trans_upcall
(
@
block_ctxt
cx
,
str
name
,
vec
[
ValueRef
]
args
)
->
ValueRef
{
let
int
n
=
_
vec
.len
[
ValueRef
](
args
)
as
int
;
let
ValueRef
llupcall
=
get_upcall
(
cx
.fcx.tcx
,
name
,
n
);
llupcall
=
llvm
.LLVMConstPointerCast
(
llupcall
,
T_int
());
let
ValueRef
llglue
=
cx
.fcx.tcx.glues.upcall_glues
.
(
n
);
let
vec
[
ValueRef
]
call_args
=
vec
(
cx
.fcx.lltaskptr
,
llupcall
)
+
args
;
log
"emitting indirect-upcall via "
+
abi
.upcall_glue_name
(
n
);
for
(
ValueRef
v
in
call_args
)
{
log
"arg: "
+
lib
.llvm
.type_to_str
(
llvm
.LLVMTypeOf
(
v
));
}
log
"emitting call to callee of type: "
+
lib
.llvm
.type_to_str
(
llvm
.LLVMTypeOf
(
llglue
));
ret
cx
.build
.Call
(
llglue
,
call_args
);
}
fn
trans_log
(
@
block_ctxt
cx
,
&
ast
.atom
a
)
{
alt
(
a
)
{
case
(
ast
.atom_lit
(
?
lit
))
{
alt
(
*
lit
)
{
case
(
ast
.lit_int
(
?
i
))
{
cx
.sess
.unimpl
(
"log int"
);
trans_upcall
(
cx
,
"upcall_log_int"
,
vec
(
C_int
(
i
))
);
}
case
(
_
)
{
cx
.sess
.unimpl
(
"literal variant in trans_log"
);
cx
.
fcx.tcx.
sess
.unimpl
(
"literal variant in trans_log"
);
}
}
}
case
(
_
)
{
cx
.sess
.unimpl
(
"atom variant in trans_log"
);
cx
.
fcx.tcx.
sess
.unimpl
(
"atom variant in trans_log"
);
}
}
}
fn
trans_stmt
(
&
trans_ctxt
cx
,
builder
b
,
&
ast
.stmt
s
,
terminator
t
)
{
fn
trans_stmt
(
@
block_ctxt
cx
,
&
ast
.stmt
s
)
{
alt
(
s
)
{
case
(
ast
.stmt_log
(
?
a
))
{
trans_log
(
cx
,
b
,
*
a
);
trans_log
(
cx
,
*
a
);
}
case
(
_
)
{
cx
.sess
.unimpl
(
"stmt variant"
);
cx
.
fcx.tcx.
sess
.unimpl
(
"stmt variant"
);
}
}
}
fn
default_terminate
(
&
trans_ctxt
cx
,
builder
b
)
{
b
.RetVoid
();
fn
default_terminate
(
@
fn_ctxt
cx
,
builder
build
)
{
b
uild
.RetVoid
();
}
fn
trans_block
(
&
trans_ctxt
cx
,
ValueRef
llfn
,
&
ast
.block
b
,
terminator
t
)
{
fn
trans_block
(
@
fn_ctxt
cx
,
&
ast
.block
b
,
terminator
term
)
{
let
BasicBlockRef
llbb
=
llvm
.LLVMAppendBasicBlock
(
llfn
,
_
str
.buf
(
""
));
llvm
.LLVMAppendBasicBlock
(
cx
.
llfn
,
_
str
.buf
(
""
));
let
BuilderRef
llbuild
=
llvm
.LLVMCreateBuilder
();
llvm
.LLVMPositionBuilderAtEnd
(
llbuild
,
llbb
);
auto
bld
=
builder
(
llbuild
);
auto
bcx
=
@
rec
(
llbb
=
llbb
,
build
=
builder
(
llbuild
),
term
=
term
,
fcx
=
cx
);
for
(
@
ast
.stmt
s
in
b
)
{
trans_stmt
(
cx
,
bld
,
*
s
,
t
);
trans_stmt
(
bcx
,
*
s
);
}
t
(
cx
,
b
ld
);
bcx
.term
(
cx
,
bcx
.bui
ld
);
}
fn
trans_fn
(
&
trans_ctxt
cx
,
&
ast
._fn
f
)
{
let
vec
[
TypeRef
]
args
=
vec
();
fn
trans_fn
(
@
trans_ctxt
cx
,
&
ast
._fn
f
)
{
let
vec
[
TypeRef
]
args
=
vec
(
T_ptr
(
T_int
()),
// outptr.
T_ptr
(
T_task
())
// taskptr
);
let
ValueRef
llfn
=
decl_cdecl_fn
(
cx
.llmod
,
cx
.path
,
args
,
T_nil
());
let
ValueRef
lloutptr
=
llvm
.LLVMGetParam
(
llfn
,
0u
);
let
ValueRef
lltaskptr
=
llvm
.LLVMGetParam
(
llfn
,
1u
);
auto
fcx
=
@
rec
(
llfn
=
llfn
,
lloutptr
=
lloutptr
,
lltaskptr
=
lltaskptr
,
tcx
=
cx
);
auto
term
=
default_terminate
;
trans_block
(
cx
,
llfn
,
f
.body
,
term
);
trans_block
(
fcx
,
f
.body
,
term
);
}
fn
trans_item
(
&
trans_ctxt
cx
,
&
str
name
,
&
ast
.item
item
)
{
auto
sub_cx
=
rec
(
path
=
cx
.path
+
"."
+
name
with
cx
);
fn
trans_item
(
@
trans_ctxt
cx
,
&
str
name
,
&
ast
.item
item
)
{
auto
sub_cx
=
@
rec
(
path
=
cx
.path
+
"."
+
name
with
*
cx
);
alt
(
item
)
{
case
(
ast
.item_fn
(
?
f
))
{
trans_fn
(
sub_cx
,
*
f
);
...
...
@@ -170,7 +238,7 @@ fn trans_item(&trans_ctxt cx, &str name, &ast.item item) {
}
}
fn
trans_mod
(
&
trans_ctxt
cx
,
&
ast
._mod
m
)
{
fn
trans_mod
(
@
trans_ctxt
cx
,
&
ast
._mod
m
)
{
for
each
(
tup
(
str
,
ast
.item
)
pair
in
m
.items
())
{
trans_item
(
cx
,
pair
._0
,
pair
._1
);
}
...
...
@@ -183,17 +251,18 @@ fn trans_crate(session.session sess, ast.crate crate) {
llvm
.LLVMSetModuleInlineAsm
(
llmod
,
_
str
.buf
(
x86
.get_module_asm
()));
auto
glues
=
@
rec
(
activate_glue
=
decl_glue
(
llmod
,
"rust_activate_glue"
),
yield_glue
=
decl_glue
(
llmod
,
"rust_yield_glue"
),
auto
glues
=
@
rec
(
activate_glue
=
decl_glue
(
llmod
,
abi
.activate_glue_name
()),
yield_glue
=
decl_glue
(
llmod
,
abi
.yield_glue_name
()),
upcall_glues
=
_
vec
.init_fn
[
ValueRef
](
bind
decl_upcall
(
llmod
,
_
),
abi
.n_upcall_glues
as
uint
));
auto
cx
=
rec
(
sess
=
sess
,
llmod
=
llmod
,
upcalls
=
new_str_hash
[
ValueRef
](),
glues
=
glues
,
path
=
""
);
auto
cx
=
@
rec
(
sess
=
sess
,
llmod
=
llmod
,
upcalls
=
new_str_hash
[
ValueRef
](),
glues
=
glues
,
path
=
""
);
trans_mod
(
cx
,
crate
.module
);
...
...
src/comp/rustc.rc
浏览文件 @
4cfc4250
...
...
@@ -30,6 +30,7 @@ mod util {
auth
driver
.rustc.main
=
state
;
auth
middle
.trans
=
unsafe
;
auth
lib
.llvm
=
unsafe
;
mod
lib
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录