212 lines · 4.9 KB · C++
RawDownload
//// Dis VM// File: type_signature.cpp// Author: arr// #include <array>#include <vm_asm_sigkind.h>#include "rfc1321/global.h"#include "rfc1321/md5.h" using disvm::assembly::sigkind::sig_stream_t;using disvm::assembly::sigkind::Tadt_pick_tag;using disvm::assembly::sigkind::Tfixed;using disvm::assembly::sigkind::Tm;using disvm::assembly::sigkind::Ttype_ref; namespace{    // Compute the signature of the type using the MD5 checksum.    // Based on the implementation from the Limbo compiler.    // Source: limbo/types.c    uint32_t _compute_sig(std::string &str)    {        MD5_CTX context;        MD5Init(&context);         MD5Update(&context, reinterpret_cast<unsigned char *>(const_cast<char *>(str.data())), str.length());         std::array<uint8_t, 16> checksum;        MD5Final(checksum.data(), &context);         auto sig = uint32_t{ 0 };        for (auto i = std::size_t{ 0 }; i < checksum.size(); i += 4)            sig ^= checksum[i] | (checksum[i + 1] << 8) | (checksum[i + 2] << 16) | (checksum[i + 3] << 24);         return sig;    }} uint32_t sig_stream_t::compute_signature_hash(const char *sig){    std::string sig_local{ sig };    return _compute_sig(sig_local);} std::string sig_stream_t::get_signature() const{    return _ss.str();} uint32_t sig_stream_t::get_signature_hash() const{    auto sig_str = get_signature();    return _compute_sig(sig_str);} sig_stream_t &sig_stream_t::operator<<(const char c){    _ss << c;    return *this;} sig_stream_t &sig_stream_t::operator<<(const char *s){    _ss << s;    return *this;} sig_stream_t &sig_stream_t::operator<<(const uint32_t i){    _ss << i;    return *this;} sig_stream_t &sig_stream_t::operator<<(const sig_stream_t &ss){    _ss << ss._ss.rdbuf();     // Reset the input stream so it can be inserted in another stream.    ss._ss.seekg(0);    return *this;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const modifier_id_t &id){    return os << static_cast<char>(id);} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const type_id_t &id){    assert(id != type_id_t::unknown);     if (id == type_id_t::function_varargs)        return os << "f*";     return os << static_cast<char>(id);} Tfixed::Tfixed(double scale)    : _scale{ scale }{ } sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tfixed &f){    char buffer[32];    ::sprintf(buffer, "%g", f._scale);    return os << Tfixed::id << buffer;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tarray &a){    return os << a._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tref &r){    return os << r._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tlist &l){    return os << l._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tchannel &c){    return os << c._s;} const char Ttype_ref::id = '@'; Ttype_ref::Ttype_ref(uint32_t num)    : _num{ num }{ } sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttype_ref &r){    return os << Tref::id << r._num;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tm &m){    return os << m._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttuple &t){    return os << t._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tmodule &m){    return os << m._s;} Tadt_pick_tag Tadt_pick_tag::create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms){    sig_stream_t ss;    ss << pick_tag << Tadt_pick_tag::tag_delim() << Tbasic_type::id << Tadt_pick_tag::begin();     auto tm = tms.begin();    for (auto c = 0; tm != tms.end(); tm++, c++)    {        if (c > 0)            ss << sig_stream_t::delim();         ss << *tm;    }     ss << Tadt_pick_tag::end() << Tref::id << adt_ref;     return Tadt_pick_tag{ ss };} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tadt_pick_tag &t){    return os << t._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tnested_aggregate_type<type_id_t::adt> &a){    return os << a._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, Tfunction &f){    if (!f._fully_defined)        f.returns(Tnone::id);     return os << f._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tfunction &f){    assert(f._fully_defined && "Incomplete function");    return os << f._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, Tfunction_varargs &f){    if (!f._fully_defined)        f.returns(Tnone::id);     return os << f._s;} sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tfunction_varargs &f){    assert(f._fully_defined && "Incomplete function");    return os << f._s;}