|
| 1 | +// The "shape" of a type is best defined as "how a value of a type looks from |
| 2 | +// the standpoint of a certain built-in operation". |
| 3 | +// |
| 4 | +// This is used to collapse take/drop glues that would otherwise be |
| 5 | +// separate. For instance, a boxed tuple of 3 ints and a boxed tuple of 3 |
| 6 | +// uints look the same as far as reference count manipulation is concerned, so |
| 7 | +// they get the same shape so that their reference count glues can be |
| 8 | +// collapsed together. To give another example, an int and float have the |
| 9 | +// same (nonexistent!) glue as far as reference counting is concerned, since |
| 10 | +// they aren't reference counted. |
| 11 | + |
| 12 | +import front::ast; |
| 13 | +import middle::trans::variant_info; |
| 14 | +import middle::ty; |
| 15 | + |
| 16 | +type variant_getter = fn(&ast::def_id) -> vec[variant_info]; |
| 17 | + |
| 18 | + |
| 19 | +// Reference counting shapes. |
| 20 | + |
| 21 | +tag rc_shape { |
| 22 | + rs_none; // No reference count. |
| 23 | + rs_ref; // Reference counted box. |
| 24 | + rs_pair; // Pair of code/const ptr + rc box. |
| 25 | + rs_tag(vec[vec[@rc_shape]]); // Discriminated union. |
| 26 | + rs_tup(vec[@rc_shape]); // Tuple. |
| 27 | +} |
| 28 | + |
| 29 | +fn rc_shape_of(&ty::ctxt tcx, variant_getter getter, ty::t t) -> rc_shape { |
| 30 | + alt (ty::struct(tcx, t)) { |
| 31 | + // TODO: Or-patterns |
| 32 | + case (ty::ty_nil) { ret rs_none; } |
| 33 | + case (ty::ty_bool) { ret rs_none; } |
| 34 | + case (ty::ty_int) { ret rs_none; } |
| 35 | + case (ty::ty_uint) { ret rs_none; } |
| 36 | + case (ty::ty_machine(_)) { ret rs_none; } |
| 37 | + case (ty::ty_char) { ret rs_none; } |
| 38 | + case (ty::ty_str) { ret rs_none; } |
| 39 | + case (ty::ty_tag(?did, ?params)) { |
| 40 | + let vec[vec[@rc_shape]] result = vec(); |
| 41 | + |
| 42 | + auto vinfos = getter(did); |
| 43 | + for (variant_info vinfo in vinfos) { |
| 44 | + let vec[@rc_shape] variant_rcs = vec(); |
| 45 | + for (ty::t typ in vinfo.args) { |
| 46 | + auto ty_1 = ty::bind_params_in_type(tcx, typ); |
| 47 | + ty_1 = ty::substitute_type_params(tcx, params, ty_1); |
| 48 | + variant_rcs += vec(@rc_shape_of(tcx, getter, ty_1)); |
| 49 | + } |
| 50 | + result += vec(variant_rcs); |
| 51 | + } |
| 52 | + |
| 53 | + ret rs_tag(result); |
| 54 | + } |
| 55 | + case (ty::ty_box(_)) { ret rs_ref; } |
| 56 | + case (ty::ty_vec(_)) { ret rs_ref; } |
| 57 | + case (ty::ty_port(_)) { ret rs_ref; } |
| 58 | + case (ty::ty_chan(_)) { ret rs_ref; } |
| 59 | + case (ty::ty_task) { ret rs_ref; } |
| 60 | + case (ty::ty_tup(?mts)) { |
| 61 | + let vec[@rc_shape] result = vec(); |
| 62 | + for (ty::mt tm in mts) { |
| 63 | + result += vec(@rc_shape_of(tcx, getter, tm.ty)); |
| 64 | + } |
| 65 | + ret rs_tup(result); |
| 66 | + } |
| 67 | + case (ty::ty_rec(?fields)) { |
| 68 | + let vec[@rc_shape] result = vec(); |
| 69 | + for (ty::field fld in fields) { |
| 70 | + result += vec(@rc_shape_of(tcx, getter, fld.mt.ty)); |
| 71 | + } |
| 72 | + ret rs_tup(result); |
| 73 | + } |
| 74 | + case (ty::ty_fn(_, _, _)) { ret rs_pair; } |
| 75 | + case (ty::ty_native_fn(_, _, _)) { ret rs_pair; } |
| 76 | + case (ty::ty_obj(_)) { ret rs_pair; } |
| 77 | + case (ty::ty_var(_)) { log_err "var in rc_shape_of()"; fail; } |
| 78 | + case (ty::ty_local(_)) { |
| 79 | + log_err "local in rc_shape_of()"; |
| 80 | + fail; |
| 81 | + } |
| 82 | + case (ty::ty_param(_)) { |
| 83 | + log_err "param in rc_shape_of()"; |
| 84 | + fail; |
| 85 | + } |
| 86 | + case (ty::ty_bound_param(_)) { |
| 87 | + log_err "bound param in rc::shape_of()"; |
| 88 | + fail; |
| 89 | + } |
| 90 | + case (ty::ty_type) { ret rs_ref; } |
| 91 | + case (ty::ty_native) { ret rs_none; } |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +// |
| 96 | +// Local Variables: |
| 97 | +// mode: rust |
| 98 | +// fill-column: 78; |
| 99 | +// indent-tabs-mode: nil |
| 100 | +// c-basic-offset: 4 |
| 101 | +// buffer-file-coding-system: utf-8-unix |
| 102 | +// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; |
| 103 | +// End: |
| 104 | +// |
0 commit comments