Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
952
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.03 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement