} // LookupProperty // Store the given property under the given name, overwriting any // existing property of the same name. protected override void StoreProperty(string propName, JProperty prop) { Trace.Assert(prop.name == propName); UInt32 arrayIndex; if (propName == "length") { UInt32 newLength = JConvert.ToUInt32(prop.value); if (newLength != JConvert.ToNumber(prop.value)) throw new RangeError("array length set to a value outside the UInt32 range"); if (entries.Count > newLength) entries.RemoveRange((int)newLength, (int)(entries.Count - newLength)); if (newLength < arrayLength) for (uint i=newLength; i<=arrayLength && sparsePropertyCount > 0; i++) { string iAsString = ArrayIndexToString(i); if (props.ContainsKey(iAsString)) { sparsePropertyCount--; props.Remove(iAsString); } } arrayLength = newLength; } else if (IsArrayIndex(propName, out arrayIndex)) { Trace.Assert(prop.attributes == JProperty.AttrFlags.none); if (arrayIndex < entries.Count) { // This index is already in our entries array; update it. entries[(int)arrayIndex] = prop.value; } else if (arrayIndex == entries.Count) { // This index lands just after our entries array. Extend // the entries array to include it. entries.Add(prop.value); if (arrayIndex >= arrayLength) arrayLength = arrayIndex + 1; // Then, if there were any further adjacent entries being // stored in the hash table, move them to the entries array. while (sparsePropertyCount > 0) { string indexAsString = ArrayIndexToString((uint)(entries.Count)); if (props.ContainsKey(indexAsString)) { JProperty tempProp = (JProperty) (props[indexAsString]); entries.Add(tempProp.value); sparsePropertyCount--; props.Remove(indexAsString); } } } else { if (arrayIndex >= arrayLength) arrayLength = arrayIndex + 1; if (!props.ContainsKey(propName)) sparsePropertyCount++; base.StoreProperty(propName, prop); } } else base.StoreProperty(propName, prop); } // StoreProperty
} // ArrayConstructor // If this object has a property of the given name, fill in prop // and return true. Otherwise, return false (and prop is in an // undefined state). public override bool LookupProperty(string propName, out JProperty prop) { UInt32 arrayIndex; if (propName == "length") { prop.attributes = JProperty.AttrFlags.dontEnum | JProperty.AttrFlags.dontDelete; prop.name = propName; prop.value = arrayLength; return true; } else if (IsArrayIndex(propName, out arrayIndex) && arrayIndex < entries.Count) { prop.attributes = JProperty.AttrFlags.none; prop.name = propName; prop.value = entries[(int)arrayIndex]; return true; } else return base.LookupProperty(propName, out prop); } // LookupProperty
} // StringConstructor // If this object has a property of the given name, fill in prop // and return true. Otherwise, return false (and prop is in an // undefined state). public override bool LookupProperty(string propName, out JProperty prop) { if (propName == "length") { prop.attributes = JProperty.AttrFlags.readOnly | JProperty.AttrFlags.dontEnum | JProperty.AttrFlags.dontDelete; prop.name = propName; prop.value = value.Length; return true; } else return base.LookupProperty(propName, out prop); } // LookupProperty
} // LookupProperty // Store the given property under the given name, overwriting any // existing property of the same name. protected virtual void StoreProperty(string propName, JProperty prop) { Trace.Assert(prop.name == propName); props[propName] = prop; } // StoreProperty
} // HasOwnProperty // If this object has a property of the given name, fill in prop // and return true. Otherwise, return false (and prop is in an // undefined state). public virtual bool LookupProperty(string propName, out JProperty prop) { if (props.ContainsKey(propName)) { prop = (JProperty) (props[propName]); return true; } else { // Fill in prop to silence a compiler warning for uninitialized "out" prop.attributes = JProperty.AttrFlags.none; prop.name = null; prop.value = null; return false; } } // LookupProperty
// If this object has a property of the given name, fill in prop // and return true. Otherwise, return false (and prop is in an // undefined state). // // We override this to define the "prototype" property on first // use. public override bool LookupProperty(string propName, out JProperty prop) { bool result = base.LookupProperty(propName, out prop); if (!result && propName == "prototype") { prop.attributes = JProperty.AttrFlags.none; prop.name = propName; prop.value = InstancePrototype; StoreProperty(propName, prop); return true; } return result; } // LookupProperty