reader.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package ops
  3. import (
  4. "encoding/binary"
  5. )
  6. // Reader parses an ops list.
  7. type Reader struct {
  8. pc PC
  9. stack []macro
  10. ops *Ops
  11. deferOps Ops
  12. deferDone bool
  13. }
  14. // EncodedOp represents an encoded op returned by
  15. // Reader.
  16. type EncodedOp struct {
  17. Key Key
  18. Data []byte
  19. Refs []interface{}
  20. }
  21. // Key is a unique key for a given op.
  22. type Key struct {
  23. ops *Ops
  24. pc uint32
  25. version uint32
  26. }
  27. // Shadow of op.MacroOp.
  28. type macroOp struct {
  29. ops *Ops
  30. start PC
  31. end PC
  32. }
  33. // PC is an instruction counter for an operation list.
  34. type PC struct {
  35. data uint32
  36. refs uint32
  37. }
  38. type macro struct {
  39. ops *Ops
  40. retPC PC
  41. endPC PC
  42. }
  43. type opMacroDef struct {
  44. endpc PC
  45. }
  46. func (pc PC) Add(op OpType) PC {
  47. size, numRefs := op.props()
  48. return PC{
  49. data: pc.data + size,
  50. refs: pc.refs + numRefs,
  51. }
  52. }
  53. // Reset start reading from the beginning of ops.
  54. func (r *Reader) Reset(ops *Ops) {
  55. r.ResetAt(ops, PC{})
  56. }
  57. // ResetAt is like Reset, except it starts reading from pc.
  58. func (r *Reader) ResetAt(ops *Ops, pc PC) {
  59. r.stack = r.stack[:0]
  60. Reset(&r.deferOps)
  61. r.deferDone = false
  62. r.pc = pc
  63. r.ops = ops
  64. }
  65. func (r *Reader) Decode() (EncodedOp, bool) {
  66. if r.ops == nil {
  67. return EncodedOp{}, false
  68. }
  69. deferring := false
  70. for {
  71. if len(r.stack) > 0 {
  72. b := r.stack[len(r.stack)-1]
  73. if r.pc == b.endPC {
  74. r.ops = b.ops
  75. r.pc = b.retPC
  76. r.stack = r.stack[:len(r.stack)-1]
  77. continue
  78. }
  79. }
  80. data := r.ops.data
  81. data = data[r.pc.data:]
  82. refs := r.ops.refs
  83. if len(data) == 0 {
  84. if r.deferDone {
  85. return EncodedOp{}, false
  86. }
  87. r.deferDone = true
  88. // Execute deferred macros.
  89. r.ops = &r.deferOps
  90. r.pc = PC{}
  91. continue
  92. }
  93. key := Key{ops: r.ops, pc: r.pc.data, version: r.ops.version}
  94. t := OpType(data[0])
  95. n, nrefs := t.props()
  96. data = data[:n]
  97. refs = refs[r.pc.refs:]
  98. refs = refs[:nrefs]
  99. switch t {
  100. case TypeDefer:
  101. deferring = true
  102. r.pc.data += n
  103. r.pc.refs += nrefs
  104. continue
  105. case TypeAux:
  106. // An Aux operations is always wrapped in a macro, and
  107. // its length is the remaining space.
  108. block := r.stack[len(r.stack)-1]
  109. n += block.endPC.data - r.pc.data - TypeAuxLen
  110. data = data[:n]
  111. case TypeCall:
  112. if deferring {
  113. deferring = false
  114. // Copy macro for deferred execution.
  115. if nrefs != 1 {
  116. panic("internal error: unexpected number of macro refs")
  117. }
  118. deferData := Write1(&r.deferOps, int(n), refs[0])
  119. copy(deferData, data)
  120. r.pc.data += n
  121. r.pc.refs += nrefs
  122. continue
  123. }
  124. var op macroOp
  125. op.decode(data, refs)
  126. retPC := r.pc
  127. retPC.data += n
  128. retPC.refs += nrefs
  129. r.stack = append(r.stack, macro{
  130. ops: r.ops,
  131. retPC: retPC,
  132. endPC: op.end,
  133. })
  134. r.ops = op.ops
  135. r.pc = op.start
  136. continue
  137. case TypeMacro:
  138. var op opMacroDef
  139. op.decode(data)
  140. if op.endpc != (PC{}) {
  141. r.pc = op.endpc
  142. } else {
  143. // Treat an incomplete macro as containing all remaining ops.
  144. r.pc.data = uint32(len(r.ops.data))
  145. r.pc.refs = uint32(len(r.ops.refs))
  146. }
  147. continue
  148. }
  149. r.pc.data += n
  150. r.pc.refs += nrefs
  151. return EncodedOp{Key: key, Data: data, Refs: refs}, true
  152. }
  153. }
  154. func (op *opMacroDef) decode(data []byte) {
  155. if len(data) < TypeMacroLen || OpType(data[0]) != TypeMacro {
  156. panic("invalid op")
  157. }
  158. bo := binary.LittleEndian
  159. data = data[:TypeMacroLen]
  160. op.endpc.data = bo.Uint32(data[1:])
  161. op.endpc.refs = bo.Uint32(data[5:])
  162. }
  163. func (m *macroOp) decode(data []byte, refs []interface{}) {
  164. if len(data) < TypeCallLen || len(refs) < 1 || OpType(data[0]) != TypeCall {
  165. panic("invalid op")
  166. }
  167. bo := binary.LittleEndian
  168. data = data[:TypeCallLen]
  169. m.ops = refs[0].(*Ops)
  170. m.start.data = bo.Uint32(data[1:])
  171. m.start.refs = bo.Uint32(data[5:])
  172. m.end.data = bo.Uint32(data[9:])
  173. m.end.refs = bo.Uint32(data[13:])
  174. }