internal static Descriptor ToPropertyDesciptor( IGlobal global, JsDictionaryObject owner, string name, JsInstance jsInstance) { if (jsInstance.Class != "Object") { throw new JsException((JsInstance)global.TypeErrorClass.New("The target object has to be an instance of an object")); } JsObject jsObject = (JsObject)jsInstance; if ((jsObject.HasProperty("value") || jsObject.HasProperty("writable")) && (jsObject.HasProperty("set") || jsObject.HasProperty("get"))) { throw new JsException((JsInstance)global.TypeErrorClass.New("The property cannot be both writable and have get/set accessors or cannot have both a value and an accessor defined")); } JsInstance result = (JsInstance)null; Descriptor descriptor = !jsObject.HasProperty("value") ? (Descriptor) new PropertyDescriptor(global, owner, name) : (Descriptor) new ValueDescriptor(owner, name, jsObject["value"]); if (jsObject.TryGetProperty("enumerable", out result)) { descriptor.Enumerable = result.ToBoolean(); } if (jsObject.TryGetProperty("configurable", out result)) { descriptor.Configurable = result.ToBoolean(); } if (jsObject.TryGetProperty("writable", out result)) { descriptor.Writable = result.ToBoolean(); } if (jsObject.TryGetProperty("get", out result)) { if (!(result is JsFunction)) { throw new JsException((JsInstance)global.TypeErrorClass.New("The getter has to be a function")); } ((PropertyDescriptor)descriptor).GetFunction = (JsFunction)result; } if (jsObject.TryGetProperty("set", out result)) { if (!(result is JsFunction)) { throw new JsException((JsInstance)global.TypeErrorClass.New("The setter has to be a function")); } ((PropertyDescriptor)descriptor).SetFunction = (JsFunction)result; } return(descriptor); }
public JsBoolean Compare(JsInstance x, JsInstance y) { if (x.IsClr && y.IsClr) { return Global.BooleanClass.New(x.Value.Equals(y.Value)); } if (x.IsClr) { return Compare(x.ToPrimitive(Global), y); } if (y.IsClr) { return Compare(x, y.ToPrimitive(Global)); } if (x.Type == y.Type) { // if both are Objects but then only one is Clrs if (x == JsUndefined.Instance) { return Global.BooleanClass.True; } else if (x == JsNull.Instance) { return Global.BooleanClass.True; } else if (x.Type == JsInstance.TYPE_NUMBER) { if (x.ToNumber() == double.NaN) { return Global.BooleanClass.False; } else if (y.ToNumber() == double.NaN) { return Global.BooleanClass.False; } else if (x.ToNumber() == y.ToNumber()) { return Global.BooleanClass.True; } else { return Global.BooleanClass.False; } } else if (x.Type == JsInstance.TYPE_STRING) { return Global.BooleanClass.New(x.ToString() == y.ToString()); } else if (x.Type == JsInstance.TYPE_BOOLEAN) { return Global.BooleanClass.New(x.ToBoolean() == y.ToBoolean()); } else if (x.Type == JsInstance.TYPE_OBJECT ) { return Global.BooleanClass.New(x == y); } else { return Global.BooleanClass.New(x.Value.Equals(y.Value)); } } else if (x == JsNull.Instance && y == JsUndefined.Instance) { return Global.BooleanClass.True; } else if (x == JsUndefined.Instance && y == JsNull.Instance) { return Global.BooleanClass.True; } else if (x.Type == JsInstance.TYPE_NUMBER && y.Type == JsInstance.TYPE_STRING) { return Global.BooleanClass.New(x.ToNumber() == y.ToNumber()); } else if (x.Type == JsInstance.TYPE_STRING && y.Type == JsInstance.TYPE_NUMBER) { return Global.BooleanClass.New(x.ToNumber() == y.ToNumber()); } else if (x.Type == JsInstance.TYPE_BOOLEAN || y.Type == JsInstance.TYPE_BOOLEAN) { return Global.BooleanClass.New(x.ToNumber() == y.ToNumber()); } else if (y.Type == JsInstance.TYPE_OBJECT && (x.Type == JsInstance.TYPE_STRING || x.Type == JsInstance.TYPE_NUMBER)) { return Compare(x, y.ToPrimitive(Global)); } else if (x.Type == JsInstance.TYPE_OBJECT && (y.Type == JsInstance.TYPE_STRING || y.Type == JsInstance.TYPE_NUMBER)) { return Compare(x.ToPrimitive(Global), y); } else { return Global.BooleanClass.False; } }
/// <summary> /// 8.10.5 /// </summary> /// <param name="global"></param> /// <param name="obj"></param> /// <returns></returns> internal static Descriptor ToPropertyDesciptor(IGlobal global, JsDictionaryObject owner, string name, JsInstance jsInstance) { if (jsInstance.Class != JsObject.TYPEOF) { throw new JsException(global.TypeErrorClass.New("The target object has to be an instance of an object")); } JsObject obj = (JsObject)jsInstance; if ((obj.HasProperty("value") || obj.HasProperty("writable")) && (obj.HasProperty("set") || obj.HasProperty("get"))) { throw new JsException(global.TypeErrorClass.New("The property cannot be both writable and have get/set accessors or cannot have both a value and an accessor defined")); } Descriptor desc; JsInstance result = null; if (obj.HasProperty("value")) { desc = new ValueDescriptor(owner, name, obj["value"]); } else { desc = new PropertyDescriptor(global, owner, name); } if (obj.TryGetProperty("enumerable", out result)) { desc.Enumerable = result.ToBoolean(); } if (obj.TryGetProperty("configurable", out result)) { desc.Configurable = result.ToBoolean(); } if (obj.TryGetProperty("writable", out result)) { desc.Writable = result.ToBoolean(); } if (obj.TryGetProperty("get", out result)) { if (result.Class != JsFunction.TYPEOF) { throw new JsException(global.TypeErrorClass.New("The getter has to be a function")); } ((PropertyDescriptor)desc).GetFunction = (JsFunction)result; } if (obj.TryGetProperty("set", out result)) { if (result.Class != JsFunction.TYPEOF) { throw new JsException(global.TypeErrorClass.New("The setter has to be a function")); } ((PropertyDescriptor)desc).SetFunction = (JsFunction)result; } return(desc); }