2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
|
2011-06-27 18:03:01 -05:00
|
|
|
// Metadata encoding
|
|
|
|
|
2013-01-08 21:37:25 -06:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2012-12-23 16:41:37 -06:00
|
|
|
use metadata::common::*;
|
|
|
|
use metadata::csearch;
|
|
|
|
use metadata::cstore;
|
|
|
|
use metadata::decoder;
|
|
|
|
use metadata::tyencode;
|
|
|
|
use middle::resolve;
|
|
|
|
use middle::ty::node_id_to_type;
|
|
|
|
use middle::ty;
|
|
|
|
use middle;
|
2012-09-04 13:54:36 -05:00
|
|
|
use util::ppaux::ty_to_str;
|
2012-04-26 14:15:46 -05:00
|
|
|
|
2012-12-23 16:41:37 -06:00
|
|
|
use core::dvec;
|
|
|
|
use core::flate;
|
|
|
|
use core::float;
|
|
|
|
use core::hash::{Hash, HashUtil};
|
|
|
|
use core::int;
|
|
|
|
use core::io::WriterUtil;
|
|
|
|
use core::io;
|
|
|
|
use core::str::to_bytes;
|
|
|
|
use core::str;
|
|
|
|
use core::to_bytes::IterBytes;
|
|
|
|
use core::uint;
|
|
|
|
use core::vec;
|
2013-02-01 01:13:36 -06:00
|
|
|
use std::oldmap::HashMap;
|
2013-01-25 18:57:39 -06:00
|
|
|
use std::serialize::Encodable;
|
2013-02-01 01:13:36 -06:00
|
|
|
use std::{ebml, oldmap};
|
2012-12-23 16:41:37 -06:00
|
|
|
use std;
|
2012-09-04 13:54:36 -05:00
|
|
|
use syntax::ast::*;
|
2012-12-23 16:41:37 -06:00
|
|
|
use syntax::ast;
|
2012-09-04 13:54:36 -05:00
|
|
|
use syntax::ast_map;
|
2012-12-23 16:41:37 -06:00
|
|
|
use syntax::ast_util::*;
|
2012-09-04 13:54:36 -05:00
|
|
|
use syntax::attr;
|
|
|
|
use syntax::diagnostic::span_handler;
|
2013-02-11 18:28:39 -06:00
|
|
|
use syntax::parse::token::special_idents;
|
2012-12-23 16:41:37 -06:00
|
|
|
use syntax::print::pprust;
|
|
|
|
use syntax::{ast_util, visit};
|
|
|
|
use syntax;
|
|
|
|
use writer = std::ebml::writer;
|
2012-09-19 15:13:24 -05:00
|
|
|
|
2012-02-14 17:21:53 -06:00
|
|
|
// used by astencode:
|
2013-02-01 01:13:36 -06:00
|
|
|
type abbrev_map = oldmap::HashMap<ty::t, tyencode::ty_abbrev>;
|
2011-07-08 01:55:41 -05:00
|
|
|
|
2013-01-15 18:33:20 -06:00
|
|
|
pub type encode_inlined_item = fn@(ecx: @encode_ctxt,
|
|
|
|
ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
path: &[ast_map::path_elt],
|
2013-01-15 18:33:20 -06:00
|
|
|
ii: ast::inlined_item);
|
2012-05-14 19:38:17 -05:00
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub type encode_parms = {
|
2012-05-14 22:41:33 -05:00
|
|
|
diag: span_handler,
|
2012-05-13 19:01:52 -05:00
|
|
|
tcx: ty::ctxt,
|
2012-09-10 17:38:28 -05:00
|
|
|
reachable: HashMap<ast::node_id, ()>,
|
2012-08-29 15:26:26 -05:00
|
|
|
reexports2: middle::resolve::ExportMap2,
|
2012-09-10 17:38:28 -05:00
|
|
|
item_symbols: HashMap<ast::node_id, ~str>,
|
|
|
|
discrim_symbols: HashMap<ast::node_id, ~str>,
|
2012-05-14 20:29:01 -05:00
|
|
|
link_meta: link_meta,
|
2013-02-04 16:02:01 -06:00
|
|
|
cstore: @mut cstore::CStore,
|
2012-05-14 19:38:17 -05:00
|
|
|
encode_inlined_item: encode_inlined_item
|
2012-05-13 19:01:52 -05:00
|
|
|
};
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
struct Stats {
|
|
|
|
inline_bytes: uint,
|
|
|
|
attr_bytes: uint,
|
|
|
|
dep_bytes: uint,
|
|
|
|
lang_item_bytes: uint,
|
|
|
|
item_bytes: uint,
|
|
|
|
index_bytes: uint,
|
|
|
|
zero_bytes: uint,
|
|
|
|
total_bytes: uint,
|
|
|
|
|
|
|
|
n_inlines: uint
|
|
|
|
}
|
2012-08-27 18:53:54 -05:00
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub enum encode_ctxt = {
|
2012-05-14 22:41:33 -05:00
|
|
|
diag: span_handler,
|
2012-05-13 19:01:52 -05:00
|
|
|
tcx: ty::ctxt,
|
2013-02-04 16:02:01 -06:00
|
|
|
stats: @mut Stats,
|
2012-09-10 17:38:28 -05:00
|
|
|
reachable: HashMap<ast::node_id, ()>,
|
2012-08-29 15:26:26 -05:00
|
|
|
reexports2: middle::resolve::ExportMap2,
|
2012-09-10 17:38:28 -05:00
|
|
|
item_symbols: HashMap<ast::node_id, ~str>,
|
|
|
|
discrim_symbols: HashMap<ast::node_id, ~str>,
|
2012-05-14 20:29:01 -05:00
|
|
|
link_meta: link_meta,
|
2013-02-04 16:02:01 -06:00
|
|
|
cstore: @mut cstore::CStore,
|
2012-05-14 19:38:17 -05:00
|
|
|
encode_inlined_item: encode_inlined_item,
|
2012-05-13 19:01:52 -05:00
|
|
|
type_abbrevs: abbrev_map
|
|
|
|
};
|
2011-07-08 01:55:41 -05:00
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn reachable(ecx: @encode_ctxt, id: node_id) -> bool {
|
2013-02-08 16:08:02 -06:00
|
|
|
ecx.reachable.contains_key(&id)
|
2012-04-24 01:40:53 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_name(ecx: @encode_ctxt, ebml_w: writer::Encoder, name: ident) {
|
2012-07-18 18:18:02 -05:00
|
|
|
ebml_w.wr_tagged_str(tag_paths_data_name, ecx.tcx.sess.str_of(name));
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_impl_type_basename(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-10-18 15:29:34 -05:00
|
|
|
name: ident) {
|
|
|
|
ebml_w.wr_tagged_str(tag_item_impl_type_basename,
|
|
|
|
ecx.tcx.sess.str_of(name));
|
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn encode_def_id(ebml_w: writer::Encoder, id: def_id) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
|
2012-02-06 09:13:14 -06:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_region_param(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-07-11 12:28:30 -05:00
|
|
|
it: @ast::item) {
|
2013-02-05 21:41:45 -06:00
|
|
|
let opt_rp = ecx.tcx.region_paramd_items.find(&it.id);
|
2012-08-09 11:59:50 -05:00
|
|
|
for opt_rp.each |rp| {
|
|
|
|
do ebml_w.wr_tag(tag_region_param) {
|
2012-12-17 21:31:04 -06:00
|
|
|
(*rp).encode(&ebml_w);
|
2012-08-09 11:59:50 -05:00
|
|
|
}
|
|
|
|
}
|
2012-04-18 23:26:25 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_mutability(ebml_w: writer::Encoder, mt: struct_mutability) {
|
2012-12-10 15:47:54 -06:00
|
|
|
do ebml_w.wr_tag(tag_struct_mut) {
|
2012-08-06 14:34:08 -05:00
|
|
|
let val = match mt {
|
2012-12-10 15:47:54 -06:00
|
|
|
struct_immutable => 'a',
|
|
|
|
struct_mutable => 'm'
|
2012-08-03 21:59:04 -05:00
|
|
|
};
|
|
|
|
ebml_w.writer.write(&[val as u8]);
|
|
|
|
}
|
2012-03-28 00:08:48 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
type entry<T> = {val: T, pos: uint};
|
2011-07-26 07:06:02 -05:00
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn add_to_index(ecx: @encode_ctxt, ebml_w: writer::Encoder, path: &[ident],
|
2012-10-05 18:17:10 -05:00
|
|
|
index: &mut ~[entry<~str>], name: ident) {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut full_path = ~[];
|
2012-09-26 19:33:34 -05:00
|
|
|
full_path.push_all(path);
|
|
|
|
full_path.push(name);
|
|
|
|
index.push(
|
|
|
|
{val: ast_util::path_name_i(full_path,
|
|
|
|
ecx.tcx.sess.parse_sess.interner),
|
|
|
|
pos: ebml_w.writer.tell()});
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_trait_ref(ebml_w: writer::Encoder, ecx: @encode_ctxt,
|
2012-10-07 12:31:34 -05:00
|
|
|
t: @trait_ref) {
|
2012-07-03 18:30:42 -05:00
|
|
|
ebml_w.start_tag(tag_impl_trait);
|
2012-06-26 18:25:52 -05:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
|
2012-04-26 14:15:46 -05:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2011-06-27 17:20:17 -05:00
|
|
|
|
|
|
|
// Item info table encoding
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_family(ebml_w: writer::Encoder, c: char) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item_family);
|
2012-06-29 18:26:56 -05:00
|
|
|
ebml_w.writer.write(&[c as u8]);
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) }
|
2011-06-27 17:20:17 -05:00
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_ty_type_param_bounds(ebml_w: writer::Encoder, ecx: @encode_ctxt,
|
2012-08-02 18:01:38 -05:00
|
|
|
params: @~[ty::param_bounds]) {
|
2013-01-08 16:00:45 -06:00
|
|
|
let ty_str_ctxt = @tyencode::ctxt {
|
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
|
|
|
reachable: |a| reachable(ecx, a),
|
|
|
|
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
2012-06-30 18:19:07 -05:00
|
|
|
for params.each |param| {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
|
2012-09-19 18:55:01 -05:00
|
|
|
tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, *param);
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-07-29 18:40:23 -05:00
|
|
|
}
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_type_param_bounds(ebml_w: writer::Encoder, ecx: @encode_ctxt,
|
2013-01-22 13:57:39 -06:00
|
|
|
params: &[ty_param]) {
|
2012-08-02 18:01:38 -05:00
|
|
|
let ty_param_bounds =
|
2013-02-05 21:41:45 -06:00
|
|
|
@params.map(|param| ecx.tcx.ty_param_bounds.get(¶m.id));
|
2012-08-02 18:01:38 -05:00
|
|
|
encode_ty_type_param_bounds(ebml_w, ecx, ty_param_bounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_variant_id(ebml_w: writer::Encoder, vid: def_id) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item_variant);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(def_to_str(vid)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn write_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) {
|
2013-01-08 16:00:45 -06:00
|
|
|
let ty_str_ctxt = @tyencode::ctxt {
|
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
|
|
|
reachable: |a| reachable(ecx, a),
|
|
|
|
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
2012-01-11 08:15:54 -06:00
|
|
|
tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
|
2012-01-05 03:57:19 -06:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn write_vstore(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
|
|
|
vstore: ty::vstore) {
|
2013-01-08 16:00:45 -06:00
|
|
|
let ty_str_ctxt = @tyencode::ctxt {
|
|
|
|
diag: ecx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: ecx.tcx,
|
|
|
|
reachable: |a| reachable(ecx, a),
|
|
|
|
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
2012-10-05 18:55:42 -05:00
|
|
|
tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
|
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item_type);
|
2012-01-05 03:57:19 -06:00
|
|
|
write_type(ecx, ebml_w, typ);
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_symbol(ecx: @encode_ctxt, ebml_w: writer::Encoder, id: node_id) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item_symbol);
|
2013-02-05 21:41:45 -06:00
|
|
|
let sym = match ecx.item_symbols.find(&id) {
|
2013-01-07 16:16:52 -06:00
|
|
|
Some(ref x) => (/*bad*/copy *x),
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2012-05-14 22:41:33 -05:00
|
|
|
ecx.diag.handler().bug(
|
2012-08-22 19:24:52 -05:00
|
|
|
fmt!("encode_symbol: id not found %d", id));
|
2012-05-14 22:41:33 -05:00
|
|
|
}
|
2012-03-19 12:19:00 -05:00
|
|
|
};
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(sym));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_discriminant(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-10-07 12:31:34 -05:00
|
|
|
id: node_id) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item_symbol);
|
2013-02-05 21:41:45 -06:00
|
|
|
ebml_w.writer.write(str::to_bytes(ecx.discrim_symbols.get(&id)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-10-07 12:31:34 -05:00
|
|
|
disr_val: int) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_disr_val);
|
2013-01-26 20:20:15 -06:00
|
|
|
ebml_w.writer.write(str::to_bytes(int::to_str(disr_val)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2012-01-10 15:50:40 -06:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_parent_item(ebml_w: writer::Encoder, id: def_id) {
|
2012-03-08 16:13:57 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_parent_item);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(def_to_str(id)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
id: node_id, variants: &[variant],
|
|
|
|
path: &[ast_map::path_elt],
|
|
|
|
index: @mut ~[entry<int>],
|
|
|
|
ty_params: &[ty_param]) {
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut disr_val = 0;
|
|
|
|
let mut i = 0;
|
2013-01-13 13:05:40 -06:00
|
|
|
let vi = ty::enum_variants(ecx.tcx,
|
|
|
|
ast::def_id { crate: local_crate, node: id });
|
2012-06-30 18:19:07 -05:00
|
|
|
for variants.each |variant| {
|
2012-09-26 19:33:34 -05:00
|
|
|
index.push({val: variant.node.id, pos: ebml_w.writer.tell()});
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-06-27 17:20:17 -05:00
|
|
|
encode_def_id(ebml_w, local_def(variant.node.id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'v');
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, variant.node.name);
|
2012-03-08 16:13:57 -06:00
|
|
|
encode_parent_item(ebml_w, local_def(id));
|
2011-07-08 01:55:41 -05:00
|
|
|
encode_type(ecx, ebml_w,
|
2012-05-13 19:01:52 -05:00
|
|
|
node_id_to_type(ecx.tcx, variant.node.id));
|
2012-08-07 16:24:04 -05:00
|
|
|
match variant.node.kind {
|
2013-01-07 16:16:52 -06:00
|
|
|
ast::tuple_variant_kind(ref args)
|
2012-08-07 16:24:04 -05:00
|
|
|
if args.len() > 0 && ty_params.len() == 0 => {
|
|
|
|
encode_symbol(ecx, ebml_w, variant.node.id);
|
|
|
|
}
|
2012-08-08 16:17:52 -05:00
|
|
|
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) |
|
|
|
|
ast::enum_variant_kind(_) => {}
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2011-07-08 01:55:41 -05:00
|
|
|
encode_discriminant(ecx, ebml_w, variant.node.id);
|
2012-01-16 03:36:47 -06:00
|
|
|
if vi[i].disr_val != disr_val {
|
|
|
|
encode_disr_val(ecx, ebml_w, vi[i].disr_val);
|
|
|
|
disr_val = vi[i].disr_val;
|
2012-01-10 15:50:40 -06:00
|
|
|
}
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, ty_params);
|
|
|
|
encode_path(ecx, ebml_w, path,
|
2013-01-07 16:16:52 -06:00
|
|
|
ast_map::path_name(variant.node.name));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2012-01-10 15:50:40 -06:00
|
|
|
disr_val += 1;
|
2012-01-16 03:36:47 -06:00
|
|
|
i += 1;
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_path(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
path: &[ast_map::path_elt], name: ast_map::path_elt) {
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_path_elt(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-07-18 18:18:02 -05:00
|
|
|
elt: ast_map::path_elt) {
|
2012-08-06 14:34:08 -05:00
|
|
|
let (tag, name) = match elt {
|
2012-08-03 21:59:04 -05:00
|
|
|
ast_map::path_mod(name) => (tag_path_elt_mod, name),
|
|
|
|
ast_map::path_name(name) => (tag_path_elt_name, name)
|
2012-02-10 08:01:32 -06:00
|
|
|
};
|
|
|
|
|
2012-07-18 18:18:02 -05:00
|
|
|
ebml_w.wr_tagged_str(tag, ecx.tcx.sess.str_of(name));
|
2012-02-10 08:01:32 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 14:04:28 -05:00
|
|
|
do ebml_w.wr_tag(tag_path) {
|
2013-01-21 22:39:58 -06:00
|
|
|
ebml_w.wr_tagged_u32(tag_path_len, (path.len() + 1) as u32);
|
|
|
|
for path.each |pe| {
|
2012-09-18 23:41:37 -05:00
|
|
|
encode_path_elt(ecx, ebml_w, *pe);
|
|
|
|
}
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_path_elt(ecx, ebml_w, name);
|
2012-02-10 08:01:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
md: _mod, id: node_id, path: &[ast_map::path_elt],
|
2012-11-24 15:38:23 -06:00
|
|
|
name: ident) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-12-16 07:41:12 -06:00
|
|
|
encode_def_id(ebml_w, local_def(id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'm');
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, name);
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("(encoding info for module) encoding info for module ID %d", id);
|
2012-08-17 18:38:07 -05:00
|
|
|
|
|
|
|
// Encode info about all the module children.
|
|
|
|
for md.items.each |item| {
|
|
|
|
match item.node {
|
2013-02-11 18:28:39 -06:00
|
|
|
item_impl(*) => {
|
2012-08-17 18:38:07 -05:00
|
|
|
let (ident, did) = (item.ident, item.id);
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("(encoding info for module) ... encoding impl %s \
|
2013-01-30 19:20:02 -06:00
|
|
|
(%?/%?)",
|
2012-07-18 18:18:02 -05:00
|
|
|
ecx.tcx.sess.str_of(ident),
|
|
|
|
did,
|
|
|
|
ast_map::node_id_to_str(ecx.tcx.items, did, ecx.tcx
|
2013-01-30 19:20:02 -06:00
|
|
|
.sess.parse_sess.interner));
|
2012-08-17 18:38:07 -05:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_mod_impl);
|
|
|
|
ebml_w.wr_str(def_to_str(local_def(did)));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
2013-01-21 22:39:58 -06:00
|
|
|
_ => {} // FIXME #4573: Encode these too.
|
2012-08-17 18:38:07 -05:00
|
|
|
}
|
|
|
|
}
|
2012-05-17 00:28:01 -05:00
|
|
|
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_mod(name));
|
2012-08-17 14:41:34 -05:00
|
|
|
|
|
|
|
// Encode the reexports of this module.
|
|
|
|
debug!("(encoding info for module) encoding reexports for %d", id);
|
2013-02-05 21:41:45 -06:00
|
|
|
match ecx.reexports2.find(&id) {
|
2012-12-04 12:50:00 -06:00
|
|
|
Some(ref exports) => {
|
2012-08-17 14:41:34 -05:00
|
|
|
debug!("(encoding info for module) found reexports for %d", id);
|
2012-12-04 12:50:00 -06:00
|
|
|
for (*exports).each |exp| {
|
2012-08-17 14:41:34 -05:00
|
|
|
debug!("(encoding info for module) reexport '%s' for %d",
|
|
|
|
exp.name, id);
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport);
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
|
|
|
|
ebml_w.wr_str(def_to_str(exp.def_id));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_items_data_item_reexport_name);
|
|
|
|
ebml_w.wr_str(exp.name);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2012-08-17 14:41:34 -05:00
|
|
|
debug!("(encoding info for module) found no reexports for %d",
|
|
|
|
id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-12-16 07:41:12 -06:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_visibility(ebml_w: writer::Encoder, visibility: visibility) {
|
2012-08-06 14:34:08 -05:00
|
|
|
encode_family(ebml_w, match visibility {
|
2012-08-03 21:59:04 -05:00
|
|
|
public => 'g',
|
|
|
|
private => 'j',
|
|
|
|
inherited => 'N'
|
2012-05-08 09:06:24 -05:00
|
|
|
});
|
2012-03-26 11:59:59 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_self_type(ebml_w: writer::Encoder, self_type: ast::self_ty_) {
|
2012-07-31 18:32:37 -05:00
|
|
|
ebml_w.start_tag(tag_item_trait_method_self_ty);
|
|
|
|
|
|
|
|
// Encode the base self type.
|
|
|
|
let ch;
|
2012-08-06 14:34:08 -05:00
|
|
|
match self_type {
|
2012-08-02 18:01:38 -05:00
|
|
|
sty_static => { ch = 's' as u8; }
|
2012-07-31 18:32:37 -05:00
|
|
|
sty_by_ref => { ch = 'r' as u8; }
|
|
|
|
sty_value => { ch = 'v' as u8; }
|
2012-08-13 12:17:42 -05:00
|
|
|
sty_region(_) => { ch = '&' as u8; }
|
2012-07-31 18:32:37 -05:00
|
|
|
sty_box(_) => { ch = '@' as u8; }
|
|
|
|
sty_uniq(_) => { ch = '~' as u8; }
|
|
|
|
}
|
|
|
|
ebml_w.writer.write(&[ ch ]);
|
|
|
|
|
|
|
|
// Encode mutability.
|
2012-08-06 14:34:08 -05:00
|
|
|
match self_type {
|
2012-08-02 18:01:38 -05:00
|
|
|
sty_static | sty_by_ref | sty_value => { /* No-op. */ }
|
2012-08-13 12:17:42 -05:00
|
|
|
sty_region(m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
|
2012-07-31 18:32:37 -05:00
|
|
|
ebml_w.writer.write(&[ 'i' as u8 ]);
|
|
|
|
}
|
2012-08-13 12:17:42 -05:00
|
|
|
sty_region(m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
|
2012-07-31 18:32:37 -05:00
|
|
|
ebml_w.writer.write(&[ 'm' as u8 ]);
|
|
|
|
}
|
2012-08-13 12:17:42 -05:00
|
|
|
sty_region(m_const) | sty_box(m_const) | sty_uniq(m_const) => {
|
2012-07-31 18:32:37 -05:00
|
|
|
ebml_w.writer.write(&[ 'c' as u8 ]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_method_sort(ebml_w: writer::Encoder, sort: char) {
|
2012-10-08 14:39:30 -05:00
|
|
|
ebml_w.start_tag(tag_item_trait_method_sort);
|
|
|
|
ebml_w.writer.write(&[ sort as u8 ]);
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2012-03-19 12:19:00 -05:00
|
|
|
/* Returns an index of items in this class */
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
path: &[ast_map::path_elt],
|
|
|
|
fields: &[@struct_field],
|
2012-06-29 18:26:56 -05:00
|
|
|
global_index: @mut~[entry<int>]) -> ~[entry<int>] {
|
2012-06-25 18:49:14 -05:00
|
|
|
/* Each class has its own index, since different classes
|
|
|
|
may have fields with the same name */
|
2012-06-29 18:26:56 -05:00
|
|
|
let index = @mut ~[];
|
2012-05-13 19:01:52 -05:00
|
|
|
let tcx = ecx.tcx;
|
2012-03-19 12:19:00 -05:00
|
|
|
/* We encode both private and public fields -- need to include
|
|
|
|
private fields to get the offsets right */
|
2012-08-15 17:53:58 -05:00
|
|
|
for fields.each |field| {
|
2013-02-11 18:28:39 -06:00
|
|
|
let (nm, mt, vis) = match field.node.kind {
|
|
|
|
named_field(nm, mt, vis) => (nm, mt, vis),
|
|
|
|
unnamed_field => (
|
|
|
|
special_idents::unnamed_field,
|
|
|
|
struct_immutable,
|
|
|
|
inherited
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
|
|
|
let id = field.node.id;
|
|
|
|
index.push({val: id, pos: ebml_w.writer.tell()});
|
|
|
|
global_index.push({val: id, pos: ebml_w.writer.tell()});
|
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
|
|
|
debug!("encode_info_for_struct: doing %s %d",
|
|
|
|
tcx.sess.str_of(nm), id);
|
|
|
|
encode_visibility(ebml_w, vis);
|
|
|
|
encode_name(ecx, ebml_w, nm);
|
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
|
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
|
|
|
|
encode_mutability(ebml_w, mt);
|
|
|
|
encode_def_id(ebml_w, local_def(id));
|
|
|
|
ebml_w.end_tag();
|
2012-08-15 17:53:58 -05:00
|
|
|
}
|
2013-01-07 16:16:52 -06:00
|
|
|
/*bad*/copy *index
|
2012-03-06 10:02:13 -06:00
|
|
|
}
|
|
|
|
|
2012-08-23 20:17:16 -05:00
|
|
|
// This is for encoding info for ctors and dtors
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
id: node_id, ident: ident, path: &[ast_map::path_elt],
|
|
|
|
item: Option<inlined_item>, tps: &[ty_param]) {
|
2012-03-06 10:02:13 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, ident);
|
2012-03-06 10:02:13 -06:00
|
|
|
encode_def_id(ebml_w, local_def(id));
|
2012-08-23 20:17:16 -05:00
|
|
|
encode_family(ebml_w, purity_fn_family(ast::impure_fn));
|
2012-03-06 10:02:13 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
2012-05-13 19:01:52 -05:00
|
|
|
let its_ty = node_id_to_type(ecx.tcx, id);
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("fn name = %s ty = %s its node id = %d",
|
2012-07-18 18:18:02 -05:00
|
|
|
ecx.tcx.sess.str_of(ident),
|
2012-12-23 16:41:37 -06:00
|
|
|
ty_to_str(ecx.tcx, its_ty), id);
|
2012-03-06 10:02:13 -06:00
|
|
|
encode_type(ecx, ebml_w, its_ty);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(ident));
|
2012-08-06 14:34:08 -05:00
|
|
|
match item {
|
2012-12-04 12:50:00 -06:00
|
|
|
Some(ref it) => {
|
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, path, (*it));
|
2012-03-06 10:02:13 -06:00
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2012-03-06 10:02:13 -06:00
|
|
|
encode_symbol(ecx, ebml_w, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-02-11 18:28:39 -06:00
|
|
|
fn encode_info_for_struct_ctor(ecx: @encode_ctxt,
|
|
|
|
ebml_w: writer::Encoder,
|
|
|
|
path: &[ast_map::path_elt],
|
|
|
|
name: ast::ident,
|
|
|
|
ctor_id: node_id,
|
|
|
|
index: @mut ~[entry<int>]) {
|
|
|
|
index.push({ val: ctor_id, pos: ebml_w.writer.tell() });
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
|
|
|
encode_def_id(ebml_w, local_def(ctor_id));
|
|
|
|
encode_family(ebml_w, 'f');
|
|
|
|
encode_name(ecx, ebml_w, name);
|
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
|
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(name));
|
|
|
|
|
|
|
|
if ecx.item_symbols.contains_key(&ctor_id) {
|
|
|
|
encode_symbol(ecx, ebml_w, ctor_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
fn encode_info_for_method(ecx: @encode_ctxt,
|
|
|
|
ebml_w: writer::Encoder,
|
2013-01-22 13:57:39 -06:00
|
|
|
impl_path: &[ast_map::path_elt],
|
2013-01-07 16:16:52 -06:00
|
|
|
should_inline: bool,
|
2012-03-19 12:19:00 -05:00
|
|
|
parent_id: node_id,
|
2013-01-07 16:16:52 -06:00
|
|
|
m: @method,
|
|
|
|
+all_tps: ~[ty_param]) {
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("encode_info_for_method: %d %s %u", m.id,
|
|
|
|
ecx.tcx.sess.str_of(m.ident), all_tps.len());
|
2012-03-19 12:19:00 -05:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
|
|
|
encode_def_id(ebml_w, local_def(m.id));
|
2012-10-18 15:29:34 -05:00
|
|
|
match m.self_ty.node {
|
|
|
|
ast::sty_static => {
|
|
|
|
encode_family(ebml_w, purity_static_method_family(m.purity));
|
|
|
|
}
|
|
|
|
_ => encode_family(ebml_w, purity_fn_family(m.purity))
|
|
|
|
}
|
2013-01-07 16:16:52 -06:00
|
|
|
let len = all_tps.len();
|
2012-03-19 12:19:00 -05:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, all_tps);
|
2012-05-13 19:01:52 -05:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, m.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident));
|
2012-07-31 18:32:37 -05:00
|
|
|
encode_self_type(ebml_w, m.self_ty.node);
|
2013-01-07 16:16:52 -06:00
|
|
|
if len > 0u || should_inline {
|
2012-11-29 19:51:16 -06:00
|
|
|
(ecx.encode_inlined_item)(
|
2012-03-19 12:19:00 -05:00
|
|
|
ecx, ebml_w, impl_path,
|
|
|
|
ii_method(local_def(parent_id), m));
|
|
|
|
} else {
|
|
|
|
encode_symbol(ecx, ebml_w, m.id);
|
|
|
|
}
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2012-02-13 11:56:09 -06:00
|
|
|
fn purity_fn_family(p: purity) -> char {
|
2012-08-06 14:34:08 -05:00
|
|
|
match p {
|
2012-08-03 21:59:04 -05:00
|
|
|
unsafe_fn => 'u',
|
|
|
|
pure_fn => 'p',
|
|
|
|
impure_fn => 'f',
|
2012-08-02 18:01:38 -05:00
|
|
|
extern_fn => 'e'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn purity_static_method_family(p: purity) -> char {
|
|
|
|
match p {
|
|
|
|
unsafe_fn => 'U',
|
|
|
|
pure_fn => 'P',
|
|
|
|
impure_fn => 'F',
|
2013-02-11 21:26:38 -06:00
|
|
|
_ => fail!(~"extern fn can't be static")
|
2012-02-10 15:39:15 -06:00
|
|
|
}
|
2012-02-13 11:56:09 -06:00
|
|
|
}
|
|
|
|
|
2012-03-02 15:14:10 -06:00
|
|
|
|
2013-01-22 13:57:39 -06:00
|
|
|
fn should_inline(attrs: &[attribute]) -> bool {
|
2012-08-06 14:34:08 -05:00
|
|
|
match attr::find_inline_attr(attrs) {
|
2012-08-03 21:59:04 -05:00
|
|
|
attr::ia_none | attr::ia_never => false,
|
|
|
|
attr::ia_hint | attr::ia_always => true
|
2012-03-02 15:14:10 -06:00
|
|
|
}
|
2012-03-19 12:19:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-10-07 12:31:34 -05:00
|
|
|
item: @item, index: @mut ~[entry<int>],
|
2013-01-22 13:57:39 -06:00
|
|
|
path: &[ast_map::path_elt]) {
|
2012-03-02 15:14:10 -06:00
|
|
|
|
2012-05-13 19:01:52 -05:00
|
|
|
let tcx = ecx.tcx;
|
2012-04-18 23:26:25 -05:00
|
|
|
let must_write =
|
2012-08-06 14:34:08 -05:00
|
|
|
match item.node {
|
2013-01-31 14:40:05 -06:00
|
|
|
item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
|
|
|
|
item_mod(*) | item_foreign_mod(*) => true,
|
2012-08-03 21:59:04 -05:00
|
|
|
_ => false
|
2012-07-18 16:41:31 -05:00
|
|
|
};
|
2012-08-01 19:30:05 -05:00
|
|
|
if !must_write && !reachable(ecx, item.id) { return; }
|
2012-03-22 20:03:12 -05:00
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn add_to_index_(item: @item, ebml_w: writer::Encoder,
|
2012-06-29 18:26:56 -05:00
|
|
|
index: @mut ~[entry<int>]) {
|
2012-09-26 19:33:34 -05:00
|
|
|
index.push({val: item.id, pos: ebml_w.writer.tell()});
|
2012-03-22 20:03:12 -05:00
|
|
|
}
|
2013-01-15 18:33:20 -06:00
|
|
|
let add_to_index: &fn() = || add_to_index_(item, ebml_w, index);
|
2012-03-06 05:52:13 -06:00
|
|
|
|
2012-10-30 13:19:15 -05:00
|
|
|
debug!("encoding info for item at %s",
|
2012-11-12 20:24:56 -06:00
|
|
|
ecx.tcx.sess.codemap.span_to_str(item.span));
|
2012-10-30 13:19:15 -05:00
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
match /*bad*/copy item.node {
|
2012-08-03 21:59:04 -05:00
|
|
|
item_const(_, _) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-07-27 07:19:39 -05:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'c');
|
2012-01-30 10:28:30 -06:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2011-07-27 07:19:39 -05:00
|
|
|
encode_symbol(ecx, ebml_w, item.id);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-26 11:58:45 -05:00
|
|
|
item_fn(_, purity, tps, _) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-07-27 07:19:39 -05:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-08-23 20:17:16 -05:00
|
|
|
encode_family(ebml_w, purity_fn_family(purity));
|
2013-01-07 16:16:52 -06:00
|
|
|
let tps_len = tps.len();
|
2011-12-28 10:50:12 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
2012-01-30 10:28:30 -06:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
|
|
|
encode_attributes(ebml_w, item.attrs);
|
2013-01-07 16:16:52 -06:00
|
|
|
if tps_len > 0u || should_inline(item.attrs) {
|
2012-11-29 19:51:16 -06:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
|
2012-03-08 06:30:22 -06:00
|
|
|
} else {
|
|
|
|
encode_symbol(ecx, ebml_w, item.id);
|
2012-02-14 17:21:53 -06:00
|
|
|
}
|
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
item_mod(m) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-10 08:01:32 -06:00
|
|
|
encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
item_foreign_mod(_) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-07-27 07:19:39 -05:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'n');
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, item.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
item_ty(_, tps) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-07-27 07:19:39 -05:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'y');
|
2011-12-28 10:50:12 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
2012-01-30 10:28:30 -06:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, item.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-07-11 12:28:30 -05:00
|
|
|
encode_region_param(ecx, ebml_w, item);
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2013-01-07 16:16:52 -06:00
|
|
|
item_enum(ref enum_definition, ref tps) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-07-04 14:04:28 -05:00
|
|
|
do ebml_w.wr_tag(tag_items_data_item) {
|
2012-04-18 23:26:25 -05:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
|
|
|
encode_family(ebml_w, 't');
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, *tps);
|
2012-04-18 23:26:25 -05:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, item.ident);
|
2012-12-04 12:50:00 -06:00
|
|
|
for (*enum_definition).variants.each |v| {
|
2012-04-18 23:26:25 -05:00
|
|
|
encode_variant_id(ebml_w, local_def(v.node.id));
|
|
|
|
}
|
2013-01-22 13:57:39 -06:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
|
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-07-11 12:28:30 -05:00
|
|
|
encode_region_param(ecx, ebml_w, item);
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2012-12-04 23:13:02 -06:00
|
|
|
encode_enum_variant_info(ecx,
|
|
|
|
ebml_w,
|
|
|
|
item.id,
|
2013-01-22 13:57:39 -06:00
|
|
|
(*enum_definition).variants,
|
2012-12-04 23:13:02 -06:00
|
|
|
path,
|
|
|
|
index,
|
2013-01-22 13:57:39 -06:00
|
|
|
*tps);
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-12-10 15:47:54 -06:00
|
|
|
item_struct(struct_def, tps) => {
|
|
|
|
/* First, encode the fields
|
2012-03-22 20:03:12 -05:00
|
|
|
These come first because we need to write them to make
|
|
|
|
the index, and the index needs to be in the item for the
|
|
|
|
class itself */
|
2013-01-22 13:57:39 -06:00
|
|
|
let idx = encode_info_for_struct(ecx, ebml_w, path,
|
|
|
|
struct_def.fields, index);
|
2012-06-12 18:25:09 -05:00
|
|
|
/* Encode the dtor */
|
2012-09-21 21:37:57 -05:00
|
|
|
do struct_def.dtor.iter |dtor| {
|
2012-09-26 19:33:34 -05:00
|
|
|
index.push({val: dtor.node.id, pos: ebml_w.writer.tell()});
|
2013-01-10 12:59:58 -06:00
|
|
|
encode_info_for_ctor(ecx,
|
|
|
|
ebml_w,
|
|
|
|
dtor.node.id,
|
2012-08-23 20:17:16 -05:00
|
|
|
ecx.tcx.sess.ident_of(
|
|
|
|
ecx.tcx.sess.str_of(item.ident) +
|
|
|
|
~"_dtor"),
|
2013-01-10 12:59:58 -06:00
|
|
|
path,
|
|
|
|
if tps.len() > 0u {
|
|
|
|
Some(ii_dtor(copy *dtor,
|
|
|
|
item.ident,
|
|
|
|
copy tps,
|
2012-08-23 20:17:16 -05:00
|
|
|
local_def(item.id))) }
|
2013-01-10 12:59:58 -06:00
|
|
|
else {
|
|
|
|
None
|
|
|
|
},
|
|
|
|
tps);
|
2012-06-12 18:25:09 -05:00
|
|
|
}
|
|
|
|
|
2012-03-22 20:03:12 -05:00
|
|
|
/* Index the class*/
|
|
|
|
add_to_index();
|
|
|
|
/* Now, make an item for the class itself */
|
2012-03-16 21:19:37 -05:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2012-03-22 20:03:12 -05:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-10-08 13:49:01 -05:00
|
|
|
encode_family(ebml_w, 'S');
|
2012-03-22 20:03:12 -05:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
2013-02-12 11:02:17 -06:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2013-02-11 18:28:39 -06:00
|
|
|
|
|
|
|
// If this is a tuple- or enum-like struct, encode the type of the
|
|
|
|
// constructor.
|
|
|
|
if struct_def.fields.len() > 0 &&
|
|
|
|
struct_def.fields[0].node.kind == ast::unnamed_field {
|
|
|
|
let ctor_id = match struct_def.ctor_id {
|
|
|
|
Some(ctor_id) => ctor_id,
|
|
|
|
None => ecx.tcx.sess.bug(~"struct def didn't have ctor id"),
|
|
|
|
};
|
|
|
|
|
|
|
|
encode_info_for_struct_ctor(ecx,
|
|
|
|
ebml_w,
|
|
|
|
path,
|
|
|
|
item.ident,
|
|
|
|
ctor_id,
|
|
|
|
index);
|
|
|
|
}
|
|
|
|
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, item.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-07-11 12:28:30 -05:00
|
|
|
encode_region_param(ecx, ebml_w, item);
|
2012-06-12 18:25:09 -05:00
|
|
|
/* Encode the dtor */
|
|
|
|
/* Encode id for dtor */
|
2012-09-21 21:37:57 -05:00
|
|
|
do struct_def.dtor.iter |dtor| {
|
2012-07-04 14:04:28 -05:00
|
|
|
do ebml_w.wr_tag(tag_item_dtor) {
|
2012-06-12 18:25:09 -05:00
|
|
|
encode_def_id(ebml_w, local_def(dtor.node.id));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-03-22 20:03:12 -05:00
|
|
|
/* Encode def_ids for each field and method
|
2012-07-03 18:30:42 -05:00
|
|
|
for methods, write all the stuff get_trait_method
|
2012-03-22 20:03:12 -05:00
|
|
|
needs to know*/
|
2012-08-15 17:53:58 -05:00
|
|
|
for struct_def.fields.each |f| {
|
|
|
|
match f.node.kind {
|
2012-08-26 11:58:45 -05:00
|
|
|
named_field(ident, _, vis) => {
|
2012-08-15 17:53:58 -05:00
|
|
|
ebml_w.start_tag(tag_item_field);
|
|
|
|
encode_visibility(ebml_w, vis);
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, ident);
|
2012-08-15 17:53:58 -05:00
|
|
|
encode_def_id(ebml_w, local_def(f.node.id));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
2013-02-11 18:28:39 -06:00
|
|
|
unnamed_field => {
|
|
|
|
ebml_w.start_tag(tag_item_unnamed_field);
|
|
|
|
encode_def_id(ebml_w, local_def(f.node.id));
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
2012-08-15 17:53:58 -05:00
|
|
|
}
|
2012-03-22 20:03:12 -05:00
|
|
|
}
|
2012-08-15 17:53:58 -05:00
|
|
|
|
2012-03-22 20:03:12 -05:00
|
|
|
/* Each class has its own index -- encode it */
|
2012-09-19 15:13:24 -05:00
|
|
|
let bkts = create_index(idx);
|
2012-03-19 12:19:00 -05:00
|
|
|
encode_index(ebml_w, bkts, write_int);
|
2012-03-16 21:19:37 -05:00
|
|
|
ebml_w.end_tag();
|
2012-01-31 21:30:40 -06:00
|
|
|
}
|
2012-11-13 21:08:01 -06:00
|
|
|
item_impl(tps, opt_trait, ty, methods) => {
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2011-12-16 07:17:52 -06:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'i');
|
2012-07-11 12:28:30 -05:00
|
|
|
encode_region_param(ecx, ebml_w, item);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
2012-01-30 10:28:30 -06:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, item.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_attributes(ebml_w, item.attrs);
|
2012-10-18 15:29:34 -05:00
|
|
|
match ty.node {
|
|
|
|
ast::ty_path(path, _) if path.idents.len() == 1 => {
|
|
|
|
encode_impl_type_basename(ecx, ebml_w,
|
|
|
|
ast_util::path_to_ident(path));
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2012-11-13 21:08:01 -06:00
|
|
|
for methods.each |m| {
|
|
|
|
ebml_w.start_tag(tag_item_impl_method);
|
|
|
|
let method_def_id = local_def(m.id);
|
|
|
|
ebml_w.writer.write(str::to_bytes(def_to_str(method_def_id)));
|
|
|
|
ebml_w.end_tag();
|
2011-12-16 07:17:52 -06:00
|
|
|
}
|
2012-09-07 17:11:26 -05:00
|
|
|
do opt_trait.iter() |associated_trait| {
|
2012-10-30 13:19:15 -05:00
|
|
|
encode_trait_ref(ebml_w, ecx, *associated_trait);
|
2012-07-18 11:31:53 -05:00
|
|
|
}
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-12-16 07:17:52 -06:00
|
|
|
|
2013-01-22 13:57:39 -06:00
|
|
|
// >:-<
|
|
|
|
let mut impl_path = vec::append(~[], path);
|
|
|
|
impl_path += ~[ast_map::path_name(item.ident)];
|
|
|
|
|
2012-11-13 21:08:01 -06:00
|
|
|
for methods.each |m| {
|
|
|
|
index.push({val: m.id, pos: ebml_w.writer.tell()});
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_info_for_method(ecx, ebml_w, impl_path,
|
|
|
|
should_inline(m.attrs),
|
2013-01-07 16:16:52 -06:00
|
|
|
item.id, *m,
|
|
|
|
vec::append(/*bad*/copy tps, m.tps));
|
2011-12-16 07:17:52 -06:00
|
|
|
}
|
|
|
|
}
|
2013-01-07 16:16:52 -06:00
|
|
|
item_trait(ref tps, ref traits, ref ms) => {
|
2012-10-08 14:39:30 -05:00
|
|
|
let provided_methods = dvec::DVec();
|
|
|
|
|
2012-03-22 20:03:12 -05:00
|
|
|
add_to_index();
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2012-01-05 06:57:27 -06:00
|
|
|
encode_def_id(ebml_w, local_def(item.id));
|
2012-02-13 13:55:23 -06:00
|
|
|
encode_family(ebml_w, 'I');
|
2012-07-11 12:28:30 -05:00
|
|
|
encode_region_param(ecx, ebml_w, item);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, *tps);
|
2012-01-30 10:28:30 -06:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, item.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_attributes(ebml_w, item.attrs);
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut i = 0u;
|
2012-09-18 23:41:13 -05:00
|
|
|
for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
|
2012-12-04 12:50:00 -06:00
|
|
|
match (*ms)[i] {
|
|
|
|
required(ref ty_m) => {
|
2012-07-10 15:44:20 -05:00
|
|
|
ebml_w.start_tag(tag_item_trait_method);
|
2012-12-04 12:50:00 -06:00
|
|
|
encode_def_id(ebml_w, local_def((*ty_m).id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, mty.ident);
|
2013-01-07 16:16:52 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx,
|
2013-01-22 13:57:39 -06:00
|
|
|
(*ty_m).tps);
|
2013-01-31 19:12:29 -06:00
|
|
|
encode_type(ecx, ebml_w,
|
|
|
|
ty::mk_bare_fn(tcx, copy mty.fty));
|
|
|
|
encode_family(ebml_w, purity_fn_family(mty.fty.purity));
|
2012-07-31 18:32:37 -05:00
|
|
|
encode_self_type(ebml_w, mty.self_ty);
|
2012-10-08 14:39:30 -05:00
|
|
|
encode_method_sort(ebml_w, 'r');
|
2012-07-10 15:44:20 -05:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
provided(m) => {
|
2012-10-08 14:39:30 -05:00
|
|
|
provided_methods.push(m);
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_item_trait_method);
|
|
|
|
encode_def_id(ebml_w, local_def(m.id));
|
|
|
|
encode_name(ecx, ebml_w, mty.ident);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, m.tps);
|
2013-01-31 19:12:29 -06:00
|
|
|
encode_type(ecx, ebml_w,
|
|
|
|
ty::mk_bare_fn(tcx, copy mty.fty));
|
|
|
|
encode_family(ebml_w, purity_fn_family(mty.fty.purity));
|
2012-10-08 14:39:30 -05:00
|
|
|
encode_self_type(ebml_w, mty.self_ty);
|
|
|
|
encode_method_sort(ebml_w, 'p');
|
|
|
|
ebml_w.end_tag();
|
2012-07-10 15:44:20 -05:00
|
|
|
}
|
|
|
|
}
|
2013-01-22 13:57:39 -06:00
|
|
|
i += 1;
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
2012-08-03 17:02:01 -05:00
|
|
|
for traits.each |associated_trait| {
|
2012-09-19 18:55:01 -05:00
|
|
|
encode_trait_ref(ebml_w, ecx, *associated_trait)
|
2012-08-03 17:02:01 -05:00
|
|
|
}
|
2012-12-13 16:55:08 -06:00
|
|
|
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2012-08-02 18:01:38 -05:00
|
|
|
|
|
|
|
// Now, output all of the static methods as items. Note that for the
|
|
|
|
// method info, we output static methods with type signatures as
|
|
|
|
// written. Here, we output the *real* type signatures. I feel like
|
|
|
|
// maybe we should only ever handle the real type signatures.
|
2012-12-04 12:50:00 -06:00
|
|
|
for vec::each((*ms)) |m| {
|
2012-09-18 23:41:37 -05:00
|
|
|
let ty_m = ast_util::trait_method_to_ty_method(*m);
|
2012-09-07 17:32:04 -05:00
|
|
|
if ty_m.self_ty.node != ast::sty_static { loop; }
|
2012-08-02 18:01:38 -05:00
|
|
|
|
2012-09-26 19:33:34 -05:00
|
|
|
index.push({val: ty_m.id, pos: ebml_w.writer.tell()});
|
2012-08-02 18:01:38 -05:00
|
|
|
|
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
|
|
|
encode_def_id(ebml_w, local_def(ty_m.id));
|
2012-10-12 19:00:08 -05:00
|
|
|
encode_parent_item(ebml_w, local_def(item.id));
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_name(ecx, ebml_w, ty_m.ident);
|
2012-08-02 18:01:38 -05:00
|
|
|
encode_family(ebml_w,
|
2012-08-23 20:17:16 -05:00
|
|
|
purity_static_method_family(ty_m.purity));
|
2013-02-05 21:41:45 -06:00
|
|
|
let polyty = ecx.tcx.tcache.get(&local_def(ty_m.id));
|
2012-08-02 18:01:38 -05:00
|
|
|
encode_ty_type_param_bounds(ebml_w, ecx, polyty.bounds);
|
|
|
|
encode_type(ecx, ebml_w, polyty.ty);
|
2013-01-22 13:57:39 -06:00
|
|
|
let mut m_path = vec::append(~[], path); // :-(
|
|
|
|
m_path += [ast_map::path_name(item.ident)];
|
|
|
|
encode_path(ecx, ebml_w, m_path, ast_map::path_name(ty_m.ident));
|
2012-08-02 18:01:38 -05:00
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2012-10-08 14:39:30 -05:00
|
|
|
// Finally, output all the provided methods as items.
|
|
|
|
for provided_methods.each |m| {
|
|
|
|
index.push({val: m.id, pos: ebml_w.writer.tell()});
|
2013-01-07 16:16:52 -06:00
|
|
|
encode_info_for_method(ecx, ebml_w, /*bad*/copy path,
|
|
|
|
true, item.id, *m, /*bad*/copy m.tps);
|
2012-10-08 14:39:30 -05:00
|
|
|
}
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
2013-02-11 21:26:38 -06:00
|
|
|
item_mac(*) => fail!(~"item macros unimplemented")
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
fn encode_info_for_foreign_item(ecx: @encode_ctxt,
|
|
|
|
ebml_w: writer::Encoder,
|
2012-06-26 18:18:37 -05:00
|
|
|
nitem: @foreign_item,
|
2012-06-29 18:26:56 -05:00
|
|
|
index: @mut ~[entry<int>],
|
2013-01-07 16:16:52 -06:00
|
|
|
+path: ast_map::path,
|
|
|
|
abi: foreign_abi) {
|
2012-08-01 19:30:05 -05:00
|
|
|
if !reachable(ecx, nitem.id) { return; }
|
2012-09-26 19:33:34 -05:00
|
|
|
index.push({val: nitem.id, pos: ebml_w.writer.tell()});
|
2012-03-08 16:37:45 -06:00
|
|
|
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data_item);
|
2013-01-07 16:16:52 -06:00
|
|
|
match /*bad*/copy nitem.node {
|
2012-08-26 11:58:45 -05:00
|
|
|
foreign_item_fn(_, purity, tps) => {
|
2011-07-27 07:19:39 -05:00
|
|
|
encode_def_id(ebml_w, local_def(nitem.id));
|
2012-08-23 20:17:16 -05:00
|
|
|
encode_family(ebml_w, purity_fn_family(purity));
|
2011-12-28 10:50:12 -06:00
|
|
|
encode_type_param_bounds(ebml_w, ecx, tps);
|
2012-05-13 19:01:52 -05:00
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
2012-06-26 18:18:37 -05:00
|
|
|
if abi == foreign_abi_rust_intrinsic {
|
2013-01-22 13:57:39 -06:00
|
|
|
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
|
2012-03-21 09:42:20 -05:00
|
|
|
} else {
|
|
|
|
encode_symbol(ecx, ebml_w, nitem.id);
|
|
|
|
}
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-26 11:58:45 -05:00
|
|
|
foreign_item_const(*) => {
|
2012-08-25 17:09:33 -05:00
|
|
|
encode_def_id(ebml_w, local_def(nitem.id));
|
|
|
|
encode_family(ebml_w, 'c');
|
|
|
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
|
|
|
encode_symbol(ecx, ebml_w, nitem.id);
|
2013-01-22 13:57:39 -06:00
|
|
|
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
|
2012-08-25 17:09:33 -05:00
|
|
|
}
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2013-01-11 17:07:48 -06:00
|
|
|
crate: &crate) -> ~[entry<int>] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let index = @mut ~[];
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items_data);
|
2012-09-26 19:33:34 -05:00
|
|
|
index.push({val: crate_node_id, pos: ebml_w.writer.tell()});
|
2012-03-08 16:37:45 -06:00
|
|
|
encode_info_for_mod(ecx, ebml_w, crate.node.module,
|
2012-07-18 18:18:02 -05:00
|
|
|
crate_node_id, ~[],
|
|
|
|
syntax::parse::token::special_idents::invalid);
|
2013-01-08 16:00:45 -06:00
|
|
|
visit::visit_crate(*crate, (), visit::mk_vt(@visit::Visitor {
|
2012-06-30 18:19:07 -05:00
|
|
|
visit_expr: |_e, _cx, _v| { },
|
2013-01-10 12:59:58 -06:00
|
|
|
visit_item: {
|
|
|
|
let ebml_w = copy ebml_w;
|
|
|
|
|i, cx, v| {
|
|
|
|
visit::visit_item(i, cx, v);
|
2013-02-05 21:41:45 -06:00
|
|
|
match ecx.tcx.items.get(&i.id) {
|
2013-01-10 12:59:58 -06:00
|
|
|
ast_map::node_item(_, pt) => {
|
|
|
|
encode_info_for_item(ecx, ebml_w, i,
|
|
|
|
index, *pt);
|
|
|
|
}
|
2013-02-11 21:26:38 -06:00
|
|
|
_ => fail!(~"bad item")
|
2013-01-10 12:59:58 -06:00
|
|
|
}
|
2012-03-06 10:02:13 -06:00
|
|
|
}
|
2012-03-08 16:37:45 -06:00
|
|
|
},
|
2013-01-10 12:59:58 -06:00
|
|
|
visit_foreign_item: {
|
|
|
|
let ebml_w = copy ebml_w;
|
|
|
|
|ni, cx, v| {
|
|
|
|
visit::visit_foreign_item(ni, cx, v);
|
2013-02-05 21:41:45 -06:00
|
|
|
match ecx.tcx.items.get(&ni.id) {
|
2013-01-10 12:59:58 -06:00
|
|
|
ast_map::node_foreign_item(_, abi, pt) => {
|
|
|
|
encode_info_for_foreign_item(ecx, ebml_w, ni,
|
|
|
|
index, /*bad*/copy *pt,
|
|
|
|
abi);
|
|
|
|
}
|
|
|
|
// case for separate item and foreign-item tables
|
2013-02-11 21:26:38 -06:00
|
|
|
_ => fail!(~"bad foreign item")
|
2013-01-10 12:59:58 -06:00
|
|
|
}
|
2012-03-09 06:35:20 -06:00
|
|
|
}
|
2013-01-10 12:59:58 -06:00
|
|
|
},
|
|
|
|
..*visit::default_visitor()
|
2012-03-08 16:37:45 -06:00
|
|
|
}));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2013-01-07 16:16:52 -06:00
|
|
|
return /*bad*/copy *index;
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Path and definition ID indexing
|
|
|
|
|
2012-09-19 15:13:24 -05:00
|
|
|
fn create_index<T: Copy Hash IterBytes>(index: ~[entry<T>]) ->
|
2012-06-29 18:26:56 -05:00
|
|
|
~[@~[entry<T>]] {
|
|
|
|
let mut buckets: ~[@mut ~[entry<T>]] = ~[];
|
2012-09-26 19:33:34 -05:00
|
|
|
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
|
2012-06-30 18:19:07 -05:00
|
|
|
for index.each |elt| {
|
2012-09-19 15:13:24 -05:00
|
|
|
let h = elt.val.hash() as uint;
|
2012-09-26 19:33:34 -05:00
|
|
|
buckets[h % 256].push(*elt);
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2011-07-14 16:25:43 -05:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut buckets_frozen = ~[];
|
2012-06-30 18:19:07 -05:00
|
|
|
for buckets.each |bucket| {
|
2013-01-07 16:16:52 -06:00
|
|
|
buckets_frozen.push(@/*bad*/copy **bucket);
|
2011-07-14 16:25:43 -05:00
|
|
|
}
|
2012-08-01 19:30:05 -05:00
|
|
|
return buckets_frozen;
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_index<T>(ebml_w: writer::Encoder, buckets: ~[@~[entry<T>]],
|
2012-08-14 15:38:35 -05:00
|
|
|
write_fn: fn(io::Writer, T)) {
|
2012-01-11 14:52:25 -06:00
|
|
|
let writer = ebml_w.writer;
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_index);
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut bucket_locs: ~[uint] = ~[];
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_index_buckets);
|
2012-06-30 18:19:07 -05:00
|
|
|
for buckets.each |bucket| {
|
2012-09-26 19:33:34 -05:00
|
|
|
bucket_locs.push(ebml_w.writer.tell());
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_index_buckets_bucket);
|
2012-09-19 18:55:01 -05:00
|
|
|
for vec::each(**bucket) |elt| {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_index_buckets_bucket_elt);
|
2012-08-03 15:18:46 -05:00
|
|
|
assert elt.pos < 0xffff_ffff;
|
2012-08-02 19:17:07 -05:00
|
|
|
writer.write_be_u32(elt.pos as u32);
|
2011-07-26 07:06:02 -05:00
|
|
|
write_fn(writer, elt.val);
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_index_table);
|
2012-08-02 19:17:07 -05:00
|
|
|
for bucket_locs.each |pos| {
|
2012-09-19 18:55:01 -05:00
|
|
|
assert *pos < 0xffff_ffff;
|
|
|
|
writer.write_be_u32(*pos as u32);
|
2012-08-02 19:17:07 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-08-14 15:38:35 -05:00
|
|
|
fn write_str(writer: io::Writer, &&s: ~str) { writer.write_str(s); }
|
2011-06-27 17:20:17 -05:00
|
|
|
|
2012-08-14 15:38:35 -05:00
|
|
|
fn write_int(writer: io::Writer, &&n: int) {
|
2012-08-03 15:18:46 -05:00
|
|
|
assert n < 0x7fff_ffff;
|
2012-08-02 19:17:07 -05:00
|
|
|
writer.write_be_u32(n as u32);
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_meta_item(ebml_w: writer::Encoder, mi: meta_item) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match mi.node {
|
2012-12-04 12:50:00 -06:00
|
|
|
meta_word(ref name) => {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_meta_item_word);
|
|
|
|
ebml_w.start_tag(tag_meta_item_name);
|
2012-12-04 12:50:00 -06:00
|
|
|
ebml_w.writer.write(str::to_bytes((*name)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-12-04 12:50:00 -06:00
|
|
|
meta_name_value(ref name, value) => {
|
2012-08-06 14:34:08 -05:00
|
|
|
match value.node {
|
2012-08-03 21:59:04 -05:00
|
|
|
lit_str(value) => {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_meta_item_name_value);
|
|
|
|
ebml_w.start_tag(tag_meta_item_name);
|
2012-12-04 12:50:00 -06:00
|
|
|
ebml_w.writer.write(str::to_bytes((*name)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_meta_item_value);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(*value));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
_ => {/* FIXME (#623): encode other variants */ }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
}
|
2013-01-07 16:16:52 -06:00
|
|
|
meta_list(ref name, ref items) => {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_meta_item_list);
|
|
|
|
ebml_w.start_tag(tag_meta_item_name);
|
2012-12-04 12:50:00 -06:00
|
|
|
ebml_w.writer.write(str::to_bytes((*name)));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2012-06-30 18:19:07 -05:00
|
|
|
for items.each |inner_item| {
|
2012-09-20 20:15:39 -05:00
|
|
|
encode_meta_item(ebml_w, **inner_item);
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2011-06-27 21:41:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-22 13:57:39 -06:00
|
|
|
fn encode_attributes(ebml_w: writer::Encoder, attrs: &[attribute]) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_attributes);
|
2012-06-30 18:19:07 -05:00
|
|
|
for attrs.each |attr| {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_attribute);
|
2011-06-27 21:41:48 -05:00
|
|
|
encode_meta_item(ebml_w, attr.node.value);
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-06-27 21:41:48 -05:00
|
|
|
}
|
|
|
|
|
2011-06-29 17:11:20 -05:00
|
|
|
// So there's a special crate attribute called 'link' which defines the
|
|
|
|
// metadata that Rust cares about for linking crates. This attribute requires
|
2011-06-30 19:03:08 -05:00
|
|
|
// 'name' and 'vers' items, so if the user didn't provide them we will throw
|
2011-06-29 17:11:20 -05:00
|
|
|
// them in anyway with default values.
|
2013-01-11 17:07:48 -06:00
|
|
|
fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: &crate) -> ~[attribute] {
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
fn synthesize_link_attr(ecx: @encode_ctxt, +items: ~[@meta_item]) ->
|
2011-07-27 07:19:39 -05:00
|
|
|
attribute {
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2013-01-24 22:24:57 -06:00
|
|
|
assert !ecx.link_meta.name.is_empty();
|
|
|
|
assert !ecx.link_meta.vers.is_empty();
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
let name_item =
|
2013-01-07 16:16:52 -06:00
|
|
|
attr::mk_name_value_item_str(~"name",
|
2013-01-11 17:07:48 -06:00
|
|
|
ecx.link_meta.name.to_owned());
|
2011-07-27 07:19:39 -05:00
|
|
|
let vers_item =
|
2013-01-07 16:16:52 -06:00
|
|
|
attr::mk_name_value_item_str(~"vers",
|
2013-01-11 17:07:48 -06:00
|
|
|
ecx.link_meta.vers.to_owned());
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
let other_items =
|
|
|
|
{
|
2012-07-18 18:18:02 -05:00
|
|
|
let tmp = attr::remove_meta_items_by_name(items, ~"name");
|
|
|
|
attr::remove_meta_items_by_name(tmp, ~"vers")
|
2011-07-27 07:19:39 -05:00
|
|
|
};
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let meta_items = vec::append(~[name_item, vers_item], other_items);
|
2012-07-18 18:18:02 -05:00
|
|
|
let link_item = attr::mk_list_item(~"link", meta_items);
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2012-08-01 19:30:05 -05:00
|
|
|
return attr::mk_attr(link_item);
|
2011-06-29 16:17:23 -05:00
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut attrs: ~[attribute] = ~[];
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut found_link_attr = false;
|
2012-06-30 18:19:07 -05:00
|
|
|
for crate.node.attrs.each |attr| {
|
2012-09-26 19:33:34 -05:00
|
|
|
attrs.push(
|
2012-09-19 18:55:01 -05:00
|
|
|
if attr::get_attr_name(*attr) != ~"link" {
|
2013-01-07 16:16:52 -06:00
|
|
|
/*bad*/copy *attr
|
2011-07-27 07:19:39 -05:00
|
|
|
} else {
|
2013-01-07 16:16:52 -06:00
|
|
|
match /*bad*/copy attr.node.value.node {
|
2012-08-25 20:38:21 -05:00
|
|
|
meta_list(_, l) => {
|
2011-09-12 04:27:30 -05:00
|
|
|
found_link_attr = true;;
|
2012-06-28 17:00:03 -05:00
|
|
|
synthesize_link_attr(ecx, l)
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2013-01-07 16:16:52 -06:00
|
|
|
_ => /*bad*/copy *attr
|
2011-06-29 16:17:23 -05:00
|
|
|
}
|
2012-06-28 17:00:03 -05:00
|
|
|
});
|
2011-06-29 16:17:23 -05:00
|
|
|
}
|
|
|
|
|
2012-09-26 19:33:34 -05:00
|
|
|
if !found_link_attr { attrs.push(synthesize_link_attr(ecx, ~[])); }
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2012-08-01 19:30:05 -05:00
|
|
|
return attrs;
|
2011-06-29 16:17:23 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn encode_crate_deps(ecx: @encode_ctxt,
|
|
|
|
ebml_w: writer::Encoder,
|
|
|
|
cstore: @mut cstore::CStore) {
|
|
|
|
fn get_ordered_deps(ecx: @encode_ctxt, cstore: @mut cstore::CStore)
|
|
|
|
-> ~[decoder::crate_dep] {
|
2011-07-27 07:19:39 -05:00
|
|
|
type hashkv = @{key: crate_num, val: cstore::crate_metadata};
|
2012-04-07 12:59:37 -05:00
|
|
|
type numdep = decoder::crate_dep;
|
2011-07-08 13:29:56 -05:00
|
|
|
|
2012-04-07 12:59:37 -05:00
|
|
|
// Pull the cnums and name,vers,hash out of cstore
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut deps: ~[numdep] = ~[];
|
2012-06-30 18:19:07 -05:00
|
|
|
do cstore::iter_crate_data(cstore) |key, val| {
|
2013-01-07 16:16:52 -06:00
|
|
|
let dep = {cnum: key,
|
|
|
|
name: ecx.tcx.sess.ident_of(/*bad*/copy val.name),
|
2012-04-07 12:59:37 -05:00
|
|
|
vers: decoder::get_crate_vers(val.data),
|
2012-06-10 02:49:59 -05:00
|
|
|
hash: decoder::get_crate_hash(val.data)};
|
2012-09-26 19:33:34 -05:00
|
|
|
deps.push(dep);
|
2011-10-21 05:21:27 -05:00
|
|
|
};
|
2011-07-08 13:29:56 -05:00
|
|
|
|
|
|
|
// Sort by cnum
|
2012-08-02 17:42:56 -05:00
|
|
|
pure fn lteq(kv1: &numdep, kv2: &numdep) -> bool {
|
|
|
|
kv1.cnum <= kv2.cnum
|
|
|
|
}
|
2012-09-27 19:05:13 -05:00
|
|
|
std::sort::quick_sort(deps, lteq);
|
2011-07-08 13:29:56 -05:00
|
|
|
|
|
|
|
// Sanity-check the crate numbers
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut expected_cnum = 1;
|
2012-06-30 18:19:07 -05:00
|
|
|
for deps.each |n| {
|
2012-04-07 12:59:37 -05:00
|
|
|
assert (n.cnum == expected_cnum);
|
2011-07-08 13:29:56 -05:00
|
|
|
expected_cnum += 1;
|
|
|
|
}
|
|
|
|
|
2012-03-26 20:35:18 -05:00
|
|
|
// mut -> immutable hack for vec::map
|
2012-08-01 19:30:05 -05:00
|
|
|
return vec::slice(deps, 0u, vec::len(deps));
|
2011-07-08 13:29:56 -05:00
|
|
|
}
|
|
|
|
|
2012-04-07 12:59:37 -05:00
|
|
|
// We're just going to write a list of crate 'name-hash-version's, with
|
|
|
|
// the assumption that they are numbered 1 to n.
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2166): This is not nearly enough to support correct versioning
|
2011-07-08 13:29:56 -05:00
|
|
|
// but is enough to get transitive crate dependencies working.
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_crate_deps);
|
2012-07-18 18:18:02 -05:00
|
|
|
for get_ordered_deps(ecx, cstore).each |dep| {
|
2012-09-19 18:55:01 -05:00
|
|
|
encode_crate_dep(ecx, ebml_w, *dep);
|
2011-07-08 13:29:56 -05:00
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-07-08 13:29:56 -05:00
|
|
|
}
|
|
|
|
|
2013-01-07 12:51:53 -06:00
|
|
|
fn encode_lang_items(ecx: @encode_ctxt, ebml_w: writer::Encoder) {
|
|
|
|
ebml_w.start_tag(tag_lang_items);
|
|
|
|
|
|
|
|
for ecx.tcx.lang_items.each_item |def_id, i| {
|
|
|
|
if def_id.crate != local_crate {
|
|
|
|
loop;
|
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_lang_items_item);
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_lang_items_item_id);
|
|
|
|
ebml_w.writer.write_be_u32(i as u32);
|
|
|
|
ebml_w.end_tag(); // tag_lang_items_item_id
|
|
|
|
|
|
|
|
ebml_w.start_tag(tag_lang_items_item_node_id);
|
|
|
|
ebml_w.writer.write_be_u32(def_id.node as u32);
|
|
|
|
ebml_w.end_tag(); // tag_lang_items_item_node_id
|
|
|
|
|
|
|
|
ebml_w.end_tag(); // tag_lang_items_item
|
|
|
|
}
|
|
|
|
|
|
|
|
ebml_w.end_tag(); // tag_lang_items
|
|
|
|
}
|
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: writer::Encoder,
|
2012-07-18 18:18:02 -05:00
|
|
|
dep: decoder::crate_dep) {
|
2012-04-07 12:59:37 -05:00
|
|
|
ebml_w.start_tag(tag_crate_dep);
|
|
|
|
ebml_w.start_tag(tag_crate_dep_name);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(ecx.tcx.sess.str_of(dep.name)));
|
2012-04-07 12:59:37 -05:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_crate_dep_vers);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(dep.vers));
|
2012-04-07 12:59:37 -05:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.start_tag(tag_crate_dep_hash);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(dep.hash));
|
2012-04-07 12:59:37 -05:00
|
|
|
ebml_w.end_tag();
|
|
|
|
ebml_w.end_tag();
|
|
|
|
}
|
|
|
|
|
2013-01-11 17:07:48 -06:00
|
|
|
fn encode_hash(ebml_w: writer::Encoder, hash: &str) {
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_crate_hash);
|
2012-08-23 17:44:57 -05:00
|
|
|
ebml_w.writer.write(str::to_bytes(hash));
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2011-12-11 09:23:38 -06:00
|
|
|
}
|
|
|
|
|
2012-09-05 17:27:22 -05:00
|
|
|
// NB: Increment this as you change the metadata encoding version.
|
2013-01-29 18:51:16 -06:00
|
|
|
pub const metadata_encoding_version : &[u8] = &[0x72, //'r' as u8,
|
|
|
|
0x75, //'u' as u8,
|
|
|
|
0x73, //'s' as u8,
|
|
|
|
0x74, //'t' as u8,
|
|
|
|
0, 0, 0, 1 ];
|
2012-09-05 17:27:22 -05:00
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn encode_metadata(parms: encode_parms, crate: &crate) -> ~[u8] {
|
2012-09-20 13:17:15 -05:00
|
|
|
let wr = @io::BytesWriter();
|
2013-02-04 16:02:01 -06:00
|
|
|
let mut stats = Stats {
|
|
|
|
inline_bytes: 0,
|
|
|
|
attr_bytes: 0,
|
|
|
|
dep_bytes: 0,
|
|
|
|
lang_item_bytes: 0,
|
|
|
|
item_bytes: 0,
|
|
|
|
index_bytes: 0,
|
|
|
|
zero_bytes: 0,
|
|
|
|
total_bytes: 0,
|
|
|
|
n_inlines: 0
|
|
|
|
};
|
2012-05-14 19:38:17 -05:00
|
|
|
let ecx: @encode_ctxt = @encode_ctxt({
|
2012-05-14 22:41:33 -05:00
|
|
|
diag: parms.diag,
|
2012-05-13 19:01:52 -05:00
|
|
|
tcx: parms.tcx,
|
2013-02-04 16:02:01 -06:00
|
|
|
stats: @mut move stats,
|
2012-05-13 19:01:52 -05:00
|
|
|
reachable: parms.reachable,
|
2012-08-17 14:41:34 -05:00
|
|
|
reexports2: parms.reexports2,
|
2012-05-13 19:01:52 -05:00
|
|
|
item_symbols: parms.item_symbols,
|
|
|
|
discrim_symbols: parms.discrim_symbols,
|
2013-01-07 16:16:52 -06:00
|
|
|
link_meta: /*bad*/copy parms.link_meta,
|
2012-05-13 19:01:52 -05:00
|
|
|
cstore: parms.cstore,
|
2012-05-14 19:38:17 -05:00
|
|
|
encode_inlined_item: parms.encode_inlined_item,
|
2012-05-13 19:01:52 -05:00
|
|
|
type_abbrevs: ty::new_ty_hash()
|
2012-05-14 19:38:17 -05:00
|
|
|
});
|
2011-07-08 01:55:41 -05:00
|
|
|
|
2012-12-17 21:31:04 -06:00
|
|
|
let ebml_w = writer::Encoder(wr as io::Writer);
|
2011-06-27 17:20:17 -05:00
|
|
|
|
2013-01-11 17:07:48 -06:00
|
|
|
encode_hash(ebml_w, ecx.link_meta.extras_hash);
|
2011-12-11 09:23:38 -06:00
|
|
|
|
2012-09-14 11:40:28 -05:00
|
|
|
let mut i = wr.pos;
|
2011-07-27 07:19:39 -05:00
|
|
|
let crate_attrs = synthesize_crate_attrs(ecx, crate);
|
2011-06-29 16:17:23 -05:00
|
|
|
encode_attributes(ebml_w, crate_attrs);
|
2012-09-14 11:40:28 -05:00
|
|
|
ecx.stats.attr_bytes = wr.pos - i;
|
2011-07-08 13:29:56 -05:00
|
|
|
|
2012-09-14 11:40:28 -05:00
|
|
|
i = wr.pos;
|
2012-07-18 18:18:02 -05:00
|
|
|
encode_crate_deps(ecx, ebml_w, ecx.cstore);
|
2012-09-14 11:40:28 -05:00
|
|
|
ecx.stats.dep_bytes = wr.pos - i;
|
2011-07-08 13:29:56 -05:00
|
|
|
|
2013-01-07 12:51:53 -06:00
|
|
|
// Encode the language items.
|
|
|
|
i = wr.pos;
|
|
|
|
encode_lang_items(ecx, ebml_w);
|
|
|
|
ecx.stats.lang_item_bytes = wr.pos - i;
|
|
|
|
|
2012-01-11 08:15:54 -06:00
|
|
|
// Encode and index the items.
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.start_tag(tag_items);
|
2012-09-14 11:40:28 -05:00
|
|
|
i = wr.pos;
|
2012-03-08 16:37:45 -06:00
|
|
|
let items_index = encode_info_for_items(ecx, ebml_w, crate);
|
2012-09-14 11:40:28 -05:00
|
|
|
ecx.stats.item_bytes = wr.pos - i;
|
2012-08-27 18:53:54 -05:00
|
|
|
|
2012-09-14 11:40:28 -05:00
|
|
|
i = wr.pos;
|
2012-09-19 15:13:24 -05:00
|
|
|
let items_buckets = create_index(items_index);
|
2011-07-25 08:07:48 -05:00
|
|
|
encode_index(ebml_w, items_buckets, write_int);
|
2012-09-14 11:40:28 -05:00
|
|
|
ecx.stats.index_bytes = wr.pos - i;
|
2012-02-14 17:21:53 -06:00
|
|
|
ebml_w.end_tag();
|
2012-01-11 08:15:54 -06:00
|
|
|
|
2012-09-14 11:40:28 -05:00
|
|
|
ecx.stats.total_bytes = wr.pos;
|
2012-08-27 18:53:54 -05:00
|
|
|
|
|
|
|
if (parms.tcx.sess.meta_stats()) {
|
|
|
|
|
2012-10-18 11:10:37 -05:00
|
|
|
do wr.bytes.borrow |v| {
|
2012-08-27 18:53:54 -05:00
|
|
|
do v.each |e| {
|
2012-09-19 18:55:01 -05:00
|
|
|
if *e == 0 {
|
2012-08-27 18:53:54 -05:00
|
|
|
ecx.stats.zero_bytes += 1;
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
io::println("metadata stats:");
|
|
|
|
io::println(fmt!(" inline bytes: %u", ecx.stats.inline_bytes));
|
|
|
|
io::println(fmt!(" attribute bytes: %u", ecx.stats.attr_bytes));
|
|
|
|
io::println(fmt!(" dep bytes: %u", ecx.stats.dep_bytes));
|
2013-01-07 12:51:53 -06:00
|
|
|
io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes));
|
2012-08-27 18:53:54 -05:00
|
|
|
io::println(fmt!(" item bytes: %u", ecx.stats.item_bytes));
|
|
|
|
io::println(fmt!(" index bytes: %u", ecx.stats.index_bytes));
|
|
|
|
io::println(fmt!(" zero bytes: %u", ecx.stats.zero_bytes));
|
|
|
|
io::println(fmt!(" total bytes: %u", ecx.stats.total_bytes));
|
|
|
|
}
|
|
|
|
|
2011-06-27 17:20:17 -05:00
|
|
|
// Pad this, since something (LLVM, presumably) is cutting off the
|
2011-08-11 18:36:20 -05:00
|
|
|
// remaining % 4 bytes.
|
2012-09-14 11:40:28 -05:00
|
|
|
wr.write(&[0u8, 0u8, 0u8, 0u8]);
|
2012-09-05 17:27:22 -05:00
|
|
|
|
|
|
|
// FIXME #3396: weird bug here, for reasons unclear this emits random
|
|
|
|
// looking bytes (mostly 0x1) if we use the version byte-array constant
|
|
|
|
// above; so we use a string constant inline instead.
|
|
|
|
//
|
|
|
|
// Should be:
|
|
|
|
//
|
|
|
|
// vec::from_slice(metadata_encoding_version) +
|
|
|
|
|
2012-09-21 20:36:32 -05:00
|
|
|
(do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
|
2012-09-26 18:27:54 -05:00
|
|
|
vec::slice(*bytes, 0, 8)
|
2012-10-18 11:10:37 -05:00
|
|
|
}) + flate::deflate_bytes(wr.bytes.check_out(|buf| buf))
|
2011-06-27 17:20:17 -05:00
|
|
|
}
|
2011-06-27 21:16:16 -05:00
|
|
|
|
2011-07-07 14:47:39 -05:00
|
|
|
// Get the encoded string for a type
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str {
|
2013-01-08 16:00:45 -06:00
|
|
|
let cx = @tyencode::ctxt {
|
|
|
|
diag: tcx.diag,
|
|
|
|
ds: def_to_str,
|
|
|
|
tcx: tcx,
|
|
|
|
reachable: |_id| false,
|
|
|
|
abbrevs: tyencode::ac_no_abbrevs};
|
2012-09-14 11:40:28 -05:00
|
|
|
do io::with_str_writer |wr| {
|
|
|
|
tyencode::enc_ty(wr, cx, t);
|
|
|
|
}
|
2011-07-07 14:47:39 -05:00
|
|
|
}
|
|
|
|
|
2011-06-27 21:16:16 -05:00
|
|
|
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// End:
|