@@ -68,6 +68,7 @@ state type crate_ctxt = rec(session.session sess,
68
68
hashmap[ ast. def_id , @ast. item ] items,
69
69
hashmap[ ast. def_id , @tag_info] tags,
70
70
hashmap[ @ty. t , ValueRef ] tydescs,
71
+ vec[ ast. obj_field ] obj_fields,
71
72
@glue_fns glues,
72
73
namegen names,
73
74
str path) ;
@@ -77,6 +78,7 @@ state type fn_ctxt = rec(ValueRef llfn,
77
78
mutable option. t[ ValueRef ] llself ,
78
79
mutable option. t[ ValueRef ] llretptr ,
79
80
hashmap[ ast. def_id, ValueRef ] llargs ,
81
+ hashmap[ ast. def_id, ValueRef ] llobjfields ,
80
82
hashmap[ ast. def_id, ValueRef ] lllocals ,
81
83
hashmap[ ast. def_id, ValueRef ] lltydescs ,
82
84
@crate_ctxt ccx ) ;
@@ -1667,6 +1669,10 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
1667
1669
check ( cx. fcx. lllocals. contains_key( did) ) ;
1668
1670
ret lval_mem( cx, cx. fcx. lllocals. get( did) ) ;
1669
1671
}
1672
+ case ( ast. def_obj_field( ?did) ) {
1673
+ check ( cx. fcx. llobjfields. contains_key( did) ) ;
1674
+ ret lval_mem( cx, cx. fcx. llobjfields. get( did) ) ;
1675
+ }
1670
1676
case ( ast. def_fn( ?did) ) {
1671
1677
check ( cx. fcx. ccx. item_ids. contains_key( did) ) ;
1672
1678
ret lval_val( cx, cx. fcx. ccx. item_ids. get( did) ) ;
@@ -2382,15 +2388,17 @@ fn new_fn_ctxt(@crate_ctxt cx,
2382
2388
2383
2389
let ValueRef lltaskptr = llvm. LLVMGetParam ( llfndecl, 0 u) ;
2384
2390
2385
- let hashmap[ ast. def_id , ValueRef ] lllocals = new_def_hash[ ValueRef ] ( ) ;
2386
2391
let hashmap[ ast. def_id , ValueRef ] llargs = new_def_hash[ ValueRef ] ( ) ;
2392
+ let hashmap[ ast. def_id , ValueRef ] llobjfields = new_def_hash[ ValueRef ] ( ) ;
2393
+ let hashmap[ ast. def_id , ValueRef ] lllocals = new_def_hash[ ValueRef ] ( ) ;
2387
2394
let hashmap[ ast. def_id , ValueRef ] lltydescs = new_def_hash[ ValueRef ] ( ) ;
2388
2395
2389
2396
ret @rec( llfn=llfndecl,
2390
2397
lltaskptr=lltaskptr,
2391
2398
mutable llself=none[ ValueRef ] ,
2392
2399
mutable llretptr=none[ ValueRef ] ,
2393
2400
llargs=llargs,
2401
+ llobjfields=llobjfields,
2394
2402
lllocals=lllocals,
2395
2403
lltydescs=lltydescs,
2396
2404
ccx=cx) ;
@@ -2434,16 +2442,31 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
2434
2442
}
2435
2443
}
2436
2444
2437
-
2438
2445
// Recommended LLVM style, strange though this is, is to copy from args to
2439
2446
// allocas immediately upon entry; this permits us to GEP into structures we
2440
2447
// were passed and whatnot. Apparently mem2reg will mop up.
2441
2448
2442
- fn copy_args_to_allocas( @block_ctxt cx, vec[ ast. arg] args,
2443
- vec[ ty. arg] arg_tys) {
2449
+ impure fn copy_args_to_allocas( @block_ctxt cx,
2450
+ option. t[ TypeRef ] ty_self,
2451
+ vec[ ast. arg] args,
2452
+ vec[ ty. arg] arg_tys) {
2444
2453
2445
2454
let uint arg_n = 0 u;
2446
2455
2456
+ alt ( cx. fcx. llself) {
2457
+ case ( some[ ValueRef ] ( ?self_v) ) {
2458
+ alt ( ty_self) {
2459
+ case ( some[ TypeRef ] ( ?self_t) ) {
2460
+ auto alloca = cx. build. Alloca ( self_t) ;
2461
+ cx. build. Store ( self_v, alloca) ;
2462
+ cx. fcx. llself = some[ ValueRef ] ( alloca) ;
2463
+ }
2464
+ }
2465
+ }
2466
+ case ( _) {
2467
+ }
2468
+ }
2469
+
2447
2470
for ( ast. arg aarg in args) {
2448
2471
if ( aarg. mode != ast. alias) {
2449
2472
auto arg_t = type_of_arg( cx. fcx. ccx, arg_tys. ( arg_n) ) ;
@@ -2481,19 +2504,66 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
2481
2504
fail;
2482
2505
}
2483
2506
2507
+ fn create_llobjfields_for_fields( @block_ctxt cx, ValueRef llself) {
2508
+
2509
+ let vec[ TypeRef ] llfield_tys = vec( ) ;
2510
+
2511
+ for ( ast. obj_field f in cx. fcx. ccx. obj_fields) {
2512
+ llfield_tys += node_type( cx. fcx. ccx, f. ann) ;
2513
+ }
2514
+
2515
+ let TypeRef llfields_ty = T_struct ( llfield_tys) ;
2516
+ let TypeRef lltydesc_ty = T_ptr ( T_tydesc ( ) ) ;
2517
+ let TypeRef llobj_body_ty = T_struct ( vec( lltydesc_ty,
2518
+ llfields_ty) ) ;
2519
+ let TypeRef llobj_box_ty = T_ptr ( T_box ( llobj_body_ty) ) ;
2520
+
2521
+ auto box_cell =
2522
+ cx. build. GEP ( llself,
2523
+ vec( C_int ( 0 ) ,
2524
+ C_int ( abi. obj_field_box) ) ) ;
2525
+
2526
+ auto box_ptr = cx. build. Load ( box_cell) ;
2527
+
2528
+ box_ptr = cx. build. PointerCast ( box_ptr, llobj_box_ty) ;
2529
+
2530
+ auto obj_fields = cx. build. GEP ( box_ptr,
2531
+ vec( C_int ( 0 ) ,
2532
+ C_int ( abi. box_rc_field_body) ,
2533
+ C_int ( abi. obj_body_elt_fields) ) ) ;
2534
+
2535
+ let int i = 0 ;
2536
+ for ( ast. obj_field f in cx. fcx. ccx. obj_fields) {
2537
+ let ValueRef llfield = cx. build. GEP ( obj_fields,
2538
+ vec( C_int ( 0 ) ,
2539
+ C_int ( i) ) ) ;
2540
+ cx. fcx. llobjfields. insert( f. id, llfield) ;
2541
+ i += 1 ;
2542
+ }
2543
+ }
2544
+
2484
2545
impure fn trans_fn( @crate_ctxt cx, & ast. _fn f, ast. def_id fid,
2546
+ option. t[ TypeRef ] ty_self,
2485
2547
& vec[ ast. ty_param] ty_params, & ast. ann ann) {
2486
2548
2487
2549
auto llfndecl = cx. item_ids. get( fid) ;
2488
2550
cx. item_names. insert( cx. path, llfndecl) ;
2489
2551
2490
2552
auto fcx = new_fn_ctxt( cx, cx. path, llfndecl) ;
2491
- create_llargs_for_fn_args( fcx, none [ TypeRef ] , ret_ty_of_fn( ann) ,
2553
+ create_llargs_for_fn_args( fcx, ty_self , ret_ty_of_fn( ann) ,
2492
2554
f. inputs, ty_params) ;
2493
-
2494
2555
auto bcx = new_top_block_ctxt( fcx) ;
2495
2556
2496
- copy_args_to_allocas( bcx, f. inputs, arg_tys_of_fn( ann) ) ;
2557
+ copy_args_to_allocas( bcx, ty_self, f. inputs,
2558
+ arg_tys_of_fn( ann) ) ;
2559
+
2560
+ alt ( fcx. llself) {
2561
+ case ( some[ ValueRef ] ( ?llself) ) {
2562
+ create_llobjfields_for_fields( bcx, llself) ;
2563
+ }
2564
+ case ( _) {
2565
+ }
2566
+ }
2497
2567
2498
2568
auto res = trans_block( bcx, f. body) ;
2499
2569
if ( !is_terminated( res. bcx) ) {
@@ -2507,7 +2577,15 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
2507
2577
& ast. _obj ob,
2508
2578
& vec[ ast. ty_param] ty_params) -> ValueRef {
2509
2579
let vec[ ValueRef ] methods = vec( ) ;
2510
- for ( @ast. method m in ob. methods) {
2580
+
2581
+ fn meth_lteq( & @ast. method a, & @ast. method b) -> bool {
2582
+ ret _str. lteq( a. node. ident, b. node. ident) ;
2583
+ }
2584
+
2585
+ auto meths = std. sort. merge_sort[ @ast. method] ( bind meth_lteq( _, _) ,
2586
+ ob. methods) ;
2587
+
2588
+ for ( @ast. method m in meths) {
2511
2589
2512
2590
auto llfnty = T_nil ( ) ;
2513
2591
alt ( node_ann_type( cx, m. node. ann) . struct ) {
@@ -2518,11 +2596,15 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
2518
2596
}
2519
2597
}
2520
2598
2521
- let str s = cx. names. next( "_rust_method" ) + "." + cx. path;
2599
+ let @crate_ctxt mcx = @rec( path=cx. path + "." + m. node. ident
2600
+ with * cx) ;
2601
+
2602
+ let str s = cx. names. next( "_rust_method" ) + "." + mcx. path;
2522
2603
let ValueRef llfn = decl_fastcall_fn( cx. llmod, s, llfnty) ;
2523
2604
cx. item_ids. insert( m. node. id, llfn) ;
2524
2605
2525
- trans_fn( cx, m. node. meth, m. node. id, ty_params, m. node. ann) ;
2606
+ trans_fn( mcx, m. node. meth, m. node. id, some[ TypeRef ] ( self_ty) ,
2607
+ ty_params, m. node. ann) ;
2526
2608
methods += llfn;
2527
2609
}
2528
2610
auto vtbl = C_struct ( methods) ;
@@ -2556,7 +2638,7 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
2556
2638
auto bcx = new_top_block_ctxt( fcx) ;
2557
2639
2558
2640
let vec[ ty. arg] arg_tys = arg_tys_of_fn( ann) ;
2559
- copy_args_to_allocas( bcx, fn_args, arg_tys) ;
2641
+ copy_args_to_allocas( bcx, none [ TypeRef ] , fn_args, arg_tys) ;
2560
2642
2561
2643
auto llself_ty = type_of( cx, ret_ty_of_fn( ann) ) ;
2562
2644
auto pair = bcx. build. Alloca ( llself_ty) ;
@@ -2664,7 +2746,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
2664
2746
auto bcx = new_top_block_ctxt( fcx) ;
2665
2747
2666
2748
auto arg_tys = arg_tys_of_fn( variant. ann) ;
2667
- copy_args_to_allocas( bcx, fn_args, arg_tys) ;
2749
+ copy_args_to_allocas( bcx, none [ TypeRef ] , fn_args, arg_tys) ;
2668
2750
2669
2751
auto info = cx. tags. get( tag_id) ;
2670
2752
@@ -2707,10 +2789,11 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) {
2707
2789
alt ( item. node) {
2708
2790
case ( ast. item_fn( ?name, ?f, ?tps, ?fid, ?ann) ) {
2709
2791
auto sub_cx = @rec( path=cx. path + "." + name with * cx) ;
2710
- trans_fn( sub_cx, f, fid, tps, ann) ;
2792
+ trans_fn( sub_cx, f, fid, none [ TypeRef ] , tps, ann) ;
2711
2793
}
2712
2794
case ( ast. item_obj( ?name, ?ob, ?tps, ?oid, ?ann) ) {
2713
- auto sub_cx = @rec( path=cx. path + "." + name with * cx) ;
2795
+ auto sub_cx = @rec( path=cx. path + "." + name,
2796
+ obj_fields=ob. fields with * cx) ;
2714
2797
trans_obj( sub_cx, ob, oid, tps, ann) ;
2715
2798
}
2716
2799
case ( ast. item_mod( ?name, ?m, _) ) {
@@ -2927,6 +3010,7 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
2927
3010
mutable llself=none[ ValueRef ] ,
2928
3011
mutable llretptr=none[ ValueRef ] ,
2929
3012
llargs=new_def_hash[ ValueRef ] ( ) ,
3013
+ llobjfields=new_def_hash[ ValueRef ] ( ) ,
2930
3014
lllocals=new_def_hash[ ValueRef ] ( ) ,
2931
3015
lltydescs=new_def_hash[ ValueRef ] ( ) ,
2932
3016
ccx=cx) ;
@@ -3097,6 +3181,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
3097
3181
auto hasher = ty. hash_ty ;
3098
3182
auto eqer = ty. eq_ty ;
3099
3183
auto tydescs = map. mk_hashmap [ @ty. t , ValueRef ] ( hasher, eqer) ;
3184
+ let vec[ ast. obj_field ] obj_fields = vec ( ) ;
3100
3185
3101
3186
auto cx = @rec ( sess = sess,
3102
3187
llmod = llmod,
@@ -3108,6 +3193,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
3108
3193
items = new_def_hash[ @ast. item ] ( ) ,
3109
3194
tags = new_def_hash[ @tag_info] ( ) ,
3110
3195
tydescs = tydescs,
3196
+ obj_fields = obj_fields,
3111
3197
glues = glues,
3112
3198
names = namegen ( 0 ) ,
3113
3199
path = "_rust" ) ;
0 commit comments