public static bool CallProperty(mdr.DObject input, string propName, out mdr.DValue output) { if (input != null) { var propDesc = input.GetPropertyDescriptor(propName); var prop = new mdr.DValue(); propDesc.Get(input, ref prop); mdr.DFunction func = null; if (prop.ValueType == mdr.ValueTypes.Function) { func = prop.AsDFunction(); //if (toString != null) //{ mdr.CallFrame callFrame = new mdr.CallFrame(); callFrame.This = (input); callFrame.Function = func; func.Call(ref callFrame); if (ValueTypesHelper.IsPrimitive(callFrame.Return.ValueType)) { output = callFrame.Return; return(true); } } } output = new mdr.DValue(); output.SetUndefined(); return(false); }
//ECMA-262 15.2.4.2 void toString(ref mdr.CallFrame callFrame) { DObject obj; if (!ValueTypesHelper.IsDefined(callFrame.This.ValueType)) { obj = Runtime.Instance.GlobalContext; } else { obj = callFrame.This; } //callFrame.Return.Set(obj.ToString()); callFrame.Return.Set(string.Format("[object {0}]", obj.Map.Metadata.Name)); }
//ECMA-262 section 15.2.3.5 void create(ref mdr.CallFrame callFrame) { Debug.WriteLine("calling JSObject.create"); var O = callFrame.Arg0.AsDObject(); if (O == null) { Trace.Fail("TypeError"); } var obj = new DObject(O); var props = callFrame.Arg1.AsDObject(); if (!ValueTypesHelper.IsUndefined(props.ValueType)) { DefineProperties(obj, props); } callFrame.Return.Set(obj); }
//ECMA-262 15.2.4.7 void propertyIsEnumerable(ref mdr.CallFrame callFrame) { DObject obj; if (!ValueTypesHelper.IsDefined(callFrame.This.ValueType)) { obj = Runtime.Instance.GlobalContext; } else { obj = callFrame.This; } //callFrame.Return.Set(obj.ToString()); if (callFrame.PassedArgsCount == 1) { string toString; if (callFrame.Arg0.ValueType == ValueTypes.String) { toString = callFrame.Arg0.AsString(); } else { toString = callFrame.Arg0.AsDObject().GetField("toString").AsString(); } PropertyDescriptor pd = obj.GetPropertyDescriptor(toString); if (pd != null) { callFrame.Return.Set(!pd.IsNotEnumerable); } else { callFrame.Return.Set(false); } } else { callFrame.Return.Set(false); } }
private void DefineProperty(DObject O, string name, DObject desc) { if (desc == null || O == null || name == null) { Trace.Fail("TypeError"); } var getter = new DValue(); var setter = new DValue(); var value = new DValue(); var attributes = PropertyDescriptor.Attributes.NotEnumerable | PropertyDescriptor.Attributes.NotWritable | PropertyDescriptor.Attributes.NotConfigurable; attributes = PropertyDescriptor.Attributes.NotEnumerable | PropertyDescriptor.Attributes.NotWritable | PropertyDescriptor.Attributes.NotConfigurable; getter.SetUndefined(); setter.SetUndefined(); value.SetUndefined(); value = desc.HasProperty("value") ? desc.GetField("value") : value; if (desc.HasProperty("enumerable")) { attributes &= desc.GetField("enumerable").AsBoolean() ? ~PropertyDescriptor.Attributes.NotEnumerable : attributes; } if (desc.HasProperty("configurable")) { attributes &= desc.GetField("configurable").AsBoolean() ? ~PropertyDescriptor.Attributes.NotConfigurable : attributes; } if (desc.HasProperty("writable")) { attributes &= desc.GetField("writable").AsBoolean() ? ~PropertyDescriptor.Attributes.NotWritable : attributes; } if (desc.HasProperty("get")) { getter = desc.GetField("get"); if (!ValueTypesHelper.IsUndefined(getter.ValueType) && !ValueTypesHelper.IsFunction(getter.ValueType)) { Trace.Fail("TypeError"); } } if (desc.HasProperty("set")) { setter = desc.GetField("set"); if (!ValueTypesHelper.IsUndefined(setter.ValueType) && !ValueTypesHelper.IsFunction(setter.ValueType)) { Trace.Fail("TypeError"); } } Trace.Assert( !((desc.HasProperty("get") || desc.HasProperty("set")) && (desc.HasProperty("value") || desc.HasProperty("writable"))), "If either getter or setter needs to be defined, value or writable shouldn't be defined."); if (desc.HasProperty("value")) { O.DefineOwnProperty(name, ref value, attributes | PropertyDescriptor.Attributes.Data); } else { var property = new DProperty(); if (ValueTypesHelper.IsFunction(getter.ValueType)) { property.Getter = getter.AsDFunction(); } if (ValueTypesHelper.IsFunction(setter.ValueType)) { property.Setter = setter.AsDFunction(); } O.DefineOwnProperty(name, property, attributes | PropertyDescriptor.Attributes.Accessor); } }
/// <summary> /// ECMA-262, 8.12.8: Implements [[DefaultValue]] for JS objects /// </summary> /// <param name="input"></param> /// <param name="output"></param> /// <param name="stringHint">Specifies whether the hint is string or number. Default is number.</param> public static void DefaultValue(ref mdr.DValue input, out mdr.DValue output, bool stringHint = false) { Debug.Assert(ValueTypesHelper.IsObject(input.ValueType)); DefaultValue(input.AsDObject(), out output, stringHint); }