@@ -108,12 +108,14 @@ state type crate_ctxt = rec(session.session sess,
108
108
hashmap[ ast. def_id , ValueRef ] consts,
109
109
hashmap[ ast. def_id , ( ) ] obj_methods,
110
110
hashmap[ @ty. t , @tydesc_info] tydescs,
111
+ hashmap[ str, ValueRef ] module_data,
111
112
@glue_fns glues,
112
113
namegen names,
113
114
vec[ str] path,
114
115
std. sha1 . sha1 sha) ;
115
116
116
117
type local_ctxt = rec ( vec[ str] path ,
118
+ vec[ str] module_path ,
117
119
vec[ ast. ty_param] obj_typarams ,
118
120
vec[ ast. obj_field] obj_fields ,
119
121
@crate_ctxt ccx ) ;
@@ -426,7 +428,8 @@ fn T_crate(type_names tn) -> TypeRef {
426
428
T_int ( ) , // int n_rust_syms
427
429
T_int ( ) , // int n_c_syms
428
430
T_int ( ) , // int n_libs
429
- T_int ( ) // uintptr_t abi_tag
431
+ T_int ( ) , // uintptr_t abi_tag
432
+ T_int ( ) // void* crate_map
430
433
) ) ;
431
434
tn. associate ( s, t) ;
432
435
ret t;
@@ -909,6 +912,11 @@ fn C_struct(vec[ValueRef] elts) -> ValueRef {
909
912
False ) ;
910
913
}
911
914
915
+ fn C_array ( TypeRef ty, vec[ ValueRef ] elts ) -> ValueRef {
916
+ ret llvm. LLVMConstArray ( ty, _vec. buf [ ValueRef ] ( elts) ,
917
+ _vec. len [ ValueRef ] ( elts) ) ;
918
+ }
919
+
912
920
fn decl_fn ( ModuleRef llmod, str name , uint cc, TypeRef llty) -> ValueRef {
913
921
let ValueRef llfn =
914
922
llvm. LLVMAddFunction ( llmod, _str. buf ( name) , llty) ;
@@ -4925,8 +4933,28 @@ fn load_if_immediate(@block_ctxt cx, ValueRef v, @ty.t t) -> ValueRef {
4925
4933
}
4926
4934
4927
4935
fn trans_log( @block_ctxt cx, @ast. expr e) -> result {
4928
-
4929
- auto sub = trans_expr( cx, e) ;
4936
+ auto lcx = cx. fcx. lcx;
4937
+ auto modname = _str. connect( lcx. module_path, ". ") ;
4938
+ auto global;
4939
+ if ( lcx. ccx. module_data. contains_key( modname) ) {
4940
+ global = lcx. ccx. module_data. get( modname) ;
4941
+ } else {
4942
+ global = llvm. LLVMAddGlobal ( lcx. ccx. llmod, T_int ( ) ,
4943
+ _str. buf( "_rust_mod_log_" + modname) ) ;
4944
+ llvm. LLVMSetGlobalConstant ( global, False ) ;
4945
+ llvm. LLVMSetInitializer ( global, C_null ( T_int ( ) ) ) ;
4946
+ llvm. LLVMSetLinkage ( global, lib. llvm. LLVMInternalLinkage
4947
+ as llvm. Linkage ) ;
4948
+ lcx. ccx. module_data. insert( modname, global) ;
4949
+ }
4950
+
4951
+ auto log_cx = new_sub_block_ctxt( cx, "log") ;
4952
+ auto after_cx = new_sub_block_ctxt( cx, "after") ;
4953
+ auto load = cx. build. Load ( global) ;
4954
+ auto test = cx. build. ICmp ( lib. llvm. LLVMIntSGE , load, C_int ( 1 ) ) ;
4955
+ cx. build. CondBr ( test, log_cx. llbb, after_cx. llbb) ;
4956
+
4957
+ auto sub = trans_expr( log_cx, e) ;
4930
4958
auto e_ty = ty. expr_ty( e) ;
4931
4959
4932
4960
if ( ty. type_is_fp( e_ty) ) {
@@ -4945,33 +4973,34 @@ fn trans_log(@block_ctxt cx, @ast.expr e) -> result {
4945
4973
}
4946
4974
}
4947
4975
if ( is32bit) {
4948
- ret trans_upcall( sub. bcx,
4949
- "upcall_log_float",
4950
- vec( sub. val) ) ;
4976
+ trans_upcall( sub. bcx,
4977
+ "upcall_log_float",
4978
+ vec( sub. val) ) . bcx . build . Br ( after_cx . llbb ) ;
4951
4979
} else {
4952
4980
auto tmp = alloca( sub. bcx, tr) ;
4953
4981
sub. bcx. build. Store ( sub. val, tmp) ;
4954
4982
auto v = vp2i( sub. bcx, tmp) ;
4955
- ret trans_upcall( sub. bcx,
4956
- "upcall_log_double",
4957
- vec( v) ) ;
4983
+ trans_upcall( sub. bcx,
4984
+ "upcall_log_double",
4985
+ vec( v) ) . bcx . build . Br ( after_cx . llbb ) ;
4958
4986
}
4959
- }
4960
-
4961
- alt ( e_ty. struct ) {
4962
- case ( ty. ty_str) {
4963
- auto v = vp2i( sub. bcx, sub. val) ;
4964
- ret trans_upcall( sub. bcx,
4987
+ } else {
4988
+ alt ( e_ty. struct ) {
4989
+ case ( ty. ty_str) {
4990
+ auto v = vp2i( sub. bcx, sub. val) ;
4991
+ trans_upcall( sub. bcx,
4965
4992
"upcall_log_str",
4966
- vec( v) ) ;
4967
- }
4968
- case ( _) {
4969
- ret trans_upcall( sub. bcx,
4993
+ vec( v) ) . bcx . build . Br ( after_cx . llbb ) ;
4994
+ }
4995
+ case ( _) {
4996
+ trans_upcall( sub. bcx,
4970
4997
"upcall_log_int",
4971
- vec( sub. val) ) ;
4998
+ vec( sub. val) ) . bcx. build. Br ( after_cx. llbb) ;
4999
+ }
4972
5000
}
4973
5001
}
4974
- fail;
5002
+
5003
+ ret res( after_cx, C_nil ( ) ) ;
4975
5004
}
4976
5005
4977
5006
fn trans_check_expr( @block_ctxt cx, @ast. expr e) -> result {
@@ -6114,7 +6143,9 @@ fn trans_item(@local_ctxt cx, &ast.item item) {
6114
6143
trans_obj( sub_cx, ob, oid. ctor, tps, ann) ;
6115
6144
}
6116
6145
case ( ast. item_mod( ?name, ?m, _) ) {
6117
- auto sub_cx = extend_path( cx, name) ;
6146
+ auto sub_cx = @rec( path = cx. path + vec( name) ,
6147
+ module_path = cx. module_path + vec( name)
6148
+ with * cx) ;
6118
6149
trans_mod( sub_cx, m) ;
6119
6150
}
6120
6151
case ( ast. item_tag( ?name, ?variants, ?tps, ?tag_id, _) ) {
@@ -6593,7 +6624,8 @@ fn create_typedefs(@crate_ctxt cx) {
6593
6624
llvm. LLVMAddTypeName ( cx. llmod , _str. buf ( "tydesc" ) , T_tydesc ( cx. tn ) ) ;
6594
6625
}
6595
6626
6596
- fn create_crate_constant ( ValueRef crate_ptr , @glue_fns glues ) {
6627
+ fn create_crate_constant ( ValueRef crate_ptr , @glue_fns glues ,
6628
+ ValueRef crate_map ) {
6597
6629
6598
6630
let ValueRef crate_addr = p2i ( crate_ptr) ;
6599
6631
@@ -6608,7 +6640,7 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) {
6608
6640
6609
6641
let ValueRef crate_val =
6610
6642
C_struct ( vec ( C_null ( T_int ( ) ) , // ptrdiff_t image_base_off
6611
- p2i ( crate_ptr) , // uintptr_t self_addr
6643
+ p2i ( crate_ptr) , // uintptr_t self_addr
6612
6644
C_null ( T_int ( ) ) , // ptrdiff_t debug_abbrev_off
6613
6645
C_null ( T_int ( ) ) , // size_t debug_abbrev_sz
6614
6646
C_null ( T_int ( ) ) , // ptrdiff_t debug_info_off
@@ -6621,7 +6653,8 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) {
6621
6653
C_null ( T_int ( ) ) , // int n_rust_syms
6622
6654
C_null ( T_int ( ) ) , // int n_c_syms
6623
6655
C_null ( T_int ( ) ) , // int n_libs
6624
- C_int ( abi. abi_x86_rustc_fastcall ) // uintptr_t abi_tag
6656
+ C_int ( abi. abi_x86_rustc_fastcall ) , // uintptr_t abi_tag
6657
+ p2i ( crate_map) // void* crate_map
6625
6658
) ) ;
6626
6659
6627
6660
llvm. LLVMSetInitializer ( crate_ptr, crate_val) ;
@@ -7159,6 +7192,54 @@ fn make_common_glue(str output, bool optimize,
7159
7192
run_passes ( llmod, optimize, output, ot) ;
7160
7193
}
7161
7194
7195
+ fn create_module_map ( @crate_ctxt ccx ) -> ValueRef {
7196
+ auto elttype = T_struct ( vec ( T_int ( ) , T_int ( ) ) ) ;
7197
+ auto maptype = T_array ( elttype, ccx. module_data . size ( ) + 1 u) ;
7198
+ auto map = llvm. LLVMAddGlobal ( ccx. llmod , maptype,
7199
+ _str. buf ( "_rust_mod_map" ) ) ;
7200
+ llvm. LLVMSetLinkage ( map, lib. llvm . LLVMInternalLinkage as llvm . Linkage ) ;
7201
+ let vec[ ValueRef ] elts = vec ( ) ;
7202
+ for each ( @tup( str, ValueRef ) item in ccx. module_data . items ( ) ) {
7203
+ auto elt = C_struct ( vec ( p2i ( C_cstr ( ccx, item. _0 ) ) , p2i ( item. _1 ) ) ) ;
7204
+ _vec. push [ ValueRef ] ( elts, elt) ;
7205
+ }
7206
+ auto term = C_struct ( vec ( C_int ( 0 ) , C_int ( 0 ) ) ) ;
7207
+ _vec. push [ ValueRef ] ( elts, term) ;
7208
+ llvm. LLVMSetInitializer ( map, C_array ( elttype, elts) ) ;
7209
+ ret map;
7210
+ }
7211
+
7212
+ fn crate_name ( @crate_ctxt ccx , str deflt ) -> str {
7213
+ for ( @ast. meta_item item in ccx. sess. get_metadata( ) ) {
7214
+ if ( _str. eq ( item. node . name , "name" ) ) {
7215
+ ret item. node . value ;
7216
+ }
7217
+ }
7218
+ ret deflt;
7219
+ }
7220
+
7221
+ // FIXME use hashed metadata instead of crate names once we have that
7222
+ fn create_crate_map ( @crate_ctxt ccx ) -> ValueRef {
7223
+ let vec[ ValueRef ] subcrates = vec ( ) ;
7224
+ auto i = 1 ;
7225
+ while ( ccx. sess . has_external_crate ( i) ) {
7226
+ auto name = ccx. sess . get_external_crate ( i) . name ;
7227
+ auto cr = llvm. LLVMAddGlobal ( ccx. llmod , T_int ( ) ,
7228
+ _str. buf ( "_rust_crate_map_" + name) ) ;
7229
+ _vec. push [ ValueRef ] ( subcrates, p2i ( cr) ) ;
7230
+ i += 1 ;
7231
+ }
7232
+ _vec. push [ ValueRef ] ( subcrates, C_int ( 0 ) ) ;
7233
+ auto sym_name = "_rust_crate_map_" + crate_name ( ccx, "__none__" ) ;
7234
+ auto arrtype = T_array ( T_int ( ) , _vec. len [ ValueRef ] ( subcrates) ) ;
7235
+ auto maptype = T_struct ( vec ( T_int ( ) , arrtype) ) ;
7236
+ auto map = llvm. LLVMAddGlobal ( ccx. llmod , maptype, _str. buf ( sym_name) ) ;
7237
+ llvm. LLVMSetLinkage ( map, lib. llvm . LLVMExternalLinkage as llvm . Linkage ) ;
7238
+ llvm. LLVMSetInitializer ( map, C_struct ( vec ( p2i ( create_module_map ( ccx) ) ,
7239
+ C_array ( T_int ( ) , subcrates) ) ) ) ;
7240
+ ret map;
7241
+ }
7242
+
7162
7243
fn trans_crate ( session . session sess, @ast. crate crate,
7163
7244
& ty. type_cache type_cache , str output , bool shared ,
7164
7245
bool optimize , output_type ot) {
@@ -7203,25 +7284,28 @@ fn trans_crate(session.session sess, @ast.crate crate,
7203
7284
consts = new_def_hash[ ValueRef ] ( ) ,
7204
7285
obj_methods = new_def_hash[ ( ) ] ( ) ,
7205
7286
tydescs = tydescs,
7287
+ module_data = new_str_hash[ ValueRef ] ( ) ,
7206
7288
glues = glues,
7207
7289
names = namegen ( 0 ) ,
7208
7290
path = pth,
7209
7291
sha = std. sha1 . mk_sha1 ( ) ) ;
7210
7292
auto cx = @rec ( path=pth,
7293
+ module_path=vec ( crate_name ( ccx, "main" ) ) ,
7211
7294
obj_typarams = obj_typarams,
7212
7295
obj_fields = obj_fields,
7213
7296
ccx = ccx) ;
7214
7297
7215
- create_typedefs ( cx . ccx ) ;
7298
+ create_typedefs ( ccx) ;
7216
7299
7217
7300
collect_items ( cx, crate ) ;
7218
7301
collect_tag_ctors ( cx, crate ) ;
7219
7302
trans_constants ( cx, crate ) ;
7220
7303
trans_mod ( cx, crate . node. module ) ;
7221
7304
trans_vec_append_glue ( cx) ;
7305
+ auto crate_map = create_crate_map ( ccx) ;
7222
7306
if ( !shared) {
7223
7307
trans_main_fn ( cx, crate_ptr) ;
7224
- create_crate_constant ( crate_ptr, ccx. glues ) ;
7308
+ create_crate_constant ( crate_ptr, ccx. glues , crate_map ) ;
7225
7309
}
7226
7310
7227
7311
// Translate the metadata.
0 commit comments