destruct.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package goja
  2. import (
  3. "github.com/dop251/goja/unistring"
  4. "reflect"
  5. )
  6. type destructKeyedSource struct {
  7. r *Runtime
  8. wrapped Value
  9. usedKeys map[Value]struct{}
  10. }
  11. func newDestructKeyedSource(r *Runtime, wrapped Value) *destructKeyedSource {
  12. return &destructKeyedSource{
  13. r: r,
  14. wrapped: wrapped,
  15. }
  16. }
  17. func (r *Runtime) newDestructKeyedSource(wrapped Value) *Object {
  18. return &Object{
  19. runtime: r,
  20. self: newDestructKeyedSource(r, wrapped),
  21. }
  22. }
  23. func (d *destructKeyedSource) w() objectImpl {
  24. return d.wrapped.ToObject(d.r).self
  25. }
  26. func (d *destructKeyedSource) recordKey(key Value) {
  27. if d.usedKeys == nil {
  28. d.usedKeys = make(map[Value]struct{})
  29. }
  30. d.usedKeys[key] = struct{}{}
  31. }
  32. func (d *destructKeyedSource) sortLen() int64 {
  33. return d.w().sortLen()
  34. }
  35. func (d *destructKeyedSource) sortGet(i int64) Value {
  36. return d.w().sortGet(i)
  37. }
  38. func (d *destructKeyedSource) swap(i int64, i2 int64) {
  39. d.w().swap(i, i2)
  40. }
  41. func (d *destructKeyedSource) className() string {
  42. return d.w().className()
  43. }
  44. func (d *destructKeyedSource) getStr(p unistring.String, receiver Value) Value {
  45. d.recordKey(stringValueFromRaw(p))
  46. return d.w().getStr(p, receiver)
  47. }
  48. func (d *destructKeyedSource) getIdx(p valueInt, receiver Value) Value {
  49. d.recordKey(p.toString())
  50. return d.w().getIdx(p, receiver)
  51. }
  52. func (d *destructKeyedSource) getSym(p *Symbol, receiver Value) Value {
  53. d.recordKey(p)
  54. return d.w().getSym(p, receiver)
  55. }
  56. func (d *destructKeyedSource) getOwnPropStr(u unistring.String) Value {
  57. d.recordKey(stringValueFromRaw(u))
  58. return d.w().getOwnPropStr(u)
  59. }
  60. func (d *destructKeyedSource) getOwnPropIdx(v valueInt) Value {
  61. d.recordKey(v.toString())
  62. return d.w().getOwnPropIdx(v)
  63. }
  64. func (d *destructKeyedSource) getOwnPropSym(symbol *Symbol) Value {
  65. d.recordKey(symbol)
  66. return d.w().getOwnPropSym(symbol)
  67. }
  68. func (d *destructKeyedSource) setOwnStr(p unistring.String, v Value, throw bool) bool {
  69. return d.w().setOwnStr(p, v, throw)
  70. }
  71. func (d *destructKeyedSource) setOwnIdx(p valueInt, v Value, throw bool) bool {
  72. return d.w().setOwnIdx(p, v, throw)
  73. }
  74. func (d *destructKeyedSource) setOwnSym(p *Symbol, v Value, throw bool) bool {
  75. return d.w().setOwnSym(p, v, throw)
  76. }
  77. func (d *destructKeyedSource) setForeignStr(p unistring.String, v, receiver Value, throw bool) (res bool, handled bool) {
  78. return d.w().setForeignStr(p, v, receiver, throw)
  79. }
  80. func (d *destructKeyedSource) setForeignIdx(p valueInt, v, receiver Value, throw bool) (res bool, handled bool) {
  81. return d.w().setForeignIdx(p, v, receiver, throw)
  82. }
  83. func (d *destructKeyedSource) setForeignSym(p *Symbol, v, receiver Value, throw bool) (res bool, handled bool) {
  84. return d.w().setForeignSym(p, v, receiver, throw)
  85. }
  86. func (d *destructKeyedSource) hasPropertyStr(u unistring.String) bool {
  87. return d.w().hasPropertyStr(u)
  88. }
  89. func (d *destructKeyedSource) hasPropertyIdx(idx valueInt) bool {
  90. return d.w().hasPropertyIdx(idx)
  91. }
  92. func (d *destructKeyedSource) hasPropertySym(s *Symbol) bool {
  93. return d.w().hasPropertySym(s)
  94. }
  95. func (d *destructKeyedSource) hasOwnPropertyStr(u unistring.String) bool {
  96. return d.w().hasOwnPropertyStr(u)
  97. }
  98. func (d *destructKeyedSource) hasOwnPropertyIdx(v valueInt) bool {
  99. return d.w().hasOwnPropertyIdx(v)
  100. }
  101. func (d *destructKeyedSource) hasOwnPropertySym(s *Symbol) bool {
  102. return d.w().hasOwnPropertySym(s)
  103. }
  104. func (d *destructKeyedSource) defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool {
  105. return d.w().defineOwnPropertyStr(name, desc, throw)
  106. }
  107. func (d *destructKeyedSource) defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor, throw bool) bool {
  108. return d.w().defineOwnPropertyIdx(name, desc, throw)
  109. }
  110. func (d *destructKeyedSource) defineOwnPropertySym(name *Symbol, desc PropertyDescriptor, throw bool) bool {
  111. return d.w().defineOwnPropertySym(name, desc, throw)
  112. }
  113. func (d *destructKeyedSource) deleteStr(name unistring.String, throw bool) bool {
  114. return d.w().deleteStr(name, throw)
  115. }
  116. func (d *destructKeyedSource) deleteIdx(idx valueInt, throw bool) bool {
  117. return d.w().deleteIdx(idx, throw)
  118. }
  119. func (d *destructKeyedSource) deleteSym(s *Symbol, throw bool) bool {
  120. return d.w().deleteSym(s, throw)
  121. }
  122. func (d *destructKeyedSource) toPrimitiveNumber() Value {
  123. return d.w().toPrimitiveNumber()
  124. }
  125. func (d *destructKeyedSource) toPrimitiveString() Value {
  126. return d.w().toPrimitiveString()
  127. }
  128. func (d *destructKeyedSource) toPrimitive() Value {
  129. return d.w().toPrimitive()
  130. }
  131. func (d *destructKeyedSource) assertCallable() (call func(FunctionCall) Value, ok bool) {
  132. return d.w().assertCallable()
  133. }
  134. func (d *destructKeyedSource) assertConstructor() func(args []Value, newTarget *Object) *Object {
  135. return d.w().assertConstructor()
  136. }
  137. func (d *destructKeyedSource) proto() *Object {
  138. return d.w().proto()
  139. }
  140. func (d *destructKeyedSource) setProto(proto *Object, throw bool) bool {
  141. return d.w().setProto(proto, throw)
  142. }
  143. func (d *destructKeyedSource) hasInstance(v Value) bool {
  144. return d.w().hasInstance(v)
  145. }
  146. func (d *destructKeyedSource) isExtensible() bool {
  147. return d.w().isExtensible()
  148. }
  149. func (d *destructKeyedSource) preventExtensions(throw bool) bool {
  150. return d.w().preventExtensions(throw)
  151. }
  152. type destructKeyedSourceIter struct {
  153. d *destructKeyedSource
  154. wrapped iterNextFunc
  155. }
  156. func (i *destructKeyedSourceIter) next() (propIterItem, iterNextFunc) {
  157. for {
  158. item, next := i.wrapped()
  159. if next == nil {
  160. return item, nil
  161. }
  162. i.wrapped = next
  163. if _, exists := i.d.usedKeys[item.name]; !exists {
  164. return item, i.next
  165. }
  166. }
  167. }
  168. func (d *destructKeyedSource) iterateStringKeys() iterNextFunc {
  169. return (&destructKeyedSourceIter{
  170. d: d,
  171. wrapped: d.w().iterateStringKeys(),
  172. }).next
  173. }
  174. func (d *destructKeyedSource) iterateSymbols() iterNextFunc {
  175. return (&destructKeyedSourceIter{
  176. d: d,
  177. wrapped: d.w().iterateSymbols(),
  178. }).next
  179. }
  180. func (d *destructKeyedSource) iterateKeys() iterNextFunc {
  181. return (&destructKeyedSourceIter{
  182. d: d,
  183. wrapped: d.w().iterateKeys(),
  184. }).next
  185. }
  186. func (d *destructKeyedSource) export(ctx *objectExportCtx) interface{} {
  187. return d.w().export(ctx)
  188. }
  189. func (d *destructKeyedSource) exportType() reflect.Type {
  190. return d.w().exportType()
  191. }
  192. func (d *destructKeyedSource) equal(impl objectImpl) bool {
  193. return d.w().equal(impl)
  194. }
  195. func (d *destructKeyedSource) stringKeys(all bool, accum []Value) []Value {
  196. var next iterNextFunc
  197. if all {
  198. next = d.iterateStringKeys()
  199. } else {
  200. next = (&enumerableIter{
  201. o: d.wrapped.ToObject(d.r),
  202. wrapped: d.iterateStringKeys(),
  203. }).next
  204. }
  205. for item, next := next(); next != nil; item, next = next() {
  206. accum = append(accum, item.name)
  207. }
  208. return accum
  209. }
  210. func (d *destructKeyedSource) filterUsedKeys(keys []Value) []Value {
  211. k := 0
  212. for i, key := range keys {
  213. if _, exists := d.usedKeys[key]; exists {
  214. continue
  215. }
  216. if k != i {
  217. keys[k] = key
  218. }
  219. k++
  220. }
  221. return keys[:k]
  222. }
  223. func (d *destructKeyedSource) symbols(all bool, accum []Value) []Value {
  224. return d.filterUsedKeys(d.w().symbols(all, accum))
  225. }
  226. func (d *destructKeyedSource) keys(all bool, accum []Value) []Value {
  227. return d.filterUsedKeys(d.w().keys(all, accum))
  228. }
  229. func (d *destructKeyedSource) _putProp(name unistring.String, value Value, writable, enumerable, configurable bool) Value {
  230. return d.w()._putProp(name, value, writable, enumerable, configurable)
  231. }
  232. func (d *destructKeyedSource) _putSym(s *Symbol, prop Value) {
  233. d.w()._putSym(s, prop)
  234. }