value.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package lua
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. )
  7. type LValueType int
  8. const (
  9. LTNil LValueType = iota
  10. LTBool
  11. LTNumber
  12. LTString
  13. LTFunction
  14. LTUserData
  15. LTThread
  16. LTTable
  17. LTChannel
  18. )
  19. var lValueNames = [9]string{"nil", "boolean", "number", "string", "function", "userdata", "thread", "table", "channel"}
  20. func (vt LValueType) String() string {
  21. return lValueNames[int(vt)]
  22. }
  23. type LValue interface {
  24. String() string
  25. Type() LValueType
  26. // to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
  27. assertFloat64() (float64, bool)
  28. // to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
  29. assertString() (string, bool)
  30. // to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
  31. assertFunction() (*LFunction, bool)
  32. }
  33. // LVIsFalse returns true if a given LValue is a nil or false otherwise false.
  34. func LVIsFalse(v LValue) bool { return v == LNil || v == LFalse }
  35. // LVIsFalse returns false if a given LValue is a nil or false otherwise true.
  36. func LVAsBool(v LValue) bool { return v != LNil && v != LFalse }
  37. // LVAsString returns string representation of a given LValue
  38. // if the LValue is a string or number, otherwise an empty string.
  39. func LVAsString(v LValue) string {
  40. switch sn := v.(type) {
  41. case LString, LNumber:
  42. return sn.String()
  43. default:
  44. return ""
  45. }
  46. }
  47. // LVCanConvToString returns true if a given LValue is a string or number
  48. // otherwise false.
  49. func LVCanConvToString(v LValue) bool {
  50. switch v.(type) {
  51. case LString, LNumber:
  52. return true
  53. default:
  54. return false
  55. }
  56. }
  57. // LVAsNumber tries to convert a given LValue to a number.
  58. func LVAsNumber(v LValue) LNumber {
  59. switch lv := v.(type) {
  60. case LNumber:
  61. return lv
  62. case LString:
  63. if num, err := parseNumber(string(lv)); err == nil {
  64. return num
  65. }
  66. }
  67. return LNumber(0)
  68. }
  69. type LNilType struct{}
  70. func (nl *LNilType) String() string { return "nil" }
  71. func (nl *LNilType) Type() LValueType { return LTNil }
  72. func (nl *LNilType) assertFloat64() (float64, bool) { return 0, false }
  73. func (nl *LNilType) assertString() (string, bool) { return "", false }
  74. func (nl *LNilType) assertFunction() (*LFunction, bool) { return nil, false }
  75. var LNil = LValue(&LNilType{})
  76. type LBool bool
  77. func (bl LBool) String() string {
  78. if bool(bl) {
  79. return "true"
  80. }
  81. return "false"
  82. }
  83. func (bl LBool) Type() LValueType { return LTBool }
  84. func (bl LBool) assertFloat64() (float64, bool) { return 0, false }
  85. func (bl LBool) assertString() (string, bool) { return "", false }
  86. func (bl LBool) assertFunction() (*LFunction, bool) { return nil, false }
  87. var LTrue = LBool(true)
  88. var LFalse = LBool(false)
  89. type LString string
  90. func (st LString) String() string { return string(st) }
  91. func (st LString) Type() LValueType { return LTString }
  92. func (st LString) assertFloat64() (float64, bool) { return 0, false }
  93. func (st LString) assertString() (string, bool) { return string(st), true }
  94. func (st LString) assertFunction() (*LFunction, bool) { return nil, false }
  95. // fmt.Formatter interface
  96. func (st LString) Format(f fmt.State, c rune) {
  97. switch c {
  98. case 'd', 'i':
  99. if nm, err := parseNumber(string(st)); err != nil {
  100. defaultFormat(nm, f, 'd')
  101. } else {
  102. defaultFormat(string(st), f, 's')
  103. }
  104. default:
  105. defaultFormat(string(st), f, c)
  106. }
  107. }
  108. func (nm LNumber) String() string {
  109. if isInteger(nm) {
  110. return fmt.Sprint(int64(nm))
  111. }
  112. return fmt.Sprint(float64(nm))
  113. }
  114. func (nm LNumber) Type() LValueType { return LTNumber }
  115. func (nm LNumber) assertFloat64() (float64, bool) { return float64(nm), true }
  116. func (nm LNumber) assertString() (string, bool) { return "", false }
  117. func (nm LNumber) assertFunction() (*LFunction, bool) { return nil, false }
  118. // fmt.Formatter interface
  119. func (nm LNumber) Format(f fmt.State, c rune) {
  120. switch c {
  121. case 'q', 's':
  122. defaultFormat(nm.String(), f, c)
  123. case 'b', 'c', 'd', 'o', 'x', 'X', 'U':
  124. defaultFormat(int64(nm), f, c)
  125. case 'e', 'E', 'f', 'F', 'g', 'G':
  126. defaultFormat(float64(nm), f, c)
  127. case 'i':
  128. defaultFormat(int64(nm), f, 'd')
  129. default:
  130. if isInteger(nm) {
  131. defaultFormat(int64(nm), f, c)
  132. } else {
  133. defaultFormat(float64(nm), f, c)
  134. }
  135. }
  136. }
  137. type LTable struct {
  138. Metatable LValue
  139. array []LValue
  140. dict map[LValue]LValue
  141. strdict map[string]LValue
  142. keys []LValue
  143. k2i map[LValue]int
  144. }
  145. func (tb *LTable) String() string { return fmt.Sprintf("table: %p", tb) }
  146. func (tb *LTable) Type() LValueType { return LTTable }
  147. func (tb *LTable) assertFloat64() (float64, bool) { return 0, false }
  148. func (tb *LTable) assertString() (string, bool) { return "", false }
  149. func (tb *LTable) assertFunction() (*LFunction, bool) { return nil, false }
  150. type LFunction struct {
  151. IsG bool
  152. Env *LTable
  153. Proto *FunctionProto
  154. GFunction LGFunction
  155. Upvalues []*Upvalue
  156. }
  157. type LGFunction func(*LState) int
  158. func (fn *LFunction) String() string { return fmt.Sprintf("function: %p", fn) }
  159. func (fn *LFunction) Type() LValueType { return LTFunction }
  160. func (fn *LFunction) assertFloat64() (float64, bool) { return 0, false }
  161. func (fn *LFunction) assertString() (string, bool) { return "", false }
  162. func (fn *LFunction) assertFunction() (*LFunction, bool) { return fn, true }
  163. type Global struct {
  164. MainThread *LState
  165. CurrentThread *LState
  166. Registry *LTable
  167. Global *LTable
  168. builtinMts map[int]LValue
  169. tempFiles []*os.File
  170. gccount int32
  171. }
  172. type LState struct {
  173. G *Global
  174. Parent *LState
  175. Env *LTable
  176. Panic func(*LState)
  177. Dead bool
  178. Options Options
  179. stop int32
  180. reg *registry
  181. stack *callFrameStack
  182. alloc *allocator
  183. currentFrame *callFrame
  184. wrapped bool
  185. uvcache *Upvalue
  186. hasErrorFunc bool
  187. mainLoop func(*LState, *callFrame)
  188. ctx context.Context
  189. }
  190. func (ls *LState) String() string { return fmt.Sprintf("thread: %p", ls) }
  191. func (ls *LState) Type() LValueType { return LTThread }
  192. func (ls *LState) assertFloat64() (float64, bool) { return 0, false }
  193. func (ls *LState) assertString() (string, bool) { return "", false }
  194. func (ls *LState) assertFunction() (*LFunction, bool) { return nil, false }
  195. type LUserData struct {
  196. Value interface{}
  197. Env *LTable
  198. Metatable LValue
  199. }
  200. func (ud *LUserData) String() string { return fmt.Sprintf("userdata: %p", ud) }
  201. func (ud *LUserData) Type() LValueType { return LTUserData }
  202. func (ud *LUserData) assertFloat64() (float64, bool) { return 0, false }
  203. func (ud *LUserData) assertString() (string, bool) { return "", false }
  204. func (ud *LUserData) assertFunction() (*LFunction, bool) { return nil, false }
  205. type LChannel chan LValue
  206. func (ch LChannel) String() string { return fmt.Sprintf("channel: %p", ch) }
  207. func (ch LChannel) Type() LValueType { return LTChannel }
  208. func (ch LChannel) assertFloat64() (float64, bool) { return 0, false }
  209. func (ch LChannel) assertString() (string, bool) { return "", false }
  210. func (ch LChannel) assertFunction() (*LFunction, bool) { return nil, false }