123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- package goja
- type Proxy struct {
- proxy *proxyObject
- }
- type proxyPropIter struct {
- p *proxyObject
- names []Value
- idx int
- }
- func (i *proxyPropIter) next() (propIterItem, iterNextFunc) {
- for i.idx < len(i.names) {
- name := i.names[i.idx]
- i.idx++
- if prop := i.p.val.getOwnProp(name); prop != nil {
- return propIterItem{name: name.String(), value: prop}, i.next
- }
- }
- if proto := i.p.proto(); proto != nil {
- return proto.self.enumerateUnfiltered()()
- }
- return propIterItem{}, nil
- }
- func (r *Runtime) newProxyObject(target *Object, handler *Object, proto *Object) *proxyObject {
- if p, ok := target.self.(*proxyObject); ok {
- if p.handler == nil {
- panic(r.NewTypeError("Cannot create proxy with a revoked proxy as target"))
- }
- }
- if p, ok := handler.self.(*proxyObject); ok {
- if p.handler == nil {
- panic(r.NewTypeError("Cannot create proxy with a revoked proxy as handler"))
- }
- }
- v := &Object{runtime: r}
- p := &proxyObject{}
- v.self = p
- p.val = v
- p.class = classObject
- if proto == nil {
- p.prototype = r.global.ObjectPrototype
- } else {
- p.prototype = proto
- }
- p.extensible = false
- p.init()
- p.target = target
- p.handler = handler
- if call, ok := target.self.assertCallable(); ok {
- p.call = call
- }
- if ctor := target.self.assertConstructor(); ctor != nil {
- p.ctor = ctor
- }
- return p
- }
- func (p *Proxy) Revoke() {
- p.proxy.revoke()
- }
- type proxyTrap string
- const (
- proxy_trap_getPrototypeOf = "getPrototypeOf"
- proxy_trap_setPrototypeOf = "setPrototypeOf"
- proxy_trap_isExtensible = "isExtensible"
- proxy_trap_preventExtensions = "preventExtensions"
- proxy_trap_getOwnPropertyDescriptor = "getOwnPropertyDescriptor"
- proxy_trap_defineProperty = "defineProperty"
- proxy_trap_has = "has"
- proxy_trap_get = "get"
- proxy_trap_set = "set"
- proxy_trap_deleteProperty = "deleteProperty"
- proxy_trap_ownKeys = "ownKeys"
- proxy_trap_apply = "apply"
- proxy_trap_construct = "construct"
- )
- func (p proxyTrap) String() (name string) {
- return string(p)
- }
- type proxyObject struct {
- baseObject
- target *Object
- handler *Object
- call func(FunctionCall) Value
- ctor func(args []Value, newTarget *Object) *Object
- }
- func (p *proxyObject) proxyCall(trap proxyTrap, args ...Value) (Value, bool) {
- r := p.val.runtime
- if p.handler == nil {
- panic(r.NewTypeError("Proxy already revoked"))
- }
- if m := toMethod(r.getVStr(p.handler, trap.String())); m != nil {
- return m(FunctionCall{
- This: p.handler,
- Arguments: args,
- }), true
- }
- return nil, false
- }
- func (p *proxyObject) proto() *Object {
- if v, ok := p.proxyCall(proxy_trap_getPrototypeOf, p.target); ok {
- var handlerProto *Object
- if v != _null {
- handlerProto = p.val.runtime.toObject(v)
- }
- if !p.target.self.isExtensible() && !p.__sameValue(handlerProto, p.target.self.proto()) {
- panic(p.val.runtime.NewTypeError("'getPrototypeOf' on proxy: proxy target is non-extensible but the trap did not return its actual prototype"))
- }
- return handlerProto
- }
- return p.target.self.proto()
- }
- func (p *proxyObject) setProto(proto *Object, throw bool) bool {
- if v, ok := p.proxyCall(proxy_trap_setPrototypeOf, p.target, proto); ok {
- if v.ToBoolean() {
- if !p.target.self.isExtensible() && !p.__sameValue(proto, p.target.self.proto()) {
- panic(p.val.runtime.NewTypeError("'setPrototypeOf' on proxy: trap returned truish for setting a new prototype on the non-extensible proxy target"))
- }
- return true
- } else {
- p.val.runtime.typeErrorResult(throw, "'setPrototypeOf' on proxy: trap returned falsish")
- }
- }
- return p.target.self.setProto(proto, throw)
- }
- func (p *proxyObject) isExtensible() bool {
- if v, ok := p.proxyCall(proxy_trap_isExtensible, p.target); ok {
- booleanTrapResult := v.ToBoolean()
- if te := p.target.self.isExtensible(); booleanTrapResult != te {
- panic(p.val.runtime.NewTypeError("'isExtensible' on proxy: trap result does not reflect extensibility of proxy target (which is '%v')", te))
- }
- return booleanTrapResult
- }
- return p.target.self.isExtensible()
- }
- func (p *proxyObject) preventExtensions(throw bool) bool {
- if v, ok := p.proxyCall(proxy_trap_preventExtensions, p.target); ok {
- booleanTrapResult := v.ToBoolean()
- if !booleanTrapResult {
- p.val.runtime.typeErrorResult(throw, "'preventExtensions' on proxy: trap returned falsish")
- return false
- }
- if te := p.target.self.isExtensible(); booleanTrapResult && te {
- panic(p.val.runtime.NewTypeError("'preventExtensions' on proxy: trap returned truish but the proxy target is extensible"))
- }
- }
- return p.target.self.preventExtensions(throw)
- }
- func propToValueProp(v Value) *valueProperty {
- if v == nil {
- return nil
- }
- if v, ok := v.(*valueProperty); ok {
- return v
- }
- return &valueProperty{
- value: v,
- writable: true,
- configurable: true,
- enumerable: true,
- }
- }
- func (p *proxyObject) proxyDefineOwnProperty(name Value, descr PropertyDescriptor, throw bool) (bool, bool) {
- if v, ok := p.proxyCall(proxy_trap_defineProperty, p.target, name, descr.toValue(p.val.runtime)); ok {
- booleanTrapResult := v.ToBoolean()
- if !booleanTrapResult {
- p.val.runtime.typeErrorResult(throw, "'defineProperty' on proxy: trap returned falsish")
- return false, true
- }
- targetDesc := propToValueProp(p.target.getOwnProp(name))
- extensibleTarget := p.target.self.isExtensible()
- settingConfigFalse := descr.Configurable == FLAG_FALSE
- if targetDesc == nil {
- if !extensibleTarget {
- panic(p.val.runtime.NewTypeError())
- }
- if settingConfigFalse {
- panic(p.val.runtime.NewTypeError())
- }
- } else {
- if !p.__isCompatibleDescriptor(extensibleTarget, &descr, targetDesc) {
- panic(p.val.runtime.NewTypeError())
- }
- if settingConfigFalse && targetDesc.configurable {
- panic(p.val.runtime.NewTypeError())
- }
- }
- return booleanTrapResult, true
- }
- return false, false
- }
- func (p *proxyObject) defineOwnPropertyStr(name string, descr PropertyDescriptor, throw bool) bool {
- if v, ok := p.proxyDefineOwnProperty(newStringValue(name), descr, throw); ok {
- return v
- }
- return p.target.self.defineOwnPropertyStr(name, descr, throw)
- }
- func (p *proxyObject) defineOwnPropertyIdx(idx valueInt, descr PropertyDescriptor, throw bool) bool {
- if v, ok := p.proxyDefineOwnProperty(idx, descr, throw); ok {
- return v
- }
- return p.target.self.defineOwnPropertyIdx(idx, descr, throw)
- }
- func (p *proxyObject) defineOwnPropertySym(s *valueSymbol, descr PropertyDescriptor, throw bool) bool {
- if v, ok := p.proxyDefineOwnProperty(s, descr, throw); ok {
- return v
- }
- return p.target.self.defineOwnPropertySym(s, descr, throw)
- }
- func (p *proxyObject) proxyHas(name Value) (bool, bool) {
- if v, ok := p.proxyCall(proxy_trap_has, p.target, name); ok {
- booleanTrapResult := v.ToBoolean()
- if !booleanTrapResult {
- targetDesc := propToValueProp(p.target.getOwnProp(name))
- if targetDesc != nil {
- if !targetDesc.configurable {
- 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()))
- }
- if !p.target.self.isExtensible() {
- panic(p.val.runtime.NewTypeError("'has' on proxy: trap returned falsish for property '%s' but the proxy target is not extensible", name.String()))
- }
- }
- }
- return booleanTrapResult, true
- }
- return false, false
- }
- func (p *proxyObject) hasPropertyStr(name string) bool {
- if b, ok := p.proxyHas(newStringValue(name)); ok {
- return b
- }
- return p.target.self.hasPropertyStr(name)
- }
- func (p *proxyObject) hasPropertyIdx(idx valueInt) bool {
- if b, ok := p.proxyHas(idx); ok {
- return b
- }
- return p.target.self.hasPropertyIdx(idx)
- }
- func (p *proxyObject) hasPropertySym(s *valueSymbol) bool {
- if b, ok := p.proxyHas(s); ok {
- return b
- }
- return p.target.self.hasPropertySym(s)
- }
- func (p *proxyObject) hasOwnPropertyStr(name string) bool {
- return p.getOwnPropStr(name) != nil
- }
- func (p *proxyObject) hasOwnPropertyIdx(idx valueInt) bool {
- return p.getOwnPropIdx(idx) != nil
- }
- func (p *proxyObject) hasOwnPropertySym(s *valueSymbol) bool {
- return p.getOwnPropSym(s) != nil
- }
- func (p *proxyObject) proxyGetOwnPropertyDescriptor(name Value) (Value, bool) {
- target := p.target
- if v, ok := p.proxyCall(proxy_trap_getOwnPropertyDescriptor, target, name); ok {
- r := p.val.runtime
- targetDesc := propToValueProp(target.getOwnProp(name))
- var trapResultObj *Object
- if v != nil && v != _undefined {
- if obj, ok := v.(*Object); ok {
- trapResultObj = obj
- } else {
- panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap returned neither object nor undefined for property '%s'", name.String()))
- }
- }
- if trapResultObj == nil {
- if targetDesc == nil {
- return nil, true
- }
- if !targetDesc.configurable {
- panic(r.NewTypeError())
- }
- if !target.self.isExtensible() {
- panic(r.NewTypeError())
- }
- return nil, true
- }
- extensibleTarget := target.self.isExtensible()
- resultDesc := r.toPropertyDescriptor(trapResultObj)
- resultDesc.complete()
- if !p.__isCompatibleDescriptor(extensibleTarget, &resultDesc, targetDesc) {
- 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()))
- }
- if resultDesc.Configurable == FLAG_FALSE {
- if targetDesc == nil {
- panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '%s' which is non-existent in the proxy target", name.String()))
- }
- if targetDesc.configurable {
- panic(r.NewTypeError("'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '%s' which is configurable in the proxy target", name.String()))
- }
- }
- if resultDesc.Writable == FLAG_TRUE && resultDesc.Configurable == FLAG_TRUE &&
- resultDesc.Enumerable == FLAG_TRUE {
- return resultDesc.Value, true
- }
- return r.toValueProp(trapResultObj), true
- }
- return nil, false
- }
- func (p *proxyObject) getOwnPropStr(name string) Value {
- if v, ok := p.proxyGetOwnPropertyDescriptor(newStringValue(name)); ok {
- return v
- }
- return p.target.self.getOwnPropStr(name)
- }
- func (p *proxyObject) getOwnPropIdx(idx valueInt) Value {
- if v, ok := p.proxyGetOwnPropertyDescriptor(idx.toString()); ok {
- return v
- }
- return p.target.self.getOwnPropIdx(idx)
- }
- func (p *proxyObject) getOwnPropSym(s *valueSymbol) Value {
- if v, ok := p.proxyGetOwnPropertyDescriptor(s); ok {
- return v
- }
- return p.target.self.getOwnPropSym(s)
- }
- func (p *proxyObject) getStr(name string, receiver Value) Value {
- if v, ok := p.proxyGet(newStringValue(name), receiver); ok {
- return v
- }
- return p.target.self.getStr(name, receiver)
- }
- func (p *proxyObject) getIdx(idx valueInt, receiver Value) Value {
- if v, ok := p.proxyGet(idx.toString(), receiver); ok {
- return v
- }
- return p.target.self.getIdx(idx, receiver)
- }
- func (p *proxyObject) getSym(s *valueSymbol, receiver Value) Value {
- if v, ok := p.proxyGet(s, receiver); ok {
- return v
- }
- return p.target.self.getSym(s, receiver)
- }
- func (p *proxyObject) proxyGet(name, receiver Value) (Value, bool) {
- target := p.target
- if v, ok := p.proxyCall(proxy_trap_get, target, name, receiver); ok {
- if targetDesc, ok := target.getOwnProp(name).(*valueProperty); ok {
- if !targetDesc.accessor {
- if !targetDesc.writable && !targetDesc.configurable && !v.SameAs(targetDesc.value) {
- 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))
- }
- } else {
- if !targetDesc.configurable && targetDesc.getterFunc == nil && v != _undefined {
- 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))
- }
- }
- }
- return v, true
- }
- return nil, false
- }
- func (p *proxyObject) proxySet(name, value, receiver Value, throw bool) (bool, bool) {
- target := p.target
- if v, ok := p.proxyCall(proxy_trap_set, target, name, value, receiver); ok {
- if v.ToBoolean() {
- if prop, ok := target.getOwnProp(name).(*valueProperty); ok {
- if prop.accessor {
- if !prop.configurable && prop.setterFunc == nil {
- 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()))
- }
- } else if !prop.configurable && !prop.writable && !p.__sameValue(prop.value, value) {
- 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()))
- }
- }
- return true, true
- }
- if throw {
- panic(p.val.runtime.NewTypeError("'set' on proxy: trap returned falsish for property '%s'", name.String()))
- }
- return false, true
- }
- return false, false
- }
- func (p *proxyObject) setOwnStr(name string, v Value, throw bool) bool {
- if res, ok := p.proxySet(newStringValue(name), v, p.val, throw); ok {
- return res
- }
- return p.target.setStr(name, v, p.val, throw)
- }
- func (p *proxyObject) setOwnIdx(idx valueInt, v Value, throw bool) bool {
- if res, ok := p.proxySet(idx.toString(), v, p.val, throw); ok {
- return res
- }
- return p.target.setIdx(idx, v, p.val, throw)
- }
- func (p *proxyObject) setOwnSym(s *valueSymbol, v Value, throw bool) bool {
- if res, ok := p.proxySet(s, v, p.val, throw); ok {
- return res
- }
- return p.target.setSym(s, v, p.val, throw)
- }
- func (p *proxyObject) setForeignStr(name string, v, receiver Value, throw bool) (bool, bool) {
- if res, ok := p.proxySet(newStringValue(name), v, receiver, throw); ok {
- return res, true
- }
- return p.target.setStr(name, v, receiver, throw), true
- }
- func (p *proxyObject) setForeignIdx(idx valueInt, v, receiver Value, throw bool) (bool, bool) {
- if res, ok := p.proxySet(idx.toString(), v, receiver, throw); ok {
- return res, true
- }
- return p.target.setIdx(idx, v, receiver, throw), true
- }
- func (p *proxyObject) setForeignSym(s *valueSymbol, v, receiver Value, throw bool) (bool, bool) {
- if res, ok := p.proxySet(s, v, receiver, throw); ok {
- return res, true
- }
- return p.target.setSym(s, v, receiver, throw), true
- }
- func (p *proxyObject) proxyDelete(n Value) (bool, bool) {
- target := p.target
- if v, ok := p.proxyCall(proxy_trap_deleteProperty, target, n); ok {
- if v.ToBoolean() {
- if targetDesc, ok := target.getOwnProp(n).(*valueProperty); ok {
- if !targetDesc.configurable {
- panic(p.val.runtime.NewTypeError("'deleteProperty' on proxy: property '%s' is a non-configurable property but the trap returned truish", n.String()))
- }
- }
- return true, true
- }
- return false, true
- }
- return false, false
- }
- func (p *proxyObject) deleteStr(name string, throw bool) bool {
- if ret, ok := p.proxyDelete(newStringValue(name)); ok {
- return ret
- }
- return p.target.self.deleteStr(name, throw)
- }
- func (p *proxyObject) deleteIdx(idx valueInt, throw bool) bool {
- if ret, ok := p.proxyDelete(idx.toString()); ok {
- return ret
- }
- return p.target.self.deleteIdx(idx, throw)
- }
- func (p *proxyObject) deleteSym(s *valueSymbol, throw bool) bool {
- if ret, ok := p.proxyDelete(s); ok {
- return ret
- }
- return p.target.self.deleteSym(s, throw)
- }
- func (p *proxyObject) ownPropertyKeys(all bool, _ []Value) []Value {
- if v, ok := p.proxyOwnKeys(); ok {
- return v
- }
- return p.target.self.ownPropertyKeys(all, nil)
- }
- func (p *proxyObject) proxyOwnKeys() ([]Value, bool) {
- target := p.target
- if v, ok := p.proxyCall(proxy_trap_ownKeys, p.target); ok {
- keys := p.val.runtime.toObject(v)
- var keyList []Value
- keySet := make(map[Value]struct{})
- l := toLength(keys.self.getStr("length", nil))
- for k := int64(0); k < l; k++ {
- item := keys.self.getIdx(valueInt(k), nil)
- if _, ok := item.(valueString); !ok {
- if _, ok := item.(*valueSymbol); !ok {
- panic(p.val.runtime.NewTypeError("%s is not a valid property name", item.String()))
- }
- }
- keyList = append(keyList, item)
- keySet[item] = struct{}{}
- }
- ext := target.self.isExtensible()
- for _, itemName := range target.self.ownPropertyKeys(true, nil) {
- if _, exists := keySet[itemName]; exists {
- delete(keySet, itemName)
- } else {
- if !ext {
- panic(p.val.runtime.NewTypeError("'ownKeys' on proxy: trap result did not include '%s'", itemName.String()))
- }
- prop := target.getOwnProp(itemName)
- if prop, ok := prop.(*valueProperty); ok && !prop.configurable {
- panic(p.val.runtime.NewTypeError("'ownKeys' on proxy: trap result did not include non-configurable '%s'", itemName.String()))
- }
- }
- }
- if !ext && len(keyList) > 0 && len(keySet) > 0 {
- panic(p.val.runtime.NewTypeError("'ownKeys' on proxy: trap returned extra keys but proxy target is non-extensible"))
- }
- return keyList, true
- }
- return nil, false
- }
- func (p *proxyObject) enumerateUnfiltered() iterNextFunc {
- return (&proxyPropIter{
- p: p,
- names: p.ownKeys(true, nil),
- }).next
- }
- func (p *proxyObject) assertCallable() (call func(FunctionCall) Value, ok bool) {
- if p.call != nil {
- return func(call FunctionCall) Value {
- return p.apply(call)
- }, true
- }
- return nil, false
- }
- func (p *proxyObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
- if p.ctor != nil {
- return p.construct
- }
- return nil
- }
- func (p *proxyObject) apply(call FunctionCall) Value {
- if p.call == nil {
- p.val.runtime.NewTypeError("proxy target is not a function")
- }
- if v, ok := p.proxyCall(proxy_trap_apply, p.target, nilSafe(call.This), p.val.runtime.newArrayValues(call.Arguments)); ok {
- return v
- }
- return p.call(call)
- }
- func (p *proxyObject) construct(args []Value, newTarget *Object) *Object {
- if p.ctor == nil {
- panic(p.val.runtime.NewTypeError("proxy target is not a constructor"))
- }
- if newTarget == nil {
- newTarget = p.val
- }
- if v, ok := p.proxyCall(proxy_trap_construct, p.target, p.val.runtime.newArrayValues(args), newTarget); ok {
- return p.val.runtime.toObject(v)
- }
- return p.ctor(args, newTarget)
- }
- func (p *proxyObject) __isCompatibleDescriptor(extensible bool, desc *PropertyDescriptor, current *valueProperty) bool {
- if current == nil {
- return extensible
- }
- /*if desc.Empty() {
- return true
- }*/
- /*if p.__isEquivalentDescriptor(desc, current) {
- return true
- }*/
- if !current.configurable {
- if desc.Configurable == FLAG_TRUE {
- return false
- }
- if desc.Enumerable != FLAG_NOT_SET && desc.Enumerable.Bool() != current.enumerable {
- return false
- }
- if p.__isGenericDescriptor(desc) {
- return true
- }
- if p.__isDataDescriptor(desc) != !current.accessor {
- return desc.Configurable != FLAG_FALSE
- }
- if p.__isDataDescriptor(desc) && !current.accessor {
- if desc.Configurable == FLAG_FALSE {
- if desc.Writable == FLAG_FALSE && current.writable {
- return false
- }
- if desc.Writable == FLAG_FALSE {
- if desc.Value != nil && !desc.Value.SameAs(current.value) {
- return false
- }
- }
- }
- return true
- }
- if p.__isAccessorDescriptor(desc) && current.accessor {
- if desc.Configurable == FLAG_FALSE {
- if desc.Setter != nil && desc.Setter.SameAs(current.setterFunc) {
- return false
- }
- if desc.Getter != nil && desc.Getter.SameAs(current.getterFunc) {
- return false
- }
- }
- }
- }
- return true
- }
- func (p *proxyObject) __isAccessorDescriptor(desc *PropertyDescriptor) bool {
- return desc.Setter != nil || desc.Getter != nil
- }
- func (p *proxyObject) __isDataDescriptor(desc *PropertyDescriptor) bool {
- return desc.Value != nil || desc.Writable != FLAG_NOT_SET
- }
- func (p *proxyObject) __isGenericDescriptor(desc *PropertyDescriptor) bool {
- return !p.__isAccessorDescriptor(desc) && !p.__isDataDescriptor(desc)
- }
- func (p *proxyObject) __sameValue(val1, val2 Value) bool {
- if val1 == nil && val2 == nil {
- return true
- }
- if val1 != nil {
- return val1.SameAs(val2)
- }
- return false
- }
- func (p *proxyObject) filterKeys(vals []Value, all, symbols bool) []Value {
- if !all {
- k := 0
- for i, val := range vals {
- var prop Value
- if symbols {
- if s, ok := val.(*valueSymbol); ok {
- prop = p.getOwnPropSym(s)
- } else {
- continue
- }
- } else {
- if _, ok := val.(*valueSymbol); !ok {
- prop = p.getOwnPropStr(val.String())
- } else {
- continue
- }
- }
- if prop == nil {
- continue
- }
- if prop, ok := prop.(*valueProperty); ok && !prop.enumerable {
- continue
- }
- if k != i {
- vals[k] = vals[i]
- }
- k++
- }
- vals = vals[:k]
- } else {
- k := 0
- for i, val := range vals {
- if _, ok := val.(*valueSymbol); ok != symbols {
- continue
- }
- if k != i {
- vals[k] = vals[i]
- }
- k++
- }
- vals = vals[:k]
- }
- return vals
- }
- func (p *proxyObject) ownKeys(all bool, _ []Value) []Value { // we can assume accum is empty
- if vals, ok := p.proxyOwnKeys(); ok {
- return p.filterKeys(vals, all, false)
- }
- return p.target.self.ownKeys(all, nil)
- }
- func (p *proxyObject) ownSymbols() []Value {
- if vals, ok := p.proxyOwnKeys(); ok {
- return p.filterKeys(vals, true, true)
- }
- return p.target.self.ownSymbols()
- }
- func (p *proxyObject) className() string {
- if p.target == nil {
- panic(p.val.runtime.NewTypeError("proxy has been revoked"))
- }
- if p.call != nil || p.ctor != nil {
- return classFunction
- }
- return classObject
- }
- func (p *proxyObject) revoke() {
- p.handler = nil
- p.target = nil
- }
|