proxy.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. package goja
  2. type Proxy struct {
  3. proxy *proxyObject
  4. }
  5. type proxyPropIter struct {
  6. p *proxyObject
  7. names []Value
  8. idx int
  9. }
  10. func (i *proxyPropIter) next() (propIterItem, iterNextFunc) {
  11. for i.idx < len(i.names) {
  12. name := i.names[i.idx]
  13. i.idx++
  14. if prop := i.p.val.getOwnProp(name); prop != nil {
  15. return propIterItem{name: name.String(), value: prop}, i.next
  16. }
  17. }
  18. if proto := i.p.proto(); proto != nil {
  19. return proto.self.enumerateUnfiltered()()
  20. }
  21. return propIterItem{}, nil
  22. }
  23. func (r *Runtime) newProxyObject(target *Object, handler *Object, proto *Object) *proxyObject {
  24. if p, ok := target.self.(*proxyObject); ok {
  25. if p.handler == nil {
  26. panic(r.NewTypeError("Cannot create proxy with a revoked proxy as target"))
  27. }
  28. }
  29. if p, ok := handler.self.(*proxyObject); ok {
  30. if p.handler == nil {
  31. panic(r.NewTypeError("Cannot create proxy with a revoked proxy as handler"))
  32. }
  33. }
  34. v := &Object{runtime: r}
  35. p := &proxyObject{}
  36. v.self = p
  37. p.val = v
  38. p.class = classObject
  39. if proto == nil {
  40. p.prototype = r.global.ObjectPrototype
  41. } else {
  42. p.prototype = proto
  43. }
  44. p.extensible = false
  45. p.init()
  46. p.target = target
  47. p.handler = handler
  48. if call, ok := target.self.assertCallable(); ok {
  49. p.call = call
  50. }
  51. if ctor := target.self.assertConstructor(); ctor != nil {
  52. p.ctor = ctor
  53. }
  54. return p
  55. }
  56. func (p *Proxy) Revoke() {
  57. p.proxy.revoke()
  58. }
  59. type proxyTrap string
  60. const (
  61. proxy_trap_getPrototypeOf = "getPrototypeOf"
  62. proxy_trap_setPrototypeOf = "setPrototypeOf"
  63. proxy_trap_isExtensible = "isExtensible"
  64. proxy_trap_preventExtensions = "preventExtensions"
  65. proxy_trap_getOwnPropertyDescriptor = "getOwnPropertyDescriptor"
  66. proxy_trap_defineProperty = "defineProperty"
  67. proxy_trap_has = "has"
  68. proxy_trap_get = "get"
  69. proxy_trap_set = "set"
  70. proxy_trap_deleteProperty = "deleteProperty"
  71. proxy_trap_ownKeys = "ownKeys"
  72. proxy_trap_apply = "apply"
  73. proxy_trap_construct = "construct"
  74. )
  75. func (p proxyTrap) String() (name string) {
  76. return string(p)
  77. }
  78. type proxyObject struct {
  79. baseObject
  80. target *Object
  81. handler *Object
  82. call func(FunctionCall) Value
  83. ctor func(args []Value, newTarget *Object) *Object
  84. }
  85. func (p *proxyObject) proxyCall(trap proxyTrap, args ...Value) (Value, bool) {
  86. r := p.val.runtime
  87. if p.handler == nil {
  88. panic(r.NewTypeError("Proxy already revoked"))
  89. }
  90. if m := toMethod(r.getVStr(p.handler, trap.String())); m != nil {
  91. return m(FunctionCall{
  92. This: p.handler,
  93. Arguments: args,
  94. }), true
  95. }
  96. return nil, false
  97. }
  98. func (p *proxyObject) proto() *Object {
  99. if v, ok := p.proxyCall(proxy_trap_getPrototypeOf, p.target); ok {
  100. var handlerProto *Object
  101. if v != _null {
  102. handlerProto = p.val.runtime.toObject(v)
  103. }
  104. if !p.target.self.isExtensible() && !p.__sameValue(handlerProto, p.target.self.proto()) {
  105. panic(p.val.runtime.NewTypeError("'getPrototypeOf' on proxy: proxy target is non-extensible but the trap did not return its actual prototype"))
  106. }
  107. return handlerProto
  108. }
  109. return p.target.self.proto()
  110. }
  111. func (p *proxyObject) setProto(proto *Object, throw bool) bool {
  112. if v, ok := p.proxyCall(proxy_trap_setPrototypeOf, p.target, proto); ok {
  113. if v.ToBoolean() {
  114. if !p.target.self.isExtensible() && !p.__sameValue(proto, p.target.self.proto()) {
  115. panic(p.val.runtime.NewTypeError("'setPrototypeOf' on proxy: trap returned truish for setting a new prototype on the non-extensible proxy target"))
  116. }
  117. return true
  118. } else {
  119. p.val.runtime.typeErrorResult(throw, "'setPrototypeOf' on proxy: trap returned falsish")
  120. }
  121. }
  122. return p.target.self.setProto(proto, throw)
  123. }
  124. func (p *proxyObject) isExtensible() bool {
  125. if v, ok := p.proxyCall(proxy_trap_isExtensible, p.target); ok {
  126. booleanTrapResult := v.ToBoolean()
  127. if te := p.target.self.isExtensible(); booleanTrapResult != te {
  128. panic(p.val.runtime.NewTypeError("'isExtensible' on proxy: trap result does not reflect extensibility of proxy target (which is '%v')", te))
  129. }
  130. return booleanTrapResult
  131. }
  132. return p.target.self.isExtensible()
  133. }
  134. func (p *proxyObject) preventExtensions(throw bool) bool {
  135. if v, ok := p.proxyCall(proxy_trap_preventExtensions, p.target); ok {
  136. booleanTrapResult := v.ToBoolean()
  137. if !booleanTrapResult {
  138. p.val.runtime.typeErrorResult(throw, "'preventExtensions' on proxy: trap returned falsish")
  139. return false
  140. }
  141. if te := p.target.self.isExtensible(); booleanTrapResult && te {
  142. panic(p.val.runtime.NewTypeError("'preventExtensions' on proxy: trap returned truish but the proxy target is extensible"))
  143. }
  144. }
  145. return p.target.self.preventExtensions(throw)
  146. }
  147. func propToValueProp(v Value) *valueProperty {
  148. if v == nil {
  149. return nil
  150. }
  151. if v, ok := v.(*valueProperty); ok {
  152. return v
  153. }
  154. return &valueProperty{
  155. value: v,
  156. writable: true,
  157. configurable: true,
  158. enumerable: true,
  159. }
  160. }
  161. func (p *proxyObject) proxyDefineOwnProperty(name Value, descr PropertyDescriptor, throw bool) (bool, bool) {
  162. if v, ok := p.proxyCall(proxy_trap_defineProperty, p.target, name, descr.toValue(p.val.runtime)); ok {
  163. booleanTrapResult := v.ToBoolean()
  164. if !booleanTrapResult {
  165. p.val.runtime.typeErrorResult(throw, "'defineProperty' on proxy: trap returned falsish")
  166. return false, true
  167. }
  168. targetDesc := propToValueProp(p.target.getOwnProp(name))
  169. extensibleTarget := p.target.self.isExtensible()
  170. settingConfigFalse := descr.Configurable == FLAG_FALSE
  171. if targetDesc == nil {
  172. if !extensibleTarget {
  173. panic(p.val.runtime.NewTypeError())
  174. }
  175. if settingConfigFalse {
  176. panic(p.val.runtime.NewTypeError())
  177. }
  178. } else {
  179. if !p.__isCompatibleDescriptor(extensibleTarget, &descr, targetDesc) {
  180. panic(p.val.runtime.NewTypeError())
  181. }
  182. if settingConfigFalse && targetDesc.configurable {
  183. panic(p.val.runtime.NewTypeError())
  184. }
  185. }
  186. return booleanTrapResult, true
  187. }
  188. return false, false
  189. }
  190. func (p *proxyObject) defineOwnPropertyStr(name string, descr PropertyDescriptor, throw bool) bool {
  191. if v, ok := p.proxyDefineOwnProperty(newStringValue(name), descr, throw); ok {
  192. return v
  193. }
  194. return p.target.self.defineOwnPropertyStr(name, descr, throw)
  195. }
  196. func (p *proxyObject) defineOwnPropertyIdx(idx valueInt, descr PropertyDescriptor, throw bool) bool {
  197. if v, ok := p.proxyDefineOwnProperty(idx, descr, throw); ok {
  198. return v
  199. }
  200. return p.target.self.defineOwnPropertyIdx(idx, descr, throw)
  201. }
  202. func (p *proxyObject) defineOwnPropertySym(s *valueSymbol, descr PropertyDescriptor, throw bool) bool {
  203. if v, ok := p.proxyDefineOwnProperty(s, descr, throw); ok {
  204. return v
  205. }
  206. return p.target.self.defineOwnPropertySym(s, descr, throw)
  207. }
  208. func (p *proxyObject) proxyHas(name Value) (bool, bool) {
  209. if v, ok := p.proxyCall(proxy_trap_has, p.target, name); ok {
  210. booleanTrapResult := v.ToBoolean()
  211. if !booleanTrapResult {
  212. targetDesc := propToValueProp(p.target.getOwnProp(name))
  213. if targetDesc != nil {
  214. if !targetDesc.configurable {
  215. panic(p.val.runtime.NewTypeError("'has' on proxy: trap returned falsish for property '%s' which exists in the proxy target as non-configurable", name.String()))
  216. }
  217. if !p.target.self.isExtensible() {
  218. panic(p.val.runtime.NewTypeError("'has' on proxy: trap returned falsish for property '%s' but the proxy target is not extensible", name.String()))
  219. }
  220. }
  221. }
  222. return booleanTrapResult, true
  223. }
  224. return false, false
  225. }
  226. func (p *proxyObject) hasPropertyStr(name string) bool {
  227. if b, ok := p.proxyHas(newStringValue(name)); ok {
  228. return b
  229. }
  230. return p.target.self.hasPropertyStr(name)
  231. }
  232. func (p *proxyObject) hasPropertyIdx(idx valueInt) bool {
  233. if b, ok := p.proxyHas(idx); ok {
  234. return b
  235. }
  236. return p.target.self.hasPropertyIdx(idx)
  237. }
  238. func (p *proxyObject) hasPropertySym(s *valueSymbol) bool {
  239. if b, ok := p.proxyHas(s); ok {
  240. return b
  241. }
  242. return p.target.self.hasPropertySym(s)
  243. }
  244. func (p *proxyObject) hasOwnPropertyStr(name string) bool {
  245. return p.getOwnPropStr(name) != nil
  246. }
  247. func (p *proxyObject) hasOwnPropertyIdx(idx valueInt) bool {
  248. return p.getOwnPropIdx(idx) != nil
  249. }
  250. func (p *proxyObject) hasOwnPropertySym(s *valueSymbol) bool {
  251. return p.getOwnPropSym(s) != nil
  252. }
  253. func (p *proxyObject) proxyGetOwnPropertyDescriptor(name Value) (Value, bool) {
  254. target := p.target
  255. if v, ok := p.proxyCall(proxy_trap_getOwnPropertyDescriptor, target, name); ok {
  256. r := p.val.runtime
  257. targetDesc := propToValueProp(target.getOwnProp(name))
  258. var trapResultObj *Object
  259. if v != nil && v != _undefined {
  260. if obj, ok := v.(*Object); ok {
  261. trapResultObj = obj
  262. } else {
  263. panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap returned neither object nor undefined for property '%s'", name.String()))
  264. }
  265. }
  266. if trapResultObj == nil {
  267. if targetDesc == nil {
  268. return nil, true
  269. }
  270. if !targetDesc.configurable {
  271. panic(r.NewTypeError())
  272. }
  273. if !target.self.isExtensible() {
  274. panic(r.NewTypeError())
  275. }
  276. return nil, true
  277. }
  278. extensibleTarget := target.self.isExtensible()
  279. resultDesc := r.toPropertyDescriptor(trapResultObj)
  280. resultDesc.complete()
  281. if !p.__isCompatibleDescriptor(extensibleTarget, &resultDesc, targetDesc) {
  282. panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap returned descriptor for property '%s' that is incompatible with the existing property in the proxy target", name.String()))
  283. }
  284. if resultDesc.Configurable == FLAG_FALSE {
  285. if targetDesc == nil {
  286. panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '%s' which is non-existent in the proxy target", name.String()))
  287. }
  288. if targetDesc.configurable {
  289. panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '%s' which is configurable in the proxy target", name.String()))
  290. }
  291. }
  292. if resultDesc.Writable == FLAG_TRUE && resultDesc.Configurable == FLAG_TRUE &&
  293. resultDesc.Enumerable == FLAG_TRUE {
  294. return resultDesc.Value, true
  295. }
  296. return r.toValueProp(trapResultObj), true
  297. }
  298. return nil, false
  299. }
  300. func (p *proxyObject) getOwnPropStr(name string) Value {
  301. if v, ok := p.proxyGetOwnPropertyDescriptor(newStringValue(name)); ok {
  302. return v
  303. }
  304. return p.target.self.getOwnPropStr(name)
  305. }
  306. func (p *proxyObject) getOwnPropIdx(idx valueInt) Value {
  307. if v, ok := p.proxyGetOwnPropertyDescriptor(idx.toString()); ok {
  308. return v
  309. }
  310. return p.target.self.getOwnPropIdx(idx)
  311. }
  312. func (p *proxyObject) getOwnPropSym(s *valueSymbol) Value {
  313. if v, ok := p.proxyGetOwnPropertyDescriptor(s); ok {
  314. return v
  315. }
  316. return p.target.self.getOwnPropSym(s)
  317. }
  318. func (p *proxyObject) getStr(name string, receiver Value) Value {
  319. if v, ok := p.proxyGet(newStringValue(name), receiver); ok {
  320. return v
  321. }
  322. return p.target.self.getStr(name, receiver)
  323. }
  324. func (p *proxyObject) getIdx(idx valueInt, receiver Value) Value {
  325. if v, ok := p.proxyGet(idx.toString(), receiver); ok {
  326. return v
  327. }
  328. return p.target.self.getIdx(idx, receiver)
  329. }
  330. func (p *proxyObject) getSym(s *valueSymbol, receiver Value) Value {
  331. if v, ok := p.proxyGet(s, receiver); ok {
  332. return v
  333. }
  334. return p.target.self.getSym(s, receiver)
  335. }
  336. func (p *proxyObject) proxyGet(name, receiver Value) (Value, bool) {
  337. target := p.target
  338. if v, ok := p.proxyCall(proxy_trap_get, target, name, receiver); ok {
  339. if targetDesc, ok := target.getOwnProp(name).(*valueProperty); ok {
  340. if !targetDesc.accessor {
  341. if !targetDesc.writable && !targetDesc.configurable && !v.SameAs(targetDesc.value) {
  342. panic(p.val.runtime.NewTypeError("'get' on proxy: property '%s' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '%s' but got '%s')", name.String(), nilSafe(targetDesc.value), ret))
  343. }
  344. } else {
  345. if !targetDesc.configurable && targetDesc.getterFunc == nil && v != _undefined {
  346. panic(p.val.runtime.NewTypeError("'get' on proxy: property '%s' is a non-configurable accessor property on the proxy target and does not have a getter function, but the trap did not return 'undefined' (got '%s')", name.String(), ret))
  347. }
  348. }
  349. }
  350. return v, true
  351. }
  352. return nil, false
  353. }
  354. func (p *proxyObject) proxySet(name, value, receiver Value, throw bool) (bool, bool) {
  355. target := p.target
  356. if v, ok := p.proxyCall(proxy_trap_set, target, name, value, receiver); ok {
  357. if v.ToBoolean() {
  358. if prop, ok := target.getOwnProp(name).(*valueProperty); ok {
  359. if prop.accessor {
  360. if !prop.configurable && prop.setterFunc == nil {
  361. panic(p.val.runtime.NewTypeError("'set' on proxy: trap returned truish for property '%s' which exists in the proxy target as a non-configurable and non-writable accessor property without a setter", name.String()))
  362. }
  363. } else if !prop.configurable && !prop.writable && !p.__sameValue(prop.value, value) {
  364. panic(p.val.runtime.NewTypeError("'set' on proxy: trap returned truish for property '%s' which exists in the proxy target as a non-configurable and non-writable data property with a different value", name.String()))
  365. }
  366. }
  367. return true, true
  368. }
  369. if throw {
  370. panic(p.val.runtime.NewTypeError("'set' on proxy: trap returned falsish for property '%s'", name.String()))
  371. }
  372. return false, true
  373. }
  374. return false, false
  375. }
  376. func (p *proxyObject) setOwnStr(name string, v Value, throw bool) bool {
  377. if res, ok := p.proxySet(newStringValue(name), v, p.val, throw); ok {
  378. return res
  379. }
  380. return p.target.setStr(name, v, p.val, throw)
  381. }
  382. func (p *proxyObject) setOwnIdx(idx valueInt, v Value, throw bool) bool {
  383. if res, ok := p.proxySet(idx.toString(), v, p.val, throw); ok {
  384. return res
  385. }
  386. return p.target.setIdx(idx, v, p.val, throw)
  387. }
  388. func (p *proxyObject) setOwnSym(s *valueSymbol, v Value, throw bool) bool {
  389. if res, ok := p.proxySet(s, v, p.val, throw); ok {
  390. return res
  391. }
  392. return p.target.setSym(s, v, p.val, throw)
  393. }
  394. func (p *proxyObject) setForeignStr(name string, v, receiver Value, throw bool) (bool, bool) {
  395. if res, ok := p.proxySet(newStringValue(name), v, receiver, throw); ok {
  396. return res, true
  397. }
  398. return p.target.setStr(name, v, receiver, throw), true
  399. }
  400. func (p *proxyObject) setForeignIdx(idx valueInt, v, receiver Value, throw bool) (bool, bool) {
  401. if res, ok := p.proxySet(idx.toString(), v, receiver, throw); ok {
  402. return res, true
  403. }
  404. return p.target.setIdx(idx, v, receiver, throw), true
  405. }
  406. func (p *proxyObject) setForeignSym(s *valueSymbol, v, receiver Value, throw bool) (bool, bool) {
  407. if res, ok := p.proxySet(s, v, receiver, throw); ok {
  408. return res, true
  409. }
  410. return p.target.setSym(s, v, receiver, throw), true
  411. }
  412. func (p *proxyObject) proxyDelete(n Value) (bool, bool) {
  413. target := p.target
  414. if v, ok := p.proxyCall(proxy_trap_deleteProperty, target, n); ok {
  415. if v.ToBoolean() {
  416. if targetDesc, ok := target.getOwnProp(n).(*valueProperty); ok {
  417. if !targetDesc.configurable {
  418. panic(p.val.runtime.NewTypeError("'deleteProperty' on proxy: property '%s' is a non-configurable property but the trap returned truish", n.String()))
  419. }
  420. }
  421. return true, true
  422. }
  423. return false, true
  424. }
  425. return false, false
  426. }
  427. func (p *proxyObject) deleteStr(name string, throw bool) bool {
  428. if ret, ok := p.proxyDelete(newStringValue(name)); ok {
  429. return ret
  430. }
  431. return p.target.self.deleteStr(name, throw)
  432. }
  433. func (p *proxyObject) deleteIdx(idx valueInt, throw bool) bool {
  434. if ret, ok := p.proxyDelete(idx.toString()); ok {
  435. return ret
  436. }
  437. return p.target.self.deleteIdx(idx, throw)
  438. }
  439. func (p *proxyObject) deleteSym(s *valueSymbol, throw bool) bool {
  440. if ret, ok := p.proxyDelete(s); ok {
  441. return ret
  442. }
  443. return p.target.self.deleteSym(s, throw)
  444. }
  445. func (p *proxyObject) ownPropertyKeys(all bool, _ []Value) []Value {
  446. if v, ok := p.proxyOwnKeys(); ok {
  447. return v
  448. }
  449. return p.target.self.ownPropertyKeys(all, nil)
  450. }
  451. func (p *proxyObject) proxyOwnKeys() ([]Value, bool) {
  452. target := p.target
  453. if v, ok := p.proxyCall(proxy_trap_ownKeys, p.target); ok {
  454. keys := p.val.runtime.toObject(v)
  455. var keyList []Value
  456. keySet := make(map[Value]struct{})
  457. l := toLength(keys.self.getStr("length", nil))
  458. for k := int64(0); k < l; k++ {
  459. item := keys.self.getIdx(valueInt(k), nil)
  460. if _, ok := item.(valueString); !ok {
  461. if _, ok := item.(*valueSymbol); !ok {
  462. panic(p.val.runtime.NewTypeError("%s is not a valid property name", item.String()))
  463. }
  464. }
  465. keyList = append(keyList, item)
  466. keySet[item] = struct{}{}
  467. }
  468. ext := target.self.isExtensible()
  469. for _, itemName := range target.self.ownPropertyKeys(true, nil) {
  470. if _, exists := keySet[itemName]; exists {
  471. delete(keySet, itemName)
  472. } else {
  473. if !ext {
  474. panic(p.val.runtime.NewTypeError("'ownKeys' on proxy: trap result did not include '%s'", itemName.String()))
  475. }
  476. prop := target.getOwnProp(itemName)
  477. if prop, ok := prop.(*valueProperty); ok && !prop.configurable {
  478. panic(p.val.runtime.NewTypeError("'ownKeys' on proxy: trap result did not include non-configurable '%s'", itemName.String()))
  479. }
  480. }
  481. }
  482. if !ext && len(keyList) > 0 && len(keySet) > 0 {
  483. panic(p.val.runtime.NewTypeError("'ownKeys' on proxy: trap returned extra keys but proxy target is non-extensible"))
  484. }
  485. return keyList, true
  486. }
  487. return nil, false
  488. }
  489. func (p *proxyObject) enumerateUnfiltered() iterNextFunc {
  490. return (&proxyPropIter{
  491. p: p,
  492. names: p.ownKeys(true, nil),
  493. }).next
  494. }
  495. func (p *proxyObject) assertCallable() (call func(FunctionCall) Value, ok bool) {
  496. if p.call != nil {
  497. return func(call FunctionCall) Value {
  498. return p.apply(call)
  499. }, true
  500. }
  501. return nil, false
  502. }
  503. func (p *proxyObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  504. if p.ctor != nil {
  505. return p.construct
  506. }
  507. return nil
  508. }
  509. func (p *proxyObject) apply(call FunctionCall) Value {
  510. if p.call == nil {
  511. p.val.runtime.NewTypeError("proxy target is not a function")
  512. }
  513. if v, ok := p.proxyCall(proxy_trap_apply, p.target, nilSafe(call.This), p.val.runtime.newArrayValues(call.Arguments)); ok {
  514. return v
  515. }
  516. return p.call(call)
  517. }
  518. func (p *proxyObject) construct(args []Value, newTarget *Object) *Object {
  519. if p.ctor == nil {
  520. panic(p.val.runtime.NewTypeError("proxy target is not a constructor"))
  521. }
  522. if newTarget == nil {
  523. newTarget = p.val
  524. }
  525. if v, ok := p.proxyCall(proxy_trap_construct, p.target, p.val.runtime.newArrayValues(args), newTarget); ok {
  526. return p.val.runtime.toObject(v)
  527. }
  528. return p.ctor(args, newTarget)
  529. }
  530. func (p *proxyObject) __isCompatibleDescriptor(extensible bool, desc *PropertyDescriptor, current *valueProperty) bool {
  531. if current == nil {
  532. return extensible
  533. }
  534. /*if desc.Empty() {
  535. return true
  536. }*/
  537. /*if p.__isEquivalentDescriptor(desc, current) {
  538. return true
  539. }*/
  540. if !current.configurable {
  541. if desc.Configurable == FLAG_TRUE {
  542. return false
  543. }
  544. if desc.Enumerable != FLAG_NOT_SET && desc.Enumerable.Bool() != current.enumerable {
  545. return false
  546. }
  547. if p.__isGenericDescriptor(desc) {
  548. return true
  549. }
  550. if p.__isDataDescriptor(desc) != !current.accessor {
  551. return desc.Configurable != FLAG_FALSE
  552. }
  553. if p.__isDataDescriptor(desc) && !current.accessor {
  554. if desc.Configurable == FLAG_FALSE {
  555. if desc.Writable == FLAG_FALSE && current.writable {
  556. return false
  557. }
  558. if desc.Writable == FLAG_FALSE {
  559. if desc.Value != nil && !desc.Value.SameAs(current.value) {
  560. return false
  561. }
  562. }
  563. }
  564. return true
  565. }
  566. if p.__isAccessorDescriptor(desc) && current.accessor {
  567. if desc.Configurable == FLAG_FALSE {
  568. if desc.Setter != nil && desc.Setter.SameAs(current.setterFunc) {
  569. return false
  570. }
  571. if desc.Getter != nil && desc.Getter.SameAs(current.getterFunc) {
  572. return false
  573. }
  574. }
  575. }
  576. }
  577. return true
  578. }
  579. func (p *proxyObject) __isAccessorDescriptor(desc *PropertyDescriptor) bool {
  580. return desc.Setter != nil || desc.Getter != nil
  581. }
  582. func (p *proxyObject) __isDataDescriptor(desc *PropertyDescriptor) bool {
  583. return desc.Value != nil || desc.Writable != FLAG_NOT_SET
  584. }
  585. func (p *proxyObject) __isGenericDescriptor(desc *PropertyDescriptor) bool {
  586. return !p.__isAccessorDescriptor(desc) && !p.__isDataDescriptor(desc)
  587. }
  588. func (p *proxyObject) __sameValue(val1, val2 Value) bool {
  589. if val1 == nil && val2 == nil {
  590. return true
  591. }
  592. if val1 != nil {
  593. return val1.SameAs(val2)
  594. }
  595. return false
  596. }
  597. func (p *proxyObject) filterKeys(vals []Value, all, symbols bool) []Value {
  598. if !all {
  599. k := 0
  600. for i, val := range vals {
  601. var prop Value
  602. if symbols {
  603. if s, ok := val.(*valueSymbol); ok {
  604. prop = p.getOwnPropSym(s)
  605. } else {
  606. continue
  607. }
  608. } else {
  609. if _, ok := val.(*valueSymbol); !ok {
  610. prop = p.getOwnPropStr(val.String())
  611. } else {
  612. continue
  613. }
  614. }
  615. if prop == nil {
  616. continue
  617. }
  618. if prop, ok := prop.(*valueProperty); ok && !prop.enumerable {
  619. continue
  620. }
  621. if k != i {
  622. vals[k] = vals[i]
  623. }
  624. k++
  625. }
  626. vals = vals[:k]
  627. } else {
  628. k := 0
  629. for i, val := range vals {
  630. if _, ok := val.(*valueSymbol); ok != symbols {
  631. continue
  632. }
  633. if k != i {
  634. vals[k] = vals[i]
  635. }
  636. k++
  637. }
  638. vals = vals[:k]
  639. }
  640. return vals
  641. }
  642. func (p *proxyObject) ownKeys(all bool, _ []Value) []Value { // we can assume accum is empty
  643. if vals, ok := p.proxyOwnKeys(); ok {
  644. return p.filterKeys(vals, all, false)
  645. }
  646. return p.target.self.ownKeys(all, nil)
  647. }
  648. func (p *proxyObject) ownSymbols() []Value {
  649. if vals, ok := p.proxyOwnKeys(); ok {
  650. return p.filterKeys(vals, true, true)
  651. }
  652. return p.target.self.ownSymbols()
  653. }
  654. func (p *proxyObject) className() string {
  655. if p.target == nil {
  656. panic(p.val.runtime.NewTypeError("proxy has been revoked"))
  657. }
  658. if p.call != nil || p.ctor != nil {
  659. return classFunction
  660. }
  661. return classObject
  662. }
  663. func (p *proxyObject) revoke() {
  664. p.handler = nil
  665. p.target = nil
  666. }