diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs index 16a3efc06b8b..9f08bbb9476f 100644 --- a/src/comp/lib/llvm.rs +++ b/src/comp/lib/llvm.rs @@ -889,9 +889,13 @@ native "cdecl" mod llvm = "rustllvm" { * it's attached to. */ -// FIXME: Do we want to support mutable object fields? -obj builder(B: BuilderRef, terminated: @mutable bool) { +resource BuilderRef_res(B: BuilderRef) { + llvm::LLVMDisposeBuilder(B); +} +obj builder(B: BuilderRef, terminated: @mutable bool, + // Stored twice so that we don't have to constantly deref + res: @BuilderRef_res) { /* Terminators */ fn RetVoid() -> ValueRef { assert (!*terminated); @@ -1396,9 +1400,12 @@ obj builder(B: BuilderRef, terminated: @mutable bool) { fn is_terminated() -> bool { ret *terminated; } - drop { - llvm::LLVMDisposeBuilder(B); - } +} + +fn new_builder(llbb: BasicBlockRef) -> builder { + let llbuild: BuilderRef = llvm::LLVMCreateBuilder(); + llvm::LLVMPositionBuilderAtEnd(llbuild, llbb); + ret builder(llbuild, @mutable false, @BuilderRef_res(llbuild)); } /* Memory-managed object interface to type handles. */ @@ -1554,54 +1561,54 @@ fn fn_ty_param_tys(fn_ty: TypeRef) -> TypeRef[] { /* Memory-managed interface to target data. */ -obj target_data_dtor(TD: TargetDataRef) { - drop { llvm::LLVMDisposeTargetData(TD); } +resource target_data_res(TD: TargetDataRef) { + llvm::LLVMDisposeTargetData(TD); } -type target_data = {lltd: TargetDataRef, dtor: target_data_dtor}; +type target_data = {lltd: TargetDataRef, dtor: @target_data_res}; fn mk_target_data(string_rep: str) -> target_data { let lltd = llvm::LLVMCreateTargetData(str::buf(string_rep)); - ret {lltd: lltd, dtor: target_data_dtor(lltd)}; + ret {lltd: lltd, dtor: @target_data_res(lltd)}; } /* Memory-managed interface to pass managers. */ -obj pass_manager_dtor(PM: PassManagerRef) { - drop { llvm::LLVMDisposePassManager(PM); } +resource pass_manager_res(PM: PassManagerRef) { + llvm::LLVMDisposePassManager(PM); } -type pass_manager = {llpm: PassManagerRef, dtor: pass_manager_dtor}; +type pass_manager = {llpm: PassManagerRef, dtor: @pass_manager_res}; fn mk_pass_manager() -> pass_manager { let llpm = llvm::LLVMCreatePassManager(); - ret {llpm: llpm, dtor: pass_manager_dtor(llpm)}; + ret {llpm: llpm, dtor: @pass_manager_res(llpm)}; } /* Memory-managed interface to object files. */ -obj object_file_dtor(ObjectFile: ObjectFileRef) { - drop { llvm::LLVMDisposeObjectFile(ObjectFile); } +resource object_file_res(ObjectFile: ObjectFileRef) { + llvm::LLVMDisposeObjectFile(ObjectFile); } -type object_file = {llof: ObjectFileRef, dtor: object_file_dtor}; +type object_file = {llof: ObjectFileRef, dtor: @object_file_res}; fn mk_object_file(llmb: MemoryBufferRef) -> object_file { let llof = llvm::LLVMCreateObjectFile(llmb); - ret {llof: llof, dtor: object_file_dtor(llof)}; + ret {llof: llof, dtor: @object_file_res(llof)}; } /* Memory-managed interface to section iterators. */ -obj section_iter_dtor(SI: SectionIteratorRef) { - drop { llvm::LLVMDisposeSectionIterator(SI); } +resource section_iter_res(SI: SectionIteratorRef) { + llvm::LLVMDisposeSectionIterator(SI); } -type section_iter = {llsi: SectionIteratorRef, dtor: section_iter_dtor}; +type section_iter = {llsi: SectionIteratorRef, dtor: @section_iter_res}; fn mk_section_iter(llof: ObjectFileRef) -> section_iter { let llsi = llvm::LLVMGetSections(llof); - ret {llsi: llsi, dtor: section_iter_dtor(llsi)}; + ret {llsi: llsi, dtor: @section_iter_res(llsi)}; } // diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 928ae327f9bf..c1504fb9b608 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -41,6 +41,7 @@ import std::map::new_str_hash; import syntax::codemap::span; import lib::llvm::llvm; import lib::llvm::builder; +import lib::llvm::new_builder; import lib::llvm::target_data; import lib::llvm::type_names; import lib::llvm::mk_target_data; @@ -5934,13 +5935,6 @@ fn trans_stmt(cx: &@block_ctxt, s: &ast::stmt) -> result { ret rslt(bcx, C_nil()); } -fn new_builder(llbb: BasicBlockRef) -> builder { - let llbuild: BuilderRef = llvm::LLVMCreateBuilder(); - llvm::LLVMPositionBuilderAtEnd(llbuild, llbb); - ret builder(llbuild, @mutable false); -} - - // You probably don't want to use this one. See the // next three functions instead. fn new_block_ctxt(cx: &@fn_ctxt, parent: &block_parent, kind: block_kind, diff --git a/src/lib/io.rs b/src/lib/io.rs index 16868115aaa4..a4b2891770cb 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -255,7 +255,11 @@ obj FILE_writer(f: os::libc::FILE, res: option::t[@FILE_res]) { } } -obj fd_buf_writer(fd: int, must_close: bool) { +resource fd_res(fd: int) { + os::libc::close(fd); +} + +obj fd_buf_writer(fd: int, res: option::t[@fd_res]) { fn write(v: vec[u8]) { let len = vec::len[u8](v); let count = 0u; @@ -279,7 +283,6 @@ obj fd_buf_writer(fd: int, must_close: bool) { log_err "need 64-bit native calls for tell, sorry"; fail; } - drop { if must_close { os::libc::close(fd); } } } fn file_buf_writer(path: str, flags: vec[fileflag]) -> buf_writer { @@ -302,7 +305,7 @@ fn file_buf_writer(path: str, flags: vec[fileflag]) -> buf_writer { log_err sys::rustrt::last_os_error(); fail; } - ret fd_buf_writer(fd, true); + ret fd_buf_writer(fd, option::some(@fd_res(fd))); } type writer = @@ -379,9 +382,9 @@ fn buffered_file_buf_writer(path: str) -> buf_writer { // FIXME it would be great if this could be a const -fn stdout() -> writer { ret new_writer(fd_buf_writer(1, false)); } +fn stdout() -> writer { ret new_writer(fd_buf_writer(1, option::none)); } -fn stderr() -> writer { ret new_writer(fd_buf_writer(2, false)); } +fn stderr() -> writer { ret new_writer(fd_buf_writer(2, option::none)); } type str_writer = obj { diff --git a/src/lib/ioivec.rs b/src/lib/ioivec.rs index 9269607b5dd0..cae0c27787c0 100644 --- a/src/lib/ioivec.rs +++ b/src/lib/ioivec.rs @@ -55,7 +55,11 @@ fn convert_whence(whence: seek_style) -> int { ret alt whence { seek_set. { 0 } seek_cur. { 1 } seek_end. { 2 } }; } -obj FILE_buf_reader(f: os::libc::FILE, must_close: bool) { +resource FILE_res(f: os::libc::FILE) { + os::libc::fclose(f); +} + +obj FILE_buf_reader(f: os::libc::FILE, res: option::t[@FILE_res]) { fn read(len: uint) -> u8[] { let buf = ~[]; ivec::reserve[u8](buf, len); @@ -72,7 +76,6 @@ obj FILE_buf_reader(f: os::libc::FILE, must_close: bool) { fn tell() -> uint { ret os::libc::ftell(f) as uint; } - drop { if must_close { os::libc::fclose(f); } } } @@ -172,13 +175,13 @@ obj new_reader(rdr: buf_reader) { } fn stdin() -> reader { - ret new_reader(FILE_buf_reader(rustrt::rust_get_stdin(), false)); + ret new_reader(FILE_buf_reader(rustrt::rust_get_stdin(), option::none)); } fn file_reader(path: str) -> reader { let f = os::libc::fopen(str::buf(path), str::buf("r")); if f as uint == 0u { log_err "error opening " + path; fail; } - ret new_reader(FILE_buf_reader(f, true)); + ret new_reader(FILE_buf_reader(f, option::some(@FILE_res(f)))); } @@ -240,7 +243,7 @@ type buf_writer = fn tell() -> uint ; }; -obj FILE_writer(f: os::libc::FILE, must_close: bool) { +obj FILE_writer(f: os::libc::FILE, res: option::t[@FILE_res]) { fn write(v: &u8[]) { let len = ivec::len[u8](v); let vbuf = ivec::to_ptr[u8](v); @@ -253,10 +256,13 @@ obj FILE_writer(f: os::libc::FILE, must_close: bool) { fn tell() -> uint { ret os::libc::ftell(f) as uint; } - drop { if must_close { os::libc::fclose(f); } } } -obj fd_buf_writer(fd: int, must_close: bool) { +resource fd_res(fd: int) { + os::libc::close(fd); +} + +obj fd_buf_writer(fd: int, res: option::t[@fd_res]) { fn write(v: &u8[]) { let len = ivec::len[u8](v); let count = 0u; @@ -280,7 +286,6 @@ obj fd_buf_writer(fd: int, must_close: bool) { log_err "need 64-bit native calls for tell, sorry"; fail; } - drop { if must_close { os::libc::close(fd); } } } fn file_buf_writer(path: str, flags: &fileflag[]) -> buf_writer { @@ -303,7 +308,7 @@ fn file_buf_writer(path: str, flags: &fileflag[]) -> buf_writer { log_err sys::rustrt::last_os_error(); fail; } - ret fd_buf_writer(fd, true); + ret fd_buf_writer(fd, option::some(@fd_res(fd))); } type writer = @@ -377,12 +382,12 @@ fn file_writer(path: str, flags: &fileflag[]) -> writer { fn buffered_file_buf_writer(path: str) -> buf_writer { let f = os::libc::fopen(str::buf(path), str::buf("w")); if f as uint == 0u { log_err "error opening " + path; fail; } - ret FILE_writer(f, true); + ret FILE_writer(f, option::some(@FILE_res(f))); } // FIXME it would be great if this could be a const -fn stdout() -> writer { ret new_writer(fd_buf_writer(1, false)); } +fn stdout() -> writer { ret new_writer(fd_buf_writer(1, option::none)); } type str_writer = obj { diff --git a/src/lib/rand.rs b/src/lib/rand.rs index 77d62aaaea53..7b47311b04ba 100644 --- a/src/lib/rand.rs +++ b/src/lib/rand.rs @@ -11,19 +11,19 @@ native "rust" mod rustrt { fn rand_free(c: rctx); } -type rng = - obj { - fn next() -> u32 ; - }; +type rng = obj { fn next() -> u32; }; + +resource rand_res(c: rustrt::rctx) { + rustrt::rand_free(c); +} fn mk_rng() -> rng { - obj rt_rng(c: rustrt::rctx) { + obj rt_rng(c: @rand_res) { fn next() -> u32 { - ret rustrt::rand_next(c); + ret rustrt::rand_next(**c); } - drop { rustrt::rand_free(c); } } - ret rt_rng(rustrt::rand_new()); + ret rt_rng(@rand_res(rustrt::rand_new())); } // Local Variables: // mode: rust; diff --git a/src/lib/run_program.rs b/src/lib/run_program.rs index da5c1409e22a..f2dd12800594 100644 --- a/src/lib/run_program.rs +++ b/src/lib/run_program.rs @@ -35,15 +35,20 @@ fn run_program(prog: str, args: vec[str]) -> int { type program = obj { - fn get_id() -> int ; - fn input() -> io::writer ; - fn output() -> io::reader ; - fn err() -> io::reader ; - fn close_input() ; - fn finish() -> int ; + fn get_id() -> int; + fn input() -> io::writer; + fn output() -> io::reader; + fn err() -> io::reader; + fn close_input(); + fn finish() -> int; + fn destroy(); }; -fn start_program(prog: str, args: vec[str]) -> @program { +resource program_res(p: program) { + p.destroy(); +} + +fn start_program(prog: str, args: vec[str]) -> @program_res { let pipe_input = os::pipe(); let pipe_output = os::pipe(); let pipe_err = os::pipe(); @@ -61,7 +66,7 @@ fn start_program(prog: str, args: vec[str]) -> @program { mutable finished: bool) { fn get_id() -> int { ret pid; } fn input() -> io::writer { - ret io::new_writer(io::fd_buf_writer(in_fd, false)); + ret io::new_writer(io::fd_buf_writer(in_fd, option::none)); } fn output() -> io::reader { ret io::new_reader(io::FILE_buf_reader(out_file, option::none)); @@ -82,18 +87,17 @@ fn start_program(prog: str, args: vec[str]) -> @program { self.close_input(); ret os::waitpid(pid); } - drop { - self.close_input(); - if !finished { os::waitpid(pid); } + fn destroy() { + self.finish(); os::libc::fclose(out_file); os::libc::fclose(err_file); } } - ret @new_program(pid, - pipe_input.out, - os::fd_FILE(pipe_output.in), - os::fd_FILE(pipe_err.in), - false); + ret @program_res(new_program(pid, + pipe_input.out, + os::fd_FILE(pipe_output.in), + os::fd_FILE(pipe_err.in), + false)); } fn read_all(rd: &io::reader) -> str { diff --git a/src/test/compiletest/compiletest.rs b/src/test/compiletest/compiletest.rs index ff6fc171d9e1..1f5e49134148 100644 --- a/src/test/compiletest/compiletest.rs +++ b/src/test/compiletest/compiletest.rs @@ -668,7 +668,7 @@ mod procsrv { fn readclose(fd: int) -> str { // Copied from run::program_output let file = os::fd_FILE(fd); - let reader = io::new_reader(io::FILE_buf_reader(file, false)); + let reader = io::new_reader(io::FILE_buf_reader(file, option::none)); let buf = ""; while !reader.eof() { let bytes = reader.read_bytes(4096u);