示例#1
0
        internal override bool PreventExtensions()
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-preventextensions
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "preventExtensions");

            if (trap == null)
            {
                return(ProxyTarget.PreventExtensions());
            }

            var booleanTrapResult = Agent.ToBoolean(Agent.Call(trap, ProxyHandler, ProxyTarget));

            if (booleanTrapResult)
            {
                var targetIsExtensible = ProxyTarget.IsExtensible;
                if (targetIsExtensible)
                {
                    throw Agent.CreateTypeError();
                }
            }

            return(booleanTrapResult);
        }
示例#2
0
        internal override bool DefineOwnProperty(ScriptValue property, PropertyDescriptor descriptor)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
            Debug.Assert(Agent.IsPropertyKey(property));
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "defineProperty");

            if (trap == null)
            {
                return(ProxyTarget.DefineOwnProperty(property, descriptor));
            }

            var descriptorObject  = ObjectIntrinsics.FromPropertyDescriptor(Agent, descriptor);
            var booleanTrapResult = Agent.ToBoolean(Agent.Call(trap, ProxyHandler, ProxyTarget, property, descriptorObject));

            if (!booleanTrapResult)
            {
                return(false);
            }

            var targetDescriptor = ProxyTarget.GetOwnProperty(property);
            var extensibleTarget = ProxyTarget.IsExtensible;

            var settingConfigFalse = descriptor.Configurable.HasValue && !descriptor.Configurable;

            if (targetDescriptor == null)
            {
                if (!extensibleTarget)
                {
                    throw Agent.CreateTypeError();
                }

                if (settingConfigFalse)
                {
                    throw Agent.CreateTypeError();
                }
            }
            else
            {
                if (!ValidateAndApplyPropertyDescriptor(null, ScriptValue.Undefined, extensibleTarget, descriptor, targetDescriptor))
                {
                    throw Agent.CreateTypeError();
                }
                if (settingConfigFalse && targetDescriptor.Configurable)
                {
                    throw Agent.CreateTypeError();
                }
            }

            return(true);
        }
        public override void StartReaction(object o, EventArgs e)
        {
            Component componentSender = o as Component;

            if (componentSender != null)
            {
                ProxyTarget target = componentSender.gameObject.GetComponent <ProxyTarget>();

                if (target != null)
                {
                    target.FireReactions(o, e);
                }
            }
        }
示例#4
0
        internal override bool Set(ScriptValue property, ScriptValue value, ScriptValue receiver)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
            Debug.Assert(Agent.IsPropertyKey(property));
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "set");

            if (trap == null)
            {
                return(ProxyTarget.Set(property, value, receiver));
            }

            var booleanTrapResult = Agent.ToBoolean(Agent.Call(trap, ProxyHandler, ProxyTarget, property, value, receiver));

            if (!booleanTrapResult)
            {
                return(false);
            }

            var targetDescriptor = ProxyTarget.GetOwnProperty(property);

            if (targetDescriptor != null && !targetDescriptor.Configurable)
            {
                if (targetDescriptor.IsDataDescriptor && !targetDescriptor.Writable)
                {
                    Debug.Assert(targetDescriptor.Value != null, "targetDescriptor.Value != null");
                    if (!value.SameValue(targetDescriptor.Value.Value))
                    {
                        throw Agent.CreateTypeError();
                    }
                }
                else if (targetDescriptor.IsAccessorDescriptor)
                {
                    if (!targetDescriptor.Set.HasValue || targetDescriptor.Set.Value == ScriptValue.Undefined)
                    {
                        throw Agent.CreateTypeError();
                    }
                }
            }

            return(true);
        }
示例#5
0
        internal override ScriptValue Get(ScriptValue property, ScriptValue receiver)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
            Debug.Assert(Agent.IsPropertyKey(property));
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            //Let target be O.[[ProxyTarget]].
            var trap = Agent.GetMethod(ProxyHandler, "get");

            if (trap == null)
            {
                return(ProxyTarget.Get(property, receiver));
            }

            var trapResult       = Agent.Call(trap, ProxyHandler, ProxyTarget, property, receiver);
            var targetDescriptor = ProxyTarget.GetOwnProperty(property);

            if (targetDescriptor != null && !targetDescriptor.Configurable)
            {
                if (targetDescriptor.IsDataDescriptor && !targetDescriptor.Writable)
                {
                    Debug.Assert(targetDescriptor.Value != null, "targetDescriptor.Value != null");
                    if (!trapResult.SameValue(targetDescriptor.Value.Value))
                    {
                        throw Agent.CreateTypeError();
                    }
                }

                if (targetDescriptor.IsAccessorDescriptor && (!targetDescriptor.Get.HasValue || targetDescriptor.Get.Value == ScriptValue.Undefined))
                {
                    if (trapResult != ScriptValue.Undefined)
                    {
                        throw Agent.CreateTypeError();
                    }
                }
            }

            return(trapResult);
        }
示例#6
0
        internal override bool SetPrototypeOf(ScriptObject prototype)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "setPrototypeOf");

            if (trap == null)
            {
                return(ProxyTarget.SetPrototypeOf(prototype));
            }

            var booleanTrapResult = Agent.ToBoolean(Agent.Call(trap, ProxyHandler, ProxyTarget, prototype));

            if (!booleanTrapResult)
            {
                return(false);
            }

            var extensibleTarget = ProxyTarget.IsExtensible;

            if (extensibleTarget)
            {
                return(true);
            }

            var targetPrototype = ProxyTarget.GetPrototypeOf();

            if (prototype != targetPrototype)
            {
                throw Agent.CreateTypeError();
            }

            return(true);
        }
示例#7
0
        public override bool HasProperty(ScriptValue property)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p
            Debug.Assert(Agent.IsPropertyKey(property));
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "has");

            if (trap == null)
            {
                return(ProxyTarget.HasProperty(property));
            }

            var booleanTrapResult = Agent.ToBoolean(Agent.Call(trap, ProxyHandler, ProxyTarget, property));

            if (!booleanTrapResult)
            {
                var targetDescriptor = ProxyTarget.GetOwnProperty(property);
                if (targetDescriptor != null)
                {
                    if (!targetDescriptor.Configurable)
                    {
                        throw Agent.CreateTypeError();
                    }

                    var extensibleTarget = ProxyTarget.IsExtensible;
                    if (!extensibleTarget)
                    {
                        throw Agent.CreateTypeError();
                    }
                }
            }

            return(booleanTrapResult);
        }
示例#8
0
        internal override bool Delete(ScriptValue property)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-delete-p
            Debug.Assert(Agent.IsPropertyKey(property));
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "deleteProperty");

            if (trap == null)
            {
                return(ProxyTarget.Delete(property));
            }

            var booleanTrapResult = Agent.ToBoolean(Agent.Call(trap, ProxyHandler, ProxyTarget, property));

            if (!booleanTrapResult)
            {
                return(false);
            }

            var targetDescriptor = ProxyTarget.GetOwnProperty(property);

            if (targetDescriptor == null)
            {
                return(true);
            }

            if (!targetDescriptor.Configurable)
            {
                throw Agent.CreateTypeError();
            }

            return(true);
        }
示例#9
0
        internal override ScriptObject GetPrototypeOf()
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "getPrototypeOf");

            if (trap == null)
            {
                return(ProxyTarget.GetPrototypeOf());
            }

            var handlerPrototype = Agent.Call(trap, ProxyHandler, ProxyTarget);

            if (handlerPrototype != ScriptValue.Null && !handlerPrototype.IsObject)
            {
                throw Agent.CreateTypeError();
            }

            var extensibleTarget = ProxyTarget.IsExtensible;

            if (extensibleTarget)
            {
                return(handlerPrototype == ScriptValue.Null ? null : (ScriptObject)handlerPrototype);
            }

            var targetPrototype = ProxyTarget.GetPrototypeOf();

            if (!handlerPrototype.SameValue(targetPrototype))
            {
                throw Agent.CreateTypeError();
            }
            return(handlerPrototype == ScriptValue.Null ? null : (ScriptObject)handlerPrototype);
        }
示例#10
0
        internal override IEnumerable <ScriptValue> OwnPropertyKeys()
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys
            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "ownKeys");

            if (trap == null)
            {
                return(ProxyTarget.OwnPropertyKeys());
            }

            var trapResultArray = Agent.Call(trap, ProxyHandler, ProxyTarget);
            var trapResult      = Agent.CreateListFromArrayLike(trapResultArray, new[]
            {
                ScriptValue.Type.String,
                ScriptValue.Type.Symbol
            });

            if (new HashSet <ScriptValue>(trapResult).Count != trapResult.Count)
            {
                throw Agent.CreateTypeError();
            }

            var extensibleTarget = ProxyTarget.IsExtensible;
            var targetKeys       = ProxyTarget.OwnPropertyKeys().ToArray();

            Debug.Assert(targetKeys.All(x => x.IsString || x.IsSymbol));
            Debug.Assert(new HashSet <ScriptValue>(targetKeys).Count == targetKeys.Length);

            var targetConfigurableKeys    = new List <ScriptValue>();
            var targetNonconfigurableKeys = new List <ScriptValue>();

            foreach (var key in targetKeys)
            {
                var descriptor = ProxyTarget.GetOwnProperty(key);
                if (descriptor != null && !descriptor.Configurable)
                {
                    targetNonconfigurableKeys.Add(key);
                }
                else
                {
                    targetConfigurableKeys.Add(key);
                }
            }

            if (extensibleTarget && targetNonconfigurableKeys.Count == 0)
            {
                return(trapResult);
            }

            var uncheckedResultKeys = new HashSet <ScriptValue>(trapResult);

            foreach (var key in targetNonconfigurableKeys)
            {
                if (!uncheckedResultKeys.Contains(key))
                {
                    throw Agent.CreateTypeError();
                }

                uncheckedResultKeys.Remove(key);
            }

            if (extensibleTarget)
            {
                return(trapResult);
            }

            foreach (var key in targetConfigurableKeys)
            {
                if (!uncheckedResultKeys.Contains(key))
                {
                    throw Agent.CreateTypeError();
                }

                uncheckedResultKeys.Remove(key);
            }

            if (uncheckedResultKeys.Count > 0)
            {
                throw Agent.CreateTypeError();
            }

            return(trapResult);
        }
示例#11
0
        internal override PropertyDescriptor GetOwnProperty(ScriptValue property)
        {
            //https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
            Debug.Assert(Agent.IsPropertyKey(property));

            if (ProxyHandler == null)
            {
                throw Agent.CreateTypeError();
            }
            Debug.Assert(ProxyTarget != null, nameof(ProxyTarget) + " != null");

            var trap = Agent.GetMethod(ProxyHandler, "getOwnPropertyDescriptor");

            if (trap == null)
            {
                return(ProxyTarget.GetOwnProperty(property));
            }

            var trapResultObj = Agent.Call(trap, ProxyHandler, ProxyTarget, property);

            if (!trapResultObj.IsObject && trapResultObj != ScriptValue.Undefined)
            {
                throw Agent.CreateTypeError();
            }

            var  targetDescriptor = ProxyTarget.GetOwnProperty(property);
            bool extensibleTarget;

            if (trapResultObj == ScriptValue.Undefined)
            {
                if (targetDescriptor == null)
                {
                    return(null);
                }

                if (!targetDescriptor.Configurable)
                {
                    throw Agent.CreateTypeError();
                }

                extensibleTarget = ProxyTarget.IsExtensible;
                if (!extensibleTarget)
                {
                    throw Agent.CreateTypeError();
                }

                return(null);
            }

            extensibleTarget = ProxyTarget.IsExtensible;
            var resultDescriptor = ObjectIntrinsics.ToPropertyDescriptor(Agent, trapResultObj);

            resultDescriptor.CompletePropertyDescriptor();
            var valid = ValidateAndApplyPropertyDescriptor(null, ScriptValue.Undefined, extensibleTarget, resultDescriptor, targetDescriptor);

            if (!valid)
            {
                throw Agent.CreateTypeError();
            }

            if (!resultDescriptor.Configurable)
            {
                if (targetDescriptor == null || targetDescriptor.Configurable)
                {
                    throw Agent.CreateTypeError();
                }
            }

            return(resultDescriptor);
        }