object_goslice_reflect.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package goja
  2. import (
  3. "reflect"
  4. "strconv"
  5. )
  6. type objectGoSliceReflect struct {
  7. objectGoReflect
  8. lengthProp valueProperty
  9. }
  10. func (o *objectGoSliceReflect) init() {
  11. o.objectGoReflect.init()
  12. o.class = classArray
  13. o.prototype = o.val.runtime.global.ArrayPrototype
  14. o.lengthProp.writable = false
  15. o._setLen()
  16. o.baseObject._put("length", &o.lengthProp)
  17. }
  18. func (o *objectGoSliceReflect) _setLen() {
  19. o.lengthProp.value = intToValue(int64(o.value.Len()))
  20. }
  21. func (o *objectGoSliceReflect) _has(n Value) bool {
  22. if idx := toIdx(n); idx >= 0 {
  23. return idx < int64(o.value.Len())
  24. }
  25. return false
  26. }
  27. func (o *objectGoSliceReflect) _hasStr(name string) bool {
  28. if idx := strToIdx(name); idx >= 0 {
  29. return idx < int64(o.value.Len())
  30. }
  31. return false
  32. }
  33. func (o *objectGoSliceReflect) getIdx(idx int64) Value {
  34. if idx < int64(o.value.Len()) {
  35. return o.val.runtime.ToValue(o.value.Index(int(idx)).Interface())
  36. }
  37. return nil
  38. }
  39. func (o *objectGoSliceReflect) _get(n Value) Value {
  40. if idx := toIdx(n); idx >= 0 {
  41. return o.getIdx(idx)
  42. }
  43. return nil
  44. }
  45. func (o *objectGoSliceReflect) _getStr(name string) Value {
  46. if idx := strToIdx(name); idx >= 0 {
  47. return o.getIdx(idx)
  48. }
  49. return nil
  50. }
  51. func (o *objectGoSliceReflect) get(n Value) Value {
  52. if v := o._get(n); v != nil {
  53. return v
  54. }
  55. return o.objectGoReflect.get(n)
  56. }
  57. func (o *objectGoSliceReflect) getProp(n Value) Value {
  58. if v := o._get(n); v != nil {
  59. return v
  60. }
  61. return o.objectGoReflect.getProp(n)
  62. }
  63. func (o *objectGoSliceReflect) getPropStr(name string) Value {
  64. if v := o._getStr(name); v != nil {
  65. return v
  66. }
  67. return o.objectGoReflect.getPropStr(name)
  68. }
  69. func (o *objectGoSliceReflect) getOwnProp(name string) Value {
  70. if v := o._getStr(name); v != nil {
  71. return v
  72. }
  73. return o.objectGoReflect.getOwnProp(name)
  74. }
  75. func (o *objectGoSliceReflect) putIdx(idx int64, v Value, throw bool) {
  76. if idx >= int64(o.value.Len()) {
  77. o.val.runtime.typeErrorResult(throw, "Cannot extend a Go reflect slice")
  78. return
  79. }
  80. val, err := o.val.runtime.toReflectValue(v, o.value.Type().Elem())
  81. if err != nil {
  82. o.val.runtime.typeErrorResult(throw, "Go type conversion error: %v", err)
  83. return
  84. }
  85. o.value.Index(int(idx)).Set(val)
  86. }
  87. func (o *objectGoSliceReflect) put(n Value, val Value, throw bool) {
  88. if idx := toIdx(n); idx >= 0 {
  89. o.putIdx(idx, val, throw)
  90. return
  91. }
  92. // TODO: length
  93. o.objectGoReflect.put(n, val, throw)
  94. }
  95. func (o *objectGoSliceReflect) putStr(name string, val Value, throw bool) {
  96. if idx := strToIdx(name); idx >= 0 {
  97. o.putIdx(idx, val, throw)
  98. return
  99. }
  100. // TODO: length
  101. o.objectGoReflect.putStr(name, val, throw)
  102. }
  103. func (o *objectGoSliceReflect) hasProperty(n Value) bool {
  104. if o._has(n) {
  105. return true
  106. }
  107. return o.objectGoReflect.hasProperty(n)
  108. }
  109. func (o *objectGoSliceReflect) hasPropertyStr(name string) bool {
  110. if o._hasStr(name) {
  111. return true
  112. }
  113. return o.objectGoReflect.hasOwnPropertyStr(name)
  114. }
  115. func (o *objectGoSliceReflect) hasOwnProperty(n Value) bool {
  116. if o._has(n) {
  117. return true
  118. }
  119. return o.objectGoReflect.hasOwnProperty(n)
  120. }
  121. func (o *objectGoSliceReflect) hasOwnPropertyStr(name string) bool {
  122. if o._hasStr(name) {
  123. return true
  124. }
  125. return o.objectGoReflect.hasOwnPropertyStr(name)
  126. }
  127. func (o *objectGoSliceReflect) _putProp(name string, value Value, writable, enumerable, configurable bool) Value {
  128. o.putStr(name, value, false)
  129. return value
  130. }
  131. func (o *objectGoSliceReflect) defineOwnProperty(name Value, descr propertyDescr, throw bool) bool {
  132. if !o.val.runtime.checkHostObjectPropertyDescr(name.String(), descr, throw) {
  133. return false
  134. }
  135. o.put(name, descr.Value, throw)
  136. return true
  137. }
  138. func (o *objectGoSliceReflect) toPrimitiveNumber() Value {
  139. return o.toPrimitiveString()
  140. }
  141. func (o *objectGoSliceReflect) toPrimitiveString() Value {
  142. return o.val.runtime.arrayproto_join(FunctionCall{
  143. This: o.val,
  144. })
  145. }
  146. func (o *objectGoSliceReflect) toPrimitive() Value {
  147. return o.toPrimitiveString()
  148. }
  149. func (o *objectGoSliceReflect) deleteStr(name string, throw bool) bool {
  150. if idx := strToIdx(name); idx >= 0 && idx < int64(o.value.Len()) {
  151. o.value.Index(int(idx)).Set(reflect.Zero(o.value.Type().Elem()))
  152. return true
  153. }
  154. return o.objectGoReflect.deleteStr(name, throw)
  155. }
  156. func (o *objectGoSliceReflect) delete(name Value, throw bool) bool {
  157. if idx := toIdx(name); idx >= 0 && idx < int64(o.value.Len()) {
  158. o.value.Index(int(idx)).Set(reflect.Zero(o.value.Type().Elem()))
  159. return true
  160. }
  161. return true
  162. }
  163. type gosliceReflectPropIter struct {
  164. o *objectGoSliceReflect
  165. recursive bool
  166. idx, limit int
  167. }
  168. func (i *gosliceReflectPropIter) next() (propIterItem, iterNextFunc) {
  169. if i.idx < i.limit && i.idx < i.o.value.Len() {
  170. name := strconv.Itoa(i.idx)
  171. i.idx++
  172. return propIterItem{name: name, enumerable: _ENUM_TRUE}, i.next
  173. }
  174. if i.recursive {
  175. return i.o.prototype.self._enumerate(i.recursive)()
  176. }
  177. return propIterItem{}, nil
  178. }
  179. func (o *objectGoSliceReflect) enumerate(all, recursive bool) iterNextFunc {
  180. return (&propFilterIter{
  181. wrapped: o._enumerate(recursive),
  182. all: all,
  183. seen: make(map[string]bool),
  184. }).next
  185. }
  186. func (o *objectGoSliceReflect) _enumerate(recursive bool) iterNextFunc {
  187. return (&gosliceReflectPropIter{
  188. o: o,
  189. recursive: recursive,
  190. limit: o.value.Len(),
  191. }).next
  192. }
  193. func (o *objectGoSliceReflect) equal(other objectImpl) bool {
  194. if other, ok := other.(*objectGoSliceReflect); ok {
  195. return o.value.Interface() == other.value.Interface()
  196. }
  197. return false
  198. }
  199. func (o *objectGoSliceReflect) sortLen() int64 {
  200. return int64(o.value.Len())
  201. }
  202. func (o *objectGoSliceReflect) sortGet(i int64) Value {
  203. return o.get(intToValue(i))
  204. }
  205. func (o *objectGoSliceReflect) swap(i, j int64) {
  206. ii := intToValue(i)
  207. jj := intToValue(j)
  208. x := o.get(ii)
  209. y := o.get(jj)
  210. o.put(ii, y, false)
  211. o.put(jj, x, false)
  212. }