reader.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Author: simon
  2. // Author: ynwdlxm@163.com
  3. // Date: 2024/4/5 17:02
  4. // Desc:
  5. package binchunk
  6. import (
  7. "encoding/binary"
  8. "math"
  9. )
  10. type reader struct {
  11. data []byte
  12. }
  13. func (r *reader) checkHeader() {
  14. if string(r.readBytes(4)) != LUA_SIGNATURE {
  15. panic("not a precompiled chunk!")
  16. } else if r.readByte() != LUAC_VERSION {
  17. panic("version mismatch!")
  18. } else if r.readByte() != LUAC_FORMAT {
  19. panic("format mismatch!")
  20. } else if string(r.readBytes(6)) != LUAC_DATA {
  21. panic("corrupted!")
  22. } else if r.readByte() != CINT_SIZE {
  23. panic("int size mismatch!")
  24. } else if r.readByte() != CSZIET_SIZE {
  25. panic("size_t size mismatch!")
  26. } else if r.readByte() != INSTRUCTION_SIZE {
  27. panic("instruction size mismatch!")
  28. } else if r.readByte() != LUA_INTEGER_SIZE {
  29. panic("lua_Integer size mismatch!")
  30. } else if r.readByte() != LUA_NUMBER_SIZE {
  31. panic("lua_number size mismatch!")
  32. } else if r.readLuaInteger() != LUAC_INT {
  33. panic("endianness mismatch!")
  34. } else if r.readLuaNumber() != LUAC_NUM {
  35. panic("float format mismatch")
  36. }
  37. }
  38. func (r *reader) readByte() byte {
  39. b := r.data[0]
  40. r.data = r.data[1:]
  41. return b
  42. }
  43. func (r *reader) readUint32() uint32 {
  44. i := binary.LittleEndian.Uint32(r.data)
  45. r.data = r.data[4:]
  46. return i
  47. }
  48. func (r *reader) readUint64() uint64 {
  49. i := binary.LittleEndian.Uint64(r.data)
  50. r.data = r.data[8:]
  51. return i
  52. }
  53. func (r *reader) readLuaInteger() int64 {
  54. return int64(r.readUint64())
  55. }
  56. func (r *reader) readLuaNumber() float64 {
  57. return math.Float64frombits(r.readUint64())
  58. }
  59. func (r *reader) readString() string {
  60. size := uint(r.readByte())
  61. if size == 0 {
  62. // NUll 字符串
  63. return ""
  64. }
  65. if size == 0XFF {
  66. // 长字符串
  67. size = uint(r.readUint64())
  68. }
  69. bytes := r.readBytes(size - 1)
  70. return string(bytes)
  71. }
  72. func (r *reader) readBytes(n uint) []byte {
  73. bytes := r.data[:n]
  74. r.data = r.data[n:]
  75. return bytes
  76. }
  77. func (r *reader) readProto(parentSource string) *Prototype {
  78. source := r.readString()
  79. if source == "" {
  80. source = parentSource
  81. }
  82. return &Prototype{
  83. Source: source,
  84. LineDefined: r.readUint32(),
  85. LastLineDefined: r.readUint32(),
  86. NumParams: r.readByte(),
  87. IsVararg: r.readByte(),
  88. MaxStackSize: r.readByte(),
  89. Code: r.readCode(),
  90. Constants: r.readConstants(),
  91. Upvalues: r.readUpvalues(),
  92. Protos: r.readProtos(source),
  93. LineInfo: r.readLineInfo(),
  94. LocVars: r.readLocVars(),
  95. UpvalueNames: r.readUpvalueNames(),
  96. }
  97. }
  98. func (r *reader) readCode() []uint32 {
  99. code := make([]uint32, r.readUint32())
  100. for i := range code {
  101. code[i] = r.readUint32()
  102. }
  103. return code
  104. }
  105. func (r *reader) readConstants() []interface{} {
  106. constants := make([]interface{}, r.readUint32())
  107. for i := range constants {
  108. constants[i] = r.readConstant()
  109. }
  110. return constants
  111. }
  112. func (r *reader) readConstant() interface{} {
  113. switch r.readByte() { // tag
  114. case TAG_NIL:
  115. return nil
  116. case TAG_BOOLEAN:
  117. return r.readByte() != 0
  118. case TAG_INTEGER:
  119. return r.readLuaInteger()
  120. case TAG_NUMBER:
  121. return r.readLuaNumber()
  122. case TAG_SHORT_STR:
  123. return r.readString()
  124. case TAG_LONG_STR:
  125. return r.readString()
  126. default:
  127. panic("corrupted!")
  128. }
  129. }
  130. func (r *reader) readUpvalues() []Upvalue {
  131. upvalues := make([]Upvalue, r.readUint32())
  132. for i := range upvalues {
  133. upvalues[i] = Upvalue{
  134. Instack: r.readByte(),
  135. Idx: r.readByte(),
  136. }
  137. }
  138. return upvalues
  139. }
  140. func (r *reader) readProtos(parentSource string) []*Prototype {
  141. protos := make([]*Prototype, r.readUint32())
  142. for i := range protos {
  143. protos[i] = r.readProto(parentSource)
  144. }
  145. return protos
  146. }
  147. func (r *reader) readLineInfo() []uint32 {
  148. lineInfo := make([]uint32, r.readUint32())
  149. for i := range lineInfo {
  150. lineInfo[i] = r.readUint32()
  151. }
  152. return lineInfo
  153. }
  154. func (r *reader) readLocVars() []LocVar {
  155. locVars := make([]LocVar, r.readUint32())
  156. for i := range locVars {
  157. locVars[i] = LocVar{
  158. VarName: r.readString(),
  159. StartPC: r.readUint32(),
  160. EndPC: r.readUint32(),
  161. }
  162. }
  163. return locVars
  164. }
  165. func (r *reader) readUpvalueNames() []string {
  166. names := make([]string, r.readUint32())
  167. for i := range names {
  168. names[i] = r.readString()
  169. }
  170. return names
  171. }