summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-10-18 21:17:13 +0800
committerJohn Hodge <tpg@mutabah.net>2016-10-18 21:17:13 +0800
commit1daa57b7cfd4dc609502f28eeaecdad4cb43b3d4 (patch)
tree4a66d171abd4c41cdc1f4c585f4fe1b793d66968 /src
parentce853ffc73fc2cc743bf2b03cfd1e0d4130ffd30 (diff)
downloadmrust-1daa57b7cfd4dc609502f28eeaecdad4cb43b3d4.tar.gz
HIR Serialise - Compress (now requires boost, sorry)
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp329
-rw-r--r--src/hir/serialise.cpp368
-rw-r--r--src/hir/serialise_lowlevel.cpp37
-rw-r--r--src/hir/serialise_lowlevel.hpp247
4 files changed, 535 insertions, 446 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index 75efdccf..e40788d3 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -10,6 +10,7 @@
#include <serialiser_texttree.hpp>
#include <mir/mir.hpp>
#include <macro_rules/macro_rules.hpp>
+#include "serialise_lowlevel.hpp"
namespace {
@@ -21,132 +22,24 @@ namespace {
class HirDeserialiser
{
const ::std::string& m_crate_name;
- ::std::istream& m_is;
+ ::HIR::serialise::Reader& m_in;
public:
- HirDeserialiser(const ::std::string& crate_name, ::std::istream& is):
+ HirDeserialiser(const ::std::string& crate_name, ::HIR::serialise::Reader& in):
m_crate_name( crate_name ),
- m_is(is)
+ m_in(in)
{}
- uint8_t read_u8() {
- uint8_t v;
- m_is.read(reinterpret_cast<char*>(&v), 1);
- if( !m_is ) {
- throw "";
- }
- assert( m_is );
- return v;
- }
- uint16_t read_u16() {
- uint16_t v;
- v = static_cast<uint16_t>(read_u8());
- v |= static_cast<uint16_t>(read_u8()) << 8;
- return v;
- }
- uint32_t read_u32() {
- uint32_t v;
- v = static_cast<uint32_t>(read_u8());
- v |= static_cast<uint32_t>(read_u8()) << 8;
- v |= static_cast<uint32_t>(read_u8()) << 16;
- v |= static_cast<uint32_t>(read_u8()) << 24;
- return v;
- }
- uint64_t read_u64() {
- uint64_t v;
- v = static_cast<uint64_t>(read_u8());
- v |= static_cast<uint64_t>(read_u8()) << 8;
- v |= static_cast<uint64_t>(read_u8()) << 16;
- v |= static_cast<uint64_t>(read_u8()) << 24;
- v |= static_cast<uint64_t>(read_u8()) << 32;
- v |= static_cast<uint64_t>(read_u8()) << 40;
- v |= static_cast<uint64_t>(read_u8()) << 48;
- v |= static_cast<uint64_t>(read_u8()) << 56;
- return v;
- }
- // Variable-length encoded u64 (for array sizes)
- uint64_t read_u64c() {
- auto v = read_u8();
- if( v < (1<<7) ) {
- return static_cast<uint64_t>(v);
- }
- else if( v < 0xC0 ) {
- uint64_t rv = static_cast<uint64_t>(v & 0x3F) << 16;
- rv |= static_cast<uint64_t>(read_u8()) << 8;
- rv |= static_cast<uint64_t>(read_u8());
- return rv;
- }
- else if( v < 0xFF ) {
- uint64_t rv = static_cast<uint64_t>(v & 0x3F) << 32;
- rv |= static_cast<uint64_t>(read_u8()) << 24;
- rv |= static_cast<uint64_t>(read_u8()) << 16;
- rv |= static_cast<uint64_t>(read_u8()) << 8;
- rv |= static_cast<uint64_t>(read_u8());
- return rv;
- }
- else {
- return read_u64();
- }
- }
- int64_t read_i64c() {
- uint64_t va = read_u64c();
- bool sign = (va & 0x1) != 0;
- va >>= 1;
-
- if( va == 0 && sign ) {
- return INT64_MIN;
- }
- else if( sign ) {
- return -static_cast<int64_t>(va);
- }
- else {
- return -static_cast<uint64_t>(va);
- }
- }
- double read_double() {
- double v;
- m_is.read(reinterpret_cast<char*>(&v), sizeof v);
- return v;
- }
- unsigned int read_tag() {
- return static_cast<unsigned int>( read_u8() );
- }
- size_t read_count() {
- auto v = read_u8();
- if( v < 0xFE ) {
- return v;
- }
- else if( v == 0xFE ) {
- return read_u16( );
- }
- else /*if( v == 0xFF )*/ {
- return ~0u;
- }
- }
- ::std::string read_string() {
- size_t len = read_u8();
- if( len < 128 ) {
- }
- else {
- len = (len & 0x7F) << 16;
- len |= read_u16();
- }
- ::std::string rv(len, '\0');
- m_is.read(const_cast<char*>(rv.data()), len);
- return rv;
- }
- bool read_bool() {
- return read_u8() != 0x00;
- }
+ ::std::string read_string() { return m_in.read_string(); }
template<typename V>
::std::map< ::std::string,V> deserialise_strmap()
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
::std::map< ::std::string, V> rv;
//rv.reserve(n);
for(size_t i = 0; i < n; i ++)
{
- auto s = read_string();
+ auto s = m_in.read_string();
rv.insert( ::std::make_pair( mv$(s), D<V>::des(*this) ) );
}
return rv;
@@ -154,12 +47,12 @@ namespace {
template<typename V>
::std::unordered_map< ::std::string,V> deserialise_strumap()
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
::std::unordered_map< ::std::string, V> rv;
//rv.reserve(n);
for(size_t i = 0; i < n; i ++)
{
- auto s = read_string();
+ auto s = m_in.read_string();
DEBUG("- " << s);
rv.insert( ::std::make_pair( mv$(s), D<V>::des(*this) ) );
}
@@ -169,7 +62,7 @@ namespace {
template<typename T>
::std::vector<T> deserialise_vec()
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
::std::vector<T> rv;
rv.reserve(n);
for(size_t i = 0; i < n; i ++)
@@ -179,7 +72,7 @@ namespace {
template<typename T>
::std::vector<T> deserialise_vec_c(::std::function<T()> cb)
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
::std::vector<T> rv;
rv.reserve(n);
for(size_t i = 0; i < n; i ++)
@@ -189,7 +82,7 @@ namespace {
template<typename T>
::HIR::VisEnt<T> deserialise_visent()
{
- return ::HIR::VisEnt<T> { read_bool(), D<T>::des(*this) };
+ return ::HIR::VisEnt<T> { m_in.read_bool(), D<T>::des(*this) };
}
template<typename T>
@@ -220,20 +113,20 @@ namespace {
rv.m_params = deserialise_genericparams();
rv.m_type = deserialise_type();
- size_t method_count = read_count();
+ size_t method_count = m_in.read_count();
for(size_t i = 0; i < method_count; i ++)
{
- auto name = read_string();
+ auto name = m_in.read_string();
rv.m_methods.insert( ::std::make_pair( mv$(name), ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> {
- read_bool(), read_bool(), deserialise_function()
+ m_in.read_bool(), m_in.read_bool(), deserialise_function()
} ) );
}
- size_t const_count = read_count();
+ size_t const_count = m_in.read_count();
for(size_t i = 0; i < const_count; i ++)
{
- auto name = read_string();
+ auto name = m_in.read_string();
rv.m_constants.insert( ::std::make_pair( mv$(name), ::HIR::TypeImpl::VisImplEnt< ::HIR::Constant> {
- read_bool(), read_bool(), deserialise_constant()
+ m_in.read_bool(), m_in.read_bool(), deserialise_constant()
} ) );
}
// m_src_module doesn't matter after typeck
@@ -249,28 +142,28 @@ namespace {
rv.m_type = deserialise_type();
- size_t method_count = read_count();
+ size_t method_count = m_in.read_count();
for(size_t i = 0; i < method_count; i ++)
{
- auto name = read_string();
+ auto name = m_in.read_string();
rv.m_methods.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> {
- read_bool(), deserialise_function()
+ m_in.read_bool(), deserialise_function()
} ) );
}
- size_t const_count = read_count();
+ size_t const_count = m_in.read_count();
for(size_t i = 0; i < const_count; i ++)
{
- auto name = read_string();
+ auto name = m_in.read_string();
rv.m_constants.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::Constant> {
- read_bool(), deserialise_constant()
+ m_in.read_bool(), deserialise_constant()
} ) );
}
- size_t type_count = read_count();
+ size_t type_count = m_in.read_count();
for(size_t i = 0; i < type_count; i ++)
{
- auto name = read_string();
+ auto name = m_in.read_string();
rv.m_types.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> {
- read_bool(), deserialise_type()
+ m_in.read_bool(), deserialise_type()
} ) );
}
@@ -282,7 +175,7 @@ namespace {
return ::HIR::MarkerImpl {
deserialise_genericparams(),
deserialise_pathparams(),
- read_bool(),
+ m_in.read_bool(),
deserialise_type()
};
}
@@ -297,16 +190,16 @@ namespace {
// NOTE: This is set after loading.
//rv.m_exported = true;
rv.m_rules = deserialise_vec_c< ::MacroRulesArm>( [&](){ return deserialise_macrorulesarm(); });
- rv.m_source_crate = read_string();
+ rv.m_source_crate = m_in.read_string();
if(rv.m_source_crate == "")
rv.m_source_crate = m_crate_name;
return rv;
}
::MacroPatEnt deserialise_macropatent() {
::MacroPatEnt rv {
- read_string(),
- static_cast<unsigned int>(read_count()),
- static_cast< ::MacroPatEnt::Type>(read_tag())
+ m_in.read_string(),
+ static_cast<unsigned int>(m_in.read_count()),
+ static_cast< ::MacroPatEnt::Type>(m_in.read_tag())
};
switch(rv.type)
{
@@ -341,22 +234,22 @@ namespace {
return rv;
}
::MacroExpansionEnt deserialise_macroexpansionent() {
- switch(read_tag())
+ switch(m_in.read_tag())
{
case 0:
return ::MacroExpansionEnt( deserialise_token() );
case 1: {
- unsigned int v = static_cast<unsigned int>(read_u8()) << 24;
- return ::MacroExpansionEnt( v | read_count() );
+ unsigned int v = static_cast<unsigned int>(m_in.read_u8()) << 24;
+ return ::MacroExpansionEnt( v | m_in.read_count() );
}
case 2: {
auto entries = deserialise_vec_c< ::MacroExpansionEnt>( [&](){ return deserialise_macroexpansionent(); } );
auto joiner = deserialise_token();
::std::map<unsigned int, bool> variables;
- size_t n = read_count();
+ size_t n = m_in.read_count();
while(n--) {
- auto idx = static_cast<unsigned int>(read_count());
- bool flag = read_bool();
+ auto idx = static_cast<unsigned int>(m_in.read_count());
+ bool flag = m_in.read_bool();
variables.insert( ::std::make_pair(idx, flag) );
}
return ::MacroExpansionEnt::make_Loop({
@@ -371,7 +264,7 @@ namespace {
::Token deserialise_token() {
::Token tok;
// HACK: Hand off to old serialiser code
- auto s = read_string();
+ auto s = m_in.read_string();
::std::stringstream tmp(s);
{
Deserialiser_TextTree ser(tmp);
@@ -385,7 +278,7 @@ namespace {
::HIR::ExprPtr deserialise_exprptr()
{
::HIR::ExprPtr rv;
- if( read_bool() )
+ if( m_in.read_bool() )
{
rv.m_mir = deserialise_mir();
}
@@ -404,17 +297,17 @@ namespace {
}
::MIR::LValue deserialise_mir_lvalue_()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::MIR::LValue::TAG_##x: return ::MIR::LValue::make_##x( __VA_ARGS__ );
- _(Variable, static_cast<unsigned int>(read_count()) )
- _(Temporary, { static_cast<unsigned int>(read_count()) } )
- _(Argument, { static_cast<unsigned int>(read_count()) } )
+ _(Variable, static_cast<unsigned int>(m_in.read_count()) )
+ _(Temporary, { static_cast<unsigned int>(m_in.read_count()) } )
+ _(Argument, { static_cast<unsigned int>(m_in.read_count()) } )
_(Static, deserialise_path() )
_(Return, {})
_(Field, {
box$( deserialise_mir_lvalue() ),
- static_cast<unsigned int>(read_count())
+ static_cast<unsigned int>(m_in.read_count())
} )
_(Deref, { box$( deserialise_mir_lvalue() ) })
_(Index, {
@@ -423,7 +316,7 @@ namespace {
} )
_(Downcast, {
box$( deserialise_mir_lvalue() ),
- static_cast<unsigned int>(read_count())
+ static_cast<unsigned int>(m_in.read_count())
} )
#undef _
default:
@@ -434,18 +327,18 @@ namespace {
{
TRACE_FUNCTION;
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::MIR::RValue::TAG_##x: return ::MIR::RValue::make_##x( __VA_ARGS__ );
_(Use, deserialise_mir_lvalue() )
_(Constant, deserialise_mir_constant() )
_(SizedArray, {
deserialise_mir_lvalue(),
- static_cast<unsigned int>(read_u64c())
+ static_cast<unsigned int>(m_in.read_u64c())
})
_(Borrow, {
0, // TODO: Region?
- static_cast< ::HIR::BorrowType>( read_tag() ),
+ static_cast< ::HIR::BorrowType>( m_in.read_tag() ),
deserialise_mir_lvalue()
})
_(Cast, {
@@ -454,12 +347,12 @@ namespace {
})
_(BinOp, {
deserialise_mir_lvalue(),
- static_cast< ::MIR::eBinOp>( read_tag() ),
+ static_cast< ::MIR::eBinOp>( m_in.read_tag() ),
deserialise_mir_lvalue()
})
_(UniOp, {
deserialise_mir_lvalue(),
- static_cast< ::MIR::eUniOp>( read_tag() )
+ static_cast< ::MIR::eUniOp>( m_in.read_tag() )
})
_(DstMeta, {
deserialise_mir_lvalue()
@@ -487,20 +380,20 @@ namespace {
{
TRACE_FUNCTION;
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::MIR::Constant::TAG_##x: DEBUG("- " #x); return ::MIR::Constant::make_##x( __VA_ARGS__ );
- _(Int, read_i64c())
- _(Uint, read_u64c())
- _(Float, read_double())
- _(Bool, read_bool())
+ _(Int, m_in.read_i64c())
+ _(Uint, m_in.read_u64c())
+ _(Float, m_in.read_double())
+ _(Bool, m_in.read_bool())
case ::MIR::Constant::TAG_Bytes: {
::std::vector<unsigned char> bytes;
- bytes.resize( read_count() );
- m_is.read( reinterpret_cast<char*>(bytes.data()), bytes.size() );
+ bytes.resize( m_in.read_count() );
+ m_in.read( bytes.data(), bytes.size() );
return ::MIR::Constant::make_Bytes( mv$(bytes) );
}
- _(StaticString, read_string() )
+ _(StaticString, m_in.read_string() )
_(Const, { deserialise_path() } )
_(ItemAddr, deserialise_path() )
#undef _
@@ -511,7 +404,7 @@ namespace {
::HIR::TypeItem deserialise_typeitem()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case 0:
return ::HIR::TypeItem( deserialise_simplepath() );
@@ -531,7 +424,7 @@ namespace {
}
::HIR::ValueItem deserialise_valueitem()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case 0:
return ::HIR::ValueItem( deserialise_simplepath() );
@@ -556,13 +449,13 @@ namespace {
TRACE_FUNCTION;
::HIR::Function rv {
- static_cast< ::HIR::Function::Receiver>( read_tag() ),
- read_string(),
- read_bool(),
- read_bool(),
+ static_cast< ::HIR::Function::Receiver>( m_in.read_tag() ),
+ m_in.read_string(),
+ m_in.read_bool(),
+ m_in.read_bool(),
deserialise_genericparams(),
deserialise_fcnargs(),
- read_bool(),
+ m_in.read_bool(),
deserialise_type(),
deserialise_exprptr()
};
@@ -570,7 +463,7 @@ namespace {
}
::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > deserialise_fcnargs()
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > rv;
rv.reserve(n);
for(size_t i = 0; i < n; i ++)
@@ -594,7 +487,7 @@ namespace {
TRACE_FUNCTION;
return ::HIR::Static {
- read_bool(),
+ m_in.read_bool(),
deserialise_type(),
::HIR::ExprPtr {}
};
@@ -616,7 +509,7 @@ namespace {
::HIR::TraitValueItem deserialise_traitvalueitem()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::HIR::TraitValueItem::TAG_##x: DEBUG("- " #x); return ::HIR::TraitValueItem::make_##x( __VA_ARGS__ );
_(Constant, deserialise_constant() )
@@ -631,7 +524,7 @@ namespace {
::HIR::AssociatedType deserialise_associatedtype()
{
return ::HIR::AssociatedType {
- read_bool(),
+ m_in.read_bool(),
"", // TODO: Better lifetime type
deserialise_vec< ::HIR::TraitPath>(),
deserialise_type()
@@ -687,21 +580,21 @@ namespace {
::HIR::TypeRef HirDeserialiser::deserialise_type()
{
TRACE_FUNCTION;
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::HIR::TypeRef::Data::TAG_##x: DEBUG("- "#x); return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_##x( __VA_ARGS__ ) );
_(Infer, {})
_(Diverge, {})
_(Primitive,
- static_cast< ::HIR::CoreType>( read_tag() )
+ static_cast< ::HIR::CoreType>( m_in.read_tag() )
)
_(Path, {
deserialise_path(),
{}
})
_(Generic, {
- read_string(),
- read_u16()
+ m_in.read_string(),
+ m_in.read_u16()
})
_(TraitObject, {
deserialise_traitpath(),
@@ -711,7 +604,7 @@ namespace {
_(Array, {
deserialise_ptr< ::HIR::TypeRef>(),
::HIR::ExprPtr(),
- read_u64c()
+ m_in.read_u64c()
})
_(Slice, {
deserialise_ptr< ::HIR::TypeRef>()
@@ -720,16 +613,16 @@ namespace {
deserialise_vec< ::HIR::TypeRef>()
)
_(Borrow, {
- static_cast< ::HIR::BorrowType>( read_tag() ),
+ static_cast< ::HIR::BorrowType>( m_in.read_tag() ),
deserialise_ptr< ::HIR::TypeRef>()
})
_(Pointer, {
- static_cast< ::HIR::BorrowType>( read_tag() ),
+ static_cast< ::HIR::BorrowType>( m_in.read_tag() ),
deserialise_ptr< ::HIR::TypeRef>()
})
_(Function, {
- read_bool(),
- read_string(),
+ m_in.read_bool(),
+ m_in.read_string(),
deserialise_ptr< ::HIR::TypeRef>(),
deserialise_vec< ::HIR::TypeRef>()
})
@@ -743,7 +636,7 @@ namespace {
{
TRACE_FUNCTION;
// HACK! If the read crate name is empty, replace it with the name we're loaded with
- auto crate_name = read_string();
+ auto crate_name = m_in.read_string();
if( crate_name == "" )
crate_name = m_crate_name;
return ::HIR::SimplePath {
@@ -778,7 +671,7 @@ namespace {
::HIR::Path HirDeserialiser::deserialise_path()
{
TRACE_FUNCTION;
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case 0:
DEBUG("Generic");
@@ -787,7 +680,7 @@ namespace {
DEBUG("Inherent");
return ::HIR::Path {
deserialise_type(),
- read_string(),
+ m_in.read_string(),
deserialise_pathparams()
};
case 2:
@@ -795,7 +688,7 @@ namespace {
return ::HIR::Path {
deserialise_type(),
deserialise_genericpath(),
- read_string(),
+ m_in.read_string(),
deserialise_pathparams()
};
default:
@@ -815,14 +708,14 @@ namespace {
::HIR::TypeParamDef HirDeserialiser::deserialise_typaramdef()
{
return ::HIR::TypeParamDef {
- read_string(),
+ m_in.read_string(),
deserialise_type(),
- read_bool()
+ m_in.read_bool()
};
}
::HIR::GenericBound HirDeserialiser::deserialise_genericbound()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case 0:
case 1:
@@ -848,13 +741,13 @@ namespace {
TRACE_FUNCTION;
return ::HIR::Enum {
deserialise_genericparams(),
- static_cast< ::HIR::Enum::Repr>(read_tag()),
+ static_cast< ::HIR::Enum::Repr>(m_in.read_tag()),
deserialise_vec< ::std::pair< ::std::string, ::HIR::Enum::Variant> >()
};
}
::HIR::Enum::Variant HirDeserialiser::deserialise_enumvariant()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case ::HIR::Enum::Variant::TAG_Unit:
return ::HIR::Enum::Variant::make_Unit({});
@@ -875,10 +768,10 @@ namespace {
{
TRACE_FUNCTION;
auto params = deserialise_genericparams();
- auto repr = static_cast< ::HIR::Struct::Repr>( read_tag() );
+ auto repr = static_cast< ::HIR::Struct::Repr>( m_in.read_tag() );
DEBUG("params = " << params.fmt_args() << params.fmt_bounds());
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case ::HIR::Struct::Data::TAG_Unit:
DEBUG("Unit");
@@ -911,7 +804,7 @@ namespace {
"", // TODO: Better type for lifetime
deserialise_vec< ::HIR::TraitPath>()
};
- rv.m_is_marker = read_bool();
+ rv.m_is_marker = m_in.read_bool();
rv.m_types = deserialise_strumap< ::HIR::AssociatedType>();
rv.m_values = deserialise_strumap< ::HIR::TraitValueItem>();
return rv;
@@ -919,19 +812,19 @@ namespace {
::HIR::Literal HirDeserialiser::deserialise_literal()
{
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::HIR::Literal::TAG_##x: return ::HIR::Literal::make_##x(__VA_ARGS__);
_(Invalid, {})
_(List, deserialise_vec< ::HIR::Literal>() )
_(Variant, {
- static_cast<unsigned int>(read_count()),
+ static_cast<unsigned int>(m_in.read_count()),
deserialise_vec< ::HIR::Literal>()
})
- _(Integer, read_u64() )
- _(Float, read_double() )
+ _(Integer, m_in.read_u64() )
+ _(Float, m_in.read_double() )
_(BorrowOf, deserialise_path() )
- _(String, read_string() )
+ _(String, m_in.read_string() )
#undef _
default:
throw "";
@@ -965,7 +858,7 @@ namespace {
{
TRACE_FUNCTION;
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
case 0:
return ::MIR::Statement::make_Assign({
@@ -974,7 +867,7 @@ namespace {
});
case 1:
return ::MIR::Statement::make_Drop({
- read_bool() ? ::MIR::eDropKind::DEEP : ::MIR::eDropKind::SHALLOW,
+ m_in.read_bool() ? ::MIR::eDropKind::DEEP : ::MIR::eDropKind::SHALLOW,
deserialise_mir_lvalue()
});
default:
@@ -985,26 +878,26 @@ namespace {
{
TRACE_FUNCTION;
- switch( read_tag() )
+ switch( m_in.read_tag() )
{
#define _(x, ...) case ::MIR::Terminator::TAG_##x: return ::MIR::Terminator::make_##x( __VA_ARGS__ );
_(Incomplete, {})
_(Return, {})
_(Diverge, {})
- _(Goto, static_cast<unsigned int>(read_count()) )
- _(Panic, { static_cast<unsigned int>(read_count()) })
+ _(Goto, static_cast<unsigned int>(m_in.read_count()) )
+ _(Panic, { static_cast<unsigned int>(m_in.read_count()) })
_(If, {
deserialise_mir_lvalue(),
- static_cast<unsigned int>(read_count()),
- static_cast<unsigned int>(read_count())
+ static_cast<unsigned int>(m_in.read_count()),
+ static_cast<unsigned int>(m_in.read_count())
})
_(Switch, {
deserialise_mir_lvalue(),
- deserialise_vec_c<unsigned int>([&](){ return read_count(); })
+ deserialise_vec_c<unsigned int>([&](){ return m_in.read_count(); })
})
_(Call, {
- static_cast<unsigned int>(read_count()),
- static_cast<unsigned int>(read_count()),
+ static_cast<unsigned int>(m_in.read_count()),
+ static_cast<unsigned int>(m_in.read_count()),
deserialise_mir_lvalue(),
deserialise_mir_lvalue(),
deserialise_vec< ::MIR::LValue>()
@@ -1036,7 +929,7 @@ namespace {
rv.m_type_impls = deserialise_vec< ::HIR::TypeImpl>();
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
for(size_t i = 0; i < n; i ++)
{
auto p = deserialise_simplepath();
@@ -1044,7 +937,7 @@ namespace {
}
}
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
for(size_t i = 0; i < n; i ++)
{
auto p = deserialise_simplepath();
@@ -1056,10 +949,10 @@ namespace {
rv.m_lang_items = deserialise_strumap< ::HIR::SimplePath>();
{
- size_t n = read_count();
+ size_t n = m_in.read_count();
for(size_t i = 0; i < n; i ++)
{
- auto ext_crate_name = read_string();
+ auto ext_crate_name = m_in.read_string();
rv.m_ext_crates.insert( ::std::make_pair(ext_crate_name, ::HIR::CratePtr{}) );
}
}
@@ -1070,7 +963,7 @@ namespace {
::HIR::CratePtr HIR_Deserialise(const ::std::string& filename, const ::std::string& loaded_name)
{
- ::std::ifstream in(filename);
+ ::HIR::serialise::Reader in { filename };
HirDeserialiser s { loaded_name, in };
try
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index 0fad2942..506245c1 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -10,135 +10,47 @@
#include <serialiser_texttree.hpp>
#include <macro_rules/macro_rules.hpp>
#include <mir/mir.hpp>
+#include "serialise_lowlevel.hpp"
namespace {
class HirSerialiser
{
- ::std::ostream& m_os;
+ ::HIR::serialise::Writer& m_out;
public:
- HirSerialiser(::std::ostream& os):
- m_os(os)
+ HirSerialiser(::HIR::serialise::Writer& out):
+ m_out( out )
{}
- void write_u8(uint8_t v) {
- m_os.write(reinterpret_cast<const char*>(&v), 1);
- }
- void write_u16(uint16_t v) {
- write_u8(v & 0xFF);
- write_u8(v >> 8);
- }
- void write_u32(uint32_t v) {
- write_u8(v & 0xFF);
- write_u8(v >> 8);
- write_u8(v >> 16);
- write_u8(v >> 24);
- }
- void write_u64(uint64_t v) {
- write_u8(v & 0xFF);
- write_u8(v >> 8);
- write_u8(v >> 16);
- write_u8(v >> 24);
- write_u8(v >> 32);
- write_u8(v >> 40);
- write_u8(v >> 48);
- write_u8(v >> 56);
- }
- // Variable-length encoded u64 (for array sizes)
- void write_u64c(uint64_t v) {
- if( v < (1<<7) ) {
- write_u8(v);
- }
- else if( v < (1<<(6+16)) ) {
- write_u8( 0x80 + (v >> 16)); // 0x80 -- 0xB0
- write_u8(v >> 8);
- write_u8(v);
- }
- else if( v < (1ul << (5 + 32)) ) {
- write_u8( 0xC0 + (v >> 32)); // 0x80 -- 0xB0
- write_u8(v >> 24);
- write_u8(v >> 16);
- write_u8(v >> 8);
- write_u8(v);
- }
- else {
- write_u8(0xFF);
- write_u64(v);
- }
- }
- void write_i64c(int64_t v) {
- // Convert from 2's completement
- bool sign = (v < 0);
- uint64_t va = (v < 0 ? -v : v);
- va <<= 1;
- va |= (sign ? 1 : 0);
- write_u64c(va);
- }
- void write_double(double v) {
- m_os.write(reinterpret_cast<const char*>(&v), sizeof v);
- }
- void write_tag(unsigned int t) {
- assert(t < 256);
- write_u8( static_cast<uint8_t>(t) );
- }
- void write_count(size_t c) {
- //DEBUG("c = " << c);
- if(c < 0xFE) {
- write_u8( static_cast<uint8_t>(c) );
- }
- else if( c == ~0u ) {
- write_u8( 0xFF );
- }
- else {
- assert(c < (1u<<16));
- write_u8( 0xFE );
- write_u16( static_cast<uint16_t>(c) );
- }
- }
- void write_string(const ::std::string& v) {
- if(v.size() < 128) {
- write_u8( static_cast<uint8_t>(v.size()) );
- }
- else {
- assert(v.size() < (1u<<(16+7)));
- write_u8( static_cast<uint8_t>(128 + (v.size() >> 16)) );
- write_u16( static_cast<uint16_t>(v.size() & 0xFFFF) );
- }
- m_os.write(v.data(), v.size());
- }
- void write_bool(bool v) {
- write_u8(v ? 0xFF : 0x00);
- }
-
template<typename V>
void serialise_strmap(const ::std::map< ::std::string,V>& map)
{
- write_count(map.size());
+ m_out.write_count(map.size());
for(const auto& v : map) {
- write_string(v.first);
+ m_out.write_string(v.first);
serialise(v.second);
}
}
template<typename V>
void serialise_strmap(const ::std::unordered_map< ::std::string,V>& map)
{
- write_count(map.size());
+ m_out.write_count(map.size());
for(const auto& v : map) {
DEBUG("- " << v.first);
- write_string(v.first);
+ m_out.write_string(v.first);
serialise(v.second);
}
}
template<typename T>
void serialise_vec(const ::std::vector<T>& vec)
{
- write_count(vec.size());
+ m_out.write_count(vec.size());
for(const auto& i : vec)
serialise(i);
}
template<typename T>
void serialise(const ::HIR::VisEnt<T>& e)
{
- write_bool(e.is_public);
+ m_out.write_bool(e.is_public);
serialise(e.ent);
}
template<typename T>
@@ -147,13 +59,13 @@ namespace {
}
template<typename T>
void serialise(const ::std::pair< ::std::string, T>& e) {
- write_string(e.first);
+ m_out.write_string(e.first);
serialise(e.second);
}
void serialise_type(const ::HIR::TypeRef& ty)
{
- write_tag( ty.m_data.tag() );
+ m_out.write_tag( ty.m_data.tag() );
TU_MATCHA( (ty.m_data), (e),
(Infer,
// BAAD
@@ -161,18 +73,18 @@ namespace {
(Diverge,
),
(Primitive,
- write_tag( static_cast<int>(e) );
+ m_out.write_tag( static_cast<int>(e) );
),
(Path,
serialise_path(e.path);
),
(Generic,
- write_string(e.name);
- write_u16(e.binding);
+ m_out.write_string(e.name);
+ m_out.write_u16(e.binding);
),
(TraitObject,
serialise_traitpath(e.m_trait);
- write_count(e.m_markers.size());
+ m_out.write_count(e.m_markers.size());
for(const auto& m : e.m_markers)
serialise_genericpath(m);
//write_string(e.lifetime); // TODO: Need a better type
@@ -180,27 +92,27 @@ namespace {
(Array,
assert(e.size_val != ~0u);
serialise_type(*e.inner);
- write_u64c(e.size_val);
+ m_out.write_u64c(e.size_val);
),
(Slice,
serialise_type(*e.inner);
),
(Tuple,
- write_count(e.size());
+ m_out.write_count(e.size());
for(const auto& st : e)
serialise_type(st);
),
(Borrow,
- write_tag(static_cast<int>(e.type));
+ m_out.write_tag(static_cast<int>(e.type));
serialise_type(*e.inner);
),
(Pointer,
- write_tag(static_cast<int>(e.type));
+ m_out.write_tag(static_cast<int>(e.type));
serialise_type(*e.inner);
),
(Function,
- write_bool(e.is_unsafe);
- write_string(e.m_abi);
+ m_out.write_bool(e.is_unsafe);
+ m_out.write_string(e.m_abi);
serialise_type(*e.m_rettype);
serialise_vec(e.m_arg_types);
),
@@ -213,14 +125,14 @@ namespace {
void serialise_simplepath(const ::HIR::SimplePath& path)
{
//TRACE_FUNCTION_F("path="<<path);
- write_string(path.m_crate_name);
- write_count(path.m_components.size());
+ m_out.write_string(path.m_crate_name);
+ m_out.write_count(path.m_components.size());
for(const auto& c : path.m_components)
- write_string(c);
+ m_out.write_string(c);
}
void serialise_pathparams(const ::HIR::PathParams& pp)
{
- write_count(pp.m_types.size());
+ m_out.write_count(pp.m_types.size());
for(const auto& t : pp.m_types)
serialise_type(t);
}
@@ -241,20 +153,20 @@ namespace {
TRACE_FUNCTION_F("path="<<path);
TU_MATCHA( (path.m_data), (e),
(Generic,
- write_tag(0);
+ m_out.write_tag(0);
serialise_genericpath(e);
),
(UfcsInherent,
- write_tag(1);
+ m_out.write_tag(1);
serialise_type(*e.type);
- write_string(e.item);
+ m_out.write_string(e.item);
serialise_pathparams(e.params);
),
(UfcsKnown,
- write_tag(2);
+ m_out.write_tag(2);
serialise_type(*e.type);
serialise_genericpath(e.trait);
- write_string(e.item);
+ m_out.write_string(e.item);
serialise_pathparams(e.params);
),
(UfcsUnknown,
@@ -272,25 +184,25 @@ namespace {
serialise_vec(params.m_bounds);
}
void serialise(const ::HIR::TypeParamDef& pd) {
- write_string(pd.m_name);
+ m_out.write_string(pd.m_name);
serialise_type(pd.m_default);
- write_bool(pd.m_is_sized);
+ m_out.write_bool(pd.m_is_sized);
}
void serialise(const ::HIR::GenericBound& b) {
TU_MATCHA( (b), (e),
(Lifetime,
- write_tag(0);
+ m_out.write_tag(0);
),
(TypeLifetime,
- write_tag(1);
+ m_out.write_tag(1);
),
(TraitBound,
- write_tag(2);
+ m_out.write_tag(2);
serialise_type(e.type);
serialise_traitpath(e.trait);
),
(TypeEquality,
- write_tag(3);
+ m_out.write_tag(3);
serialise_type(e.type);
serialise_type(e.other_type);
)
@@ -302,16 +214,16 @@ namespace {
{
serialise_module(crate.m_root_module);
- write_count(crate.m_type_impls.size());
+ m_out.write_count(crate.m_type_impls.size());
for(const auto& impl : crate.m_type_impls) {
serialise_typeimpl(impl);
}
- write_count(crate.m_trait_impls.size());
+ m_out.write_count(crate.m_trait_impls.size());
for(const auto& tr_impl : crate.m_trait_impls) {
serialise_simplepath(tr_impl.first);
serialise_traitimpl(tr_impl.second);
}
- write_count(crate.m_marker_impls.size());
+ m_out.write_count(crate.m_marker_impls.size());
for(const auto& tr_impl : crate.m_marker_impls) {
serialise_simplepath(tr_impl.first);
serialise_markerimpl(tr_impl.second);
@@ -320,9 +232,9 @@ namespace {
serialise_strmap(crate.m_exported_macros);
serialise_strmap(crate.m_lang_items);
- write_count(crate.m_ext_crates.size());
+ m_out.write_count(crate.m_ext_crates.size());
for(const auto& ext : crate.m_ext_crates)
- write_string(ext.first);
+ m_out.write_string(ext.first);
}
void serialise_module(const ::HIR::Module& mod)
{
@@ -339,18 +251,18 @@ namespace {
serialise_generics(impl.m_params);
serialise_type(impl.m_type);
- write_count(impl.m_methods.size());
+ m_out.write_count(impl.m_methods.size());
for(const auto& v : impl.m_methods) {
- write_string(v.first);
- write_bool(v.second.is_pub);
- write_bool(v.second.is_specialisable);
+ m_out.write_string(v.first);
+ m_out.write_bool(v.second.is_pub);
+ m_out.write_bool(v.second.is_specialisable);
serialise(v.second.data);
}
- write_count(impl.m_constants.size());
+ m_out.write_count(impl.m_constants.size());
for(const auto& v : impl.m_constants) {
- write_string(v.first);
- write_bool(v.second.is_pub);
- write_bool(v.second.is_specialisable);
+ m_out.write_string(v.first);
+ m_out.write_bool(v.second.is_pub);
+ m_out.write_bool(v.second.is_specialisable);
serialise(v.second.data);
}
// m_src_module doesn't matter after typeck
@@ -362,25 +274,25 @@ namespace {
serialise_pathparams(impl.m_trait_args);
serialise_type(impl.m_type);
- write_count(impl.m_methods.size());
+ m_out.write_count(impl.m_methods.size());
for(const auto& v : impl.m_methods) {
DEBUG("fn " << v.first);
- write_string(v.first);
- write_bool(v.second.is_specialisable);
+ m_out.write_string(v.first);
+ m_out.write_bool(v.second.is_specialisable);
serialise(v.second.data);
}
- write_count(impl.m_constants.size());
+ m_out.write_count(impl.m_constants.size());
for(const auto& v : impl.m_constants) {
DEBUG("const " << v.first);
- write_string(v.first);
- write_bool(v.second.is_specialisable);
+ m_out.write_string(v.first);
+ m_out.write_bool(v.second.is_specialisable);
serialise(v.second.data);
}
- write_count(impl.m_types.size());
+ m_out.write_count(impl.m_types.size());
for(const auto& v : impl.m_types) {
DEBUG("type " << v.first);
- write_string(v.first);
- write_bool(v.second.is_specialisable);
+ m_out.write_string(v.first);
+ m_out.write_bool(v.second.is_specialisable);
serialise(v.second.data);
}
// m_src_module doesn't matter after typeck
@@ -389,7 +301,7 @@ namespace {
{
serialise_generics(impl.m_params);
serialise_pathparams(impl.m_trait_args);
- write_bool(impl.is_positive);
+ m_out.write_bool(impl.is_positive);
serialise_type(impl.m_type);
}
@@ -403,7 +315,7 @@ namespace {
serialise_traitpath(p);
}
void serialise(const ::std::string& v) {
- write_string(v);
+ m_out.write_string(v);
}
void serialise(const ::MacroRulesPtr& mac)
@@ -414,12 +326,12 @@ namespace {
{
//m_exported: IGNORE, should be set
serialise_vec(mac.m_rules);
- write_string(mac.m_source_crate);
+ m_out.write_string(mac.m_source_crate);
}
void serialise(const ::MacroPatEnt& pe) {
- write_string(pe.name);
- write_count(pe.name_index);
- write_tag( static_cast<int>(pe.type) );
+ m_out.write_string(pe.name);
+ m_out.write_count(pe.name_index);
+ m_out.write_tag( static_cast<int>(pe.type) );
if( pe.type == ::MacroPatEnt::PAT_TOKEN ) {
serialise(pe.tok);
}
@@ -436,23 +348,23 @@ namespace {
void serialise(const ::MacroExpansionEnt& ent) {
TU_MATCHA( (ent), (e),
(Token,
- write_tag(0);
+ m_out.write_tag(0);
serialise(e);
),
(NamedValue,
- write_tag(1);
- write_u8(e >> 24);
- write_count(e & 0x00FFFFFF);
+ m_out.write_tag(1);
+ m_out.write_u8(e >> 24);
+ m_out.write_count(e & 0x00FFFFFF);
),
(Loop,
- write_tag(2);
+ m_out.write_tag(2);
serialise_vec(e.entries);
serialise(e.joiner);
// ::std::map<unsigned int,bool>
- write_count(e.variables.size());
+ m_out.write_count(e.variables.size());
for(const auto& var : e.variables) {
- write_count(var.first);
- write_bool(var.second);
+ m_out.write_count(var.first);
+ m_out.write_bool(var.second);
}
)
)
@@ -465,12 +377,12 @@ namespace {
tok.serialise( ser );
}
- write_string(tmp.str());
+ m_out.write_string(tmp.str());
}
void serialise(const ::HIR::Literal& lit)
{
- write_tag(lit.tag());
+ m_out.write_tag(lit.tag());
TU_MATCHA( (lit), (e),
(Invalid,
//BUG(Span(), "Literal::Invalid encountered in HIR");
@@ -479,27 +391,27 @@ namespace {
serialise_vec(e);
),
(Variant,
- write_count(e.idx);
+ m_out.write_count(e.idx);
serialise_vec(e.vals);
),
(Integer,
- write_u64(e);
+ m_out.write_u64(e);
),
(Float,
- write_double(e);
+ m_out.write_double(e);
),
(BorrowOf,
serialise_path(e);
),
(String,
- write_string(e);
+ m_out.write_string(e);
)
)
}
void serialise(const ::HIR::ExprPtr& exp)
{
- write_bool( (bool)exp.m_mir );
+ m_out.write_bool( (bool)exp.m_mir );
if( exp.m_mir ) {
serialise(*exp.m_mir);
}
@@ -520,21 +432,21 @@ namespace {
{
TU_MATCHA( (stmt), (e),
(Assign,
- write_tag(0);
+ m_out.write_tag(0);
serialise(e.dst);
serialise(e.src);
),
(Drop,
- write_tag(1);
+ m_out.write_tag(1);
assert(e.kind == ::MIR::eDropKind::DEEP || e.kind == ::MIR::eDropKind::SHALLOW);
- write_bool(e.kind == ::MIR::eDropKind::DEEP);
+ m_out.write_bool(e.kind == ::MIR::eDropKind::DEEP);
serialise(e.slot);
)
)
}
void serialise(const ::MIR::Terminator& term)
{
- write_tag( static_cast<int>(term.tag()) );
+ m_out.write_tag( static_cast<int>(term.tag()) );
TU_MATCHA( (term), (e),
(Incomplete,
// NOTE: loops that diverge (don't break) leave a dangling bb
@@ -545,25 +457,25 @@ namespace {
(Diverge,
),
(Goto,
- write_count(e);
+ m_out.write_count(e);
),
(Panic,
- write_count(e.dst);
+ m_out.write_count(e.dst);
),
(If,
serialise(e.cond);
- write_count(e.bb0);
- write_count(e.bb1);
+ m_out.write_count(e.bb0);
+ m_out.write_count(e.bb1);
),
(Switch,
serialise(e.val);
- write_count(e.targets.size());
+ m_out.write_count(e.targets.size());
for(auto t : e.targets)
- write_count(t);
+ m_out.write_count(t);
),
(Call,
- write_count(e.ret_block);
- write_count(e.panic_block);
+ m_out.write_count(e.ret_block);
+ m_out.write_count(e.panic_block);
serialise(e.ret_val);
serialise(e.fcn_val);
serialise_vec(e.args);
@@ -573,16 +485,16 @@ namespace {
void serialise(const ::MIR::LValue& lv)
{
TRACE_FUNCTION_F("LValue = "<<lv);
- write_tag( static_cast<int>(lv.tag()) );
+ m_out.write_tag( static_cast<int>(lv.tag()) );
TU_MATCHA( (lv), (e),
(Variable,
- write_count(e);
+ m_out.write_count(e);
),
(Temporary,
- write_count(e.idx);
+ m_out.write_count(e.idx);
),
(Argument,
- write_count(e.idx);
+ m_out.write_count(e.idx);
),
(Static,
serialise_path(e);
@@ -591,7 +503,7 @@ namespace {
),
(Field,
serialise(e.val);
- write_count(e.field_index);
+ m_out.write_count(e.field_index);
),
(Deref,
serialise(e.val);
@@ -602,14 +514,14 @@ namespace {
),
(Downcast,
serialise(e.val);
- write_count(e.variant_index);
+ m_out.write_count(e.variant_index);
)
)
}
void serialise(const ::MIR::RValue& val)
{
TRACE_FUNCTION_F("RValue = "<<val);
- write_tag( val.tag() );
+ m_out.write_tag( val.tag() );
TU_MATCHA( (val), (e),
(Use,
serialise(e);
@@ -619,11 +531,11 @@ namespace {
),
(SizedArray,
serialise(e.val);
- write_u64c(e.count);
+ m_out.write_u64c(e.count);
),
(Borrow,
// TODO: Region?
- write_tag( static_cast<int>(e.type) );
+ m_out.write_tag( static_cast<int>(e.type) );
serialise(e.val);
),
(Cast,
@@ -632,12 +544,12 @@ namespace {
),
(BinOp,
serialise(e.val_l);
- write_tag( static_cast<int>(e.op) );
+ m_out.write_tag( static_cast<int>(e.op) );
serialise(e.val_r);
),
(UniOp,
serialise(e.val);
- write_tag( static_cast<int>(e.op) );
+ m_out.write_tag( static_cast<int>(e.op) );
),
(DstMeta,
serialise(e.val);
@@ -660,26 +572,26 @@ namespace {
}
void serialise(const ::MIR::Constant& v)
{
- write_tag(v.tag());
+ m_out.write_tag(v.tag());
TU_MATCHA( (v), (e),
(Int,
- write_i64c(e);
+ m_out.write_i64c(e);
),
(Uint,
- write_u64c(e);
+ m_out.write_u64c(e);
),
(Float,
- write_double(e);
+ m_out.write_double(e);
),
(Bool,
- write_bool(e);
+ m_out.write_bool(e);
),
(Bytes,
- write_count(e.size());
- m_os.write( reinterpret_cast<const char*>(e.data()), e.size() );
+ m_out.write_count(e.size());
+ m_out.write( e.data(), e.size() );
),
(StaticString,
- write_string(e);
+ m_out.write_string(e);
),
(Const,
serialise_path(e.p);
@@ -694,27 +606,27 @@ namespace {
{
TU_MATCHA( (item), (e),
(Import,
- write_tag(0);
+ m_out.write_tag(0);
serialise_simplepath(e);
),
(Module,
- write_tag(1);
+ m_out.write_tag(1);
serialise_module(e);
),
(TypeAlias,
- write_tag(2);
+ m_out.write_tag(2);
serialise(e);
),
(Enum,
- write_tag(3);
+ m_out.write_tag(3);
serialise(e);
),
(Struct,
- write_tag(4);
+ m_out.write_tag(4);
serialise(e);
),
(Trait,
- write_tag(5);
+ m_out.write_tag(5);
serialise(e);
)
)
@@ -723,27 +635,27 @@ namespace {
{
TU_MATCHA( (item), (e),
(Import,
- write_tag(0);
+ m_out.write_tag(0);
serialise_simplepath(e);
),
(Constant,
- write_tag(1);
+ m_out.write_tag(1);
serialise(e);
),
(Static,
- write_tag(2);
+ m_out.write_tag(2);
serialise(e);
),
(StructConstant,
- write_tag(3);
+ m_out.write_tag(3);
serialise_simplepath(e.ty);
),
(Function,
- write_tag(4);
+ m_out.write_tag(4);
serialise(e);
),
(StructConstructor,
- write_tag(5);
+ m_out.write_tag(5);
serialise_simplepath(e.ty);
)
)
@@ -754,16 +666,16 @@ namespace {
{
TRACE_FUNCTION_F("_function:");
- write_tag( static_cast<int>(fcn.m_receiver) );
- write_string(fcn.m_abi);
- write_bool(fcn.m_unsafe);
- write_bool(fcn.m_const);
+ m_out.write_tag( static_cast<int>(fcn.m_receiver) );
+ m_out.write_string(fcn.m_abi);
+ m_out.write_bool(fcn.m_unsafe);
+ m_out.write_bool(fcn.m_const);
serialise_generics(fcn.m_params);
- write_count(fcn.m_args.size());
+ m_out.write_count(fcn.m_args.size());
for(const auto& a : fcn.m_args)
serialise(a.second);
- write_bool(fcn.m_variadic);
+ m_out.write_bool(fcn.m_variadic);
serialise(fcn.m_return);
DEBUG("m_args = " << fcn.m_args);
@@ -782,7 +694,7 @@ namespace {
{
TRACE_FUNCTION_F("_static:");
- write_bool(item.m_is_mut);
+ m_out.write_bool(item.m_is_mut);
serialise(item.m_type);
// NOTE: Omit the rest, not generic and emitted as part of the image.
}
@@ -796,12 +708,12 @@ namespace {
void serialise(const ::HIR::Enum& ta)
{
serialise_generics(ta.m_params);
- write_tag( static_cast<int>(ta.m_repr) );
+ m_out.write_tag( static_cast<int>(ta.m_repr) );
serialise_vec( ta.m_variants );
}
void serialise(const ::HIR::Enum::Variant& v)
{
- write_tag( v.tag() );
+ m_out.write_tag( v.tag() );
TU_MATCHA( (v), (e),
(Unit,
),
@@ -823,9 +735,9 @@ namespace {
TRACE_FUNCTION;
serialise_generics(item.m_params);
- write_tag( static_cast<int>(item.m_repr) );
+ m_out.write_tag( static_cast<int>(item.m_repr) );
- write_tag( item.m_data.tag() );
+ m_out.write_tag( item.m_data.tag() );
TU_MATCHA( (item.m_data), (e),
(Unit,
),
@@ -841,15 +753,15 @@ namespace {
{
TRACE_FUNCTION_F("_trait:");
serialise_generics(item.m_params);
- //write_string(item.m_lifetime); // TODO: Better type for lifetime
+ //m_out.write_string(item.m_lifetime); // TODO: Better type for lifetime
serialise_vec( item.m_parent_traits );
- write_bool( item.m_is_marker );
+ m_out.write_bool( item.m_is_marker );
serialise_strmap( item.m_types );
serialise_strmap( item.m_values );
}
void serialise(const ::HIR::TraitValueItem& tvi)
{
- write_tag( tvi.tag() );
+ m_out.write_tag( tvi.tag() );
TU_MATCHA( (tvi), (e),
(Constant,
DEBUG("Constant");
@@ -867,8 +779,8 @@ namespace {
}
void serialise(const ::HIR::AssociatedType& at)
{
- write_bool(at.is_sized);
- //write_string(at.m_lifetime_bound); // TODO: better type for lifetime
+ m_out.write_bool(at.is_sized);
+ //m_out.write_string(at.m_lifetime_bound); // TODO: better type for lifetime
serialise_vec(at.m_trait_bounds);
serialise_type(at.m_default);
}
@@ -877,7 +789,7 @@ namespace {
void HIR_Serialise(const ::std::string& filename, const ::HIR::Crate& crate)
{
- ::std::ofstream out(filename);
+ ::HIR::serialise::Writer out { filename };
HirSerialiser s { out };
s.serialise_crate(crate);
}
diff --git a/src/hir/serialise_lowlevel.cpp b/src/hir/serialise_lowlevel.cpp
new file mode 100644
index 00000000..a8f69eb2
--- /dev/null
+++ b/src/hir/serialise_lowlevel.cpp
@@ -0,0 +1,37 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * hir/serialise_lowlevel.cpp
+ * - HIR (De)Serialisation low-level "protocol"
+ */
+#include "serialise_lowlevel.hpp"
+#include <boost/iostreams/filter/zlib.hpp>
+
+::HIR::serialise::Writer::Writer(const ::std::string& filename):
+ m_backing( filename )
+{
+ m_os.push( ::boost::iostreams::zlib_compressor() );
+ m_os.push( m_backing );
+}
+
+void ::HIR::serialise::Writer::write(const void* buf, size_t len)
+{
+ m_os.write(reinterpret_cast<const char*>(buf), len);
+}
+
+
+::HIR::serialise::Reader::Reader(const ::std::string& filename):
+ m_backing( filename )
+{
+ m_is.push( ::boost::iostreams::zlib_decompressor() );
+ m_is.push( m_backing );
+}
+
+void ::HIR::serialise::Reader::read(void* buf, size_t len)
+{
+ m_is.read(reinterpret_cast<char*>(buf), len);
+ if( !m_is ) {
+ throw "";
+ }
+}
diff --git a/src/hir/serialise_lowlevel.hpp b/src/hir/serialise_lowlevel.hpp
new file mode 100644
index 00000000..34464683
--- /dev/null
+++ b/src/hir/serialise_lowlevel.hpp
@@ -0,0 +1,247 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * hir/serialise_lowlevel.hpp
+ * - HIR (De)Serialisation low-level "protocol"
+ */
+#pragma once
+
+#include <boost/iostreams/filtering_stream.hpp>
+#include <fstream>
+
+namespace HIR {
+namespace serialise {
+
+class Writer
+{
+ ::std::ofstream m_backing;
+ ::boost::iostreams::filtering_ostream m_os;
+public:
+ Writer(const ::std::string& path);
+ Writer(const Writer&) = delete;
+ Writer(Writer&&) = delete;
+
+ void write(const void* data, size_t count);
+
+ void write_u8(uint8_t v) {
+ write(reinterpret_cast<const char*>(&v), 1);
+ }
+ void write_u16(uint16_t v) {
+ uint8_t buf[] = { static_cast<uint8_t>(v & 0xFF), static_cast<uint8_t>(v >> 8) };
+ this->write(buf, 2);
+ }
+ void write_u32(uint32_t v) {
+ uint8_t buf[] = {
+ static_cast<uint8_t>(v & 0xFF), static_cast<uint8_t>(v >> 8),
+ static_cast<uint8_t>(v >> 16), static_cast<uint8_t>(v >> 24) };
+ this->write(buf, 4);
+ }
+ void write_u64(uint64_t v) {
+ uint8_t buf[] = {
+ static_cast<uint8_t>(v & 0xFF), static_cast<uint8_t>(v >> 8), static_cast<uint8_t>(v >> 16), static_cast<uint8_t>(v >> 24),
+ static_cast<uint8_t>(v >> 32), static_cast<uint8_t>(v >> 40), static_cast<uint8_t>(v >> 48), static_cast<uint8_t>(v >> 56)
+ };
+ this->write(buf, 8);
+ }
+ // Variable-length encoded u64 (for array sizes)
+ void write_u64c(uint64_t v) {
+ if( v < (1<<7) ) {
+ write_u8(v);
+ }
+ else if( v < (1<<(6+16)) ) {
+ uint8_t buf[] = {
+ static_cast<uint8_t>(0x80 + (v >> 16)), // 0x80 -- 0xBF
+ static_cast<uint8_t>(v >> 8),
+ static_cast<uint8_t>(v & 0xFF)
+ };
+ this->write(buf, sizeof buf);
+ }
+ else if( v < (1ul << (5 + 32)) ) {
+ uint8_t buf[] = {
+ static_cast<uint8_t>(0xC0 + (v >> 32)), // 0xC0 -- 0xDF
+ static_cast<uint8_t>(v >> 24),
+ static_cast<uint8_t>(v >> 16),
+ static_cast<uint8_t>(v >> 8),
+ static_cast<uint8_t>(v)
+ };
+ this->write(buf, sizeof buf);
+ }
+ else {
+ uint8_t buf[] = {
+ 0xFF,
+ static_cast<uint8_t>(v & 0xFF), static_cast<uint8_t>(v >> 8), static_cast<uint8_t>(v >> 16), static_cast<uint8_t>(v >> 24),
+ static_cast<uint8_t>(v >> 32), static_cast<uint8_t>(v >> 40), static_cast<uint8_t>(v >> 48), static_cast<uint8_t>(v >> 56)
+ };
+ this->write(buf, sizeof buf);
+ }
+ }
+ void write_i64c(int64_t v) {
+ // Convert from 2's completement
+ bool sign = (v < 0);
+ uint64_t va = (v < 0 ? -v : v);
+ va <<= 1;
+ va |= (sign ? 1 : 0);
+ write_u64c(va);
+ }
+ void write_double(double v) {
+ // - Just raw-writes the double
+ this->write(&v, sizeof v);
+ }
+ void write_tag(unsigned int t) {
+ assert(t < 256);
+ write_u8( static_cast<uint8_t>(t) );
+ }
+ void write_count(size_t c) {
+ //DEBUG("c = " << c);
+ if(c < 0xFE) {
+ write_u8( static_cast<uint8_t>(c) );
+ }
+ else if( c == ~0u ) {
+ write_u8( 0xFF );
+ }
+ else {
+ assert(c < (1u<<16));
+ write_u8( 0xFE );
+ write_u16( static_cast<uint16_t>(c) );
+ }
+ }
+ void write_string(const ::std::string& v) {
+ if(v.size() < 128) {
+ write_u8( static_cast<uint8_t>(v.size()) );
+ }
+ else {
+ assert(v.size() < (1u<<(16+7)));
+ write_u8( static_cast<uint8_t>(128 + (v.size() >> 16)) );
+ write_u16( static_cast<uint16_t>(v.size() & 0xFFFF) );
+ }
+ this->write(v.data(), v.size());
+ }
+ void write_bool(bool v) {
+ write_u8(v ? 0xFF : 0x00);
+ }
+};
+
+
+class Reader
+{
+ ::std::ifstream m_backing;
+ ::boost::iostreams::filtering_istream m_is;
+public:
+ Reader(const ::std::string& path);
+ Reader(const Writer&) = delete;
+ Reader(Writer&&) = delete;
+
+ void read(void* dst, size_t count);
+
+ uint8_t read_u8() {
+ uint8_t v;
+ read(&v, sizeof v);
+ return v;
+ }
+ uint16_t read_u16() {
+ uint8_t buf[2];
+ read(buf, sizeof buf);
+ return static_cast<uint16_t>(buf[0]) | (static_cast<uint16_t>(buf[1]) << 8);
+ }
+ uint32_t read_u32() {
+ uint8_t buf[4];
+ read(buf, sizeof buf);
+ return static_cast<uint32_t>(buf[0])
+ | (static_cast<uint32_t>(buf[1]) << 8)
+ | (static_cast<uint32_t>(buf[2]) << 16)
+ | (static_cast<uint32_t>(buf[3]) << 24)
+ ;
+ }
+ uint64_t read_u64() {
+ uint8_t buf[8];
+ read(buf, sizeof buf);
+ return static_cast<uint64_t>(buf[0])
+ | (static_cast<uint64_t>(buf[1]) << 8)
+ | (static_cast<uint64_t>(buf[2]) << 16)
+ | (static_cast<uint64_t>(buf[3]) << 24)
+ | (static_cast<uint64_t>(buf[4]) << 32)
+ | (static_cast<uint64_t>(buf[5]) << 40)
+ | (static_cast<uint64_t>(buf[6]) << 48)
+ | (static_cast<uint64_t>(buf[7]) << 56)
+ ;
+ }
+ // Variable-length encoded u64 (for array sizes)
+ uint64_t read_u64c() {
+ auto v = read_u8();
+ if( v < (1<<7) ) {
+ return static_cast<uint64_t>(v);
+ }
+ else if( v < 0xC0 ) {
+ uint64_t rv = static_cast<uint64_t>(v & 0x3F) << 16;
+ rv |= static_cast<uint64_t>(read_u8()) << 8;
+ rv |= static_cast<uint64_t>(read_u8());
+ return rv;
+ }
+ else if( v < 0xFF ) {
+ uint64_t rv = static_cast<uint64_t>(v & 0x3F) << 32;
+ rv |= static_cast<uint64_t>(read_u8()) << 24;
+ rv |= static_cast<uint64_t>(read_u8()) << 16;
+ rv |= static_cast<uint64_t>(read_u8()) << 8;
+ rv |= static_cast<uint64_t>(read_u8());
+ return rv;
+ }
+ else {
+ return read_u64();
+ }
+ }
+ int64_t read_i64c() {
+ uint64_t va = read_u64c();
+ bool sign = (va & 0x1) != 0;
+ va >>= 1;
+
+ if( va == 0 && sign ) {
+ return INT64_MIN;
+ }
+ else if( sign ) {
+ return -static_cast<int64_t>(va);
+ }
+ else {
+ return -static_cast<uint64_t>(va);
+ }
+ }
+ double read_double() {
+ double v;
+ read(reinterpret_cast<char*>(&v), sizeof v);
+ return v;
+ }
+ unsigned int read_tag() {
+ return static_cast<unsigned int>( read_u8() );
+ }
+ size_t read_count() {
+ auto v = read_u8();
+ if( v < 0xFE ) {
+ return v;
+ }
+ else if( v == 0xFE ) {
+ return read_u16( );
+ }
+ else /*if( v == 0xFF )*/ {
+ return ~0u;
+ }
+ }
+ ::std::string read_string() {
+ size_t len = read_u8();
+ if( len < 128 ) {
+ }
+ else {
+ len = (len & 0x7F) << 16;
+ len |= read_u16();
+ }
+ ::std::string rv(len, '\0');
+ read( const_cast<char*>(rv.data()), len);
+ return rv;
+ }
+ bool read_bool() {
+ return read_u8() != 0x00;
+ }
+};
+
+} // namespace serialise
+} // namespace HIR
+