Capture typarams into obj, independent of body tydesc.
This commit is contained in:
parent
ce17fe2a90
commit
be97a77be8
@ -44,7 +44,8 @@ const int obj_field_vtbl = 0;
|
|||||||
const int obj_field_box = 1;
|
const int obj_field_box = 1;
|
||||||
|
|
||||||
const int obj_body_elt_tydesc = 0;
|
const int obj_body_elt_tydesc = 0;
|
||||||
const int obj_body_elt_fields = 1;
|
const int obj_body_elt_typarams = 1;
|
||||||
|
const int obj_body_elt_fields = 2;
|
||||||
|
|
||||||
const int fn_field_code = 0;
|
const int fn_field_code = 0;
|
||||||
const int fn_field_box = 1;
|
const int fn_field_box = 1;
|
||||||
|
@ -75,6 +75,7 @@ state type crate_ctxt = rec(session.session sess,
|
|||||||
hashmap[ast.def_id, ValueRef] consts,
|
hashmap[ast.def_id, ValueRef] consts,
|
||||||
hashmap[ast.def_id,()] obj_methods,
|
hashmap[ast.def_id,()] obj_methods,
|
||||||
hashmap[@ty.t, ValueRef] tydescs,
|
hashmap[@ty.t, ValueRef] tydescs,
|
||||||
|
vec[ast.ty_param] obj_typarams,
|
||||||
vec[ast.obj_field] obj_fields,
|
vec[ast.obj_field] obj_fields,
|
||||||
@glue_fns glues,
|
@glue_fns glues,
|
||||||
namegen names,
|
namegen names,
|
||||||
@ -327,6 +328,24 @@ fn T_opaque_closure_ptr() -> TypeRef {
|
|||||||
T_nil());
|
T_nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn T_captured_tydescs(uint n) -> TypeRef {
|
||||||
|
ret T_struct(_vec.init_elt[TypeRef](T_ptr(T_tydesc()), n));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn T_obj(uint n_captured_tydescs, TypeRef llfields_ty) -> TypeRef {
|
||||||
|
ret T_struct(vec(T_ptr(T_tydesc()),
|
||||||
|
T_captured_tydescs(n_captured_tydescs),
|
||||||
|
llfields_ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn T_obj_ptr(uint n_captured_tydescs, TypeRef llfields_ty) -> TypeRef {
|
||||||
|
ret T_ptr(T_box(T_obj(n_captured_tydescs, llfields_ty)));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn T_opaque_obj_ptr() -> TypeRef {
|
||||||
|
ret T_obj_ptr(0u, T_nil());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
|
fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
|
||||||
let TypeRef llty = type_of_inner(cx, t);
|
let TypeRef llty = type_of_inner(cx, t);
|
||||||
@ -455,11 +474,9 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
|
|||||||
mtys += T_ptr(mty);
|
mtys += T_ptr(mty);
|
||||||
}
|
}
|
||||||
let TypeRef vtbl = T_struct(mtys);
|
let TypeRef vtbl = T_struct(mtys);
|
||||||
let TypeRef body = T_struct(vec(T_ptr(T_tydesc()),
|
let TypeRef pair = T_struct(vec(T_ptr(vtbl),
|
||||||
T_nil()));
|
T_opaque_obj_ptr()));
|
||||||
let TypeRef pair =
|
|
||||||
T_struct(vec(T_ptr(vtbl),
|
|
||||||
T_ptr(T_box(body))));
|
|
||||||
auto abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
|
auto abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
|
||||||
llvm.LLVMRefineType(abs_pair, pair);
|
llvm.LLVMRefineType(abs_pair, pair);
|
||||||
abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
|
abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
|
||||||
@ -963,6 +980,7 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
|
|||||||
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
||||||
alt (ty.type_param(t)) {
|
alt (ty.type_param(t)) {
|
||||||
case (some[ast.def_id](?id)) {
|
case (some[ast.def_id](?id)) {
|
||||||
|
check (cx.fcx.lltydescs.contains_key(id));
|
||||||
ret res(cx, cx.fcx.lltydescs.get(id));
|
ret res(cx, cx.fcx.lltydescs.get(id));
|
||||||
}
|
}
|
||||||
case (none[ast.def_id]) { /* fall through */ }
|
case (none[ast.def_id]) { /* fall through */ }
|
||||||
@ -3474,7 +3492,7 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
|
|||||||
ret ret_ty_of_fn_ty(ty.ann_to_type(ann));
|
ret ret_ty_of_fn_ty(ty.ann_to_type(ann));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
|
fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) {
|
||||||
|
|
||||||
let vec[TypeRef] llfield_tys = vec();
|
let vec[TypeRef] llfield_tys = vec();
|
||||||
|
|
||||||
@ -3482,11 +3500,9 @@ fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
|
|||||||
llfield_tys += node_type(cx.fcx.ccx, f.ann);
|
llfield_tys += node_type(cx.fcx.ccx, f.ann);
|
||||||
}
|
}
|
||||||
|
|
||||||
let TypeRef llfields_ty = T_struct(llfield_tys);
|
auto n_typarams = _vec.len[ast.ty_param](cx.fcx.ccx.obj_typarams);
|
||||||
let TypeRef lltydesc_ty = T_ptr(T_tydesc());
|
let TypeRef llobj_box_ty = T_obj_ptr(n_typarams,
|
||||||
let TypeRef llobj_body_ty = T_struct(vec(lltydesc_ty,
|
T_struct(llfield_tys));
|
||||||
llfields_ty));
|
|
||||||
let TypeRef llobj_box_ty = T_ptr(T_box(llobj_body_ty));
|
|
||||||
|
|
||||||
auto box_cell =
|
auto box_cell =
|
||||||
cx.build.GEP(llself,
|
cx.build.GEP(llself,
|
||||||
@ -3497,12 +3513,28 @@ fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
|
|||||||
|
|
||||||
box_ptr = cx.build.PointerCast(box_ptr, llobj_box_ty);
|
box_ptr = cx.build.PointerCast(box_ptr, llobj_box_ty);
|
||||||
|
|
||||||
|
auto obj_typarams = cx.build.GEP(box_ptr,
|
||||||
|
vec(C_int(0),
|
||||||
|
C_int(abi.box_rc_field_body),
|
||||||
|
C_int(abi.obj_body_elt_typarams)));
|
||||||
|
|
||||||
auto obj_fields = cx.build.GEP(box_ptr,
|
auto obj_fields = cx.build.GEP(box_ptr,
|
||||||
vec(C_int(0),
|
vec(C_int(0),
|
||||||
C_int(abi.box_rc_field_body),
|
C_int(abi.box_rc_field_body),
|
||||||
C_int(abi.obj_body_elt_fields)));
|
C_int(abi.obj_body_elt_fields)));
|
||||||
|
|
||||||
let int i = 0;
|
let int i = 0;
|
||||||
|
|
||||||
|
for (ast.ty_param p in cx.fcx.ccx.obj_typarams) {
|
||||||
|
let ValueRef lltyparam = cx.build.GEP(obj_typarams,
|
||||||
|
vec(C_int(0),
|
||||||
|
C_int(i)));
|
||||||
|
lltyparam = cx.build.Load(lltyparam);
|
||||||
|
cx.fcx.lltydescs.insert(p.id, lltyparam);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
|
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
|
||||||
let ValueRef llfield = cx.build.GEP(obj_fields,
|
let ValueRef llfield = cx.build.GEP(obj_fields,
|
||||||
vec(C_int(0),
|
vec(C_int(0),
|
||||||
@ -3529,7 +3561,7 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
|
|||||||
|
|
||||||
alt (fcx.llself) {
|
alt (fcx.llself) {
|
||||||
case (some[ValueRef](?llself)) {
|
case (some[ValueRef](?llself)) {
|
||||||
create_llobjfields_for_fields(bcx, llself);
|
populate_fn_ctxt_from_llself(bcx, llself);
|
||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
}
|
}
|
||||||
@ -3623,10 +3655,11 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
|
|||||||
C_int(abi.obj_field_box)));
|
C_int(abi.obj_field_box)));
|
||||||
bcx.build.Store(vtbl, pair_vtbl);
|
bcx.build.Store(vtbl, pair_vtbl);
|
||||||
|
|
||||||
let TypeRef llbox_ty = T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc()),
|
let TypeRef llbox_ty = T_opaque_obj_ptr();
|
||||||
T_nil()))));
|
|
||||||
if (_vec.len[ty.arg](arg_tys) == 0u) {
|
if (_vec.len[ast.ty_param](ty_params) == 0u &&
|
||||||
// Store null into pair, if no args.
|
_vec.len[ty.arg](arg_tys) == 0u) {
|
||||||
|
// Store null into pair, if no args or typarams.
|
||||||
bcx.build.Store(C_null(llbox_ty), pair_box);
|
bcx.build.Store(C_null(llbox_ty), pair_box);
|
||||||
} else {
|
} else {
|
||||||
// Malloc a box for the body and copy args in.
|
// Malloc a box for the body and copy args in.
|
||||||
@ -3636,8 +3669,16 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Synthesize an obj body type.
|
// Synthesize an obj body type.
|
||||||
|
auto tydesc_ty = plain_ty(ty.ty_type);
|
||||||
|
let vec[@ty.t] tps = vec();
|
||||||
|
for (ast.ty_param tp in ty_params) {
|
||||||
|
append[@ty.t](tps, tydesc_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
let @ty.t typarams_ty = plain_ty(ty.ty_tup(tps));
|
||||||
let @ty.t fields_ty = plain_ty(ty.ty_tup(obj_fields));
|
let @ty.t fields_ty = plain_ty(ty.ty_tup(obj_fields));
|
||||||
let @ty.t body_ty = plain_ty(ty.ty_tup(vec(plain_ty(ty.ty_type),
|
let @ty.t body_ty = plain_ty(ty.ty_tup(vec(tydesc_ty,
|
||||||
|
typarams_ty,
|
||||||
fields_ty)));
|
fields_ty)));
|
||||||
let @ty.t boxed_body_ty = plain_ty(ty.ty_box(body_ty));
|
let @ty.t boxed_body_ty = plain_ty(ty.ty_box(body_ty));
|
||||||
|
|
||||||
@ -3664,13 +3705,28 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
|
|||||||
bcx = body_td.bcx;
|
bcx = body_td.bcx;
|
||||||
bcx.build.Store(body_td.val, body_tydesc.val);
|
bcx.build.Store(body_td.val, body_tydesc.val);
|
||||||
|
|
||||||
|
// Copy typarams into captured typarams.
|
||||||
|
auto body_typarams =
|
||||||
|
GEP_tup_like(bcx, body_ty, body.val,
|
||||||
|
vec(0, abi.obj_body_elt_typarams));
|
||||||
|
bcx = body_typarams.bcx;
|
||||||
|
let int i = 0;
|
||||||
|
for (ast.ty_param tp in ty_params) {
|
||||||
|
auto typaram = bcx.fcx.lltydescs.get(tp.id);
|
||||||
|
auto capture = GEP_tup_like(bcx, typarams_ty, body_typarams.val,
|
||||||
|
vec(0, i));
|
||||||
|
bcx = capture.bcx;
|
||||||
|
bcx = copy_ty(bcx, INIT, capture.val, typaram, tydesc_ty).bcx;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy args into body fields.
|
// Copy args into body fields.
|
||||||
auto body_fields =
|
auto body_fields =
|
||||||
GEP_tup_like(bcx, body_ty, body.val,
|
GEP_tup_like(bcx, body_ty, body.val,
|
||||||
vec(0, abi.obj_body_elt_fields));
|
vec(0, abi.obj_body_elt_fields));
|
||||||
bcx = body_fields.bcx;
|
bcx = body_fields.bcx;
|
||||||
|
|
||||||
let int i = 0;
|
i = 0;
|
||||||
for (ast.obj_field f in ob.fields) {
|
for (ast.obj_field f in ob.fields) {
|
||||||
auto arg = bcx.fcx.llargs.get(f.id);
|
auto arg = bcx.fcx.llargs.get(f.id);
|
||||||
arg = load_scalar_or_boxed(bcx, arg, arg_tys.(i).ty);
|
arg = load_scalar_or_boxed(bcx, arg, arg_tys.(i).ty);
|
||||||
@ -3792,6 +3848,7 @@ fn trans_item(@crate_ctxt cx, &ast.item item) {
|
|||||||
}
|
}
|
||||||
case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
|
case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
|
||||||
auto sub_cx = @rec(path=cx.path + "." + name,
|
auto sub_cx = @rec(path=cx.path + "." + name,
|
||||||
|
obj_typarams=tps,
|
||||||
obj_fields=ob.fields with *cx);
|
obj_fields=ob.fields with *cx);
|
||||||
trans_obj(sub_cx, ob, oid, tps, ann);
|
trans_obj(sub_cx, ob, oid, tps, ann);
|
||||||
}
|
}
|
||||||
@ -4353,6 +4410,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
|
|||||||
auto hasher = ty.hash_ty;
|
auto hasher = ty.hash_ty;
|
||||||
auto eqer = ty.eq_ty;
|
auto eqer = ty.eq_ty;
|
||||||
auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
|
auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
|
||||||
|
let vec[ast.ty_param] obj_typarams = vec();
|
||||||
let vec[ast.obj_field] obj_fields = vec();
|
let vec[ast.obj_field] obj_fields = vec();
|
||||||
|
|
||||||
auto cx = @rec(sess = sess,
|
auto cx = @rec(sess = sess,
|
||||||
@ -4369,6 +4427,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
|
|||||||
consts = new_def_hash[ValueRef](),
|
consts = new_def_hash[ValueRef](),
|
||||||
obj_methods = new_def_hash[()](),
|
obj_methods = new_def_hash[()](),
|
||||||
tydescs = tydescs,
|
tydescs = tydescs,
|
||||||
|
obj_typarams = obj_typarams,
|
||||||
obj_fields = obj_fields,
|
obj_fields = obj_fields,
|
||||||
glues = glues,
|
glues = glues,
|
||||||
names = namegen(0),
|
names = namegen(0),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user