SHARE
TWEET

Untitled

a guest Sep 20th, 2019 85 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Mathias Pedersen 2019 */
  2.  
  3. #include <Serializer.hpp>
  4. #include <VectorStream.hpp>
  5. #include <Compiler.hpp>
  6. #include <InstructionConverter.hpp>
  7. #include <unordered_map>
  8. #include <iostream>
  9.  
  10. extern "C"
  11. {
  12. #include <Lua/lauxlib.h>
  13. #include <Lua/lobject.h>
  14. #include <Lua/lstring.h>
  15. }
  16.  
  17. void writeProto(VectorStream& vs, std::unordered_map<TString*, int>& stringTable, std::unordered_map<Proto*, int>& protoTable, Proto* p);
  18.  
  19. class StringTable
  20. {
  21.     VectorStream& vs;
  22.    
  23.     size_t stringCount = 1;
  24.     std::unordered_map<TString*, int> stringMap;
  25.     std::vector<TString*> strings;
  26.  
  27.     void getProtoStrings(Proto* p)
  28.     {
  29.         for (int i = 0; i < p->sizek; i++)
  30.         {
  31.             if (p->k[i].tt == LUA_TSTRING)
  32.                 insert(&p->k[i].value.gc->ts);
  33.         }
  34.  
  35.         for (int i = 0; i < p->sizep; i++)
  36.             getProtoStrings(p->p[i]);
  37.     }
  38.  
  39. public:
  40.     void insert(TString* ts)
  41.     {
  42.         if (stringMap.find(ts) != stringMap.end())
  43.             return;
  44.         stringMap[ts] = stringCount++;
  45.         strings.push_back(ts);
  46.     }
  47.  
  48.     std::unordered_map<TString*, int> write(Proto* p)
  49.     {
  50.         getProtoStrings(p);
  51.  
  52.         vs.writeCompressedInt(strings.size());
  53.         for (TString* ts : strings)
  54.             vs.writeString(std::string(getstr(ts), ts->tsv.len));
  55.  
  56.         return stringMap;
  57.     }
  58.  
  59.     StringTable(VectorStream& vs) : vs(vs) {}
  60. };
  61.  
  62. class ProtoTable
  63. {
  64.     VectorStream& vs;
  65.  
  66.     size_t protoCount = 0;
  67.     std::unordered_map<Proto*, int> protoMap;
  68.     std::vector<Proto*> protos;
  69.  
  70.     void addProto(Proto* p)
  71.     {
  72.         for (int i = 0; i < p->sizep; i++)
  73.             addProto(p->p[i]);
  74.  
  75.         protoMap[p] = protoCount++;
  76.         protos.push_back(p);
  77.     }
  78.  
  79. public:
  80.     std::unordered_map<Proto*, int> write(Proto* p, std::unordered_map<TString*, int>& stringTable)
  81.     {
  82.         addProto(p);
  83.  
  84.         vs.writeCompressedInt(protos.size());
  85.         for (Proto* np : protos)
  86.             writeProto(vs, stringTable, protoMap, np);
  87.  
  88.         return protoMap;
  89.     }
  90.  
  91.     ProtoTable(VectorStream& vs) : vs(vs) {}
  92. };
  93.  
  94. enum ConstantType
  95. {
  96.     ConstantNil,
  97.     ConstantBoolean,
  98.     ConstantNumber,
  99.     ConstantString
  100. };
  101.  
  102. void writeProto(VectorStream& vs, std::unordered_map<TString*, int>& stringTable, std::unordered_map<Proto*, int>& protoTable, Proto* p)
  103. {
  104.     vs.writeByte(p->maxstacksize);
  105.     vs.writeByte(p->numparams);
  106.     vs.writeByte(p->nups);
  107.     vs.writeByte(p->is_vararg);
  108.  
  109.     InstructionConverter ic(p);
  110.     std::vector<Instruction> instructions = ic.convertInstructions();
  111.  
  112.     /* Instructions */
  113.     vs.writeCompressedInt(instructions.size());
  114.     for (size_t i = 0; i < instructions.size(); i++)
  115.         vs.writeInt(instructions[i]);
  116.  
  117.     /* Constants */
  118.     vs.writeCompressedInt(p->sizek);
  119.     for (int i = 0; i < p->sizek; i++)
  120.     {
  121.         TValue* k = &p->k[i];
  122.         switch (k->tt)
  123.         {
  124.         case LUA_TNIL:
  125.         {
  126.             vs.writeByte(ConstantNil);
  127.             break;
  128.         }
  129.         case LUA_TBOOLEAN:
  130.         {
  131.             vs.writeByte(ConstantBoolean);
  132.             vs.writeByte(k->value.b);
  133.             break;
  134.         }
  135.         case LUA_TNUMBER:
  136.         {
  137.             vs.writeByte(ConstantNumber);
  138.             vs.writeDouble(k->value.n);
  139.             break;
  140.         }
  141.         case LUA_TSTRING:
  142.         {
  143.             vs.writeByte(ConstantString);
  144.             vs.writeCompressedInt(stringTable[rawtsvalue(k)]);
  145.             break;
  146.         }
  147.         }
  148.     }
  149.  
  150.     /* Prototypes */
  151.     vs.writeCompressedInt(p->sizep);
  152.     for (int i = 0; i < p->sizep; i++)
  153.         vs.writeCompressedInt(protoTable[p->p[i]]);
  154.  
  155.     /* Some string index */
  156.     vs.writeCompressedInt(1);
  157.  
  158.     /* Lineinfo */
  159.     vs.writeCompressedInt(instructions.size());
  160.     for (size_t i = 0; i < instructions.size(); i++)
  161.         vs.writeCompressedInt(0);
  162.  
  163.     /* Write 0 for no debug info */
  164.     vs.writeByte(0);
  165. }
  166.  
  167. std::string serialize(lua_State* L, const std::string& source)
  168. {
  169.     VectorStream vs;
  170.  
  171.     const LClosure* cl = Compiler::compile(L, source);
  172.     if (cl == nullptr)
  173.     {
  174.         vs.writeByte(0);
  175.         vs.writeString(lua_tostring(L, -1));
  176.         return vs.str();
  177.     }
  178.  
  179.     vs.writeByte(1);
  180.  
  181.     /* Write string table */
  182.     StringTable st(vs);
  183.     st.insert(luaS_new(L, ""));
  184.     std::unordered_map<TString*, int> stringTable = st.write(cl->p);
  185.  
  186.     /* Write proto table */
  187.     ProtoTable pt(vs);
  188.     std::unordered_map<Proto*, int> protoTable = pt.write(cl->p, stringTable);
  189.  
  190.     /* Entry point in proto table */
  191.     vs.writeCompressedInt(protoTable[cl->p]);
  192.  
  193.     return vs.str();
  194. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top