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); }