提交 29584cc5 编写于 作者: N Niko Matsakis 提交者: Brian Anderson

Extend the unchecked block stuff to allow unsafe blocks as well.

上级 58b8e883
......@@ -184,7 +184,7 @@ fn mk_tests(cx: test_ctxt) -> @ast::item {
let test_descs = mk_test_desc_vec(cx);
let body_: ast::blk_ =
checked_blk([], option::some(test_descs), cx.next_node_id());
checked_block([], option::some(test_descs), cx.next_node_id());
let body = nospan(body_);
let fn_ = {decl: decl, proto: proto, body: body};
......@@ -303,7 +303,8 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
let test_main_call_expr = mk_test_main_call(cx);
let body_: ast::blk_ =
checked_blk([], option::some(test_main_call_expr), cx.next_node_id());
checked_block([], option::some(test_main_call_expr),
cx.next_node_id());
let body = {node: body_, span: dummy_sp()};
let fn_ = {decl: decl, proto: proto, body: body};
......
......@@ -175,6 +175,7 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
let def =
alt fam_ch as char {
'c' { ast::def_const(did) }
'u' { ast::def_fn(did, ast::unsafe_fn) }
'f' { ast::def_fn(did, ast::impure_fn) }
'p' { ast::def_fn(did, ast::pure_fn) }
'F' { ast::def_native_fn(did) }
......
......@@ -252,6 +252,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w,
alt fd.decl.purity {
unsafe_fn. { 'u' }
pure_fn. { 'p' }
impure_fn. { 'f' }
} as u8);
......
......@@ -4380,11 +4380,11 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
assert dest == ignore;
ret trans_check_expr(bcx, a, "Assertion");
}
ast::expr_check(ast::checked., a) {
ast::expr_check(ast::checked_expr., a) {
assert dest == ignore;
ret trans_check_expr(bcx, a, "Predicate");
}
ast::expr_check(ast::unchecked., a) {
ast::expr_check(ast::claimed_expr., a) {
assert dest == ignore;
/* Claims are turned on and off by a global variable
that the RTS sets. This case generates code to
......
......@@ -1523,6 +1523,15 @@ fn matches(name: str, f: ty::field) -> bool {
}
}
fn require_unsafe(sess: session::session, f_purity: ast::purity, sp: span) {
alt f_purity {
ast::unsafe_fn. { ret; }
_ {
sess.span_fatal(sp, "Found unsafe expression in safe function decl");
}
}
}
fn require_impure(sess: session::session, f_purity: ast::purity, sp: span) {
alt f_purity {
ast::unsafe_fn. { ret; }
......@@ -1536,7 +1545,22 @@ fn require_impure(sess: session::session, f_purity: ast::purity, sp: span) {
fn require_pure_call(ccx: @crate_ctxt, caller_purity: ast::purity,
callee: @ast::expr, sp: span) {
alt caller_purity {
ast::impure_fn. { ret; }
ast::unsafe_fn. { ret; }
ast::impure_fn. {
alt ccx.tcx.def_map.find(callee.id) {
some(ast::def_fn(_, ast::unsafe_fn.)) {
ccx.tcx.sess.span_fatal
(sp, "safe function calls function marked unsafe");
}
//some(ast::def_native_fn(_)) {
// ccx.tcx.sess.span_fatal
// (sp, "native functions can only be invoked from unsafe code");
//}
_ {
}
}
ret;
}
ast::pure_fn. {
alt ccx.tcx.def_map.find(callee.id) {
some(ast::def_fn(_, ast::pure_fn.)) { ret; }
......@@ -2066,8 +2090,9 @@ fn check_binop_type_compat(fcx: @fn_ctxt, span: span, ty: ty::t,
// If this is an unchecked block, turn off purity-checking
let fcx_for_block =
alt b.node.rules {
ast::unchecked. { @{purity: ast::impure_fn with *fcx} }
_ { fcx }
ast::unchecked_blk. { @{purity: ast::impure_fn with *fcx} }
ast::unsafe_blk. { @{purity: ast::unsafe_fn with *fcx} }
ast::checked_blk. { fcx }
};
bot = check_block(fcx_for_block, b);
let typ =
......
......@@ -78,7 +78,8 @@
type blk = spanned<blk_>;
type blk_ =
{stmts: [@stmt], expr: option::t<@expr>, id: node_id, rules: check_mode};
{stmts: [@stmt], expr: option::t<@expr>, id: node_id,
rules: blk_check_mode};
type pat = {id: node_id, node: pat_, span: span};
......@@ -173,7 +174,9 @@
type field = spanned<field_>;
tag check_mode { checked; unchecked; }
tag blk_check_mode { checked_blk; unchecked_blk; unsafe_blk; }
tag expr_check_mode { claimed_expr; checked_expr; }
type expr = {id: node_id, node: expr_, span: span};
......@@ -222,7 +225,7 @@
expr_assert(@expr);
/* preds that typestate is aware of */
expr_check(check_mode, @expr);
expr_check(expr_check_mode, @expr);
/* FIXME Would be nice if expr_check desugared
to expr_if_check. */
......
......@@ -185,13 +185,13 @@ fn is_constraint_arg(e: @expr) -> bool {
fn hash_ty(&&t: @ty) -> uint { ret t.span.lo << 16u + t.span.hi; }
fn block_from_expr(e: @expr) -> blk {
let blk_ = checked_blk([], option::some::<@expr>(e), e.id);
let blk_ = checked_block([], option::some::<@expr>(e), e.id);
ret {node: blk_, span: e.span};
}
fn checked_blk(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id) ->
fn checked_block(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id) ->
blk_ {
ret {stmts: stmts1, expr: expr1, id: id1, rules: checked};
ret {stmts: stmts1, expr: expr1, id: id1, rules: checked_blk};
}
fn obj_field_from_anon_obj_field(f: anon_obj_field) -> obj_field {
......
......@@ -828,7 +828,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
p.peek() == token::OROR {
ret parse_fn_block_expr(p);
} else {
let blk = parse_block_tail(p, lo, ast::checked);
let blk = parse_block_tail(p, lo, ast::checked_blk);
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
}
} else if eat_word(p, "if") {
......@@ -853,9 +853,9 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
} else if eat_word(p, "lambda") {
ret parse_fn_expr(p, ast::proto_closure);
} else if eat_word(p, "unchecked") {
expect(p, token::LBRACE);
let blk = parse_block_tail(p, lo, ast::unchecked);
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
ret parse_block_expr(p, lo, ast::unchecked_blk);
} else if eat_word(p, "unsafe") {
ret parse_block_expr(p, lo, ast::unsafe_blk);
} else if p.peek() == token::LBRACKET {
p.bump();
let mut = parse_mutability(p);
......@@ -872,7 +872,8 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
ret mk_mac_expr(p, lo, p.get_hi_pos(), ast::mac_embed_type(ty));
} else if p.peek() == token::POUND_LBRACE {
p.bump();
let blk = ast::mac_embed_block(parse_block_tail(p, lo, ast::checked));
let blk = ast::mac_embed_block(
parse_block_tail(p, lo, ast::checked_blk));
ret mk_mac_expr(p, lo, p.get_hi_pos(), blk);
} else if p.peek() == token::ELLIPSIS {
p.bump();
......@@ -948,7 +949,7 @@ fn parse_expr_opt(p: parser) -> option::t<@ast::expr> {
let e = parse_expr(p);
hi = e.span.hi;
ex = ast::expr_check(ast::checked, e);
ex = ast::expr_check(ast::checked_expr, e);
} else if eat_word(p, "claim") {
/* Same rules as check, except that if check-claims
is enabled (a command-line flag), then the parser turns
......@@ -956,7 +957,7 @@ fn parse_expr_opt(p: parser) -> option::t<@ast::expr> {
let e = parse_expr(p);
hi = e.span.hi;
ex = ast::expr_check(ast::unchecked, e);
ex = ast::expr_check(ast::claimed_expr, e);
} else if eat_word(p, "ret") {
if can_begin_expr(p.peek()) {
let e = parse_expr(p);
......@@ -1014,6 +1015,14 @@ fn parse_expr_opt(p: parser) -> option::t<@ast::expr> {
ret mk_expr(p, lo, hi, ex);
}
fn parse_block_expr(p: parser,
lo: uint,
blk_mode: ast::blk_check_mode) -> @ast::expr {
expect(p, token::LBRACE);
let blk = parse_block_tail(p, lo, blk_mode);
ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk));
}
fn parse_syntax_ext(p: parser) -> @ast::expr {
let lo = p.get_lo_pos();
expect(p, token::POUND);
......@@ -1311,7 +1320,7 @@ fn parse_fn_expr(p: parser, proto: ast::proto) -> @ast::expr {
fn parse_fn_block_expr(p: parser) -> @ast::expr {
let lo = p.get_last_lo_pos();
let decl = parse_fn_block_decl(p);
let body = parse_block_tail(p, lo, ast::checked);
let body = parse_block_tail(p, lo, ast::checked_blk);
let _fn = {decl: decl, proto: ast::proto_block, body: body};
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn));
}
......@@ -1675,10 +1684,12 @@ fn stmt_ends_with_semi(stmt: ast::stmt) -> bool {
fn parse_block(p: parser) -> ast::blk {
let lo = p.get_lo_pos();
if eat_word(p, "unchecked") {
be parse_block_tail(p, lo, ast::unchecked);
be parse_block_tail(p, lo, ast::unchecked_blk);
} else if eat_word(p, "unsafe") {
be parse_block_tail(p, lo, ast::unsafe_blk);
} else {
expect(p, token::LBRACE);
be parse_block_tail(p, lo, ast::checked);
be parse_block_tail(p, lo, ast::checked_blk);
}
}
......@@ -1695,7 +1706,7 @@ fn parse_block_no_value(p: parser) -> ast::blk {
// I guess that also means "already parsed the 'impure'" if
// necessary, and this should take a qualifier.
// some blocks start with "#{"...
fn parse_block_tail(p: parser, lo: uint, s: ast::check_mode) -> ast::blk {
fn parse_block_tail(p: parser, lo: uint, s: ast::blk_check_mode) -> ast::blk {
let stmts: [@ast::stmt] = [];
let expr: option::t<@ast::expr> = none;
while p.peek() != token::RBRACE {
......
......@@ -572,7 +572,11 @@ fn print_block(s: ps, blk: ast::blk) {
fn print_possibly_embedded_block(s: ps, blk: ast::blk, embedded: embed_type,
indented: uint) {
alt blk.node.rules { ast::unchecked. { word(s.s, "unchecked"); } _ { } }
alt blk.node.rules {
ast::unchecked_blk. { word(s.s, "unchecked"); }
ast::unsafe_blk. { word(s.s, "unsafe"); }
ast::checked_blk. { }
}
maybe_print_comment(s, blk.span.lo);
let ann_node = node_block(s, blk);
......@@ -934,8 +938,8 @@ fn print_opt(s: ps, expr: option::t<@ast::expr>) {
}
ast::expr_check(m, expr) {
alt m {
ast::unchecked. { word_nbsp(s, "claim"); }
ast::checked. { word_nbsp(s, "check"); }
ast::claimed_expr. { word_nbsp(s, "claim"); }
ast::checked_expr. { word_nbsp(s, "check"); }
}
popen(s);
print_expr(s, expr);
......
......@@ -263,7 +263,7 @@ fn write(v: [u8]) {
let nout = os::libc::write(fd, vbuf, len);
if nout < 0 {
log_err "error dumping buffer";
log_err sys::rustrt::last_os_error();
log_err sys::last_os_error();
fail;
}
count += nout as uint;
......@@ -299,7 +299,7 @@ fn file_buf_writer(path: str, flags: [fileflag]) -> buf_writer {
});
if fd < 0 {
log_err "error opening file for writing";
log_err sys::rustrt::last_os_error();
log_err sys::last_os_error();
fail;
}
ret fd_buf_writer(fd, option::some(@fd_res(fd)));
......
import rustrt::size_of;
export rustrt;
export size_of;
//export rustrt;
//export size_of;
native "rust" mod rustrt {
// Explicitly re-export native stuff we want to be made
// available outside this crate. Otherwise it's
// visible-in-crate, but not re-exported.
......@@ -17,6 +14,42 @@
fn unsupervise();
}
fn last_os_error() -> str {
//unsafe {
ret rustrt::last_os_error();
//}
}
fn size_of<T>() -> uint {
//unsafe {
ret rustrt::size_of::<T>();
//}
}
fn align_of<T>() -> uint {
//unsafe {
ret rustrt::align_of::<T>();
//}
}
fn refcount<T>(t: @T) -> uint {
//unsafe {
ret rustrt::refcount::<T>(t);
//}
}
fn do_gc() -> () {
//unsafe {
ret rustrt::do_gc();
//}
}
fn unsupervise() -> () {
//unsafe {
ret rustrt::unsupervise();
//}
}
// Local Variables:
// mode: rust;
// fill-column: 78;
......
......@@ -32,7 +32,7 @@
}
fn next_power_of_two(n: uint) -> uint {
let halfbits: uint = sys::rustrt::size_of::<uint>() * 4u;
let halfbits: uint = sys::size_of::<uint>() * 4u;
let tmp: uint = n - 1u;
let shift: uint = 1u;
while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册