destruct.go 7.6 KB

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