aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/comp/middle/trans.rs46
1 files changed, 30 insertions, 16 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 0de5b56b..ac8d96ae 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -77,6 +77,7 @@ state type fn_ctxt = rec(ValueRef llfn,
ValueRef lltaskptr,
hashmap[ast.def_id, ValueRef] llargs,
hashmap[ast.def_id, ValueRef] lllocals,
+ hashmap[ast.def_id, ValueRef] lltydescs,
@crate_ctxt ccx);
tag cleanup {
@@ -2261,17 +2262,27 @@ fn new_fn_ctxt(@crate_ctxt cx,
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
let hashmap[ast.def_id, ValueRef] llargs = new_def_hash[ValueRef]();
+ let hashmap[ast.def_id, ValueRef] lltydescs = new_def_hash[ValueRef]();
ret @rec(llfn=llfndecl,
lltaskptr=lltaskptr,
llargs=llargs,
lllocals=lllocals,
+ lltydescs=lltydescs,
ccx=cx);
}
-fn create_llargs_for_fn_args(@fn_ctxt cx, vec[ast.arg] args) {
+fn create_llargs_for_fn_args(&@fn_ctxt cx, &vec[ast.arg] args,
+ &vec[ast.ty_param] ty_params) {
let uint arg_n = 1u;
+ for (ast.ty_param tp in ty_params) {
+ auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
+ check (llarg as int != 0);
+ cx.lltydescs.insert(tp.id, llarg);
+ arg_n += 1u;
+ }
+
for (ast.arg arg in args) {
auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
check (llarg as int != 0);
@@ -2328,13 +2339,13 @@ fn ret_ty_of_fn(ast.ann ann) -> @typeck.ty {
}
impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
- &ast.ann ann) {
+ &vec[ast.ty_param] ty_params, &ast.ann ann) {
auto llfndecl = cx.item_ids.get(fid);
cx.item_names.insert(cx.path, llfndecl);
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
- create_llargs_for_fn_args(fcx, f.inputs);
+ create_llargs_for_fn_args(fcx, f.inputs, ty_params);
auto bcx = new_top_block_ctxt(fcx);
@@ -2348,7 +2359,8 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
}
}
-impure fn trans_vtbl(@crate_ctxt cx, &ast._obj ob) -> ValueRef {
+impure fn trans_vtbl(@crate_ctxt cx, &ast._obj ob,
+ &vec[ast.ty_param] ty_params) -> ValueRef {
let vec[ValueRef] methods = vec();
for (@ast.method m in ob.methods) {
@@ -2357,7 +2369,7 @@ impure fn trans_vtbl(@crate_ctxt cx, &ast._obj ob) -> ValueRef {
let ValueRef llfn = decl_fastcall_fn(cx.llmod, s, llfnty);
cx.item_ids.insert(m.node.id, llfn);
- trans_fn(cx, m.node.meth, m.node.id, m.node.ann);
+ trans_fn(cx, m.node.meth, m.node.id, ty_params, m.node.ann);
methods += llfn;
}
auto vtbl = C_struct(methods);
@@ -2370,7 +2382,7 @@ impure fn trans_vtbl(@crate_ctxt cx, &ast._obj ob) -> ValueRef {
}
impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
- &ast.ann ann) {
+ &vec[ast.ty_param] ty_params, &ast.ann ann) {
auto llctor_decl = cx.item_ids.get(oid);
cx.item_names.insert(cx.path, llctor_decl);
@@ -2385,14 +2397,14 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
}
auto fcx = new_fn_ctxt(cx, cx.path, llctor_decl);
- create_llargs_for_fn_args(fcx, fn_args);
+ create_llargs_for_fn_args(fcx, fn_args, ty_params);
auto bcx = new_top_block_ctxt(fcx);
copy_args_to_allocas(bcx, fn_args, arg_tys_of_fn(ann));
auto pair = bcx.build.Alloca(type_of(cx, ret_ty_of_fn(ann)));
- auto vtbl = trans_vtbl(cx, ob);
+ auto vtbl = trans_vtbl(cx, ob, ty_params);
auto pair_vtbl = bcx.build.GEP(pair,
vec(C_int(0),
C_int(abi.obj_field_vtbl)));
@@ -2401,7 +2413,8 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
}
fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
- &ast.variant variant, int index) {
+ &ast.variant variant, int index,
+ &vec[ast.ty_param] ty_params) {
if (_vec.len[ast.variant_arg](variant.args) == 0u) {
ret; // nullary constructors are just constants
}
@@ -2427,7 +2440,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
cx.item_names.insert(cx.path, llfndecl);
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
- create_llargs_for_fn_args(fcx, fn_args);
+ create_llargs_for_fn_args(fcx, fn_args, ty_params);
auto bcx = new_top_block_ctxt(fcx);
@@ -2473,23 +2486,23 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
impure fn trans_item(@crate_ctxt cx, &ast.item item) {
alt (item.node) {
- case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
+ case (ast.item_fn(?name, ?f, ?tps, ?fid, ?ann)) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
- trans_fn(sub_cx, f, fid, ann);
+ trans_fn(sub_cx, f, fid, tps, ann);
}
- case (ast.item_obj(?name, ?ob, _, ?oid, ?ann)) {
+ case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
- trans_obj(sub_cx, ob, oid, ann);
+ trans_obj(sub_cx, ob, oid, tps, ann);
}
case (ast.item_mod(?name, ?m, _)) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
trans_mod(sub_cx, m);
}
- case (ast.item_tag(?name, ?variants, _, ?tag_id)) {
+ case (ast.item_tag(?name, ?variants, ?tps, ?tag_id)) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
auto i = 0;
for (ast.variant variant in variants) {
- trans_tag_variant(sub_cx, tag_id, variant, i);
+ trans_tag_variant(sub_cx, tag_id, variant, i, tps);
i += 1;
}
}
@@ -2694,6 +2707,7 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
lltaskptr=lltaskptr,
llargs=new_def_hash[ValueRef](),
lllocals=new_def_hash[ValueRef](),
+ lltydescs=new_def_hash[ValueRef](),
ccx=cx);
auto bcx = new_top_block_ctxt(fcx);