Glob-import trans_build in other trans files
The capitalization already prevents name clashes. Being able to refer to the bitcode-construction primitives directly makes the code cleaner.
This commit is contained in:
parent
41fb042def
commit
c1ba28c777
3 changed files with 448 additions and 449 deletions
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ import lib::llvm::llvm;
|
||||||
import lib::llvm::llvm::ValueRef;
|
import lib::llvm::llvm::ValueRef;
|
||||||
import lib::llvm::llvm::TypeRef;
|
import lib::llvm::llvm::TypeRef;
|
||||||
import lib::llvm::llvm::BasicBlockRef;
|
import lib::llvm::llvm::BasicBlockRef;
|
||||||
import bld = trans_build;
|
import trans_build::*;
|
||||||
import trans::new_sub_block_ctxt;
|
import trans::new_sub_block_ctxt;
|
||||||
import trans::new_scope_block_ctxt;
|
import trans::new_scope_block_ctxt;
|
||||||
import trans::load_if_immediate;
|
import trans::load_if_immediate;
|
||||||
|
@ -212,9 +212,9 @@ fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
|
||||||
vec::len(ty::tag_variant_with_id(ccx.tcx, vdefs.tg, vdefs.var).args);
|
vec::len(ty::tag_variant_with_id(ccx.tcx, vdefs.tg, vdefs.var).args);
|
||||||
if size > 0u && vec::len(variants) != 1u {
|
if size > 0u && vec::len(variants) != 1u {
|
||||||
let tagptr =
|
let tagptr =
|
||||||
bld::PointerCast(bcx, val,
|
PointerCast(bcx, val,
|
||||||
trans_common::T_opaque_tag_ptr(ccx.tn));
|
trans_common::T_opaque_tag_ptr(ccx.tn));
|
||||||
blobptr = bld::GEP(bcx, tagptr, [C_int(0), C_int(1)]);
|
blobptr = GEP(bcx, tagptr, [C_int(0), C_int(1)]);
|
||||||
}
|
}
|
||||||
let i = 0u;
|
let i = 0u;
|
||||||
while i < size {
|
while i < size {
|
||||||
|
@ -291,7 +291,7 @@ fn pick_col(m: &match) -> uint {
|
||||||
|
|
||||||
fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
f: &mk_fail, exits: &mutable [exit_node]) {
|
f: &mk_fail, exits: &mutable [exit_node]) {
|
||||||
if vec::len(m) == 0u { bld::Br(bcx, f()); ret; }
|
if vec::len(m) == 0u { Br(bcx, f()); ret; }
|
||||||
if vec::len(m[0].pats) == 0u {
|
if vec::len(m[0].pats) == 0u {
|
||||||
let data = m[0].data;
|
let data = m[0].data;
|
||||||
alt data.guard {
|
alt data.guard {
|
||||||
|
@ -299,7 +299,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
let guard_cx = new_scope_block_ctxt(bcx, ~"guard");
|
let guard_cx = new_scope_block_ctxt(bcx, ~"guard");
|
||||||
let next_cx = new_sub_block_ctxt(bcx, ~"next");
|
let next_cx = new_sub_block_ctxt(bcx, ~"next");
|
||||||
let else_cx = new_sub_block_ctxt(bcx, ~"else");
|
let else_cx = new_sub_block_ctxt(bcx, ~"else");
|
||||||
bld::Br(bcx, guard_cx.llbb);
|
Br(bcx, guard_cx.llbb);
|
||||||
// Temporarily set bindings. They'll be rewritten to PHI nodes for
|
// Temporarily set bindings. They'll be rewritten to PHI nodes for
|
||||||
// the actual arm block.
|
// the actual arm block.
|
||||||
for each @{key, val} in data.id_map.items() {
|
for each @{key, val} in data.id_map.items() {
|
||||||
|
@ -310,7 +310,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
let {bcx: guard_bcx, val: guard_val} =
|
let {bcx: guard_bcx, val: guard_val} =
|
||||||
trans::trans_expr(guard_cx, e);
|
trans::trans_expr(guard_cx, e);
|
||||||
guard_bcx = trans::trans_block_cleanups(guard_bcx, guard_cx);
|
guard_bcx = trans::trans_block_cleanups(guard_bcx, guard_cx);
|
||||||
bld::CondBr(guard_bcx, guard_val, next_cx.llbb, else_cx.llbb);
|
CondBr(guard_bcx, guard_val, next_cx.llbb, else_cx.llbb);
|
||||||
compile_submatch(else_cx, vec::slice(m, 1u, vec::len(m)),
|
compile_submatch(else_cx, vec::slice(m, 1u, vec::len(m)),
|
||||||
vals, f, exits);
|
vals, f, exits);
|
||||||
bcx = next_cx;
|
bcx = next_cx;
|
||||||
|
@ -318,7 +318,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
exits += [{bound: m[0].bound, from: bcx.llbb, to: data.body}];
|
exits += [{bound: m[0].bound, from: bcx.llbb, to: data.body}];
|
||||||
bld::Br(bcx, data.body);
|
Br(bcx, data.body);
|
||||||
ret;
|
ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,9 +375,9 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
|
|
||||||
// Unbox in case of a box field
|
// Unbox in case of a box field
|
||||||
if any_box_pat(m, col) {
|
if any_box_pat(m, col) {
|
||||||
let box = bld::Load(bcx, val);
|
let box = Load(bcx, val);
|
||||||
let unboxed =
|
let unboxed =
|
||||||
bld::InBoundsGEP(bcx, box,
|
InBoundsGEP(bcx, box,
|
||||||
[C_int(0),
|
[C_int(0),
|
||||||
C_int(back::abi::box_rc_field_body)]);
|
C_int(back::abi::box_rc_field_body)]);
|
||||||
compile_submatch(bcx, enter_box(m, col, val), [unboxed] + vals_left,
|
compile_submatch(bcx, enter_box(m, col, val), [unboxed] + vals_left,
|
||||||
|
@ -397,15 +397,15 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
kind = single;
|
kind = single;
|
||||||
} else {
|
} else {
|
||||||
let tagptr =
|
let tagptr =
|
||||||
bld::PointerCast(bcx, val,
|
PointerCast(bcx, val,
|
||||||
trans_common::T_opaque_tag_ptr(ccx.tn));
|
trans_common::T_opaque_tag_ptr(ccx.tn));
|
||||||
let discrimptr = bld::GEP(bcx, tagptr, [C_int(0), C_int(0)]);
|
let discrimptr = GEP(bcx, tagptr, [C_int(0), C_int(0)]);
|
||||||
test_val = bld::Load(bcx, discrimptr);
|
test_val = Load(bcx, discrimptr);
|
||||||
kind = switch;
|
kind = switch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lit(l) {
|
lit(l) {
|
||||||
test_val = bld::Load(bcx, val);
|
test_val = Load(bcx, val);
|
||||||
kind = alt l.node { ast::lit_str(_, _) { compare } _ { switch } };
|
kind = alt l.node { ast::lit_str(_, _) { compare } _ { switch } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,14 +417,14 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
};
|
};
|
||||||
let sw =
|
let sw =
|
||||||
if kind == switch {
|
if kind == switch {
|
||||||
bld::Switch(bcx, test_val, else_cx.llbb, vec::len(opts))
|
Switch(bcx, test_val, else_cx.llbb, vec::len(opts))
|
||||||
} else { C_int(0) }; // Placeholder for when not using a switch
|
} else { C_int(0) }; // Placeholder for when not using a switch
|
||||||
|
|
||||||
// Compile subtrees for each option
|
// Compile subtrees for each option
|
||||||
for opt: opt in opts {
|
for opt: opt in opts {
|
||||||
let opt_cx = new_sub_block_ctxt(bcx, ~"match_case");
|
let opt_cx = new_sub_block_ctxt(bcx, ~"match_case");
|
||||||
alt kind {
|
alt kind {
|
||||||
single. { bld::Br(bcx, opt_cx.llbb); }
|
single. { Br(bcx, opt_cx.llbb); }
|
||||||
switch. {
|
switch. {
|
||||||
let r = trans_opt(bcx, opt);
|
let r = trans_opt(bcx, opt);
|
||||||
bcx = r.bcx;
|
bcx = r.bcx;
|
||||||
|
@ -437,7 +437,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
let eq =
|
let eq =
|
||||||
trans::trans_compare(bcx, ast::eq, test_val, t, r.val, t);
|
trans::trans_compare(bcx, ast::eq, test_val, t, r.val, t);
|
||||||
bcx = new_sub_block_ctxt(bcx, ~"next");
|
bcx = new_sub_block_ctxt(bcx, ~"next");
|
||||||
bld::CondBr(eq.bcx, eq.val, opt_cx.llbb, bcx.llbb);
|
CondBr(eq.bcx, eq.val, opt_cx.llbb, bcx.llbb);
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile the fall-through case
|
// Compile the fall-through case
|
||||||
if kind == compare { bld::Br(bcx, else_cx.llbb); }
|
if kind == compare { Br(bcx, else_cx.llbb); }
|
||||||
if kind != single {
|
if kind != single {
|
||||||
compile_submatch(else_cx, enter_default(m, col, val), vals_left, f,
|
compile_submatch(else_cx, enter_default(m, col, val), vals_left, f,
|
||||||
exits);
|
exits);
|
||||||
|
@ -481,7 +481,7 @@ fn make_phi_bindings(bcx: &@block_ctxt, map: &[exit_node],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if vec::len(vals) > 0u {
|
if vec::len(vals) > 0u {
|
||||||
let phi = bld::Phi(bcx, val_ty(vals[0]), vals, llbbs);
|
let phi = Phi(bcx, val_ty(vals[0]), vals, llbbs);
|
||||||
bcx.fcx.lllocals.insert(item.val, phi);
|
bcx.fcx.lllocals.insert(item.val, phi);
|
||||||
} else { success = false; }
|
} else { success = false; }
|
||||||
}
|
}
|
||||||
|
@ -498,7 +498,7 @@ fn trans_alt(cx: &@block_ctxt, expr: &@ast::expr, arms: &[ast::arm],
|
||||||
// No need to generate code for alt,
|
// No need to generate code for alt,
|
||||||
// since the disc diverges.
|
// since the disc diverges.
|
||||||
if !is_terminated(cx) {
|
if !is_terminated(cx) {
|
||||||
ret rslt(cx, bld::Unreachable(cx));
|
ret rslt(cx, Unreachable(cx));
|
||||||
} else { ret er; }
|
} else { ret er; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,9 +596,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::pat_box(inner) {
|
ast::pat_box(inner) {
|
||||||
let box = bld::Load(bcx, val);
|
let box = Load(bcx, val);
|
||||||
let unboxed =
|
let unboxed = InBoundsGEP(bcx, box,
|
||||||
bld::InBoundsGEP(bcx, box,
|
|
||||||
[C_int(0),
|
[C_int(0),
|
||||||
C_int(back::abi::box_rc_field_body)]);
|
C_int(back::abi::box_rc_field_body)]);
|
||||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, table, true);
|
bcx = bind_irrefutable_pat(bcx, inner, unboxed, table, true);
|
||||||
|
|
|
@ -22,7 +22,7 @@ import syntax::codemap::span;
|
||||||
|
|
||||||
import trans_common::*;
|
import trans_common::*;
|
||||||
import trans::*;
|
import trans::*;
|
||||||
import bld = trans_build;
|
import trans_build::*;
|
||||||
|
|
||||||
export trans_anon_obj;
|
export trans_anon_obj;
|
||||||
export trans_obj;
|
export trans_obj;
|
||||||
|
@ -81,17 +81,17 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
||||||
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
|
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
|
||||||
// of 'pair'.
|
// of 'pair'.
|
||||||
let pair_vtbl =
|
let pair_vtbl =
|
||||||
bld::GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||||
let pair_box = bld::GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
|
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
|
||||||
|
|
||||||
// Make a vtable for this object: a static array of pointers to functions.
|
// Make a vtable for this object: a static array of pointers to functions.
|
||||||
// It will be located in the read-only memory of the executable we're
|
// It will be located in the read-only memory of the executable we're
|
||||||
// creating and will contain ValueRefs for all of this object's methods.
|
// creating and will contain ValueRefs for all of this object's methods.
|
||||||
// create_vtbl returns a pointer to the vtable, which we store.
|
// create_vtbl returns a pointer to the vtable, which we store.
|
||||||
let vtbl = create_vtbl(cx, sp, self_ty, ob, ty_params, none, []);
|
let vtbl = create_vtbl(cx, sp, self_ty, ob, ty_params, none, []);
|
||||||
vtbl = bld::PointerCast(bcx, vtbl, T_ptr(T_empty_struct()));
|
vtbl = PointerCast(bcx, vtbl, T_ptr(T_empty_struct()));
|
||||||
|
|
||||||
bld::Store(bcx, vtbl, pair_vtbl);
|
Store(bcx, vtbl, pair_vtbl);
|
||||||
|
|
||||||
// Next we have to take care of the other half of the pair we're
|
// Next we have to take care of the other half of the pair we're
|
||||||
// returning: a boxed (reference-counted) tuple containing a tydesc,
|
// returning: a boxed (reference-counted) tuple containing a tydesc,
|
||||||
|
@ -104,7 +104,7 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
||||||
// there's not much to do.
|
// there's not much to do.
|
||||||
|
|
||||||
// Store null into pair, if no args or typarams.
|
// Store null into pair, if no args or typarams.
|
||||||
bld::Store(bcx, C_null(llbox_ty), pair_box);
|
Store(bcx, C_null(llbox_ty), pair_box);
|
||||||
} else {
|
} else {
|
||||||
let obj_fields: [ty::t] = [];
|
let obj_fields: [ty::t] = [];
|
||||||
for a: ty::arg in arg_tys { obj_fields += [a.ty]; }
|
for a: ty::arg in arg_tys { obj_fields += [a.ty]; }
|
||||||
|
@ -146,7 +146,7 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
||||||
bcx = body_td.bcx;
|
bcx = body_td.bcx;
|
||||||
bld::Store(bcx, body_td.val, body_tydesc.val);
|
Store(bcx, body_td.val, body_tydesc.val);
|
||||||
|
|
||||||
// Copy the object's type parameters and fields into the space we
|
// Copy the object's type parameters and fields into the space we
|
||||||
// allocated for the object body. (This is something like saving the
|
// allocated for the object body. (This is something like saving the
|
||||||
|
@ -193,8 +193,8 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store box ptr in outer pair.
|
// Store box ptr in outer pair.
|
||||||
let p = bld::PointerCast(bcx, box.box, llbox_ty);
|
let p = PointerCast(bcx, box.box, llbox_ty);
|
||||||
bld::Store(bcx, p, pair_box);
|
Store(bcx, p, pair_box);
|
||||||
}
|
}
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
|
|
||||||
|
@ -287,11 +287,11 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
||||||
|
|
||||||
// Grab onto the first and second elements of the pair.
|
// Grab onto the first and second elements of the pair.
|
||||||
let pair_vtbl =
|
let pair_vtbl =
|
||||||
bld::GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||||
let pair_box = bld::GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
|
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
|
||||||
|
|
||||||
vtbl = bld::PointerCast(bcx, vtbl, T_ptr(T_empty_struct()));
|
vtbl = PointerCast(bcx, vtbl, T_ptr(T_empty_struct()));
|
||||||
bld::Store(bcx, vtbl, pair_vtbl);
|
Store(bcx, vtbl, pair_vtbl);
|
||||||
|
|
||||||
// Next we have to take care of the other half of the pair we're
|
// Next we have to take care of the other half of the pair we're
|
||||||
// returning: a boxed (reference-counted) tuple containing a tydesc,
|
// returning: a boxed (reference-counted) tuple containing a tydesc,
|
||||||
|
@ -303,7 +303,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
||||||
|
|
||||||
// If the object we're translating has no fields and no inner_obj,
|
// If the object we're translating has no fields and no inner_obj,
|
||||||
// there's not much to do.
|
// there's not much to do.
|
||||||
bld::Store(bcx, C_null(llbox_ty), pair_box);
|
Store(bcx, C_null(llbox_ty), pair_box);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
|
||||||
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
|
||||||
bcx = body_td.bcx;
|
bcx = body_td.bcx;
|
||||||
bld::Store(bcx, body_td.val, body_tydesc.val);
|
Store(bcx, body_td.val, body_tydesc.val);
|
||||||
|
|
||||||
// Copy the object's fields into the space we allocated for the object
|
// Copy the object's fields into the space we allocated for the object
|
||||||
// body. (This is something like saving the lexical environment of a
|
// body. (This is something like saving the lexical environment of a
|
||||||
|
@ -377,8 +377,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store box ptr in outer pair.
|
// Store box ptr in outer pair.
|
||||||
let p = bld::PointerCast(bcx, box.box, llbox_ty);
|
let p = PointerCast(bcx, box.box, llbox_ty);
|
||||||
bld::Store(bcx, p, pair_box);
|
Store(bcx, p, pair_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the object we built.
|
// return the object we built.
|
||||||
|
@ -630,15 +630,15 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
|
|
||||||
// Cast to self-stack's type.
|
// Cast to self-stack's type.
|
||||||
let llenv =
|
let llenv =
|
||||||
bld::PointerCast(bcx, fcx.llenv,
|
PointerCast(bcx, fcx.llenv,
|
||||||
T_ptr(T_struct([cx.ccx.rust_object_type,
|
T_ptr(T_struct([cx.ccx.rust_object_type,
|
||||||
T_ptr(cx.ccx.rust_object_type)])));
|
T_ptr(cx.ccx.rust_object_type)])));
|
||||||
let llself_obj_ptr = bld::GEP(bcx, llenv, [C_int(0), C_int(1)]);
|
let llself_obj_ptr = GEP(bcx, llenv, [C_int(0), C_int(1)]);
|
||||||
llself_obj_ptr = bld::Load(bcx, llself_obj_ptr);
|
llself_obj_ptr = Load(bcx, llself_obj_ptr);
|
||||||
|
|
||||||
// Cast it back to pointer-to-object-type, so LLVM won't complain.
|
// Cast it back to pointer-to-object-type, so LLVM won't complain.
|
||||||
llself_obj_ptr =
|
llself_obj_ptr =
|
||||||
bld::PointerCast(bcx, llself_obj_ptr, T_ptr(cx.ccx.rust_object_type));
|
PointerCast(bcx, llself_obj_ptr, T_ptr(cx.ccx.rust_object_type));
|
||||||
|
|
||||||
// The 'llretptr' that will arrive in the backwarding function we're
|
// The 'llretptr' that will arrive in the backwarding function we're
|
||||||
// creating also needs to be the correct type. Cast it to the method's
|
// creating also needs to be the correct type. Cast it to the method's
|
||||||
|
@ -646,7 +646,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
let llretptr = fcx.llretptr;
|
let llretptr = fcx.llretptr;
|
||||||
if ty::type_contains_params(cx.ccx.tcx, m.output) {
|
if ty::type_contains_params(cx.ccx.tcx, m.output) {
|
||||||
let llretty = type_of_inner(cx.ccx, sp, m.output);
|
let llretty = type_of_inner(cx.ccx, sp, m.output);
|
||||||
llretptr = bld::PointerCast(bcx, llretptr, T_ptr(llretty));
|
llretptr = PointerCast(bcx, llretptr, T_ptr(llretty));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the index of the method we want.
|
// Get the index of the method we want.
|
||||||
|
@ -666,12 +666,12 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
|
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
|
||||||
|
|
||||||
let llouter_obj_vtbl =
|
let llouter_obj_vtbl =
|
||||||
bld::GEP(bcx, llself_obj_ptr, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
GEP(bcx, llself_obj_ptr, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||||
llouter_obj_vtbl = bld::Load(bcx, llouter_obj_vtbl);
|
llouter_obj_vtbl = Load(bcx, llouter_obj_vtbl);
|
||||||
llouter_obj_vtbl = bld::PointerCast(bcx, llouter_obj_vtbl, vtbl_type);
|
llouter_obj_vtbl = PointerCast(bcx, llouter_obj_vtbl, vtbl_type);
|
||||||
|
|
||||||
let llouter_mthd =
|
let llouter_mthd =
|
||||||
bld::GEP(bcx, llouter_obj_vtbl, [C_int(0), C_int(ix as int)]);
|
GEP(bcx, llouter_obj_vtbl, [C_int(0), C_int(ix as int)]);
|
||||||
|
|
||||||
// Set up the outer method to be called.
|
// Set up the outer method to be called.
|
||||||
let outer_mthd_ty = ty::method_ty_to_fn_ty(cx.ccx.tcx, *m);
|
let outer_mthd_ty = ty::method_ty_to_fn_ty(cx.ccx.tcx, *m);
|
||||||
|
@ -681,8 +681,8 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
m.inputs, m.output,
|
m.inputs, m.output,
|
||||||
std::vec::len::<ast::ty_param>(ty_params));
|
std::vec::len::<ast::ty_param>(ty_params));
|
||||||
llouter_mthd =
|
llouter_mthd =
|
||||||
bld::PointerCast(bcx, llouter_mthd, T_ptr(T_ptr(llouter_mthd_ty)));
|
PointerCast(bcx, llouter_mthd, T_ptr(T_ptr(llouter_mthd_ty)));
|
||||||
llouter_mthd = bld::Load(bcx, llouter_mthd);
|
llouter_mthd = Load(bcx, llouter_mthd);
|
||||||
|
|
||||||
// Set up the three implicit arguments to the outer method we'll need to
|
// Set up the three implicit arguments to the outer method we'll need to
|
||||||
// call.
|
// call.
|
||||||
|
@ -703,7 +703,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
}
|
}
|
||||||
|
|
||||||
// And, finally, call the outer method.
|
// And, finally, call the outer method.
|
||||||
bld::FastCall(bcx, llouter_mthd, llouter_mthd_args);
|
FastCall(bcx, llouter_mthd, llouter_mthd_args);
|
||||||
|
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
finish_fn(fcx, lltop);
|
finish_fn(fcx, lltop);
|
||||||
|
@ -765,7 +765,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
let llretptr = fcx.llretptr;
|
let llretptr = fcx.llretptr;
|
||||||
if ty::type_contains_params(cx.ccx.tcx, m.output) {
|
if ty::type_contains_params(cx.ccx.tcx, m.output) {
|
||||||
let llretty = type_of_inner(cx.ccx, sp, m.output);
|
let llretty = type_of_inner(cx.ccx, sp, m.output);
|
||||||
llretptr = bld::PointerCast(bcx, llretptr, T_ptr(llretty));
|
llretptr = PointerCast(bcx, llretptr, T_ptr(llretty));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, we have to get the the inner_obj's vtbl out of the self_obj. This
|
// Now, we have to get the the inner_obj's vtbl out of the self_obj. This
|
||||||
|
@ -774,16 +774,16 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
// First, grab the box out of the self_obj. It contains a refcount and a
|
// First, grab the box out of the self_obj. It contains a refcount and a
|
||||||
// body.
|
// body.
|
||||||
let llself_obj_box =
|
let llself_obj_box =
|
||||||
bld::GEP(bcx, llself_obj_ptr, [C_int(0), C_int(abi::obj_field_box)]);
|
GEP(bcx, llself_obj_ptr, [C_int(0), C_int(abi::obj_field_box)]);
|
||||||
llself_obj_box = bld::Load(bcx, llself_obj_box);
|
llself_obj_box = Load(bcx, llself_obj_box);
|
||||||
|
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let llbox_ty = T_opaque_obj_ptr(*ccx);
|
let llbox_ty = T_opaque_obj_ptr(*ccx);
|
||||||
llself_obj_box = bld::PointerCast(bcx, llself_obj_box, llbox_ty);
|
llself_obj_box = PointerCast(bcx, llself_obj_box, llbox_ty);
|
||||||
|
|
||||||
// Now, reach into the box and grab the body.
|
// Now, reach into the box and grab the body.
|
||||||
let llself_obj_body =
|
let llself_obj_body =
|
||||||
bld::GEP(bcx, llself_obj_box,
|
GEP(bcx, llself_obj_box,
|
||||||
[C_int(0), C_int(abi::box_rc_field_body)]);
|
[C_int(0), C_int(abi::box_rc_field_body)]);
|
||||||
|
|
||||||
// Now, we need to figure out exactly what type the body is supposed to be
|
// Now, we need to figure out exactly what type the body is supposed to be
|
||||||
|
@ -793,7 +793,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
some(inner_obj_ty));
|
some(inner_obj_ty));
|
||||||
// And cast to that type.
|
// And cast to that type.
|
||||||
llself_obj_body =
|
llself_obj_body =
|
||||||
bld::PointerCast(bcx, llself_obj_body,
|
PointerCast(bcx, llself_obj_body,
|
||||||
T_ptr(type_of(cx.ccx, sp, body_ty)));
|
T_ptr(type_of(cx.ccx, sp, body_ty)));
|
||||||
|
|
||||||
// Now, reach into the body and grab the inner_obj.
|
// Now, reach into the body and grab the inner_obj.
|
||||||
|
@ -807,13 +807,13 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
// method's entry out of the vtable so that the forwarding function can
|
// method's entry out of the vtable so that the forwarding function can
|
||||||
// call it.
|
// call it.
|
||||||
let llinner_obj_vtbl =
|
let llinner_obj_vtbl =
|
||||||
bld::GEP(bcx, llinner_obj.val,
|
GEP(bcx, llinner_obj.val,
|
||||||
[C_int(0), C_int(abi::obj_field_vtbl)]);
|
[C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||||
llinner_obj_vtbl = bld::Load(bcx, llinner_obj_vtbl);
|
llinner_obj_vtbl = Load(bcx, llinner_obj_vtbl);
|
||||||
|
|
||||||
let llinner_obj_body =
|
let llinner_obj_body =
|
||||||
bld::GEP(bcx, llinner_obj.val, [C_int(0), C_int(abi::obj_field_box)]);
|
GEP(bcx, llinner_obj.val, [C_int(0), C_int(abi::obj_field_box)]);
|
||||||
llinner_obj_body = bld::Load(bcx, llinner_obj_body);
|
llinner_obj_body = Load(bcx, llinner_obj_body);
|
||||||
|
|
||||||
// Get the index of the method we want.
|
// Get the index of the method we want.
|
||||||
let ix: uint = 0u;
|
let ix: uint = 0u;
|
||||||
|
@ -830,10 +830,10 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
|
|
||||||
// Pick out the original method from the vtable.
|
// Pick out the original method from the vtable.
|
||||||
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
|
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
|
||||||
llinner_obj_vtbl = bld::PointerCast(bcx, llinner_obj_vtbl, vtbl_type);
|
llinner_obj_vtbl = PointerCast(bcx, llinner_obj_vtbl, vtbl_type);
|
||||||
|
|
||||||
let llorig_mthd =
|
let llorig_mthd =
|
||||||
bld::GEP(bcx, llinner_obj_vtbl, [C_int(0), C_int(ix as int)]);
|
GEP(bcx, llinner_obj_vtbl, [C_int(0), C_int(ix as int)]);
|
||||||
|
|
||||||
// Set up the original method to be called.
|
// Set up the original method to be called.
|
||||||
let orig_mthd_ty = ty::method_ty_to_fn_ty(cx.ccx.tcx, *m);
|
let orig_mthd_ty = ty::method_ty_to_fn_ty(cx.ccx.tcx, *m);
|
||||||
|
@ -843,8 +843,8 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
m.inputs, m.output,
|
m.inputs, m.output,
|
||||||
std::vec::len::<ast::ty_param>(ty_params));
|
std::vec::len::<ast::ty_param>(ty_params));
|
||||||
llorig_mthd =
|
llorig_mthd =
|
||||||
bld::PointerCast(bcx, llorig_mthd, T_ptr(T_ptr(llorig_mthd_ty)));
|
PointerCast(bcx, llorig_mthd, T_ptr(T_ptr(llorig_mthd_ty)));
|
||||||
llorig_mthd = bld::Load(bcx, llorig_mthd);
|
llorig_mthd = Load(bcx, llorig_mthd);
|
||||||
|
|
||||||
// Set up the self-stack.
|
// Set up the self-stack.
|
||||||
let self_stack =
|
let self_stack =
|
||||||
|
@ -857,7 +857,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
|
|
||||||
// Cast self_stack back to pointer-to-object-type to make LLVM happy.
|
// Cast self_stack back to pointer-to-object-type to make LLVM happy.
|
||||||
self_stack =
|
self_stack =
|
||||||
bld::PointerCast(bcx, self_stack, T_ptr(cx.ccx.rust_object_type));
|
PointerCast(bcx, self_stack, T_ptr(cx.ccx.rust_object_type));
|
||||||
|
|
||||||
// Set up the three implicit arguments to the original method we'll need
|
// Set up the three implicit arguments to the original method we'll need
|
||||||
// to call.
|
// to call.
|
||||||
|
@ -877,7 +877,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
||||||
}
|
}
|
||||||
|
|
||||||
// And, finally, call the original (inner) method.
|
// And, finally, call the original (inner) method.
|
||||||
bld::FastCall(bcx, llorig_mthd, llorig_mthd_args);
|
FastCall(bcx, llorig_mthd, llorig_mthd_args);
|
||||||
|
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
finish_fn(fcx, lltop);
|
finish_fn(fcx, lltop);
|
||||||
|
@ -955,19 +955,19 @@ fn populate_self_stack(bcx: @block_ctxt, self_stack: ValueRef,
|
||||||
inner_obj_body: ValueRef) -> ValueRef {
|
inner_obj_body: ValueRef) -> ValueRef {
|
||||||
|
|
||||||
// Drop the outer obj into the second slot.
|
// Drop the outer obj into the second slot.
|
||||||
let self_pair_ptr = bld::GEP(bcx, self_stack, [C_int(0), C_int(1)]);
|
let self_pair_ptr = GEP(bcx, self_stack, [C_int(0), C_int(1)]);
|
||||||
bld::Store(bcx, outer_obj, self_pair_ptr);
|
Store(bcx, outer_obj, self_pair_ptr);
|
||||||
|
|
||||||
// Drop in the backwarding vtbl.
|
// Drop in the backwarding vtbl.
|
||||||
let wrapper_pair = bld::GEP(bcx, self_stack, [C_int(0), C_int(0)]);
|
let wrapper_pair = GEP(bcx, self_stack, [C_int(0), C_int(0)]);
|
||||||
let wrapper_vtbl_ptr = bld::GEP(bcx, wrapper_pair, [C_int(0), C_int(0)]);
|
let wrapper_vtbl_ptr = GEP(bcx, wrapper_pair, [C_int(0), C_int(0)]);
|
||||||
let backwarding_vtbl_cast =
|
let backwarding_vtbl_cast =
|
||||||
bld::PointerCast(bcx, backwarding_vtbl, T_ptr(T_empty_struct()));
|
PointerCast(bcx, backwarding_vtbl, T_ptr(T_empty_struct()));
|
||||||
bld::Store(bcx, backwarding_vtbl_cast, wrapper_vtbl_ptr);
|
Store(bcx, backwarding_vtbl_cast, wrapper_vtbl_ptr);
|
||||||
|
|
||||||
// Drop in the inner obj body.
|
// Drop in the inner obj body.
|
||||||
let wrapper_body_ptr = bld::GEP(bcx, wrapper_pair, [C_int(0), C_int(1)]);
|
let wrapper_body_ptr = GEP(bcx, wrapper_pair, [C_int(0), C_int(1)]);
|
||||||
bld::Store(bcx, inner_obj_body, wrapper_body_ptr);
|
Store(bcx, inner_obj_body, wrapper_body_ptr);
|
||||||
|
|
||||||
ret self_stack;
|
ret self_stack;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue