vm_parse.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include "vm_parse.h"
  2. namespace NSc::NUt {
  3. #define Y_TRY_READ_BITS(state, out, bits, res) do { if (!state.Input.Read(out, bits)) { return res; } } while (false)
  4. #define Y_TRY_READ_BITS_BOOL(state, out, bits) Y_TRY_READ_BITS(state, out, bits, false)
  5. #define Y_TRY_READ_BITS_MAYBE(state, out, bits) Y_TRY_READ_BITS(state, out, bits, Nothing())
  6. TMaybe<TIdx> ParseIdx(TVMState& st) {
  7. static_assert(IsPowerOf2(TIdx::ValueCount));
  8. static const auto bits = GetCountWidth(TIdx::ValueCount);
  9. TIdx idx;
  10. if (!st.Input.Read(idx.Idx, bits)) {
  11. return Nothing();
  12. }
  13. return idx;
  14. }
  15. namespace {
  16. bool DoParsePos(TVMState& st, TPos& pos) {
  17. static const auto bits = GetCountWidth(TPos::ValueCount);
  18. const ui32 sz = st.Memory.size();
  19. ui32 neg = -1;
  20. Y_TRY_READ_BITS_BOOL(st, neg, 1);
  21. ui32 delta = -1;
  22. Y_TRY_READ_BITS_BOOL(st, delta, bits);
  23. if (neg) {
  24. if (st.Pos < delta) {
  25. return false;
  26. }
  27. pos.Pos = st.Pos - delta;
  28. } else {
  29. if (st.Pos + delta >= sz) {
  30. return false;
  31. }
  32. pos.Pos = st.Pos + delta;
  33. }
  34. return true;
  35. }
  36. template <class T>
  37. bool DoParseType(TVMState& state, T& res) {
  38. static const auto bits = GetCountWidth(T::TypeCount);
  39. ui32 type = -1;
  40. if (state.Input.Read(type, bits) && type < T::TypeCount) {
  41. res.Type = (typename T::EType)(type);
  42. return true;
  43. } else {
  44. return false;
  45. }
  46. }
  47. }
  48. TMaybe<TPos> ParsePos(TVMState& state) {
  49. TPos res;
  50. if (DoParsePos(state, res)) {
  51. return res;
  52. }
  53. return Nothing();
  54. }
  55. TMaybe<TRef> ParseRef(TVMState& state) {
  56. TRef ref;
  57. if (!DoParseType(state, ref)) {
  58. return Nothing();
  59. }
  60. switch (ref.Type) {
  61. case TRef::T_REF__POS:
  62. if (!DoParsePos(state, ref)) {
  63. return Nothing();
  64. }
  65. [[fallthrough]];
  66. case TRef::T_CREATE_FRONT:
  67. case TRef::T_CREATE_BACK:
  68. return ref;
  69. default:
  70. Y_ABORT();
  71. }
  72. }
  73. TMaybe<TSrc> ParseSrc(TVMState& state) {
  74. TSrc src;
  75. if (!DoParseType(state, src)) {
  76. return Nothing();
  77. }
  78. switch (src.Type) {
  79. case TSrc::T_LREF__POS:
  80. case TSrc::T_CREF__POS:
  81. case TSrc::T_RREF__POS:
  82. if (!DoParsePos(state, src)) {
  83. return Nothing();
  84. }
  85. return src;
  86. default:
  87. Y_ABORT();
  88. }
  89. }
  90. TMaybe<TDst> ParseDst(TVMState& state) {
  91. TDst dst;
  92. if (!DoParseType(state, dst)) {
  93. return Nothing();
  94. }
  95. switch (dst.Type) {
  96. case TDst::T_LREF__POS:
  97. case TDst::T_CREF__POS:
  98. case TDst::T_RREF__POS:
  99. if (!DoParsePos(state, dst)) {
  100. return Nothing();
  101. }
  102. [[fallthrough]];
  103. case TDst::T_CREATE_FRONT_LREF:
  104. case TDst::T_CREATE_FRONT_CREF:
  105. case TDst::T_CREATE_FRONT_RREF:
  106. case TDst::T_CREATE_BACK_LREF:
  107. case TDst::T_CREATE_BACK_CREF:
  108. case TDst::T_CREATE_BACK_RREF:
  109. return dst;
  110. default:
  111. Y_ABORT();
  112. }
  113. }
  114. TMaybe<TPath> ParsePath(TVMState& state) {
  115. static const ui32 bits = GetCountWidth(TPath::MaxLength);
  116. TPath path;
  117. ui32 len = -1;
  118. Y_TRY_READ_BITS_MAYBE(state, len, bits);
  119. while (len--) {
  120. ui8 c;
  121. Y_TRY_READ_BITS_MAYBE(state, c, 8);
  122. path.Path.push_back(c);
  123. }
  124. return path;
  125. }
  126. TMaybe<TVMAction> ParseNextAction(TVMState& state) {
  127. TVMAction res;
  128. if (!DoParseType(state, res)) {
  129. return Nothing();
  130. }
  131. switch (res.Type) {
  132. case VMA_CREATE_BACK:
  133. case VMA_CREATE_FRONT:
  134. case VMA_DESTROY_BACK:
  135. case VMA_DESTROY_FRONT:
  136. case VMA_SET_DICT:
  137. case VMA_SET_ARRAY:
  138. case VMA_SET_NULL:
  139. case VMA_GET_JSON:
  140. case VMA_ARRAY_CLEAR:
  141. case VMA_ARRAY_PUSH:
  142. case VMA_DICT_CLEAR:
  143. return res;
  144. case VMA_JMP__POS:
  145. case VMA_MERGE_UPDATE__POS:
  146. case VMA_MERGE_REVERSE__POS:
  147. case VMA_MERGE_COPY_FROM__POS:
  148. case VMA_SWAP__POS:
  149. if (res.SetArg(ParsePos(state))) {
  150. return res;
  151. } else {
  152. return Nothing();
  153. }
  154. case VMA_ARRAY_POP__REF:
  155. if (res.SetArg(ParseRef(state))) {
  156. return res;
  157. } else {
  158. return Nothing();
  159. }
  160. case VMA_SET_STRING__IDX:
  161. case VMA_SET_INT_NUMBER__IDX:
  162. case VMA_ARRAY_INSERT__IDX:
  163. case VMA_ARRAY_GET_OR_ADD__IDX:
  164. case VMA_DICT_GET_OR_ADD__IDX:
  165. if (res.SetArg(ParseIdx(state))) {
  166. return res;
  167. } else {
  168. return Nothing();
  169. }
  170. case VMA_CREATE_BACK__SRC:
  171. case VMA_CREATE_FRONT__SRC:
  172. case VMA_ASSIGN__SRC:
  173. case VMA_ARRAY_PUSH__SRC:
  174. if (res.SetArg(ParseSrc(state))) {
  175. return res;
  176. } else {
  177. return Nothing();
  178. }
  179. case VMA_ARRAY_PUSH__DST:
  180. if (res.SetArg(ParseDst(state))) {
  181. return res;
  182. } else {
  183. return Nothing();
  184. }
  185. case VMA_ARRAY_DELETE__IDX_REF:
  186. case VMA_ARRAY_GET__IDX_REF:
  187. case VMA_ARRAY_GET_NO_ADD__IDX_REF:
  188. case VMA_DICT_DELETE__IDX_REF:
  189. case VMA_DICT_GET__IDX_REF:
  190. case VMA_DICT_GET_NO_ADD__IDX_REF:
  191. if (res.SetArg(ParseIdx(state)) && res.SetArg(ParseRef(state))) {
  192. return res;
  193. } else {
  194. return Nothing();
  195. }
  196. case VMA_ARRAY_INSERT__IDX_SRC:
  197. case VMA_ARRAY_GET_OR_ADD__IDX_SRC:
  198. case VMA_DICT_GET_OR_ADD__IDX_SRC:
  199. if (res.SetArg(ParseIdx(state)) && res.SetArg(ParseSrc(state))) {
  200. return res;
  201. } else {
  202. return Nothing();
  203. }
  204. case VMA_ARRAY_INSERT__IDX_DST:
  205. case VMA_ARRAY_GET_OR_ADD__IDX_DST:
  206. case VMA_DICT_GET_OR_ADD__IDX_DST:
  207. if (res.SetArg(ParseIdx(state)) && res.SetArg(ParseDst(state))) {
  208. return res;
  209. } else {
  210. return Nothing();
  211. }
  212. case VMA_EQUAL__POS_POS:
  213. if (res.SetArg(ParsePos(state)) && res.SetArg(ParsePos(state))) {
  214. return res;
  215. } else {
  216. return Nothing();
  217. }
  218. case VMA_SELECT_NO_ADD__PATH_REF:
  219. case VMA_SELECT_OR_ADD__PATH_REF:
  220. case VMA_SELECT_AND_DELETE__PATH_REF:
  221. if (res.SetArg(ParsePath(state)) && res.SetArg(ParseRef(state))) {
  222. return res;
  223. } else {
  224. return Nothing();
  225. }
  226. default:
  227. return Nothing();
  228. }
  229. }
  230. }