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 Engine _engine; private readonly ObjectInstance _bindingObject; private readonly bool _provideThis; public ObjectEnvironmentRecord(Engine engine, ObjectInstance bindingObject, bool provideThis) : base(engine) { _engine = engine; _bindingObject = bindingObject; _provideThis = provideThis; } public override bool HasBinding(string name) { return _bindingObject.HasProperty(name); } /// /// http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.1.2.2 /// /// /// public override void CreateMutableBinding(string name, bool configurable = true) { _bindingObject.DefineOwnProperty(name, new PropertyDescriptor(Undefined.Instance, true, true, configurable), true); } public override void SetMutableBinding(string name, JsValue value, bool strict) { _bindingObject.Put(name, value, strict); } public override JsValue GetBindingValue(string name, bool strict) { // todo: can be optimized if (!_bindingObject.HasProperty(name)) { if(!strict) { return Undefined.Instance; } throw new JavaScriptException(_engine.ReferenceError); } return _bindingObject.Get(name); } public override bool DeleteBinding(string name) { return _bindingObject.Delete(name, false); } public override JsValue ImplicitThisValue() { if (_provideThis) { return new JsValue(_bindingObject); } return Undefined.Instance; } public override string[] GetAllBindingNames() { if (_bindingObject != null) { return _bindingObject.GetOwnProperties().Select( x=> x.Key).ToArray(); } return new string[0]; } } }