Esempio n. 1
0
        public override bool Set(EcmaPropertyKey propertyKey, EcmaValue value, RuntimeObject receiver)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.Set);

            if (trap == null)
            {
                return(target.Set(propertyKey, value, receiver));
            }
            if (!(bool)trap.Call(handler, target, propertyKey.ToValue(), value, receiver))
            {
                return(false);
            }
            EcmaPropertyDescriptor descriptor = target.GetOwnProperty(propertyKey);

            if (descriptor != null && !descriptor.Configurable)
            {
                if (descriptor.IsDataDescriptor && !descriptor.Writable && !descriptor.Value.Equals(value, EcmaValueComparison.SameValue))
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                if (descriptor.IsAccessorDescriptor && descriptor.Set == default)
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
            }
            return(true);
        }
Esempio n. 2
0
        public override bool Delete(EcmaPropertyKey propertyKey)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.DeleteProperty);

            if (trap == null)
            {
                return(target.Delete(propertyKey));
            }
            if (!(bool)trap.Call(handler, target, propertyKey.ToValue()))
            {
                return(false);
            }
            EcmaPropertyDescriptor descriptor = target.GetOwnProperty(propertyKey);

            if (descriptor == null)
            {
                return(true);
            }
            if (!descriptor.Configurable)
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            return(true);
        }
Esempio n. 3
0
        public override EcmaPropertyDescriptor GetOwnProperty(EcmaPropertyKey propertyKey)
        {
            RuntimeObject          target     = ThrowIfProxyRevoked();
            RuntimeObject          method     = handler.GetMethod(WellKnownProperty.GetOwnPropertyDescriptor);
            EcmaPropertyDescriptor targetDesc = target.GetOwnProperty(propertyKey);

            if (method != null)
            {
                EcmaValue result = method.Call(handler, target, propertyKey.ToValue());
                if (result.Type == EcmaValueType.Undefined)
                {
                    if (targetDesc != null && (!targetDesc.Configurable || !target.IsExtensible))
                    {
                        throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                    }
                    return(null);
                }
                EcmaPropertyDescriptor resultDesc = EcmaPropertyDescriptor.FromValue(result);
                resultDesc.CompleteDescriptor();
                if (!EcmaPropertyDescriptor.ValidateAndApplyPropertyDescriptor(ref resultDesc, targetDesc, !target.IsExtensible) ||
                    resultDesc.Configurable == false && (targetDesc == null || targetDesc.Configurable == true))
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                return(resultDesc);
            }
            return(targetDesc);
        }
Esempio n. 4
0
        public override bool HasProperty(EcmaPropertyKey propertyKey)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.Has);

            if (trap == null)
            {
                return(target.HasProperty(propertyKey));
            }
            bool result = (bool)trap.Call(handler, target, propertyKey.ToValue());

            if (!result)
            {
                EcmaPropertyDescriptor descriptor = target.GetOwnProperty(propertyKey);
                if (descriptor != null && !descriptor.Configurable)
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                if (!target.IsExtensible)
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
            }
            return(result);
        }
Esempio n. 5
0
        public override RuntimeObject GetPrototypeOf()
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.GetPrototypeOf);

            if (trap == null)
            {
                return(target.GetPrototypeOf());
            }
            EcmaValue handlerProto = trap.Call(handler, target);

            if (handlerProto.Type != EcmaValueType.Object && handlerProto.Type != EcmaValueType.Null)
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            if (target.IsExtensible)
            {
                return(handlerProto.ToObject());
            }
            if (!handlerProto.Equals(target.GetPrototypeOf()))
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            return(handlerProto.ToObject());
        }
Esempio n. 6
0
        public EcmaValue Invoke(EcmaPropertyKey propertyKey, params EcmaValue[] arguments)
        {
            RuntimeObject method = homeObject.GetPrototypeOf().GetMethod(propertyKey);

            if (method == null)
            {
                throw new EcmaTypeErrorException(InternalString.Error.NotFunction);
            }
            return(method.Call(invocation.ThisValue, arguments));
        }
Esempio n. 7
0
        public override EcmaValue Call(EcmaValue thisValue, params EcmaValue[] arguments)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.Apply);

            if (trap == null)
            {
                return(target.Call(thisValue, arguments));
            }
            return(trap.Call(handler, target, thisValue, new EcmaArray(arguments)));
        }
Esempio n. 8
0
        public static EcmaIteratorEnumerator GetIterator(this RuntimeObject obj)
        {
            Guard.ArgumentNotNull(obj, "obj");
            RuntimeObject method = obj.GetMethod(Symbol.Iterator);

            if (method == null)
            {
                throw new EcmaTypeErrorException(InternalString.Error.NotIterable);
            }
            EcmaValue iterator = method.Call(obj);

            Guard.ArgumentIsObject(iterator);
            return(new EcmaIteratorEnumerator(iterator));
        }
Esempio n. 9
0
        public static StatefulIterator GetAsyncIterator(this RuntimeObject obj)
        {
            Guard.ArgumentNotNull(obj, "obj");
            RuntimeObject method = obj.GetMethod(Symbol.AsyncIterator);

            if (method == null)
            {
                EcmaIteratorEnumerator syncIterator = GetIterator(obj);
                return(new AsyncFromSyncIterator(syncIterator));
            }
            EcmaValue iterator = method.Call(obj);

            Guard.ArgumentIsObject(iterator);
            return(iterator.GetUnderlyingObject <AsyncGenerator>());
        }
Esempio n. 10
0
        private bool GetIsExtensible()
        {
            RuntimeObject target       = ThrowIfProxyRevoked();
            RuntimeObject trap         = handler.GetMethod(WellKnownProperty.IsExtensible);
            bool          isExtensible = target.IsExtensible;

            if (trap == null)
            {
                return(isExtensible);
            }
            if ((bool)trap.Call(handler, target) != isExtensible)
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            return(isExtensible);
        }
Esempio n. 11
0
        public override EcmaValue Construct(EcmaValue[] arguments, RuntimeObject newTarget)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.Construct);

            if (trap == null)
            {
                return(target.Construct(arguments, newTarget));
            }
            EcmaValue returnValue = trap.Call(handler, target, new EcmaArray(arguments), newTarget);

            if (returnValue.Type != EcmaValueType.Object)
            {
                throw new EcmaTypeErrorException(InternalString.Error.NotObject);
            }
            return(returnValue);
        }
Esempio n. 12
0
        public override bool PreventExtensions()
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.PreventExtensions);

            if (trap == null)
            {
                return(target.PreventExtensions());
            }
            if ((bool)trap.Call(handler, target))
            {
                if (target.IsExtensible)
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                return(true);
            }
            return(false);
        }
Esempio n. 13
0
        public override bool SetPrototypeOf(RuntimeObject proto)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.SetPrototypeOf);

            if (trap == null)
            {
                return(target.SetPrototypeOf(proto));
            }
            if (!(bool)trap.Call(handler, target, proto))
            {
                return(false);
            }
            if (target.IsExtensible)
            {
                return(true);
            }
            if (!proto.Equals(target.GetPrototypeOf()))
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            return(true);
        }
Esempio n. 14
0
        public override bool DefineOwnProperty(EcmaPropertyKey propertyKey, EcmaPropertyDescriptor descriptor)
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.DefineProperty);

            if (trap == null)
            {
                return(target.DefineOwnProperty(propertyKey, descriptor));
            }
            if (!(bool)trap.Call(handler, target, propertyKey.ToValue(), descriptor.ToValue()))
            {
                return(false);
            }
            bool settingUnconfigurable     = descriptor.Configurable == false;
            EcmaPropertyDescriptor current = target.GetOwnProperty(propertyKey);

            if (current == null)
            {
                if (!target.IsExtensible || settingUnconfigurable)
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
            }
            else
            {
                if (!EcmaPropertyDescriptor.ValidateAndApplyPropertyDescriptor(ref descriptor, current, !target.IsExtensible))
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                if (settingUnconfigurable && current.Configurable)
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
            }
            return(true);
        }
Esempio n. 15
0
        public override IEnumerable <EcmaPropertyKey> GetOwnPropertyKeys()
        {
            RuntimeObject target = ThrowIfProxyRevoked();
            RuntimeObject trap   = handler.GetMethod(WellKnownProperty.OwnKeys);

            if (trap == null)
            {
                return(target.GetOwnPropertyKeys());
            }
            EcmaValue resultArray = trap.Call(handler, target);

            Guard.ArgumentIsObject(resultArray);
            List <EcmaPropertyKey> list = new List <EcmaPropertyKey>();
            long len = resultArray[WellKnownProperty.Length].ToLength();

            for (long i = 0; i < len; i++)
            {
                EcmaValue value = resultArray[i];
                if (!EcmaPropertyKey.IsPropertyKey(value))
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                EcmaPropertyKey key = EcmaPropertyKey.FromValue(value);
                if (list.Contains(key))
                {
                    throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
                }
                list.Add(key);
            }

            List <EcmaPropertyKey> targetKeys                = new List <EcmaPropertyKey>(target.GetOwnPropertyKeys());
            List <EcmaPropertyKey> targetConfigurableKeys    = new List <EcmaPropertyKey>();
            List <EcmaPropertyKey> targetNonConfigurableKeys = new List <EcmaPropertyKey>();

            foreach (EcmaPropertyKey key in targetKeys)
            {
                EcmaPropertyDescriptor descriptor = target.GetOwnProperty(key);
                (descriptor.Configurable != false ? targetConfigurableKeys : targetNonConfigurableKeys).Add(key);
            }
            if (target.IsExtensible && targetNonConfigurableKeys.Count == 0)
            {
                return(list);
            }
            if (!targetNonConfigurableKeys.TrueForAll(list.Contains))
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            if (target.IsExtensible)
            {
                return(list);
            }
            if (!targetConfigurableKeys.TrueForAll(list.Contains))
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            if (!list.TrueForAll(targetKeys.Contains))
            {
                throw new EcmaTypeErrorException(InternalString.Error.InvalidTrapResult);
            }
            return(list);
        }