Skip to content

Commit fa925ba

Browse files
committed
---
yaml --- r: 1197 b: refs/heads/master c: 5d2a6c7 h: refs/heads/master i: 1195: cfca48f v: v3
1 parent b97e5fc commit fa925ba

File tree

3 files changed

+133
-39
lines changed

3 files changed

+133
-39
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 4fca7d61dd83dbef35f386a96929a6139a0531a8
2+
refs/heads/master: 5d2a6c73ca5b0e082c3fb2a3eee40e18029355f9

trunk/src/comp/lib/llvm.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ const uint LLVMColdCallConv = 9u;
4242
const uint LLVMX86StdcallCallConv = 64u;
4343
const uint LLVMX86FastcallCallConv = 65u;
4444

45+
46+
const uint LLVMExternalLinkage = 0u;
47+
const uint LLVMAvailableExternallyLinkage = 1u;
48+
const uint LLVMLinkOnceAnyLinkage = 2u;
49+
const uint LLVMLinkOnceODRLinkage = 3u;
50+
const uint LLVMWeakAnyLinkage = 4u;
51+
const uint LLVMWeakODRLinkage = 5u;
52+
const uint LLVMAppendingLinkage = 6u;
53+
const uint LLVMInternalLinkage = 7u;
54+
const uint LLVMPrivateLinkage = 8u;
55+
const uint LLVMDLLImportLinkage = 9u;
56+
const uint LLVMDLLExportLinkage = 10u;
57+
const uint LLVMExternalWeakLinkage = 11u;
58+
const uint LLVMGhostLinkage = 12u;
59+
const uint LLVMCommonLinkage = 13u;
60+
const uint LLVMLinkerPrivateLinkage = 14u;
61+
const uint LLVMLinkerPrivateWeakLinkage = 15u;
62+
63+
4564
// Consts for the LLVM IntPredicate type, pre-cast to uint.
4665
// FIXME: as above.
4766

trunk/src/comp/middle/trans.rs

Lines changed: 113 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ state type crate_ctxt = rec(session.session sess,
6767
hashmap[ast.def_id, ValueRef] item_ids,
6868
hashmap[ast.def_id, @ast.item] items,
6969
hashmap[ast.def_id, @tag_info] tags,
70+
hashmap[ast.def_id, ValueRef] fn_pairs,
71+
hashmap[ast.def_id,()] obj_methods,
7072
hashmap[@ty.t, ValueRef] tydescs,
7173
vec[ast.obj_field] obj_fields,
7274
@glue_fns glues,
@@ -193,7 +195,7 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
193195
False);
194196
}
195197

196-
fn T_closure(TypeRef tfn) -> TypeRef {
198+
fn T_fn_pair(TypeRef tfn) -> TypeRef {
197199
ret T_struct(vec(T_ptr(tfn),
198200
T_ptr(T_box(T_nil()))));
199201
}
@@ -389,7 +391,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
389391
ret T_struct(tys);
390392
}
391393
case (ty.ty_fn(?args, ?out)) {
392-
ret type_of_fn(cx, args, out);
394+
ret T_fn_pair(type_of_fn(cx, args, out));
393395
}
394396
case (ty.ty_obj(?meths)) {
395397
auto th = mk_type_handle();
@@ -500,6 +502,8 @@ fn C_str(@crate_ctxt cx, str s) -> ValueRef {
500502
_str.buf(cx.names.next("str")));
501503
llvm.LLVMSetInitializer(g, sc);
502504
llvm.LLVMSetGlobalConstant(g, True);
505+
llvm.LLVMSetLinkage(g, lib.llvm.LLVMPrivateLinkage
506+
as llvm.Linkage);
503507
ret g;
504508
}
505509

@@ -679,6 +683,8 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t) {
679683
auto gvar = llvm.LLVMAddGlobal(cx.llmod, val_ty(tydesc), _str.buf(name));
680684
llvm.LLVMSetInitializer(gvar, tydesc);
681685
llvm.LLVMSetGlobalConstant(gvar, True);
686+
llvm.LLVMSetLinkage(gvar, lib.llvm.LLVMPrivateLinkage
687+
as llvm.Linkage);
682688
cx.tydescs.insert(t, gvar);
683689
}
684690

@@ -1725,17 +1731,22 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
17251731
ret lval_mem(cx, cx.fcx.llobjfields.get(did));
17261732
}
17271733
case (ast.def_fn(?did)) {
1728-
check (cx.fcx.ccx.item_ids.contains_key(did));
1729-
ret lval_val(cx, cx.fcx.ccx.item_ids.get(did));
1734+
check (cx.fcx.ccx.fn_pairs.contains_key(did));
1735+
ret lval_val(cx, cx.fcx.ccx.fn_pairs.get(did));
17301736
}
17311737
case (ast.def_obj(?did)) {
1732-
check (cx.fcx.ccx.item_ids.contains_key(did));
1733-
ret lval_val(cx, cx.fcx.ccx.item_ids.get(did));
1738+
check (cx.fcx.ccx.fn_pairs.contains_key(did));
1739+
ret lval_val(cx, cx.fcx.ccx.fn_pairs.get(did));
17341740
}
17351741
case (ast.def_variant(?tid, ?vid)) {
17361742
check (cx.fcx.ccx.tags.contains_key(tid));
1737-
check (cx.fcx.ccx.item_ids.contains_key(vid));
1738-
ret lval_val(cx, cx.fcx.ccx.item_ids.get(vid));
1743+
if (cx.fcx.ccx.fn_pairs.contains_key(vid)) {
1744+
ret lval_val(cx, cx.fcx.ccx.fn_pairs.get(vid));
1745+
} else {
1746+
// Nullary variants are just scalar constants.
1747+
check (cx.fcx.ccx.item_ids.contains_key(vid));
1748+
ret lval_val(cx, cx.fcx.ccx.item_ids.get(vid));
1749+
}
17391750
}
17401751
case (_) {
17411752
cx.fcx.ccx.sess.unimpl("def variant in trans");
@@ -1942,7 +1953,7 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f,
19421953
&ast.ann ann) -> result {
19431954
auto f_res = trans_lval(cx, f);
19441955
auto bcx = f_res.res.bcx;
1945-
auto pair_t = T_closure(node_type(cx.fcx.ccx, ann));
1956+
auto pair_t = node_type(cx.fcx.ccx, ann);
19461957
auto pair_v = bcx.build.Alloca(pair_t);
19471958
if (f_res.is_mem) {
19481959
cx.fcx.ccx.sess.unimpl("re-binding existing function");
@@ -1959,19 +1970,18 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f,
19591970
vec[@ast.expr] args, &ast.ann ann) -> result {
19601971
auto f_res = trans_lval(cx, f);
19611972
auto faddr = f_res.res.val;
1962-
if (f_res.is_mem) {
1963-
alt (f_res.llobj) {
1964-
case (some[ValueRef](_)) {
1965-
// It's a vtbl entry.
1966-
faddr = f_res.res.bcx.build.Load(faddr);
1967-
}
1968-
case (none[ValueRef]) {
1969-
// It's a closure.
1970-
auto bcx = f_res.res.bcx;
1971-
faddr = bcx.build.GEP(faddr, vec(C_int(0),
1972-
C_int(abi.fn_field_code)));
1973-
faddr = bcx.build.Load(faddr);
1974-
}
1973+
1974+
alt (f_res.llobj) {
1975+
case (some[ValueRef](_)) {
1976+
// It's a vtbl entry.
1977+
faddr = f_res.res.bcx.build.Load(faddr);
1978+
}
1979+
case (none[ValueRef]) {
1980+
// It's a closure.
1981+
auto bcx = f_res.res.bcx;
1982+
faddr = bcx.build.GEP(faddr, vec(C_int(0),
1983+
C_int(abi.fn_field_code)));
1984+
faddr = bcx.build.Load(faddr);
19751985
}
19761986
}
19771987
auto fn_ty = ty.expr_ty(f);
@@ -2701,6 +2711,8 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
27012711
_str.buf("_rust_vtbl" + "." + cx.path));
27022712
llvm.LLVMSetInitializer(gvar, vtbl);
27032713
llvm.LLVMSetGlobalConstant(gvar, True);
2714+
llvm.LLVMSetLinkage(gvar, lib.llvm.LLVMPrivateLinkage
2715+
as llvm.Linkage);
27042716
ret gvar;
27052717
}
27062718

@@ -2818,15 +2830,8 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
28182830
id=varg.id));
28192831
}
28202832

2821-
auto var_ty = ty.ann_to_type(variant.ann);
2822-
auto llfnty = type_of(cx, var_ty);
2823-
2824-
let str s = cx.names.next("_rust_tag") + "." + cx.path;
2825-
let ValueRef llfn = decl_fastcall_fn(cx.llmod, s, llfnty);
2826-
cx.item_ids.insert(variant.id, llfn);
2827-
2833+
check (cx.item_ids.contains_key(variant.id));
28282834
let ValueRef llfndecl = cx.item_ids.get(variant.id);
2829-
cx.item_names.insert(cx.path, llfndecl);
28302835

28312836
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
28322837
create_llargs_for_fn_args(fcx, none[TypeRef], ret_ty_of_fn(variant.ann),
@@ -2907,25 +2912,59 @@ impure fn trans_mod(@crate_ctxt cx, &ast._mod m) {
29072912
}
29082913
}
29092914

2915+
fn decl_fn_and_pair(@crate_ctxt cx,
2916+
str kind,
2917+
str name,
2918+
&ast.ann ann,
2919+
ast.def_id id) {
2920+
2921+
// Bit of a kludge: pick the fn typeref out of the pair.
2922+
auto llpairty = node_type(cx, ann);
2923+
let vec[TypeRef] pair_tys = vec(T_nil(), T_nil());
2924+
llvm.LLVMGetStructElementTypes(llpairty,
2925+
_vec.buf[TypeRef](pair_tys));
2926+
auto llfty = llvm.LLVMGetElementType(pair_tys.(0));
2927+
2928+
// Declare the function itself.
2929+
let str s = cx.names.next("_rust_" + kind) + "." + name;
2930+
let ValueRef llfn = decl_fastcall_fn(cx.llmod, s, llfty);
2931+
2932+
// Declare the global constant pair that points to it.
2933+
let str ps = cx.names.next("_rust_" + kind + "_pair") + "." + name;
2934+
let ValueRef gvar = llvm.LLVMAddGlobal(cx.llmod, llpairty,
2935+
_str.buf(ps));
2936+
auto pair = C_struct(vec(llfn,
2937+
C_null(T_ptr(T_box(T_nil())))));
2938+
2939+
llvm.LLVMSetInitializer(gvar, pair);
2940+
llvm.LLVMSetGlobalConstant(gvar, True);
2941+
llvm.LLVMSetLinkage(gvar,
2942+
lib.llvm.LLVMPrivateLinkage
2943+
as llvm.Linkage);
2944+
2945+
cx.item_ids.insert(id, llfn);
2946+
cx.fn_pairs.insert(id, gvar);
2947+
}
2948+
29102949

29112950
fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
2951+
29122952
alt (i.node) {
29132953
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
29142954
// TODO: type-params
29152955
cx.items.insert(fid, i);
2916-
auto llty = node_type(cx, ann);
2917-
let str s = cx.names.next("_rust_fn") + "." + name;
2918-
let ValueRef llfn = decl_fastcall_fn(cx.llmod, s, llty);
2919-
cx.item_ids.insert(fid, llfn);
2956+
if (! cx.obj_methods.contains_key(fid)) {
2957+
decl_fn_and_pair(cx, "fn", name, ann, fid);
2958+
}
29202959
}
29212960

29222961
case (ast.item_obj(?name, ?ob, _, ?oid, ?ann)) {
29232962
// TODO: type-params
29242963
cx.items.insert(oid, i);
2925-
auto llty = node_type(cx, ann);
2926-
let str s = cx.names.next("_rust_obj_ctor") + "." + name;
2927-
let ValueRef llfn = decl_fastcall_fn(cx.llmod, s, llty);
2928-
cx.item_ids.insert(oid, llfn);
2964+
decl_fn_and_pair(cx, "obj_ctor", name, ann, oid);
2965+
for (@ast.method m in ob.methods) {
2966+
cx.obj_methods.insert(m.node.id, ());
2967+
}
29292968
}
29302969

29312970
case (ast.item_const(?name, _, _, ?cid, _)) {
@@ -2963,6 +3002,36 @@ fn collect_items(@crate_ctxt cx, @ast.crate crate) {
29633002
fold.fold_crate[@crate_ctxt](cx, fld, crate);
29643003
}
29653004

3005+
fn collect_tag_ctor(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
3006+
3007+
alt (i.node) {
3008+
3009+
case (ast.item_tag(_, ?variants, _, _)) {
3010+
for (ast.variant variant in variants) {
3011+
if (_vec.len[ast.variant_arg](variant.args) != 0u) {
3012+
decl_fn_and_pair(cx, "tag", variant.name,
3013+
variant.ann, variant.id);
3014+
}
3015+
}
3016+
}
3017+
3018+
case (_) { /* fall through */ }
3019+
}
3020+
ret cx;
3021+
}
3022+
3023+
fn collect_tag_ctors(@crate_ctxt cx, @ast.crate crate) {
3024+
3025+
let fold.ast_fold[@crate_ctxt] fld =
3026+
fold.new_identity_fold[@crate_ctxt]();
3027+
3028+
fld = @rec( update_env_for_item = bind collect_tag_ctor(_,_)
3029+
with *fld );
3030+
3031+
fold.fold_crate[@crate_ctxt](cx, fld, crate);
3032+
}
3033+
3034+
29663035
// The tag type resolution pass, which determines all the LLVM types that
29673036
// correspond to each tag type in the crate.
29683037

@@ -3048,6 +3117,9 @@ fn trans_constant(&@crate_ctxt cx, @ast.item it) -> @crate_ctxt {
30483117
_str.buf("tag"));
30493118
llvm.LLVMSetInitializer(gvar, val);
30503119
llvm.LLVMSetGlobalConstant(gvar, True);
3120+
llvm.LLVMSetLinkage(gvar,
3121+
lib.llvm.LLVMPrivateLinkage
3122+
as llvm.Linkage);
30513123
cx.item_ids.insert(variant_info._0, gvar);
30523124
}
30533125
case (n_ary) {
@@ -3281,6 +3353,8 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
32813353
item_ids = new_def_hash[ValueRef](),
32823354
items = new_def_hash[@ast.item](),
32833355
tags = new_def_hash[@tag_info](),
3356+
fn_pairs = new_def_hash[ValueRef](),
3357+
obj_methods = new_def_hash[()](),
32843358
tydescs = tydescs,
32853359
obj_fields = obj_fields,
32863360
glues = glues,
@@ -3291,6 +3365,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
32913365

32923366
collect_items(cx, crate);
32933367
resolve_tag_types(cx, crate);
3368+
collect_tag_ctors(cx, crate);
32943369
trans_constants(cx, crate);
32953370

32963371
trans_mod(cx, crate.node.module);

0 commit comments

Comments
 (0)