public void Add(PropertyDescriptor property, PropertyMap map) { var index = GetIndex(property.NameId); var line = _lines[index]; if (line == null) _lines[index] = line = new LineItem(); line.Property = property; line.Map = map; }
///// <summary> ///// List of all DTypes whose prorotype is using this DType! ///// </summary> //LinkedList<WeakReference> _subTypes; ///// <summary> ///// Number of actual fields (as opposed to inherited fields that might be added) ///// if (DObject.DType==this) DObject.Fields.Length >= this.OwnFiledsCount; ///// </summary> //public int OwnFieldsCount { get; private set; } internal PropertyMap(PropertyMapMetadata metadata, PropertyMap parent, PropertyDescriptor property, PropertyDescriptor overriddenProperty) { Metadata = metadata; Parent = parent; Property = property; OverriddenPropery = overriddenProperty; UniqueId = _uniqueIdCounter++; Debug.Assert(Metadata != null, "PropertyMap.Metadata cannot be null"); Debug.Assert(Property != null, "PropertyMap.Property cannot be null"); }
/// <summary> /// This method is public for the compiler to generate faster code by directly manipulating the map when needed /// </summary> public PropertyMap AddOwnProperty(string field, int fieldId, PropertyDescriptor.Attributes attributes) { Debug.Assert(fieldId != Runtime.InvalidFieldId, "Invalid situation! FieldId of {0} is not assigned", field); Debug.Assert(GetOwnPropertyDescriptorByFieldId(fieldId) == null, "Invalid situation! Field {0} alread exists in the map", field); PropertyMap newMap = null; if (_children == null) _children = new Dictionary<int, PropertyMap>(); int key = ((int)attributes << 16) | (fieldId & 0xFFFF); if (!_children.TryGetValue(key, out newMap)) { var overridenProperty = Metadata.GetInheritedPropertyDescriptorByFieldId(fieldId); newMap = new PropertyMap(Metadata, this, new PropertyDescriptor(field, fieldId, this.Property.Index + 1, attributes), overridenProperty); _children[key] = newMap; } return newMap; }
internal void PropagateDeletionDownPrototypeChain(DObject obj, PropertyDescriptor propDesc) { //We should only find at most one matching element foreach (var p in _inheritedProperties) { if (p.NameId == propDesc.NameId) { Debug.Assert(p.IsInherited, "{0} has invalid descriptor type {1}", p.Name, p.GetAttributes()); if (p.Container.Map.Metadata.Level > obj.Map.Metadata.Level) { //this property is inherited from an object lower in the property chain. So no longer need to propogate return; } Debug.Assert(p.Container == obj, "Invalid situation!"); //We check to see if the property exists in higher parts of protoype chain var upperPropDesc = obj.Map.Metadata.GetInheritedPropertyDescriptorByFieldId(propDesc.NameId); if (upperPropDesc == null || upperPropDesc.IsUndefined) { p.Container = null; p.Index = propDesc.Index; p.ResetAttributes(PropertyDescriptor.Attributes.Undefined); } else { if (p.Container != upperPropDesc.Container) { if (p.ObjectCacheIndex != -1 && p.ObjectCacheIndex < Runtime._inheritPropertyObjectCache.Length) { Runtime._inheritPropertyObjectCache[p.ObjectCacheIndex] = null; } } p.Container = upperPropDesc.Container; p.Index = upperPropDesc.Index; p.ResetAttributes(upperPropDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited); } } } foreach (var child in _children) if (child.IsAlive) (child.Target as PropertyMapMetadata).PropagateDeletionDownPrototypeChain(obj, propDesc); }
internal void PropagateAdditionDownPrototypeChain(DObject obj, PropertyDescriptor propDesc) { //We should only find at most one matching element foreach (var p in _inheritedProperties) { if (p.NameId == propDesc.NameId) { if (p.IsUndefined) { p.Container = obj; p.Index = propDesc.Index; p.ResetAttributes(propDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited); } else { Debug.Assert(p.IsInherited, "{0} has invalid descriptor type {1}", p.Name, p.GetAttributes()); if (p.Container.Map.Metadata.Level > obj.Map.Metadata.Level) { //this property is inherited from an object lower in the property chain. So no longer need to propogate return; } if (p.Container != obj && p.Container.Map.Metadata.Level < obj.Map.Metadata.Level) { p.Container = obj; p.Index = propDesc.Index; p.ResetAttributes(propDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited); if (p.ObjectCacheIndex != -1 && p.ObjectCacheIndex < Runtime._inheritPropertyObjectCache.Length) { Runtime._inheritPropertyObjectCache[p.ObjectCacheIndex] = null; } } } } } foreach (var child in _children) if (child.IsAlive) (child.Target as PropertyMapMetadata).PropagateAdditionDownPrototypeChain(obj, propDesc); }
PropertyDescriptor AddInheritedProperty(PropertyDescriptor propDesc) { if (propDesc != null) { var inheritedPD = AddInheritedProperty(propDesc.Name, propDesc.NameId, propDesc.Index, propDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited); if (propDesc.IsInherited) inheritedPD.Container = propDesc.Container; else inheritedPD.Container = Prototype; return inheritedPD; } return null; }
internal PropertyDescriptor AddInheritedProperty(string field, int fieldId, int index, PropertyDescriptor.Attributes attributes = PropertyDescriptor.Attributes.Undefined) { var propDesc = new PropertyDescriptor(field, fieldId, index, attributes); _inheritedProperties.AddFirst(propDesc); return propDesc; }
protected Runtime(RuntimeConfiguration configuration) { _inheritPropertyObjectCacheMaxIndex = 0; //We need to first set the Instance since the following constructors may use it! Runtime.Instance = this; Configuration = configuration; configuration.ParseArgs();//Do this now before anyone tries to read any configuration value. if (configuration.EnableTimers) { Timers = new m.Util.Timers(); _timer = StartSimpleTimer(true, "MCJS"); } if (configuration.EnableCounters) Counters = new m.Util.Counters(); EmptyPropertyMapMetadata = new PropertyMapMetadata(null); ///We can initialize commong field Ids to save lookups later ValueOfFieldId = GetFieldId("valueOf"); ToStringFieldId = GetFieldId("toString"); PrototypeFieldId = GetFieldId("prototype"); LengthFieldId = GetFieldId("length"); ///In each instance of Runtime we need to first reset prototypes in case a program has changed them //DUndefinedPrototype = new DObject(root.Root); DObjectPrototype = new DObject(EmptyPropertyMapMetadata.Root); DObjectMap = GetRootMapOfPrototype(DObjectPrototype); DFunctionPrototype = new DObject(DObjectMap); DFunctionMap = GetRootMapOfPrototype(DFunctionPrototype); DNumberPrototype = new DObject(DObjectMap); DNumberMap = GetRootMapOfPrototype(DNumberPrototype); DStringPrototype = new DObject(DObjectMap); DStringMap = GetRootMapOfPrototype(DStringPrototype); DBooleanPrototype = new DObject(DObjectMap); DBooleanMap = GetRootMapOfPrototype(DBooleanPrototype); DArrayPrototype = new DObject(DObjectMap); DArrayMap = GetRootMapOfPrototype(DArrayPrototype); DRegExpPrototype = new DObject(DObjectMap); DRegExpMap = GetRootMapOfPrototype(DRegExpPrototype); //Now need to recreate default values based on fresh prototypes. DefaultDUndefined = new DUndefined(); DefaultDNull = new DNull(); //DefaultDObject = new DObject(); //DefaultDDouble = new DDouble(default(double)); //DefaultDString = new DString(default(string)); //DefaultDInt = new DInt(default(int)); //DefaultDBoolean = new DBoolean(default(bool)); //DefaultDFunction = new DFunction(null); //DefaultDArray = new DArray(); //DefaultDProperty = new DProperty(); ArrayItemAccessor = new PropertyDescriptor(null) { Getter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { value = (obj as DArray).Elements[pd.Index]; /*if (mdr.Runtime.Instance.Configuration.ProfileStats) { mdr.Runtime.Instance.Counters.GetCounter("ArrayItemAccessor").Count++; }*/ }, Setter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { (obj as DArray).Elements[pd.Index] = value; }, }; StringItemAccessor = new PropertyDescriptor(null) { Getter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { var strObj = obj.FirstInPrototypeChainAs<DString>(); value.Set(strObj.PrimitiveValue.AsString()[pd.Index]); }, Setter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { var strObj = obj.FirstInPrototypeChainAs<DString>(); var chars = strObj.PrimitiveValue.AsString().ToCharArray(); chars[pd.Index] = value.AsChar(); strObj.PrimitiveValue.Set(new String(chars)); }, }; var lengthFieldName = GetFieldName(LengthFieldId); ProtoInitializer.InitDArrayPrototype(DArrayPrototype, lengthFieldName); ProtoInitializer.InitDStringPrototype(DStringPrototype, lengthFieldName); var protoFieldName = GetFieldName(PrototypeFieldId); ProtoInitializer.InitDFunctionPrototype(DFunctionPrototype, protoFieldName, PrototypeFieldId); }
static public void UpdateLastAcessedPropertyCache(int index, PropertyMap map, PropertyDescriptor pd) { //We need to check the index and extent or map if needed. //index &=0xFFFF _lastAccessedPropertyCache[index].Map = map; _lastAccessedPropertyCache[index].Map = map; _lastAccessedPropertyCache[index].PropDesc = pd; }
static public int UpdateInheritPropertyObjectCache(PropertyDescriptor pd) { if (pd.ObjectCacheIndex != -1) { return pd.ObjectCacheIndex; } if (_inheritPropertyObjectCacheMaxIndex < _inheritPropertyObjectCache.Length) { _inheritPropertyObjectCache[_inheritPropertyObjectCacheMaxIndex] = pd.Container; pd.ObjectCacheIndex = _inheritPropertyObjectCacheMaxIndex; _inheritPropertyObjectCacheMaxIndex++; // Trace.WriteLine("inherit pobject index = {0}", _inheritPropertyObjectCacheMaxIndex); return _inheritPropertyObjectCacheMaxIndex - 1; } else { return -1; } }
public static PropertyDescriptor UpdateMapProfile(PropertyDescriptor pd, mjr.CodeGen.Profiler profiler, int profileIndex, PropertyMap map) { if (profiler != null) { profiler.GetOrAddMapNodeProfile(profileIndex).UpdateNodeProfile(map, pd); } return pd; }
internal PropertyDescriptor AddOwnProperty(DObject obj, string field, int fieldId, PropertyDescriptor.Attributes attributes) { PropertyMap newMap = AddOwnProperty(field, fieldId, attributes); obj.Map = newMap; var mapMetadata = Metadata.GetMapMetadataOfPrototype(obj, false); if (mapMetadata != null) mapMetadata.PropagateAdditionDownPrototypeChain(obj, newMap.Property); //obj is some other objects' prototype return newMap.Property; }