public override object ExecIdCall(IdFunctionObject f, Context cx, IScriptable scope, IScriptable thisObj, object [] args) { if (!f.HasTag(OBJECT_TAG)) { return(base.ExecIdCall(f, cx, scope, thisObj, args)); } int id = f.MethodId; switch (id) { case Id_constructor: { if (thisObj != null) { // BaseFunction.construct will set up parent, proto return(f.Construct(cx, scope, args)); } if (args.Length == 0 || args [0] == null || args [0] == Undefined.Value) { return(new BuiltinObject()); } return(ScriptConvert.ToObject(cx, scope, args [0])); } case Id_toLocaleString: // For now just alias toString case Id_toString: { if (cx.HasFeature(Context.Features.ToStringAsSource)) { string s = ScriptRuntime.defaultObjectToSource(cx, scope, thisObj, args); int L = s.Length; if (L != 0 && s [0] == '(' && s [L - 1] == ')') { // Strip () that surrounds toSource s = s.Substring(1, (L - 1) - (1)); } return(s); } return(ScriptRuntime.DefaultObjectToString(thisObj)); } case Id_valueOf: return(thisObj); case Id_hasOwnProperty: { bool result; if (args.Length == 0) { result = false; } else { string s = ScriptRuntime.ToStringIdOrIndex(cx, args [0]); if (s == null) { int index = ScriptRuntime.lastIndexResult(cx); result = thisObj.Has(index, thisObj); } else { result = thisObj.Has(s, thisObj); } } return(result); } case Id_propertyIsEnumerable: { bool result; if (args.Length == 0) { result = false; } else { string s = ScriptRuntime.ToStringIdOrIndex(cx, args [0]); if (s == null) { int index = ScriptRuntime.lastIndexResult(cx); result = thisObj.Has(index, thisObj); if (result && thisObj is ScriptableObject) { ScriptableObject so = (ScriptableObject)thisObj; int attrs = so.GetAttributes(index); result = ((attrs & ScriptableObject.DONTENUM) == 0); } } else { result = thisObj.Has(s, thisObj); if (result && thisObj is ScriptableObject) { ScriptableObject so = (ScriptableObject)thisObj; int attrs = so.GetAttributes(s); result = ((attrs & ScriptableObject.DONTENUM) == 0); } } } return(result); } case Id_isPrototypeOf: { bool result = false; if (args.Length != 0 && args [0] is IScriptable) { IScriptable v = (IScriptable)args [0]; do { v = v.GetPrototype(); if (v == thisObj) { result = true; break; } }while (v != null); } return(result); } case Id_toSource: return(ScriptRuntime.defaultObjectToSource(cx, scope, thisObj, args)); case Id___lookupGetter__: case Id___lookupSetter__: { if (args.Length < 1) { return(Undefined.Value); } string name = ScriptRuntime.ToStringIdOrIndex(cx, args [0]); int index = (name != null) ? name.GetHashCode() : ScriptRuntime.lastIndexResult(cx); // TODO: delegate way up to prototypes? ScriptableObject so = (thisObj as ScriptableObject); if (so == null) { throw ScriptRuntime.TypeError("this is not a scriptable object."); } if (id == Id___lookupGetter__) { return(so.LookupGetter(name)); } else { return(so.LookupSetter(name)); } } case Id___defineGetter__: case Id___defineSetter__: { if (args.Length < 2 || args.Length > 0 && !(args [1] is ICallable)) { object badArg = (args.Length > 1 ? args [1] : Undefined.Value); throw ScriptRuntime.NotFunctionError(badArg); } string name = ScriptRuntime.ToStringIdOrIndex(cx, args [0]); int index = (name != null) ? name.GetHashCode() : ScriptRuntime.lastIndexResult(cx); // TODO: delegate way up to prototypes? ScriptableObject so = (thisObj as ScriptableObject); if (so == null) { throw ScriptRuntime.TypeError("this is not a scriptable object."); } ICallable getterOrSetter = (ICallable)args [1]; if (id == Id___defineGetter__) { if (name == null) { so.DefineGetter(index, getterOrSetter); } else { so.DefineGetter(name, getterOrSetter); } } else { if (name == null) { so.DefineSetter(index, getterOrSetter); } else { so.DefineSetter(name, getterOrSetter); } } return(Undefined.Value); break; } default: throw new ArgumentException(Convert.ToString(id)); } }