Пример #1
0
        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));
            }
        }