aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-29 17:22:07 -0700
committerGraydon Hoare <[email protected]>2010-09-29 17:22:13 -0700
commitb970563fe3f36853250f4cef65a8425431789e8b (patch)
treec09d7d39a46419c24ea88164ee047c10ebd7da39 /src/comp
parentAllow tag recursion through vectors as well as boxes (diff)
downloadrust-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/comp')
-rw-r--r--src/comp/driver/rustc.rs2
-rw-r--r--src/comp/front/lexer.rs18
-rw-r--r--src/comp/front/parser.rs78
-rw-r--r--src/comp/middle/trans.rs88
4 files changed, 118 insertions, 68 deletions
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);
}