Exemplo n.º 1
0
        internal JsValue GetValue(object value, bool returnReferenceToPool)
        {
            if (value is JsValue)
            {
                return(value as JsValue);
            }

            if (!(value is Reference))
            {
                return(((Completion)value).Value);
            }

            var reference = value as Reference;

            if (reference._baseValue._type == Types.Undefined)
            {
                JsValue val = default(JsValue);
                if (_referenceResolver != null &&
                    _referenceResolver.TryUnresolvableReference(this, reference, out val))
                {
                    return(val);
                }
                ExceptionHelper.ThrowReferenceError(this, reference.GetReferencedName() + " is not defined");
            }

            var baseValue = reference._baseValue;

            if (reference.IsPropertyReference())
            {
                if (_referenceResolver != null &&
                    _referenceResolver.TryPropertyReference(this, reference, ref baseValue))
                {
                    return(baseValue);
                }

                var referencedName = reference._name;
                if (returnReferenceToPool)
                {
                    _referencePool.Return(reference);
                }
                if (!(reference._baseValue._type != Types.Object && reference._baseValue._type != Types.None))
                {
                    var o = TypeConverter.ToObject(this, baseValue);
                    var v = o.Get(referencedName);
                    return(v);
                }
                else
                {
                    var o    = TypeConverter.ToObject(this, baseValue);
                    var desc = o.GetProperty(referencedName);
                    if (desc == PropertyDescriptor.Undefined)
                    {
                        return(JsValue.Undefined);
                    }

                    if (desc.IsDataDescriptor())
                    {
                        return(desc.Value);
                    }

                    var getter = desc.Get;
                    if (getter.IsUndefined())
                    {
                        return(Undefined.Instance);
                    }

                    var callable = (ICallable)getter.AsObject();
                    return(callable.Call(baseValue, Arguments.Empty));
                }
            }

            var record = (EnvironmentRecord)baseValue;

            if (ReferenceEquals(record, null))
            {
                ExceptionHelper.ThrowArgumentException();
            }

            var bindingValue = record.GetBindingValue(reference._name, reference._strict);

            if (returnReferenceToPool)
            {
                _referencePool.Return(reference);
            }

            return(bindingValue);
        }