aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-12-22 13:56:51 -0800
committerGraydon Hoare <[email protected]>2010-12-22 13:56:51 -0800
commitac270fc8549b12040b6e71ad8e30634157ec6c96 (patch)
tree04a49655b00c05e8fc879e68227911a5a877f010 /src
parentrustc: Move unification out of typeck.rs; trans will need it too. (diff)
downloadrust-ac270fc8549b12040b6e71ad8e30634157ec6c96.tar.xz
rust-ac270fc8549b12040b6e71ad8e30634157ec6c96.zip
Allocate heap cells to store non-empty object bodies.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs55
1 files changed, 45 insertions, 10 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 190b71f0..1ed9370c 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -18,6 +18,7 @@ import back.abi;
import middle.ty.pat_ty;
import util.common;
+import util.common.append;
import util.common.istr;
import util.common.new_def_hash;
import util.common.new_str_hash;
@@ -566,15 +567,20 @@ fn align_of(TypeRef t) -> ValueRef {
ret llvm.LLVMConstIntCast(lib.llvm.llvm.LLVMAlignOf(t), T_int(), False);
}
-fn trans_malloc(@block_ctxt cx, @ty.t t) -> result {
- auto scope_cx = find_scope_cx(cx);
- auto ptr_ty = type_of(cx.fcx.ccx, t);
- auto body_ty = lib.llvm.llvm.LLVMGetElementType(ptr_ty);
+fn trans_malloc_inner(@block_ctxt cx, TypeRef llptr_ty) -> result {
+ auto llbody_ty = lib.llvm.llvm.LLVMGetElementType(llptr_ty);
// FIXME: need a table to collect tydesc globals.
auto tydesc = C_int(0);
- auto sz = size_of(body_ty);
+ auto sz = size_of(llbody_ty);
auto sub = trans_upcall(cx, "upcall_malloc", vec(sz, tydesc));
- sub.val = sub.bcx.build.IntToPtr(sub.val, ptr_ty);
+ sub.val = sub.bcx.build.IntToPtr(sub.val, llptr_ty);
+ ret sub;
+}
+
+fn trans_malloc(@block_ctxt cx, @ty.t t) -> result {
+ auto scope_cx = find_scope_cx(cx);
+ auto llptr_ty = type_of(cx.fcx.ccx, t);
+ auto sub = trans_malloc_inner(cx, llptr_ty);
scope_cx.cleanups += clean(bind drop_ty(_, sub.val, t));
ret sub;
}
@@ -2442,7 +2448,7 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
auto llctor_decl = cx.item_ids.get(oid);
cx.item_names.insert(cx.path, llctor_decl);
- // Translate obj ctor fields to function arguments.
+ // Translate obj ctor args to function arguments.
let vec[ast.arg] fn_args = vec();
for (ast.obj_field f in ob.fields) {
fn_args += vec(rec(mode=ast.alias,
@@ -2456,7 +2462,8 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
auto bcx = new_top_block_ctxt(fcx);
- copy_args_to_allocas(bcx, fn_args, arg_tys_of_fn(ann));
+ let vec[ty.arg] arg_tys = arg_tys_of_fn(ann);
+ copy_args_to_allocas(bcx, fn_args, arg_tys);
auto pair = bcx.build.Alloca(type_of(cx, ret_ty_of_fn(ann)));
auto vtbl = trans_vtbl(cx, ob, ty_params);
@@ -2468,9 +2475,37 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
C_int(abi.obj_field_box)));
bcx.build.Store(vtbl, pair_vtbl);
- // FIXME: allocate the object body, copy the args in, etc.
- bcx.build.Store(C_null(T_ptr(T_box(T_nil()))), pair_box);
+ let TypeRef llbox_ty = T_ptr(T_box(T_nil()));
+ if (_vec.len[ty.arg](arg_tys) == 0u) {
+ // Store null into pair, if no args.
+ bcx.build.Store(C_null(llbox_ty), pair_box);
+ } else {
+ // Malloc a box for the body and copy args in.
+ let vec[@ty.t] obj_fields = vec();
+ for (ty.arg a in arg_tys) {
+ append[@ty.t](obj_fields, a.ty);
+ }
+ // Synthesize an obj body:
+ let @ty.t fields_ty = ty.plain_ty(ty.ty_tup(obj_fields));
+ let TypeRef llfields_ty = type_of(bcx.fcx.ccx, fields_ty);
+ let TypeRef llobj_body_ty =
+ T_ptr(T_box(T_struct(vec(T_tydesc(),
+ llfields_ty))));
+ auto r = trans_malloc_inner(bcx, llobj_body_ty);
+ auto box = r.val;
+ auto rc = r.bcx.build.GEP(box,
+ vec(C_int(0),
+ C_int(abi.box_rc_field_refcnt)));
+ auto body = r.bcx.build.GEP(box,
+ vec(C_int(0),
+ C_int(abi.box_rc_field_body)));
+ r.bcx.build.Store(C_int(1), rc);
+
+ // FIXME: Copy args into body
+ auto p = r.bcx.build.PointerCast(box, llbox_ty);
+ r.bcx.build.Store(p, pair_box);
+ }
bcx.build.Ret(bcx.build.Load(pair));
}