parent
371b61a23d
commit
1741ef75ac
@ -80,13 +80,12 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
|
||||
// - create_llargs_for_fn_args.
|
||||
// - new_fn_ctxt
|
||||
// - trans_args
|
||||
fn type_of_fn(cx: @crate_ctxt, sp: span,
|
||||
is_method: bool, inputs: [ty::arg],
|
||||
output: ty::t, params: [ty::param_bounds])
|
||||
: non_ty_var(cx, output) -> TypeRef {
|
||||
fn type_of_fn(cx: @crate_ctxt, sp: span, is_method: bool, inputs: [ty::arg],
|
||||
output: ty::t, params: [ty::param_bounds]) -> TypeRef {
|
||||
let atys: [TypeRef] = [];
|
||||
|
||||
// Arg 0: Output pointer.
|
||||
check non_ty_var(cx, output);
|
||||
let out_ty = T_ptr(type_of_inner(cx, sp, output));
|
||||
atys += [out_ty];
|
||||
|
||||
@ -117,7 +116,6 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
|
||||
// by returns_non_ty_var(t). Make that a postcondition
|
||||
// (see Issue #586)
|
||||
let ret_ty = ty::ty_fn_ret(cx.tcx, fty);
|
||||
check non_ty_var(cx, ret_ty);
|
||||
ret type_of_fn(cx, sp, false, ty::ty_fn_args(cx.tcx, fty),
|
||||
ret_ty, param_bounds);
|
||||
}
|
||||
@ -2771,8 +2769,6 @@ fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef,
|
||||
let fn_ty: ty::t = ty::mk_fn(tcx, mths[ix].fty);
|
||||
let ret_ty = ty::ty_fn_ret(tcx, fn_ty);
|
||||
// FIXME: constrain ty_obj?
|
||||
check non_ty_var(ccx, ret_ty);
|
||||
|
||||
let ll_fn_ty = type_of_fn(ccx, bcx.sp, true,
|
||||
ty::ty_fn_args(tcx, fn_ty), ret_ty, []);
|
||||
v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty))));
|
||||
@ -5123,8 +5119,6 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
|
||||
ty: ty::mk_vec(ccx.tcx, {ty: unit_ty, mut: ast::imm})};
|
||||
// FIXME: mk_nil should have a postcondition
|
||||
let nt = ty::mk_nil(ccx.tcx);
|
||||
check non_ty_var(ccx, nt);
|
||||
|
||||
let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, []);
|
||||
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
|
||||
lib::llvm::LLVMCCallConv, llfty);
|
||||
@ -5223,7 +5217,6 @@ fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span,
|
||||
x: ty::t) -> TypeRef {
|
||||
alt ty::struct(cx.tcx, x) {
|
||||
ty::ty_native_fn(args, out) {
|
||||
check non_ty_var(cx, out);
|
||||
ret type_of_fn(cx, sp, false, args, out, param_bounds);
|
||||
}
|
||||
}
|
||||
@ -5377,7 +5370,7 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str],
|
||||
ast::item_tag(variants, _) {
|
||||
let i = 0u;
|
||||
for variant in variants {
|
||||
let p = new_pt + [it.ident, variant.node.name, "discrim"];
|
||||
let p = new_pt + [variant.node.name, "discrim"];
|
||||
let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx));
|
||||
let discrim_gvar = str::as_buf(s, {|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
|
||||
@ -5390,6 +5383,28 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str],
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
ast::item_impl(tps, some(@{node: ast::ty_path(_, id), _}), _, ms) {
|
||||
let i_did = ast_util::def_id_of_def(ccx.tcx.def_map.get(id));
|
||||
let ty = ty::lookup_item_type(ccx.tcx, i_did).ty;
|
||||
// FIXME[impl] use the same name as used in collect_items, for
|
||||
// slightly more consistent symbol names?
|
||||
let new_pt = pt + [ccx.names.next(it.ident)];
|
||||
let extra_tps = vec::map(tps, {|p| param_bounds(ccx, p)});
|
||||
let tbl = C_struct(vec::map(*ty::iface_methods(ccx.tcx, i_did), {|im|
|
||||
alt vec::find(ms, {|m| m.ident == im.ident}) {
|
||||
some(m) {
|
||||
trans_impl::trans_wrapper(ccx, new_pt, extra_tps, m)
|
||||
}
|
||||
}
|
||||
}));
|
||||
let s = mangle_exported_name(ccx, new_pt + ["!vtable"], ty);
|
||||
let vt_gvar = str::as_buf(s, {|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
|
||||
});
|
||||
llvm::LLVMSetInitializer(vt_gvar, tbl);
|
||||
llvm::LLVMSetGlobalConstant(vt_gvar, True);
|
||||
ccx.item_ids.insert(it.id, vt_gvar);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ fn ty_str(tn: type_names, t: TypeRef) -> str {
|
||||
ret lib::llvm::type_to_str(tn, t);
|
||||
}
|
||||
|
||||
fn val_ty(v: ValueRef) -> TypeRef { ret llvm::LLVMTypeOf(v); }
|
||||
fn val_ty(&&v: ValueRef) -> TypeRef { ret llvm::LLVMTypeOf(v); }
|
||||
|
||||
fn val_str(tn: type_names, v: ValueRef) -> str { ret ty_str(tn, val_ty(v)); }
|
||||
|
||||
|
@ -2,8 +2,10 @@ import trans::*;
|
||||
import trans_common::*;
|
||||
import trans_build::*;
|
||||
import option::{some, none};
|
||||
import syntax::ast;
|
||||
import syntax::{ast, ast_util};
|
||||
import back::link;
|
||||
import lib::llvm;
|
||||
import llvm::llvm::{ValueRef, TypeRef, LLVMGetParam};
|
||||
|
||||
fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method],
|
||||
id: ast::node_id, tps: [ast::ty_param],
|
||||
@ -19,3 +21,51 @@ fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn llfn_arg_tys(ft: TypeRef) -> {inputs: [TypeRef], output: TypeRef} {
|
||||
let out_ty = llvm::llvm::LLVMGetReturnType(ft);
|
||||
let n_args = llvm::llvm::LLVMCountParamTypes(ft);
|
||||
let args = vec::init_elt(0 as TypeRef, n_args);
|
||||
unsafe { llvm::llvm::LLVMGetParamTypes(ft, vec::to_ptr(args)); }
|
||||
{inputs: args, output: out_ty}
|
||||
}
|
||||
|
||||
fn trans_wrapper(ccx: @crate_ctxt, pt: [ast::ident],
|
||||
extra_tps: [ty::param_bounds], m: @ast::method) -> ValueRef {
|
||||
let real_fn = ccx.item_ids.get(m.id);
|
||||
let {inputs: real_args, output: real_ret} =
|
||||
llfn_arg_tys(llvm::llvm::LLVMGetElementType(val_ty(real_fn)));
|
||||
let env_ty = T_ptr(T_struct([T_ptr(T_i8())] +
|
||||
vec::map(extra_tps,
|
||||
{|_p| T_ptr(ccx.tydesc_type)})));
|
||||
// FIXME[impl] filter and pass along dicts for bounds
|
||||
let wrap_args = [env_ty] + vec::slice(real_args, 0u, 2u) +
|
||||
vec::slice(real_args, 2u + vec::len(extra_tps), vec::len(real_args));
|
||||
let llfn_ty = T_fn(wrap_args, real_ret);
|
||||
|
||||
let lcx = @{path: pt + ["wrapper", m.ident], module_path: [],
|
||||
obj_typarams: [], obj_fields: [], ccx: ccx};
|
||||
let name = link::mangle_internal_name_by_path_and_seq(ccx, pt, m.ident);
|
||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, name, llfn_ty);
|
||||
let fcx = new_fn_ctxt(lcx, ast_util::dummy_sp(), llfn);
|
||||
let bcx = new_top_block_ctxt(fcx), lltop = bcx.llbb;
|
||||
|
||||
let dict = LLVMGetParam(llfn, 0u);
|
||||
// retptr, self
|
||||
let args = [LLVMGetParam(llfn, 1u), LLVMGetParam(llfn, 2u)], i = 1;
|
||||
// saved tydescs/dicts
|
||||
for extra_tp in extra_tps {
|
||||
args += [load_inbounds(bcx, dict, [0, i])];
|
||||
i += 1;
|
||||
}
|
||||
// the rest of the parameters
|
||||
let i = 3u, params_total = llvm::llvm::LLVMCountParamTypes(llfn_ty);
|
||||
while i < params_total {
|
||||
args += [LLVMGetParam(llfn, i)];
|
||||
i += 1u;
|
||||
}
|
||||
Call(bcx, ccx.item_ids.get(m.id), args);
|
||||
finish_fn(fcx, lltop);
|
||||
ret llfn;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user