destruct.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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() valueString {
  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) toPrimitiveNumber() Value {
  126. return d.w().toPrimitiveNumber()
  127. }
  128. func (d *destructKeyedSource) toPrimitiveString() Value {
  129. return d.w().toPrimitiveString()
  130. }
  131. func (d *destructKeyedSource) toPrimitive() Value {
  132. return d.w().toPrimitive()
  133. }
  134. func (d *destructKeyedSource) assertCallable() (call func(FunctionCall) Value, ok bool) {
  135. return d.w().assertCallable()
  136. }
  137. func (d *destructKeyedSource) vmCall(vm *vm, n int) {
  138. d.w().vmCall(vm, n)
  139. }
  140. func (d *destructKeyedSource) assertConstructor() func(args []Value, newTarget *Object) *Object {
  141. return d.w().assertConstructor()
  142. }
  143. func (d *destructKeyedSource) proto() *Object {
  144. return d.w().proto()
  145. }
  146. func (d *destructKeyedSource) setProto(proto *Object, throw bool) bool {
  147. return d.w().setProto(proto, throw)
  148. }
  149. func (d *destructKeyedSource) hasInstance(v Value) bool {
  150. return d.w().hasInstance(v)
  151. }
  152. func (d *destructKeyedSource) isExtensible() bool {
  153. return d.w().isExtensible()
  154. }
  155. func (d *destructKeyedSource) preventExtensions(throw bool) bool {
  156. return d.w().preventExtensions(throw)
  157. }
  158. type destructKeyedSourceIter struct {
  159. d *destructKeyedSource
  160. wrapped iterNextFunc
  161. }
  162. func (i *destructKeyedSourceIter) next() (propIterItem, iterNextFunc) {
  163. for {
  164. item, next := i.wrapped()
  165. if next == nil {
  166. return item, nil
  167. }
  168. i.wrapped = next
  169. if _, exists := i.d.usedKeys[item.name]; !exists {
  170. return item, i.next
  171. }
  172. }
  173. }
  174. func (d *destructKeyedSource) iterateStringKeys() iterNextFunc {
  175. return (&destructKeyedSourceIter{
  176. d: d,
  177. wrapped: d.w().iterateStringKeys(),
  178. }).next
  179. }
  180. func (d *destructKeyedSource) iterateSymbols() iterNextFunc {
  181. return (&destructKeyedSourceIter{
  182. d: d,
  183. wrapped: d.w().iterateSymbols(),
  184. }).next
  185. }
  186. func (d *destructKeyedSource) iterateKeys() iterNextFunc {
  187. return (&destructKeyedSourceIter{
  188. d: d,
  189. wrapped: d.w().iterateKeys(),
  190. }).next
  191. }
  192. func (d *destructKeyedSource) export(ctx *objectExportCtx) interface{} {
  193. return d.w().export(ctx)
  194. }
  195. func (d *destructKeyedSource) exportType() reflect.Type {
  196. return d.w().exportType()
  197. }
  198. func (d *destructKeyedSource) exportToMap(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
  199. return d.w().exportToMap(dst, typ, ctx)
  200. }
  201. func (d *destructKeyedSource) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
  202. return d.w().exportToArrayOrSlice(dst, typ, ctx)
  203. }
  204. func (d *destructKeyedSource) equal(impl objectImpl) bool {
  205. return d.w().equal(impl)
  206. }
  207. func (d *destructKeyedSource) stringKeys(all bool, accum []Value) []Value {
  208. var next iterNextFunc
  209. if all {
  210. next = d.iterateStringKeys()
  211. } else {
  212. next = (&enumerableIter{
  213. o: d.wrapped.ToObject(d.r),
  214. wrapped: d.iterateStringKeys(),
  215. }).next
  216. }
  217. for item, next := next(); next != nil; item, next = next() {
  218. accum = append(accum, item.name)
  219. }
  220. return accum
  221. }
  222. func (d *destructKeyedSource) filterUsedKeys(keys []Value) []Value {
  223. k := 0
  224. for i, key := range keys {
  225. if _, exists := d.usedKeys[key]; exists {
  226. continue
  227. }
  228. if k != i {
  229. keys[k] = key
  230. }
  231. k++
  232. }
  233. return keys[:k]
  234. }
  235. func (d *destructKeyedSource) symbols(all bool, accum []Value) []Value {
  236. return d.filterUsedKeys(d.w().symbols(all, accum))
  237. }
  238. func (d *destructKeyedSource) keys(all bool, accum []Value) []Value {
  239. return d.filterUsedKeys(d.w().keys(all, accum))
  240. }
  241. func (d *destructKeyedSource) _putProp(name unistring.String, value Value, writable, enumerable, configurable bool) Value {
  242. return d.w()._putProp(name, value, writable, enumerable, configurable)
  243. }
  244. func (d *destructKeyedSource) _putSym(s *Symbol, prop Value) {
  245. d.w()._putSym(s, prop)
  246. }
  247. func (d *destructKeyedSource) getPrivateEnv(typ *privateEnvType, create bool) *privateElements {
  248. return d.w().getPrivateEnv(typ, create)
  249. }