提交 b970563f 编写于 作者: G Graydon Hoare

Patchwork of attempted fixes to effect system and gc system; eventually give...

Patchwork of attempted fixes to effect system and gc system; eventually give up and disable it entirely in the runtime. Will need extensive reworking.
上级 7e733bf2
......@@ -103,7 +103,7 @@ let iterator_args_elt_outer_frame_ptr = 1;;
let indirect_args_elt_closure = 0;;
(* Current worst case is by vec grow glue *)
let worst_case_glue_call_args = 7;;
let worst_case_glue_call_args = 8;;
type abi =
{
......
......@@ -1893,24 +1893,27 @@ let trans_visitor
get_typed_mem_glue g fty inner
(*
* Vector-growth glue takes four arguments:
* Vector-growth glue takes the following arguments:
*
* 0. (Implicit) task ptr
* 1. Pointer to the typarams of the caller's frame (possibly required to
* be passed to element's copy glue).
* 2. Pointer to tydesc of the vec's stored element type, so that elements
* 2. Pointer to the tydesc of the vec, so that we can tell if it's gc
* mem, and have a tydesc to pass to malloc if we're allocating anew.
* 3. Pointer to tydesc of the vec's stored element type, so that elements
* can be copied to a newly alloc'ed vec if one must be created.
* 3. Alias to vec that needs to grow (i.e. ptr to ptr to rust_vec).
* 4. Number of bytes of growth requested
* 4. Alias to vec that needs to grow (i.e. ptr to ptr to rust_vec).
* 5. Number of bytes of growth requested
*)
and emit_vec_grow_glue
(fix:fixup)
(g:glue)
: unit =
let arg_typarams_ptr = 0 in
let arg_tydesc_ptr = 1 in
let arg_vec_alias = 2 in
let arg_nbytes = 3 in
let arg_vec_tydesc_ptr = 1 in
let arg_elt_tydesc_ptr = 2 in
let arg_vec_alias = 3 in
let arg_nbytes = 4 in
let name = glue_str cx g in
log cx "emitting glue: %s" name;
......@@ -1918,9 +1921,10 @@ let trans_visitor
let fn_ty =
mk_simple_ty_fn
[| ty_params_covering Ast.TY_int; (* an OK lie *)
local_slot Ast.TY_type;
local_slot Ast.TY_type;
alias_slot (Ast.TY_vec Ast.TY_int); (* an OK lie *)
local_slot Ast.TY_uint; |]
local_slot Ast.TY_uint |]
in
let args_rty = call_args_referent_type cx 0 fn_ty None in
......@@ -1936,7 +1940,8 @@ let trans_visitor
let vec_alias_cell = get_element_ptr args_cell arg_vec_alias in
let vec_cell = deref vec_alias_cell in
let nbytes_cell = get_element_ptr args_cell arg_nbytes in
let td_ptr_cell = get_element_ptr args_cell arg_tydesc_ptr in
let vec_td_ptr_cell = get_element_ptr args_cell arg_vec_tydesc_ptr in
let elt_td_ptr_cell = get_element_ptr args_cell arg_elt_tydesc_ptr in
let ty_params_cell =
deref (get_element_ptr args_cell arg_typarams_ptr)
in
......@@ -1951,7 +1956,8 @@ let trans_visitor
new_vec_cell
[| Il.Cell vec_cell;
Il.Cell nbytes_cell;
Il.Cell need_copy_alias_cell |]
Il.Cell need_copy_alias_cell;
Il.Cell vec_td_ptr_cell; |]
end;
let no_copy_jmps =
......@@ -1965,7 +1971,7 @@ let trans_visitor
get_element_ptr_dyn ty_params_cell src_vec Abi.vec_elt_fill
in
let elt_sz =
get_element_ptr (deref td_ptr_cell) Abi.tydesc_field_size
get_element_ptr (deref elt_td_ptr_cell) Abi.tydesc_field_size
in
let dst_buf =
......@@ -1993,11 +1999,11 @@ let trans_visitor
(* Copy *)
let ty_params_ptr =
get_tydesc_params ty_params_cell td_ptr_cell
get_tydesc_params ty_params_cell elt_td_ptr_cell
in
let initflag = Il.Reg (force_to_reg one) in
trans_call_dynamic_glue
td_ptr_cell
elt_td_ptr_cell
Abi.tydesc_field_copy_glue
(Some (deref dptr))
[| ty_params_ptr; sptr; initflag |]
......@@ -2971,8 +2977,8 @@ let trans_visitor
(ty:Ast.ty)
: unit =
let ty = strip_mutable_or_constrained_ty ty in
let mctrl = ty_mem_ctrl cx ty in
let ty = strip_mutable_or_constrained_ty ty in
match ty with
......@@ -3173,7 +3179,7 @@ let trans_visitor
check_box_rty cell;
note_drop_step ty "in free-ty";
begin
match simplified_ty ty with
match strip_mutable_or_constrained_ty ty with
Ast.TY_port _ -> trans_del_port cell
| Ast.TY_chan _ -> trans_del_chan cell
| Ast.TY_task -> trans_kill_task cell
......@@ -3183,14 +3189,13 @@ let trans_visitor
(fun _ src ty -> drop_ty ty_params src ty);
trans_free cell is_gc
| _ ->
| Ast.TY_box body_ty ->
note_drop_step ty "in free-ty, dropping structured body";
let (body_mem, _) =
need_mem_cell
(get_element_ptr_dyn ty_params (deref cell)
Abi.box_rc_field_body)
in
let body_ty = simplified_ty ty in
let vr = next_vreg_cell Il.voidptr_t in
lea vr body_mem;
trace_word cx.ctxt_sess.Session.sess_trace_drop vr;
......@@ -3201,6 +3206,8 @@ let trans_visitor
None;
note_drop_step ty "in free-ty, calling free";
trans_free cell is_gc;
| t -> bug () "freeing unexpected type: %a" Ast.sprintf_ty t
end;
note_drop_step ty "free-ty done";
......@@ -3268,13 +3275,17 @@ let trans_visitor
(slot:Ast.slot)
: unit =
check_and_flush_chan cell slot;
drop_slot (get_ty_params_of_current_frame()) cell slot
drop_slot (get_ty_params_of_current_frame()) cell
{ slot with
Ast.slot_ty = Some (strip_mutable_or_constrained_ty
(slot_ty slot)) }
and drop_ty_in_current_frame
(cell:Il.cell)
(ty:Ast.ty)
: unit =
drop_ty (get_ty_params_of_current_frame()) cell ty
drop_ty (get_ty_params_of_current_frame()) cell
(strip_mutable_or_constrained_ty ty)
(* Returns a mark for a jmp that must be patched to the continuation of
* the null case (i.e. fall-through means not null).
......@@ -4755,7 +4766,8 @@ let trans_visitor
trans_call_simple_static_glue
(get_vec_grow_glue ())
(get_ty_params_of_current_frame ())
[| get_tydesc None elt_ty;
[| get_tydesc None dst_ty;
get_tydesc None elt_ty;
dst_vec_alias;
src_fill; |]
None
......@@ -4827,7 +4839,8 @@ let trans_visitor
trans_call_simple_static_glue
(get_vec_grow_glue ())
(get_ty_params_of_current_frame ())
[| get_tydesc None elt_ty;
[| get_tydesc None dst_ty;
get_tydesc None elt_ty;
dst_vec_alias;
elt_sz_cell; |]
None
......
......@@ -4,7 +4,7 @@
import front.token;
import middle.trans;
fn main(vec[str] args) {
io fn main(vec[str] args) {
log "This is the rust 'self-hosted' compiler.";
log "The one written in rust.";
......
......@@ -9,8 +9,8 @@
fn is_eof() -> bool;
fn curr() -> char;
fn next() -> char;
state fn bump();
state fn mark();
io fn bump();
fn mark();
fn get_filename() -> str;
fn get_mark_pos() -> common.pos;
fn get_curr_pos() -> common.pos;
......@@ -55,7 +55,7 @@ fn next() -> char {
ret n;
}
state fn bump() {
io fn bump() {
c = n;
if (c == (-1) as char) {
......@@ -72,7 +72,7 @@ fn next() -> char {
n = rdr.getc() as char;
}
state fn mark() {
fn mark() {
mark_line = line;
mark_col = col;
}
......@@ -243,14 +243,14 @@ fn is_whitespace(char c) -> bool {
ret c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
state fn consume_any_whitespace(reader rdr) {
io fn consume_any_whitespace(reader rdr) {
while (is_whitespace(rdr.curr())) {
rdr.bump();
}
be consume_any_line_comment(rdr);
}
state fn consume_any_line_comment(reader rdr) {
io fn consume_any_line_comment(reader rdr) {
if (rdr.curr() == '/') {
alt (rdr.next()) {
case ('/') {
......@@ -273,7 +273,7 @@ fn is_whitespace(char c) -> bool {
}
state fn consume_block_comment(reader rdr) {
io fn consume_block_comment(reader rdr) {
let int level = 1;
while (level > 0) {
if (rdr.curr() == '/' && rdr.next() == '*') {
......@@ -294,7 +294,7 @@ fn is_whitespace(char c) -> bool {
be consume_any_whitespace(rdr);
}
state fn next_token(reader rdr) -> token.token {
io fn next_token(reader rdr) -> token.token {
auto accum_str = "";
auto accum_int = 0;
......@@ -355,7 +355,7 @@ fn is_whitespace(char c) -> bool {
ret token.LIT_INT(accum_int);
}
state fn binop(reader rdr, token.binop op) -> token.token {
io fn binop(reader rdr, token.binop op) -> token.token {
rdr.bump();
if (rdr.next() == '=') {
rdr.bump();
......
......@@ -14,26 +14,26 @@
state type parser =
state obj {
state fn peek() -> token.token;
state fn bump();
fn peek() -> token.token;
io fn bump();
io fn err(str s);
fn get_session() -> session.session;
fn get_span() -> common.span;
};
state fn new_parser(session.session sess, str path) -> parser {
io fn new_parser(session.session sess, str path) -> parser {
state obj stdio_parser(session.session sess,
mutable token.token tok,
mutable common.pos lo,
mutable common.pos hi,
lexer.reader rdr)
{
state fn peek() -> token.token {
fn peek() -> token.token {
log token.to_str(tok);
ret tok;
}
state fn bump() {
io fn bump() {
tok = lexer.next_token(rdr);
lo = rdr.get_mark_pos();
hi = rdr.get_curr_pos();
......@@ -60,7 +60,7 @@ fn get_span() -> common.span {
ret stdio_parser(sess, lexer.next_token(rdr), npos, npos, rdr);
}
state fn expect(parser p, token.token t) {
io fn expect(parser p, token.token t) {
if (p.peek() == t) {
p.bump();
} else {
......@@ -72,7 +72,7 @@ fn get_span() -> common.span {
}
}
state fn parse_ident(parser p) -> ast.ident {
io fn parse_ident(parser p) -> ast.ident {
alt (p.peek()) {
case (token.IDENT(?i)) { p.bump(); ret i; }
case (_) {
......@@ -82,7 +82,7 @@ fn get_span() -> common.span {
}
}
state fn parse_ty(parser p) -> ast.ty {
io fn parse_ty(parser p) -> ast.ty {
alt (p.peek()) {
case (token.INT) { p.bump(); ret ast.ty_int; }
case (token.UINT) { p.bump(); ret ast.ty_int; }
......@@ -94,7 +94,7 @@ fn get_span() -> common.span {
fail;
}
state fn parse_slot(parser p) -> ast.slot {
io fn parse_slot(parser p) -> ast.slot {
let ast.mode m = ast.val;
if (p.peek() == token.BINOP(token.AND)) {
m = ast.alias;
......@@ -104,10 +104,10 @@ fn get_span() -> common.span {
ret rec(ty=t, mode=m);
}
state fn parse_seq[T](token.token bra,
io fn parse_seq[T](token.token bra,
token.token ket,
option[token.token] sep,
(state fn(parser) -> T) f,
(io fn(parser) -> T) f,
parser p) -> vec[T] {
let bool first = true;
expect(p, bra);
......@@ -132,7 +132,7 @@ fn get_span() -> common.span {
ret v;
}
state fn parse_lit(parser p) -> @ast.lit {
io fn parse_lit(parser p) -> @ast.lit {
alt (p.peek()) {
case (token.LIT_INT(?i)) {
p.bump();
......@@ -161,7 +161,7 @@ fn get_span() -> common.span {
state fn parse_bottom_expr(parser p) -> @ast.expr {
io fn parse_bottom_expr(parser p) -> @ast.expr {
alt (p.peek()) {
case (token.LPAREN) {
p.bump();
......@@ -192,7 +192,7 @@ fn get_span() -> common.span {
case (token.REC) {
p.bump();
state fn parse_entry(parser p) ->
io fn parse_entry(parser p) ->
tup(ast.ident, @ast.expr) {
auto i = parse_ident(p);
expect(p, token.EQ);
......@@ -219,7 +219,7 @@ fn get_span() -> common.span {
}
}
state fn parse_path_expr(parser p) -> @ast.expr {
io fn parse_path_expr(parser p) -> @ast.expr {
auto e = parse_bottom_expr(p);
while (true) {
alt (p.peek()) {
......@@ -246,7 +246,7 @@ fn get_span() -> common.span {
ret e;
}
state fn parse_prefix_expr(parser p) -> @ast.expr {
io fn parse_prefix_expr(parser p) -> @ast.expr {
alt (p.peek()) {
case (token.NOT) {
......@@ -294,8 +294,8 @@ fn get_span() -> common.span {
}
}
state fn parse_binops(parser p,
(state fn(parser) -> @ast.expr) sub,
io fn parse_binops(parser p,
(io fn(parser) -> @ast.expr) sub,
vec[tup(token.binop, ast.binop)] ops)
-> @ast.expr {
auto e = sub(p);
......@@ -317,8 +317,8 @@ fn get_span() -> common.span {
ret e;
}
state fn parse_binary_exprs(parser p,
(state fn(parser) -> @ast.expr) sub,
io fn parse_binary_exprs(parser p,
(io fn(parser) -> @ast.expr) sub,
vec[tup(token.token, ast.binop)] ops)
-> @ast.expr {
auto e = sub(p);
......@@ -336,42 +336,42 @@ fn get_span() -> common.span {
ret e;
}
state fn parse_factor_expr(parser p) -> @ast.expr {
io fn parse_factor_expr(parser p) -> @ast.expr {
auto sub = parse_prefix_expr;
ret parse_binops(p, sub, vec(tup(token.STAR, ast.mul),
tup(token.SLASH, ast.div),
tup(token.PERCENT, ast.rem)));
}
state fn parse_term_expr(parser p) -> @ast.expr {
io fn parse_term_expr(parser p) -> @ast.expr {
auto sub = parse_factor_expr;
ret parse_binops(p, sub, vec(tup(token.PLUS, ast.add),
tup(token.MINUS, ast.sub)));
}
state fn parse_shift_expr(parser p) -> @ast.expr {
io fn parse_shift_expr(parser p) -> @ast.expr {
auto sub = parse_term_expr;
ret parse_binops(p, sub, vec(tup(token.LSL, ast.lsl),
tup(token.LSR, ast.lsr),
tup(token.ASR, ast.asr)));
}
state fn parse_bitand_expr(parser p) -> @ast.expr {
io fn parse_bitand_expr(parser p) -> @ast.expr {
auto sub = parse_shift_expr;
ret parse_binops(p, sub, vec(tup(token.AND, ast.bitand)));
}
state fn parse_bitxor_expr(parser p) -> @ast.expr {
io fn parse_bitxor_expr(parser p) -> @ast.expr {
auto sub = parse_bitand_expr;
ret parse_binops(p, sub, vec(tup(token.CARET, ast.bitxor)));
}
state fn parse_bitor_expr(parser p) -> @ast.expr {
io fn parse_bitor_expr(parser p) -> @ast.expr {
auto sub = parse_bitxor_expr;
ret parse_binops(p, sub, vec(tup(token.OR, ast.bitor)));
}
state fn parse_cast_expr(parser p) -> @ast.expr {
io fn parse_cast_expr(parser p) -> @ast.expr {
auto e = parse_bitor_expr(p);
while (true) {
alt (p.peek()) {
......@@ -389,7 +389,7 @@ fn get_span() -> common.span {
ret e;
}
state fn parse_relational_expr(parser p) -> @ast.expr {
io fn parse_relational_expr(parser p) -> @ast.expr {
auto sub = parse_cast_expr;
ret parse_binary_exprs(p, sub, vec(tup(token.LT, ast.lt),
tup(token.LE, ast.le),
......@@ -398,27 +398,27 @@ fn get_span() -> common.span {
}
state fn parse_equality_expr(parser p) -> @ast.expr {
io fn parse_equality_expr(parser p) -> @ast.expr {
auto sub = parse_relational_expr;
ret parse_binary_exprs(p, sub, vec(tup(token.EQEQ, ast.eq),
tup(token.NE, ast.ne)));
}
state fn parse_and_expr(parser p) -> @ast.expr {
io fn parse_and_expr(parser p) -> @ast.expr {
auto sub = parse_equality_expr;
ret parse_binary_exprs(p, sub, vec(tup(token.ANDAND, ast.and)));
}
state fn parse_or_expr(parser p) -> @ast.expr {
io fn parse_or_expr(parser p) -> @ast.expr {
auto sub = parse_and_expr;
ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or)));
}
state fn parse_expr(parser p) -> @ast.expr {
io fn parse_expr(parser p) -> @ast.expr {
ret parse_or_expr(p);
}
state fn parse_stmt(parser p) -> @ast.stmt {
io fn parse_stmt(parser p) -> @ast.stmt {
alt (p.peek()) {
case (token.LOG) {
p.bump();
......@@ -431,7 +431,7 @@ fn get_span() -> common.span {
fail;
}
state fn parse_block(parser p) -> ast.block {
io fn parse_block(parser p) -> ast.block {
auto f = parse_stmt;
// FIXME: passing parse_stmt as an lval doesn't work at the moment.
ret parse_seq[@ast.stmt](token.LBRACE,
......@@ -440,14 +440,14 @@ fn get_span() -> common.span {
f, p);
}
state fn parse_slot_ident_pair(parser p) ->
io fn parse_slot_ident_pair(parser p) ->
rec(ast.slot slot, ast.ident ident) {
auto s = parse_slot(p);
auto i = parse_ident(p);
ret rec(slot=s, ident=i);
}
state fn parse_fn(parser p) -> tup(ast.ident, ast.item) {
io fn parse_fn(parser p) -> tup(ast.ident, ast.item) {
expect(p, token.FN);
auto id = parse_ident(p);
auto pf = parse_slot_ident_pair;
......@@ -477,7 +477,7 @@ fn get_span() -> common.span {
ret tup(id, ast.item_fn(@f));
}
state fn parse_mod(parser p) -> tup(ast.ident, ast.item) {
io fn parse_mod(parser p) -> tup(ast.ident, ast.item) {
expect(p, token.MOD);
auto id = parse_ident(p);
expect(p, token.LBRACE);
......@@ -490,7 +490,7 @@ fn get_span() -> common.span {
ret tup(id, ast.item_mod(@m));
}
state fn parse_item(parser p) -> tup(ast.ident, ast.item) {
io fn parse_item(parser p) -> tup(ast.ident, ast.item) {
alt (p.peek()) {
case (token.FN) {
ret parse_fn(p);
......@@ -503,7 +503,7 @@ fn get_span() -> common.span {
fail;
}
state fn parse_crate(parser p) -> ast.crate {
io fn parse_crate(parser p) -> ast.crate {
let ast._mod m = new_str_hash[ast.item]();
while (p.peek() != token.EOF) {
auto i = parse_item(p);
......
......@@ -50,10 +50,28 @@ fn next(str prefix) -> str {
type terminator = fn(@fn_ctxt cx, builder build);
type block_ctxt = rec(BasicBlockRef llbb,
builder build,
terminator term,
@fn_ctxt fcx);
tag cleanup {
clean(fn(@block_ctxt cx, ValueRef v), ValueRef);
}
state type block_ctxt = rec(BasicBlockRef llbb,
builder build,
terminator term,
mutable vec[cleanup] cleanups,
@fn_ctxt fcx);
fn ty_str(TypeRef t) -> str {
ret lib.llvm.type_to_str(t);
}
fn val_ty(ValueRef v) -> TypeRef {
ret llvm.LLVMTypeOf(v);
}
fn val_str(ValueRef v) -> str {
ret ty_str(val_ty(v));
}
// LLVM type constructors.
......@@ -120,6 +138,12 @@ fn T_task() -> TypeRef {
));
}
fn T_str() -> TypeRef {
ret T_struct(vec(T_int(), // Refcount
T_int() // Lie about the remainder
));
}
fn T_crate() -> TypeRef {
ret T_struct(vec(T_int(), // ptrdiff_t image_base_off
T_int(), // uintptr_t self_addr
......@@ -134,7 +158,7 @@ fn T_crate() -> TypeRef {
T_int(), // size_t main_exit_task_glue_off
T_int(), // int n_rust_syms
T_int(), // int n_c_syms
T_int() //int n_libs
T_int() // int n_libs
));
}
......@@ -146,7 +170,6 @@ fn T_taskptr() -> TypeRef {
ret T_ptr(T_task());
}
// LLVM constant constructors.
fn C_null(TypeRef t) -> ValueRef {
......@@ -177,7 +200,7 @@ fn C_int(int i) -> ValueRef {
fn C_str(@trans_ctxt cx, str s) -> ValueRef {
auto sc = llvm.LLVMConstString(_str.buf(s), _str.byte_len(s), False);
auto g = llvm.LLVMAddGlobal(cx.llmod, llvm.LLVMTypeOf(sc),
auto g = llvm.LLVMAddGlobal(cx.llmod, val_ty(sc),
_str.buf(cx.names.next("str")));
llvm.LLVMSetInitializer(g, sc);
ret g;
......@@ -192,7 +215,7 @@ fn C_struct(vec[ValueRef] elts) -> ValueRef {
fn decl_cdecl_fn(ModuleRef llmod, str name,
vec[TypeRef] inputs, TypeRef output) -> ValueRef {
let TypeRef llty = T_fn(inputs, output);
log "declaring " + name + " with type " + lib.llvm.type_to_str(llty);
log "declaring " + name + " with type " + ty_str(llty);
let ValueRef llfn =
llvm.LLVMAddFunction(llmod, _str.buf(name), llty);
llvm.LLVMSetFunctionCallConv(llfn, lib.llvm.LLVMCCallConv);
......@@ -224,7 +247,7 @@ fn get_upcall(@trans_ctxt cx, str name, int n_args) -> ValueRef {
}
auto inputs = vec(T_taskptr());
inputs += _vec.init_elt[TypeRef](T_int(), n_args as uint);
auto output = T_nil();
auto output = T_int();
auto f = decl_cdecl_fn(cx.llmod, name, inputs, output);
cx.upcalls.insert(name, f);
ret f;
......@@ -240,15 +263,26 @@ fn trans_upcall(@block_ctxt cx, str name, vec[ValueRef] args) -> ValueRef {
for (ValueRef a in args) {
call_args += cx.build.ZExtOrBitCast(a, T_int());
}
log "emitting indirect-upcall via " + abi.upcall_glue_name(n);
for (ValueRef v in call_args) {
log "arg: " + lib.llvm.type_to_str(llvm.LLVMTypeOf(v));
}
log "emitting call to callee of type: " +
lib.llvm.type_to_str(llvm.LLVMTypeOf(llglue));
/*
log "emitting indirect-upcall via " + abi.upcall_glue_name(n);
for (ValueRef v in call_args) {
log "arg: " + val_str(v);
}
log "emitting call to llglue of type: " + val_str(llglue);
*/
ret cx.build.Call(llglue, call_args);
}
fn build_non_gc_free(@block_ctxt cx, ValueRef v) {
trans_upcall(cx, "upcall_free", vec(cx.build.PtrToInt(v, T_int()),
C_int(0)));
}
fn drop_str(@block_ctxt cx, ValueRef v) {
build_non_gc_free(cx, v);
}
fn trans_lit(@block_ctxt cx, &ast.lit lit) -> ValueRef {
alt (lit) {
case (ast.lit_int(?i)) {
......@@ -265,9 +299,13 @@ fn trans_lit(@block_ctxt cx, &ast.lit lit) -> ValueRef {
}
case (ast.lit_str(?s)) {
auto len = (_str.byte_len(s) as int) + 1;
ret trans_upcall(cx, "upcall_new_str",
vec(p2i(C_str(cx.fcx.tcx, s)),
C_int(len)));
auto v = trans_upcall(cx, "upcall_new_str",
vec(p2i(C_str(cx.fcx.tcx, s)),
C_int(len)));
v = cx.build.IntToPtr(v, T_ptr(T_str()));
auto f = drop_str;
cx.cleanups += vec(clean(f, v));
ret v;
}
}
}
......@@ -402,7 +440,8 @@ fn trans_log(@block_ctxt cx, &ast.expr e) {
alt (*lit) {
case (ast.lit_str(_)) {
auto v = trans_expr(cx, e);
trans_upcall(cx, "upcall_log_str", vec(v));
trans_upcall(cx, "upcall_log_str",
vec(cx.build.PtrToInt(v, T_int())));
}
case (_) {
auto v = trans_expr(cx, e);
......@@ -441,9 +480,11 @@ fn new_builder(BasicBlockRef llbb) -> builder {
fn new_block_ctxt(@fn_ctxt cx, terminator term) -> @block_ctxt {
let BasicBlockRef llbb =
llvm.LLVMAppendBasicBlock(cx.llfn, _str.buf(""));
let vec[cleanup] cleanups = vec();
ret @rec(llbb=llbb,
build=new_builder(llbb),
term=term,
mutable cleanups=cleanups,
fcx=cx);
}
......@@ -452,6 +493,15 @@ fn trans_block(@fn_ctxt cx, &ast.block b, terminator term) {
for (@ast.stmt s in b) {
trans_stmt(bcx, *s);
}
for (cleanup c in bcx.cleanups) {
alt (c) {
case (clean(?cfn, ?v)) {
cfn(bcx, v);
}
}
}
bcx.term(cx, bcx.build);
}
......
......@@ -12,15 +12,15 @@
type hashfn[K] = fn(&K) -> uint;
type eqfn[K] = fn(&K, &K) -> bool;
type hashmap[K, V] = obj {
fn size() -> uint;
fn insert(&K key, &V val) -> bool;
fn contains_key(&K key) -> bool;
fn get(&K key) -> V;
fn find(&K key) -> util.option[V];
fn remove(&K key) -> util.option[V];
fn rehash();
iter items() -> tup(K,V);
state type hashmap[K, V] = state obj {
fn size() -> uint;
fn insert(&K key, &V val) -> bool;
fn contains_key(&K key) -> bool;
fn get(&K key) -> V;
fn find(&K key) -> util.option[V];
fn remove(&K key) -> util.option[V];
fn rehash();
iter items() -> tup(K,V);
};
fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
......@@ -141,12 +141,12 @@ fn rehash[K, V](&hashfn[K] hasher,
}
}
obj hashmap[K, V](hashfn[K] hasher,
eqfn[K] eqer,
mutable vec[mutable bucket[K, V]] bkts,
mutable uint nbkts,
mutable uint nelts,
util.rational lf)
state obj hashmap[K, V](hashfn[K] hasher,
eqfn[K] eqer,
mutable vec[mutable bucket[K, V]] bkts,
mutable uint nbkts,
mutable uint nelts,
util.rational lf)
{
fn size() -> uint { ret nelts; }
......
......@@ -488,6 +488,10 @@ rust_task::unlink_gc(gc_alloc *gcm) {
void *
rust_task::malloc(size_t sz, type_desc *td)
{
// FIXME: GC is disabled for now.
// Effects, GC-memory classification are all wrong.
td = NULL;
if (td) {
sz += sizeof(gc_alloc);
}
......@@ -512,6 +516,9 @@ rust_task::malloc(size_t sz, type_desc *td)
void *
rust_task::realloc(void *data, size_t sz, bool is_gc)
{
// FIXME: GC is disabled for now.
// Effects, GC-memory classification are all wrong.
is_gc = false;
if (is_gc) {
gc_alloc *gcm = (gc_alloc*)(((char *)data) - sizeof(gc_alloc));
unlink_gc(gcm);
......@@ -534,6 +541,9 @@ rust_task::realloc(void *data, size_t sz, bool is_gc)
void
rust_task::free(void *p, bool is_gc)
{
// FIXME: GC is disabled for now.
// Effects, GC-memory classification are all wrong.
is_gc = false;
if (is_gc) {
gc_alloc *gcm = (gc_alloc*)(((char *)p) - sizeof(gc_alloc));
unlink_gc(gcm);
......
......@@ -312,8 +312,8 @@ upcall_free(rust_task *task, void* ptr, uintptr_t is_gc) {
LOG_UPCALL_ENTRY(task);
rust_dom *dom = task->dom;
dom->log(rust_log::UPCALL|rust_log::MEM,
"upcall free(0x%" PRIxPTR ")",
(uintptr_t)ptr);
"upcall free(0x%" PRIxPTR ", is_gc=%" PRIdPTR ")",
(uintptr_t)ptr, is_gc);
task->free(ptr, (bool) is_gc);
}
......@@ -338,7 +338,7 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) {
LOG_UPCALL_ENTRY(task);
rust_dom *dom = task->dom;
size_t alloc = next_power_of_two(sizeof(rust_str) + fill);
void *mem = dom->malloc(alloc);
void *mem = task->malloc(alloc);
if (!mem) {
task->fail(3);
return NULL;
......@@ -373,7 +373,8 @@ extern "C" CDECL rust_vec *
upcall_vec_grow(rust_task *task,
rust_vec *v,
size_t n_bytes,
uintptr_t *need_copy)
uintptr_t *need_copy,
type_desc *td)
{
LOG_UPCALL_ENTRY(task);
rust_dom *dom = task->dom;
......@@ -396,7 +397,7 @@ upcall_vec_grow(rust_task *task,
// Second-fastest path: can at least realloc.
task->log(rust_log::UPCALL | rust_log::MEM, "realloc path");
v = (rust_vec*) dom->realloc(v, alloc);
v = (rust_vec*) task->realloc(v, alloc, td->is_stateful);
if (!v) {
task->fail(4);
return NULL;
......@@ -418,7 +419,7 @@ upcall_vec_grow(rust_task *task,
* that we need the copies performed for us.
*/
task->log(rust_log::UPCALL | rust_log::MEM, "new vec path");
void *mem = dom->malloc(alloc);
void *mem = task->malloc(alloc, td);
if (!mem) {
task->fail(4);
return NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册