diff options
| author | Graydon Hoare <[email protected]> | 2010-09-29 17:22:07 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-09-29 17:22:13 -0700 |
| commit | b970563fe3f36853250f4cef65a8425431789e8b (patch) | |
| tree | c09d7d39a46419c24ea88164ee047c10ebd7da39 /src | |
| parent | Allow tag recursion through vectors as well as boxes (diff) | |
| download | rust-b970563fe3f36853250f4cef65a8425431789e8b.tar.xz rust-b970563fe3f36853250f4cef65a8425431789e8b.zip | |
Patchwork of attempted fixes to effect system and gc system; eventually give up and disable it entirely in the runtime. Will need extensive reworking.
Diffstat (limited to 'src')
| -rw-r--r-- | src/boot/be/abi.ml | 2 | ||||
| -rw-r--r-- | src/boot/me/trans.ml | 55 | ||||
| -rw-r--r-- | src/comp/driver/rustc.rs | 2 | ||||
| -rw-r--r-- | src/comp/front/lexer.rs | 18 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 78 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 88 | ||||
| -rw-r--r-- | src/lib/map.rs | 30 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 10 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 13 |
9 files changed, 185 insertions, 111 deletions
diff --git a/src/boot/be/abi.ml b/src/boot/be/abi.ml index 2bb10870..c16fec36 100644 --- a/src/boot/be/abi.ml +++ b/src/boot/be/abi.ml @@ -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 = { diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index eb02d8e0..fb5c2aec 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -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; @@ -1919,8 +1922,9 @@ let trans_visitor 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 diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index e3eb10cf..b9e4aef1 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -4,7 +4,7 @@ import front.parser; 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."; diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index d058db4a..f38f5024 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -9,8 +9,8 @@ state type reader = state obj { 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 new_reader(stdio_reader rdr, str filename) -> reader ret n; } - state fn bump() { + io fn bump() { c = n; if (c == (-1) as char) { @@ -72,7 +72,7 @@ fn new_reader(stdio_reader rdr, str filename) -> reader 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 @@ state fn consume_any_line_comment(reader rdr) { } -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 @@ state fn consume_block_comment(reader rdr) { 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 @@ state fn next_token(reader rdr) -> token.token { 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(); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 98cb7e1e..44bddf08 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -14,26 +14,26 @@ tag option[T] { 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 @@ state fn new_parser(session.session sess, str path) -> parser { 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 @@ state fn expect(parser p, token.token t) { } } -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 @@ state fn parse_ident(parser p) -> ast.ident { } } -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 @@ state fn parse_ty(parser p) -> ast.ty { 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 @@ state fn parse_slot(parser p) -> ast.slot { 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 @@ state fn parse_seq[T](token.token bra, 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 @@ state fn parse_lit(parser p) -> @ast.lit { -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 @@ state fn parse_bottom_expr(parser p) -> @ast.expr { 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 @@ state fn parse_bottom_expr(parser p) -> @ast.expr { } } -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 @@ state fn parse_path_expr(parser p) -> @ast.expr { 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 @@ state fn parse_prefix_expr(parser p) -> @ast.expr { } } -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 @@ state fn parse_binops(parser p, 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 @@ state fn parse_binary_exprs(parser p, 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 @@ state fn parse_cast_expr(parser p) -> @ast.expr { 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 @@ state fn parse_relational_expr(parser p) -> @ast.expr { } -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 @@ state fn parse_stmt(parser p) -> @ast.stmt { 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 @@ state fn parse_block(parser p) -> ast.block { 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 @@ state fn parse_fn(parser p) -> tup(ast.ident, ast.item) { 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 @@ state fn parse_mod(parser p) -> tup(ast.ident, ast.item) { 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 @@ state fn parse_item(parser p) -> tup(ast.ident, ast.item) { 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); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index eb396976..1828271f 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -50,10 +50,28 @@ state type fn_ctxt = rec(ValueRef llfn, 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); } diff --git a/src/lib/map.rs b/src/lib/map.rs index 9ebfd4b6..cdc2d025 100644 --- a/src/lib/map.rs +++ b/src/lib/map.rs @@ -12,15 +12,15 @@ import std._vec; 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 mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] { } } - 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; } diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 3bc41b93..97eeb4bf 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -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); diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 9a5e73f8..9742b22a 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -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; |