using System; using System.Linq; using Jint.Native; using Jint.Native.Object; using Jint.Runtime.Descriptors; namespace Jint.Runtime.Environments { /// /// Represents an object environment record /// http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.1.2 /// public sealed class ObjectEnvironmentRecord : EnvironmentRecord { private readonly ObjectInstance _bindingObject; private readonly bool _provideThis; public ObjectEnvironmentRecord(Engine engine, ObjectInstance bindingObject, bool provideThis) : base(engine) { _bindingObject = bindingObject; _provideThis = provideThis; } public override bool HasBinding(in Key name) { return _bindingObject.HasProperty(name); } internal override bool TryGetBinding( in Key name, bool strict, out Binding binding, out JsValue value) { // we unwrap by name binding = default; var desc = _bindingObject.GetProperty(name); if (desc == PropertyDescriptor.Undefined) { value = default; return false; } value = ObjectInstance.UnwrapJsValue(desc, this); return true; } /// /// http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.1.2.2 /// public override void CreateMutableBinding(in Key name, JsValue value, bool configurable = true) { var propertyDescriptor = configurable ? new PropertyDescriptor(value, PropertyFlag.ConfigurableEnumerableWritable) : new PropertyDescriptor(value, PropertyFlag.NonConfigurable); _bindingObject.SetOwnProperty(name, propertyDescriptor); } public override void SetMutableBinding(in Key name, JsValue value, bool strict) { _bindingObject.Put(name, value, strict); } public override JsValue GetBindingValue(in Key name, bool strict) { var desc = _bindingObject.GetProperty(name); if (strict && desc == PropertyDescriptor.Undefined) { ExceptionHelper.ThrowReferenceError(_engine, name); } return ObjectInstance.UnwrapJsValue(desc, this); } public override bool DeleteBinding(in Key name) { return _bindingObject.Delete(name, false); } public override JsValue ImplicitThisValue() { if (_provideThis) { return _bindingObject; } return Undefined; } public override string[] GetAllBindingNames() { if (!ReferenceEquals(_bindingObject, null)) { return _bindingObject.GetOwnProperties().Select( x=> x.Key).ToArray(); } return ArrayExt.Empty(); } public override bool Equals(JsValue other) { return ReferenceEquals(_bindingObject, other); } internal override void FunctionWasCalled() { } } }