put serializer into the build and encode full item paths

This commit is contained in:
Niko Matsakis 2012-02-10 06:01:32 -08:00
parent dbcb54f4dc
commit fdddf8f9e1
15 changed files with 238 additions and 29 deletions

View File

@ -410,6 +410,7 @@ TSREQS := \
FUZZ := $(HBIN3_H_$(CFG_HOST_TRIPLE))/fuzzer$(X)
CARGO := $(HBIN3_H_$(CFG_HOST_TRIPLE))/cargo$(X)
RUSTDOC := $(HBIN3_H_$(CFG_HOST_TRIPLE))/rustdoc$(X)
SERIALIZER := $(HBIN3_H_$(CFG_HOST_TRIPLE))/serializer$(X)
all: rustc $(GENERATED) docs $(FUZZ) $(CARGO) $(RUSTDOC)

View File

@ -16,6 +16,11 @@ CARGO_INPUTS := $(wildcard $(S)src/cargo/*rs)
RUSTDOC_CRATE := $(S)src/rustdoc/rustdoc.rc
RUSTDOC_INPUTS := $(wildcard $(S)src/rustdoc/*.rs)
# Serializer, generates serialization code
# (Should eventually move into a compiler ext)
SERIALIZER_CRATE := $(S)src/serializer/serializer.rc
SERIALIZER_INPUTS := $(wildcard $(S)src/serializer/*.rs)
# FIXME: These are only built for the host arch. Eventually we'll
# have tools that need to built for other targets.
define TOOLS_STAGE_N
@ -83,6 +88,21 @@ $$(HBIN$(2)_H_$(4))/rustdoc$$(X): \
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TBIN$(1)_T_$(4)_H_$(3))/serializer$$(X): \
$$(SERIALIZER_CRATE) $$(SERIALIZER_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC)
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
$$(HBIN$(2)_H_$(4))/serializer$$(X): \
$$(TBIN$(1)_T_$(4)_H_$(3))/serializer$$(X) \
$$(HSREQ$(2)_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
endef
$(foreach host,$(CFG_TARGET_TRIPLES), \

View File

@ -70,6 +70,13 @@ const tag_impl_iface: uint = 0x32u;
// discriminator value for variants
const tag_disr_val: uint = 0x34u;
// used to encode ast_map::path and ast_map::path_elt
const tag_path: uint = 0x40u;
const tag_path_len: uint = 0x41u;
const tag_path_elt_mod: uint = 0x42u;
const tag_path_elt_name: uint = 0x43u;
// djb's cdb hashes.
fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); }

View File

@ -2,7 +2,8 @@
import syntax::ast;
import syntax::ast_util;
import middle::ty;
import middle::{ty, ast_map};
import option::{some, none};
import driver::session;
export get_symbol;
@ -13,6 +14,7 @@ export get_impls_for_mod;
export get_iface_methods;
export get_type;
export get_impl_iface;
export get_item_path;
fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
let cdata = cstore::get_crate_data(cstore, def.crate).data;
@ -55,6 +57,12 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
ret result;
}
fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
let cstore = tcx.sess.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);
ret decoder::get_item_path(cdata, def.node);
}
fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id) -> [ty::variant_info] {
let cstore = tcx.sess.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);

View File

@ -6,6 +6,7 @@ import syntax::{ast, ast_util};
import driver::session::session;
import front::attr;
import middle::ty;
import middle::ast_map;
import common::*;
import tydecode::{parse_ty_data, parse_def_id, parse_bounds_data};
import syntax::print::pprust;
@ -28,6 +29,7 @@ export get_crate_hash;
export get_impls_for_mod;
export get_iface_methods;
export get_crate_module_paths;
export get_item_path;
// A function that takes a def_id relative to the crate being searched and
// returns a def_id relative to the compilation environment, i.e. if we hit a
@ -176,6 +178,30 @@ fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] {
ret result;
}
fn item_path(item_doc: ebml::doc) -> ast_map::path {
let path_doc = ebml::get_doc(item_doc, tag_path);
let len_doc = ebml::get_doc(path_doc, tag_path_len);
let len = ebml::doc_as_uint(len_doc);
let result = [];
vec::reserve(result, len);
ebml::docs(path_doc) {|tag, elt_doc|
if tag == tag_path_elt_mod {
let str = ebml::doc_str(elt_doc);
result += [ast_map::path_mod(str)];
} else if tag == tag_path_elt_name {
let str = ebml::doc_str(elt_doc);
result += [ast_map::path_name(str)];
} else {
// ignore tag_path_len element
}
}
ret result;
}
fn item_name(item: ebml::doc) -> ast::ident {
let name = ebml::get_doc(item, tag_paths_data_name);
str::from_bytes(ebml::doc_data(name))
@ -234,6 +260,10 @@ fn get_symbol(data: @[u8], id: ast::node_id) -> str {
ret item_symbol(lookup_item(id, data));
}
fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path {
item_path(lookup_item(id, cdata.data))
}
fn get_enum_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
-> [ty::variant_info] {
let data = cdata.data;

View File

@ -10,6 +10,7 @@ import common::*;
import middle::trans::common::crate_ctxt;
import middle::ty;
import middle::ty::node_id_to_type;
import middle::ast_map;
import front::attr;
import driver::session::session;
@ -233,8 +234,9 @@ fn encode_enum_id(ebml_w: ebml::writer, id: def_id) {
}
fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
id: node_id, variants: [variant],
&index: [entry<int>], ty_params: [ty_param]) {
id: node_id, variants: [variant],
path: ast_map::path, &index: [entry<int>],
ty_params: [ty_param]) {
let disr_val = 0;
let i = 0;
let vi = ty::enum_variants(ecx.ccx.tcx, {crate: local_crate, node: id});
@ -256,14 +258,38 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
disr_val = vi[i].disr_val;
}
encode_type_param_bounds(ebml_w, ecx, ty_params);
encode_path(ebml_w, path, ast_map::path_name(variant.node.name));
ebml::end_tag(ebml_w);
disr_val += 1;
i += 1;
}
}
fn encode_path(ebml_w: ebml::writer,
path: ast_map::path,
name: ast_map::path_elt) {
fn encode_path_elt(ebml_w: ebml::writer, elt: ast_map::path_elt) {
let (tag, name) = alt elt {
ast_map::path_mod(name) { (tag_path_elt_mod, name) }
ast_map::path_name(name) { (tag_path_elt_name, name) }
};
ebml_w.wr_tag(tag) {||
ebml_w.wr_str(name)
}
}
ebml_w.wr_tag(tag_path) {||
ebml_w.wr_tag(tag_path_len) {||
ebml_w.wr_uint(vec::len(path) + 1u);
}
vec::iter(path) {|pe| encode_path_elt(ebml_w, pe); }
encode_path_elt(ebml_w, name);
}
}
fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
id: node_id, name: ident) {
id: node_id, path: ast_map::path, name: ident) {
ebml::start_tag(ebml_w, tag_items_data_item);
encode_def_id(ebml_w, local_def(id));
encode_family(ebml_w, 'm' as u8);
@ -281,11 +307,12 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
_ { ecx.ccx.tcx.sess.bug("encode_info_for_mod: \
undocumented invariant"); }
}
encode_path(ebml_w, path, ast_map::path_mod(name));
ebml::end_tag(ebml_w);
}
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
&index: [entry<int>]) {
&index: [entry<int>], path: ast_map::path) {
let tcx = ecx.ccx.tcx;
alt item.node {
item_const(_, _) {
@ -294,6 +321,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_family(ebml_w, 'c' as u8);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_symbol(ecx, ebml_w, item.id);
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
}
item_fn(decl, tps, _) {
@ -308,16 +336,18 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_symbol(ecx, ebml_w, item.id);
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
}
item_mod(m) {
encode_info_for_mod(ecx, ebml_w, m, item.id, item.ident);
encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
}
item_native_mod(_) {
ebml::start_tag(ebml_w, tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'n' as u8);
encode_name(ebml_w, item.ident);
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
}
item_ty(_, tps) {
@ -327,6 +357,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ebml_w, item.ident);
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
}
item_enum(variants, tps) {
@ -339,8 +370,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
for v: variant in variants {
encode_variant_id(ebml_w, local_def(v.node.id));
}
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
encode_enum_variant_info(ecx, ebml_w, item.id, variants, index, tps);
encode_enum_variant_info(ecx, ebml_w, item.id, variants,
path, index, tps);
}
item_class(_,_,_,_,_) {
fail "encode: implement item_class";
@ -355,6 +388,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_type(ecx, ebml_w, ty::ty_fn_ret(fn_ty));
encode_name(ebml_w, item.ident);
encode_symbol(ecx, ebml_w, item.id);
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
index += [{val: ctor_id, pos: ebml_w.writer.tell()}];
@ -364,6 +398,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, fn_ty);
encode_symbol(ecx, ebml_w, ctor_id);
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
}
item_impl(tps, ifce, _, methods) {
@ -388,8 +423,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
}
_ {}
}
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
let impl_path = path + [ast_map::path_name(item.ident)];
for m in methods {
index += [{val: m.id, pos: ebml_w.writer.tell()}];
ebml::start_tag(ebml_w, tag_items_data_item);
@ -400,6 +437,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
node_id_to_type(tcx, m.id));
encode_name(ebml_w, m.ident);
encode_symbol(ecx, ebml_w, m.id);
encode_path(ebml_w, impl_path, ast_map::path_name(m.ident));
ebml::end_tag(ebml_w);
}
}
@ -419,13 +457,14 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml::end_tag(ebml_w);
i += 1u;
}
encode_path(ebml_w, path, ast_map::path_name(item.ident));
ebml::end_tag(ebml_w);
}
}
}
fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
nitem: @native_item) {
nitem: @native_item, path: ast_map::path) {
ebml::start_tag(ebml_w, tag_items_data_item);
alt nitem.node {
native_item_fn(fn_decl, tps) {
@ -439,6 +478,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
encode_symbol(ecx, ebml_w, nitem.id);
encode_path(ebml_w, path, ast_map::path_name(nitem.ident));
}
}
ebml::end_tag(ebml_w);
@ -449,16 +489,16 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
let index: [entry<int>] = [];
ebml::start_tag(ebml_w, tag_items_data);
index += [{val: crate_node_id, pos: ebml_w.writer.tell()}];
encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, "");
encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, [], "");
ecx.ccx.ast_map.items {|key, val|
alt val {
middle::ast_map::node_item(i, _) {
middle::ast_map::node_item(i, path) {
index += [{val: key, pos: ebml_w.writer.tell()}];
encode_info_for_item(ecx, ebml_w, i, index);
encode_info_for_item(ecx, ebml_w, i, index, *path);
}
middle::ast_map::node_native_item(i, _) {
middle::ast_map::node_native_item(i, path) {
index += [{val: key, pos: ebml_w.writer.tell()}];
encode_info_for_native_item(ecx, ebml_w, i);
encode_info_for_native_item(ecx, ebml_w, i, *path);
}
_ { }
}

View File

@ -6,6 +6,20 @@ import syntax::{visit, codemap};
enum path_elt { path_mod(str), path_name(str) }
type path = [path_elt];
fn path_to_str_with_sep(p: path, sep: str) -> str {
let strs = vec::map(p) {|e|
alt e {
path_mod(s) { s }
path_name(s) { s }
}
};
str::connect(strs, sep)
}
fn path_to_str(p: path) -> str {
path_to_str_with_sep(p, "::")
}
enum ast_node {
node_item(@item, @path),
node_native_item(@native_item, @path),

View File

@ -128,6 +128,7 @@ export ck_uniq;
export param_bound, param_bounds, bound_copy, bound_send, bound_iface;
export param_bounds_to_kind;
export default_arg_mode_for_ty;
export item_path;
// Data types
@ -2371,6 +2372,44 @@ fn substd_enum_variants(cx: ctxt, id: ast::def_id, tps: [ty::t])
}
}
fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
if id.crate != ast::local_crate {
csearch::get_item_path(cx, id)
} else {
let node = cx.items.get(id.node);
alt node {
ast_map::node_item(item, path) {
let item_elt = alt item.node {
item_mod(_) | item_native_mod(_) {
ast_map::path_mod(item.ident)
}
_ {
ast_map::path_name(item.ident)
}
};
*path + [item_elt]
}
ast_map::node_native_item(nitem, path) {
*path + [ast_map::path_name(nitem.ident)]
}
ast_map::node_method(method, path) {
*path + [ast_map::path_name(method.ident)]
}
ast_map::node_variant(variant, _, path) {
vec::init(*path) + [ast_map::path_name(variant.node.name)]
}
ast_map::node_expr(_) | ast_map::node_arg(_, _) |
ast_map::node_local(_) | ast_map::node_res_ctor(_) {
cx.sess.bug(#fmt["cannot find item_path for node %?", node]);
}
}
}
}
fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
alt cx.enum_var_cache.find(id) {
some(variants) { ret variants; }

View File

@ -110,6 +110,16 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
ty_param(id, _) {
"'" + str::from_bytes([('a' as u8) + (id as u8)])
}
ty_enum(did, tps) {
let path = ty::item_path(cx, did);
let base = ast_map::path_to_str(path);
if vec::is_empty(tps) {
base
} else {
let tps_strs = vec::map(tps) {|t| ty_to_str(cx, t) };
#fmt["%s<%s>", base, str::connect(tps_strs, ",")]
}
}
_ { ty_to_short_str(cx, typ) }
}
}

View File

@ -20,6 +20,20 @@ This is 2^wordsize - 1
*/
const max_value: uint = 0u - 1u;
/*
Function: max
*/
fn max(x: uint, y: uint) -> uint {
if x > y { x } else { y }
}
/*
Function: min
*/
fn min(x: uint, y: uint) -> uint {
if x < y { x } else { y }
}
/* Function: add */
pure fn add(x: uint, y: uint) -> uint { ret x + y; }
@ -252,6 +266,15 @@ Convert to a string
*/
fn str(i: uint) -> str { ret to_str(i, 10u); }
/*
Function: compl
Computes the bitwise complement.
*/
fn compl(i: uint) -> uint {
uint::max_value ^ i
}
#[cfg(test)]
mod tests {

View File

@ -97,6 +97,8 @@ fn tagged_docs(d: doc, tg: uint, it: fn(doc)) {
fn doc_data(d: doc) -> [u8] { ret vec::slice::<u8>(*d.data, d.start, d.end); }
fn doc_str(d: doc) -> str { ret str::from_bytes(doc_data(d)); }
fn be_uint_from_bytes(data: @[u8], start: uint, size: uint) -> uint {
let sz = size;
assert (sz <= 4u);
@ -136,11 +138,11 @@ fn write_sized_vint(w: io::writer, n: uint, size: uint) {
w.write(buf);
}
fn write_vint(w: io::writer, n: uint) {
if n < 0x7fu { write_sized_vint(w, n, 1u); ret; }
if n < 0x4000u { write_sized_vint(w, n, 2u); ret; }
if n < 0x200000u { write_sized_vint(w, n, 3u); ret; }
if n < 0x10000000u { write_sized_vint(w, n, 4u); ret; }
fn write_vint(w: io::writer, n: u64) {
if n < 0x7f_u64 { write_sized_vint(w, n, 1u); ret; }
if n < 0x4000_u64 { write_sized_vint(w, n, 2u); ret; }
if n < 0x200000_u64 { write_sized_vint(w, n, 3u); ret; }
if n < 0x10000000_u64 { write_sized_vint(w, n, 4u); ret; }
#error("vint to write too big");
fail;
}
@ -177,7 +179,11 @@ impl writer_util for writer {
end_tag(self);
}
fn wr_uint(id: uint) {
fn wr_uint(id: u64) {
write_vint(self.writer, id);
}
fn wr_int(id: uint) {
write_vint(self.writer, id);
}

BIN
src/serializer/serializer Executable file

Binary file not shown.

View File

@ -106,12 +106,8 @@ impl serialize_ctx for serialize_ctx {
ret tps_map;
}
fn path(mod_: [str], id: str) -> str {
str::connect(mod_ + [id], "::")
}
fn ident(mod_: [str], id: str) -> str {
str::connect(mod_ + [id], "_")
fn ident(base_path: ast_map::path, id: str) -> str {
#fmt["%s_%s", ast_map::path_to_str_with_sep(base_path, "_"), id]
}
fn instantiate(id: ast::def_id, args: [ty::t]) -> ty::t {
@ -134,7 +130,11 @@ impl serialize_ctx for serialize_ctx {
}
fn blk(stmts: [ast_stmt]) -> ast_blk {
"{" + str::connect(stmts, ";") + "}"
if vec::is_empty(stmts) {
""
} else {
"{" + str::connect(stmts, ";") + "}"
}
}
fn blk_expr(stmts: [ast_stmt]) -> ast_expr {
@ -159,6 +159,7 @@ impl serialize_ctx for serialize_ctx {
// in case of recursive calls:
let id = self.tyfns.size();
let ty0_str = ppaux::ty_to_str(self.tcx, ty0);
#debug["ty0_str = %s / ty0 = %?", ty0_str, ty0];
let name = #fmt["serialize_%u /*%s*/", id, ty0_str];
self.tyfns.insert(ty0, name);
let v = "v";
@ -221,11 +222,11 @@ impl serialize_ctx for serialize_ctx {
fn serialize_enum(v: ast_expr,
id: ast::def_id,
tps: [ty::t]) -> ast_expr {
let path = [];
let variants = ty::substd_enum_variants(self.tcx, id, tps);
let arms = vec::map(variants) {|variant|
let v_path = self.path(path, variant.name);
let item_path = ty::item_path(self.tcx, variant.id);
let v_path = ast_map::path_to_str(item_path);
let n_args = vec::len(variant.args);
let (v_pat, stmts) = {
if n_args == 0u {
@ -235,7 +236,8 @@ impl serialize_ctx for serialize_ctx {
}
};
let v_const = #fmt["at_%s", self.ident(path, variant.name)];
let v_ident = ast_map::path_to_str_with_sep(item_path, "_");
let v_const = #fmt["at_%s", v_ident];
#fmt["%s { \
start_variant(cx, %s); \

View File

@ -28,4 +28,13 @@ type test5 = {
type test6 = option<int>;
mod test7 {
enum testa {
}
enum testb {
t4_a(@testa), t4_b(@testb)
}
}
fn main() {}

BIN
src/test/run-pass/qquote Executable file

Binary file not shown.