reimplement some of the unsafe stuff which got lost
- blocks inherit unsafety - remove the --check-unsafe flag - add unsafe annotations where needed to get things to compile
This commit is contained in:
parent
f994871a3d
commit
e8a0e592da
23 changed files with 137 additions and 156 deletions
|
|
@ -34,16 +34,14 @@ tag output_type {
|
|||
output_type_exe;
|
||||
}
|
||||
|
||||
fn llvm_err(sess: session::session, msg: str) {
|
||||
unsafe {
|
||||
let buf = llvm::LLVMRustGetLastError();
|
||||
if buf == std::ptr::null() {
|
||||
sess.fatal(msg);
|
||||
} else { sess.fatal(msg + ": " + str::str_from_cstr(buf)); }
|
||||
}
|
||||
fn llvm_err(sess: session::session, msg: str) unsafe {
|
||||
let buf = llvm::LLVMRustGetLastError();
|
||||
if buf == std::ptr::null() {
|
||||
sess.fatal(msg);
|
||||
} else { sess.fatal(msg + ": " + str::str_from_cstr(buf)); }
|
||||
}
|
||||
|
||||
fn link_intrinsics(sess: session::session, llmod: ModuleRef) unsafe {
|
||||
fn link_intrinsics(sess: session::session, llmod: ModuleRef) {
|
||||
let path = alt filesearch::search(
|
||||
sess.filesearch(),
|
||||
bind filesearch::pick_file("intrinsics.bc", _)) {
|
||||
|
|
@ -90,8 +88,7 @@ mod write {
|
|||
} else { stem = str::substr(output_path, 0u, dot_pos as uint); }
|
||||
ret stem + "." + extension;
|
||||
}
|
||||
fn run_passes(sess: session::session, llmod: ModuleRef, output: str)
|
||||
unsafe {
|
||||
fn run_passes(sess: session::session, llmod: ModuleRef, output: str) {
|
||||
let opts = sess.get_opts();
|
||||
if opts.time_llvm_passes { llvm::LLVMRustEnableTimePasses(); }
|
||||
link_intrinsics(sess, llmod);
|
||||
|
|
|
|||
|
|
@ -325,7 +325,6 @@ fn build_session_options(match: getopts::match)
|
|||
|
||||
let parse_only = opt_present(match, "parse-only");
|
||||
let no_trans = opt_present(match, "no-trans");
|
||||
let check_unsafe = opt_present(match, "check-unsafe");
|
||||
|
||||
let output_type =
|
||||
if parse_only || no_trans {
|
||||
|
|
@ -397,8 +396,7 @@ fn build_session_options(match: getopts::match)
|
|||
parse_only: parse_only,
|
||||
no_trans: no_trans,
|
||||
do_gc: do_gc,
|
||||
stack_growth: stack_growth,
|
||||
check_unsafe: check_unsafe};
|
||||
stack_growth: stack_growth};
|
||||
ret sopts;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ type options =
|
|||
parse_only: bool,
|
||||
no_trans: bool,
|
||||
do_gc: bool,
|
||||
stack_growth: bool,
|
||||
check_unsafe: bool};
|
||||
stack_growth: bool};
|
||||
|
||||
type crate_metadata = {name: str, data: [u8]};
|
||||
|
||||
|
|
|
|||
|
|
@ -956,7 +956,7 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) ->
|
|||
7 {
|
||||
ret "i" + std::int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
|
||||
}
|
||||
8 unsafe {
|
||||
8 {
|
||||
let s = "fn(";
|
||||
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
|
||||
let n_args: uint = llvm::LLVMCountParamTypes(ty);
|
||||
|
|
@ -969,7 +969,7 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) ->
|
|||
s += type_to_str_inner(names, outer, out_ty);
|
||||
ret s;
|
||||
}
|
||||
9 unsafe {
|
||||
9 {
|
||||
let s: str = "{";
|
||||
let n_elts: uint = llvm::LLVMCountStructElementTypes(ty);
|
||||
let elts: [TypeRef] = vec::init_elt::<TypeRef>(0 as TypeRef, n_elts);
|
||||
|
|
|
|||
|
|
@ -169,27 +169,25 @@ fn find_library_crate_aux(nn: {prefix: str, suffix: str}, crate_name: str,
|
|||
});
|
||||
}
|
||||
|
||||
fn get_metadata_section(filename: str) -> option::t<@[u8]> {
|
||||
unsafe {
|
||||
let mb = str::as_buf(filename, {|buf|
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
});
|
||||
if mb as int == 0 { ret option::none::<@[u8]>; }
|
||||
let of = mk_object_file(mb);
|
||||
let si = mk_section_iter(of.llof);
|
||||
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
|
||||
let name_buf = llvm::LLVMGetSectionName(si.llsi);
|
||||
let name = str::str_from_cstr(name_buf);
|
||||
if str::eq(name, x86::get_meta_sect_name()) {
|
||||
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
||||
let csz = llvm::LLVMGetSectionSize(si.llsi);
|
||||
let cvbuf: *u8 = std::unsafe::reinterpret_cast(cbuf);
|
||||
ret option::some::<@[u8]>(@vec::unsafe::from_buf(cvbuf, csz));
|
||||
}
|
||||
llvm::LLVMMoveToNextSection(si.llsi);
|
||||
fn get_metadata_section(filename: str) -> option::t<@[u8]> unsafe {
|
||||
let mb = str::as_buf(filename, {|buf|
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
});
|
||||
if mb as int == 0 { ret option::none::<@[u8]>; }
|
||||
let of = mk_object_file(mb);
|
||||
let si = mk_section_iter(of.llof);
|
||||
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
|
||||
let name_buf = llvm::LLVMGetSectionName(si.llsi);
|
||||
let name = str::str_from_cstr(name_buf);
|
||||
if str::eq(name, x86::get_meta_sect_name()) {
|
||||
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
||||
let csz = llvm::LLVMGetSectionSize(si.llsi);
|
||||
let cvbuf: *u8 = std::unsafe::reinterpret_cast(cbuf);
|
||||
ret option::some::<@[u8]>(@vec::unsafe::from_buf(cvbuf, csz));
|
||||
}
|
||||
ret option::none::<@[u8]>;
|
||||
llvm::LLVMMoveToNextSection(si.llsi);
|
||||
}
|
||||
ret option::none::<@[u8]>;
|
||||
}
|
||||
|
||||
fn load_library_crate(sess: session::session, span: span, ident: ast::ident,
|
||||
|
|
|
|||
|
|
@ -256,6 +256,8 @@ fn family_has_type_params(fam_ch: u8) -> bool {
|
|||
'u' { true }
|
||||
'p' { true }
|
||||
'F' { true }
|
||||
'U' { true }
|
||||
'P' { true }
|
||||
'y' { true }
|
||||
't' { true }
|
||||
'T' { false }
|
||||
|
|
@ -285,6 +287,8 @@ fn item_family_to_str(fam: u8) -> str {
|
|||
'u' { ret "unsafe fn"; }
|
||||
'p' { ret "pure fn"; }
|
||||
'F' { ret "native fn"; }
|
||||
'U' { ret "unsafe native fn"; }
|
||||
'P' { ret "pure native fn"; }
|
||||
'y' { ret "type"; }
|
||||
'T' { ret "native type"; }
|
||||
't' { ret "type"; }
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ type ctxt = @{mutable next_tydesc_num: uint};
|
|||
|
||||
fn mk_ctxt() -> ctxt { ret @{mutable next_tydesc_num: 0u}; }
|
||||
|
||||
fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str)
|
||||
-> ValueRef unsafe {
|
||||
fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str) -> ValueRef {
|
||||
let llglobal =
|
||||
str::as_buf(name,
|
||||
{|buf|
|
||||
|
|
@ -28,8 +27,7 @@ fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str)
|
|||
ret llglobal;
|
||||
}
|
||||
|
||||
fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) ->
|
||||
@block_ctxt unsafe {
|
||||
fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
||||
let bcx = cx;
|
||||
if !type_is_gc_relevant(bcx_tcx(cx), ty) ||
|
||||
ty::type_has_dynamic_size(bcx_tcx(cx), ty) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ fn eq_res_info(a: res_info, b: res_info) -> bool {
|
|||
}
|
||||
|
||||
fn mk_global(ccx: @crate_ctxt, name: str, llval: ValueRef, internal: bool) ->
|
||||
ValueRef unsafe {
|
||||
ValueRef {
|
||||
let llglobal =
|
||||
str::as_buf(name,
|
||||
{|buf|
|
||||
|
|
@ -245,7 +245,7 @@ fn s_float(_tcx: ty_ctxt) -> u8 {
|
|||
ret shape_f64; // TODO: x86-64
|
||||
}
|
||||
|
||||
fn mk_ctxt(llmod: ModuleRef) -> ctxt unsafe {
|
||||
fn mk_ctxt(llmod: ModuleRef) -> ctxt {
|
||||
let llshapetablesty = trans_common::T_named_struct("shapes");
|
||||
let llshapetables =
|
||||
str::as_buf("shapes",
|
||||
|
|
@ -580,7 +580,7 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef {
|
|||
ret mk_global(ccx, "resource_shapes", C_struct(dtors), true);
|
||||
}
|
||||
|
||||
fn gen_shape_tables(ccx: @crate_ctxt) unsafe {
|
||||
fn gen_shape_tables(ccx: @crate_ctxt) {
|
||||
let lltagstable = gen_tag_shapes(ccx);
|
||||
let llresourcestable = gen_resource_shapes(ccx);
|
||||
trans_common::set_struct_body(ccx.shape_cx.llshapetablesty,
|
||||
|
|
|
|||
|
|
@ -492,16 +492,16 @@ fn _UndefReturn(Fn: ValueRef) -> ValueRef {
|
|||
}
|
||||
|
||||
fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { ret _UndefReturn(Fn); }
|
||||
unsafe {
|
||||
if cx.unreachable { ret _UndefReturn(Fn); }
|
||||
ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
}
|
||||
}
|
||||
|
||||
fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { ret _UndefReturn(Fn); }
|
||||
unsafe {
|
||||
if cx.unreachable { ret _UndefReturn(Fn); }
|
||||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv);
|
||||
|
|
@ -511,8 +511,8 @@ fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
|||
|
||||
fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint)
|
||||
-> ValueRef {
|
||||
if cx.unreachable { ret _UndefReturn(Fn); }
|
||||
unsafe {
|
||||
if cx.unreachable { ret _UndefReturn(Fn); }
|
||||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), noname());
|
||||
llvm::LLVMSetInstructionCallConv(v, Conv);
|
||||
|
|
|
|||
|
|
@ -427,14 +427,12 @@ 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)); }
|
||||
|
||||
// Returns the nth element of the given LLVM structure type.
|
||||
fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef {
|
||||
unsafe {
|
||||
let elt_count = llvm::LLVMCountStructElementTypes(llstructty);
|
||||
assert (n < elt_count);
|
||||
let elt_tys = std::vec::init_elt(T_nil(), elt_count);
|
||||
llvm::LLVMGetStructElementTypes(llstructty, to_ptr(elt_tys));
|
||||
ret llvm::LLVMGetElementType(elt_tys[n]);
|
||||
}
|
||||
fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef unsafe {
|
||||
let elt_count = llvm::LLVMCountStructElementTypes(llstructty);
|
||||
assert (n < elt_count);
|
||||
let elt_tys = std::vec::init_elt(T_nil(), elt_count);
|
||||
llvm::LLVMGetStructElementTypes(llstructty, to_ptr(elt_tys));
|
||||
ret llvm::LLVMGetElementType(elt_tys[n]);
|
||||
}
|
||||
|
||||
fn find_scope_cx(cx: @block_ctxt) -> @block_ctxt {
|
||||
|
|
@ -541,10 +539,8 @@ fn T_named_struct(name: str) -> TypeRef {
|
|||
ret str::as_buf(name, {|buf| llvm::LLVMStructCreateNamed(c, buf) });
|
||||
}
|
||||
|
||||
fn set_struct_body(t: TypeRef, elts: [TypeRef]) {
|
||||
unsafe {
|
||||
llvm::LLVMStructSetBody(t, to_ptr(elts), std::vec::len(elts), False);
|
||||
}
|
||||
fn set_struct_body(t: TypeRef, elts: [TypeRef]) unsafe {
|
||||
llvm::LLVMStructSetBody(t, to_ptr(elts), std::vec::len(elts), False);
|
||||
}
|
||||
|
||||
fn T_empty_struct() -> TypeRef { ret T_struct([]); }
|
||||
|
|
@ -581,18 +577,16 @@ fn T_task() -> TypeRef {
|
|||
ret t;
|
||||
}
|
||||
|
||||
fn T_tydesc_field(cx: crate_ctxt, field: int) -> TypeRef {
|
||||
fn T_tydesc_field(cx: crate_ctxt, field: int) -> TypeRef unsafe {
|
||||
// Bit of a kludge: pick the fn typeref out of the tydesc..
|
||||
|
||||
unsafe {
|
||||
let tydesc_elts: [TypeRef] =
|
||||
std::vec::init_elt::<TypeRef>(T_nil(),
|
||||
abi::n_tydesc_fields as uint);
|
||||
llvm::LLVMGetStructElementTypes(cx.tydesc_type,
|
||||
to_ptr::<TypeRef>(tydesc_elts));
|
||||
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
|
||||
ret t;
|
||||
}
|
||||
let tydesc_elts: [TypeRef] =
|
||||
std::vec::init_elt::<TypeRef>(T_nil(),
|
||||
abi::n_tydesc_fields as uint);
|
||||
llvm::LLVMGetStructElementTypes(cx.tydesc_type,
|
||||
to_ptr::<TypeRef>(tydesc_elts));
|
||||
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
|
||||
ret t;
|
||||
}
|
||||
|
||||
fn T_glue_fn(cx: crate_ctxt) -> TypeRef {
|
||||
|
|
@ -798,43 +792,33 @@ fn C_postr(s: str) -> ValueRef {
|
|||
});
|
||||
}
|
||||
|
||||
fn C_zero_byte_arr(size: uint) -> ValueRef {
|
||||
unsafe {
|
||||
let i = 0u;
|
||||
let elts: [ValueRef] = [];
|
||||
while i < size { elts += [C_u8(0u)]; i += 1u; }
|
||||
ret llvm::LLVMConstArray(T_i8(), std::vec::to_ptr(elts),
|
||||
std::vec::len(elts));
|
||||
}
|
||||
fn C_zero_byte_arr(size: uint) -> ValueRef unsafe {
|
||||
let i = 0u;
|
||||
let elts: [ValueRef] = [];
|
||||
while i < size { elts += [C_u8(0u)]; i += 1u; }
|
||||
ret llvm::LLVMConstArray(T_i8(), std::vec::to_ptr(elts),
|
||||
std::vec::len(elts));
|
||||
}
|
||||
|
||||
fn C_struct(elts: [ValueRef]) -> ValueRef {
|
||||
unsafe {
|
||||
ret llvm::LLVMConstStruct(std::vec::to_ptr(elts), std::vec::len(elts),
|
||||
False);
|
||||
}
|
||||
fn C_struct(elts: [ValueRef]) -> ValueRef unsafe {
|
||||
ret llvm::LLVMConstStruct(std::vec::to_ptr(elts), std::vec::len(elts),
|
||||
False);
|
||||
}
|
||||
|
||||
fn C_named_struct(T: TypeRef, elts: [ValueRef]) -> ValueRef {
|
||||
unsafe {
|
||||
ret llvm::LLVMConstNamedStruct(T, std::vec::to_ptr(elts),
|
||||
std::vec::len(elts));
|
||||
}
|
||||
fn C_named_struct(T: TypeRef, elts: [ValueRef]) -> ValueRef unsafe {
|
||||
ret llvm::LLVMConstNamedStruct(T, std::vec::to_ptr(elts),
|
||||
std::vec::len(elts));
|
||||
}
|
||||
|
||||
fn C_array(ty: TypeRef, elts: [ValueRef]) -> ValueRef {
|
||||
unsafe {
|
||||
ret llvm::LLVMConstArray(ty, std::vec::to_ptr(elts),
|
||||
std::vec::len(elts));
|
||||
}
|
||||
fn C_array(ty: TypeRef, elts: [ValueRef]) -> ValueRef unsafe {
|
||||
ret llvm::LLVMConstArray(ty, std::vec::to_ptr(elts),
|
||||
std::vec::len(elts));
|
||||
}
|
||||
|
||||
fn C_bytes(bytes: [u8]) -> ValueRef {
|
||||
unsafe {
|
||||
ret llvm::LLVMConstString(
|
||||
unsafe::reinterpret_cast(vec::to_ptr(bytes)),
|
||||
vec::len(bytes), False);
|
||||
}
|
||||
fn C_bytes(bytes: [u8]) -> ValueRef unsafe {
|
||||
ret llvm::LLVMConstString(
|
||||
unsafe::reinterpret_cast(vec::to_ptr(bytes)),
|
||||
vec::len(bytes), False);
|
||||
}
|
||||
|
||||
fn C_shape(ccx: @crate_ctxt, bytes: [u8]) -> ValueRef {
|
||||
|
|
|
|||
|
|
@ -569,7 +569,7 @@ fn create_backwarding_vtbl(cx: @local_ctxt, sp: span, inner_obj_ty: ty::t,
|
|||
// finish_vtbl: Given a vector of vtable entries, create the table in
|
||||
// read-only memory and return a pointer to it.
|
||||
fn finish_vtbl(cx: @local_ctxt, llmethods: [ValueRef], name: str) ->
|
||||
ValueRef unsafe {
|
||||
ValueRef {
|
||||
let vtbl = C_struct(llmethods);
|
||||
let vtbl_name = mangle_internal_name_by_path(cx.ccx, cx.path + [name]);
|
||||
let gvar =
|
||||
|
|
@ -619,7 +619,7 @@ fn begin_fn(cx: @local_ctxt, sp: span, m: @ty::method,
|
|||
// returns the value returned from that call.
|
||||
fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
|
||||
ty_params: [ast::ty_param], outer_obj_ty: ty::t,
|
||||
_additional_field_tys: [ty::t]) -> ValueRef unsafe {
|
||||
_additional_field_tys: [ty::t]) -> ValueRef {
|
||||
|
||||
let llbackwarding_fn = begin_fn(cx, sp, m, ty_params, "backwarding_fn");
|
||||
let fcx = new_fn_ctxt(cx, sp, llbackwarding_fn);
|
||||
|
|
|
|||
|
|
@ -1524,15 +1524,13 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
|
|||
}
|
||||
|
||||
fn require_unsafe(sess: session::session, f_purity: ast::purity, sp: span) {
|
||||
if sess.get_opts().check_unsafe {
|
||||
alt f_purity {
|
||||
ast::unsafe_fn. { ret; }
|
||||
_ {
|
||||
sess.span_err(
|
||||
sp,
|
||||
"unsafe operation requires unsafe function or block");
|
||||
}
|
||||
}
|
||||
alt f_purity {
|
||||
ast::unsafe_fn. { ret; }
|
||||
_ {
|
||||
sess.span_err(
|
||||
sp,
|
||||
"unsafe operation requires unsafe function or block");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1551,15 +1549,12 @@ fn require_pure_call(ccx: @crate_ctxt, caller_purity: ast::purity,
|
|||
alt caller_purity {
|
||||
ast::unsafe_fn. { ret; }
|
||||
ast::impure_fn. {
|
||||
let sess = ccx.tcx.sess;
|
||||
alt ccx.tcx.def_map.find(callee.id) {
|
||||
some(ast::def_fn(_, ast::unsafe_fn.)) |
|
||||
some(ast::def_native_fn(_, ast::unsafe_fn.)) {
|
||||
if sess.get_opts().check_unsafe {
|
||||
ccx.tcx.sess.span_err(
|
||||
sp,
|
||||
"safe function calls function marked unsafe");
|
||||
}
|
||||
ccx.tcx.sess.span_err(
|
||||
sp,
|
||||
"safe function calls function marked unsafe");
|
||||
}
|
||||
_ {
|
||||
}
|
||||
|
|
@ -2727,13 +2722,22 @@ fn check_constraints(fcx: @fn_ctxt, cs: [@ast::constr], args: [ast::arg]) {
|
|||
|
||||
fn check_fn(ccx: @crate_ctxt, f: ast::_fn, id: ast::node_id,
|
||||
old_fcx: option::t<@fn_ctxt>) {
|
||||
|
||||
let decl = f.decl;
|
||||
let body = f.body;
|
||||
|
||||
// If old_fcx is some(...), this is a block fn { |x| ... }.
|
||||
// In that case, the purity is inherited from the context.
|
||||
let purity = alt old_fcx {
|
||||
none. { decl.purity }
|
||||
some(f) { assert decl.purity == ast::impure_fn; f.purity }
|
||||
};
|
||||
|
||||
let gather_result = gather_locals(ccx, f, id, old_fcx);
|
||||
let fixups: [ast::node_id] = [];
|
||||
let fcx: @fn_ctxt =
|
||||
@{ret_ty: ty::ty_fn_ret(ccx.tcx, ty::node_id_to_type(ccx.tcx, id)),
|
||||
purity: decl.purity,
|
||||
purity: purity,
|
||||
proto: f.proto,
|
||||
var_bindings: gather_result.var_bindings,
|
||||
locals: gather_result.locals,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue