예제 #1
0
 internal JSFunctionObject(functionExpressionNode def, JSEnvRec Scope)
     : base(JSContext.CurrentGlobalContext.FunctionPrototype, JSContext.CurrentGlobalContext.FunctionCtor)
 {
     this.FunctionDef = def;
     JSObject p = new JSObject();
     p.SetDataProp("constructor", this, true, false, true);
     base.SetDataProp("prototype", p, true, false, false);
     this.Scope = Scope;
 }
예제 #2
0
 private void AddRegExp()
 {
     this.RegExpCtor = new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         string pattern;
         string flags;
         JSValue v = args[0];
         if (AsConstructor && (v is JSRegExp))
         {
             return v;
         }
         if (v is JSRegExp)
         {
             pattern = v["source"].StringValue();
         }
         else if (v is JSUndefined)
         {
             pattern = "";
         }
         else
         {
             pattern = v.StringValue();
         }
         v = args[1];
         if (v is JSUndefined)
         {
             flags = "";
         }
         else
         {
             flags = v.StringValue();
         }
         return new JSRegExp(this.RegExpPrototype, this.RegExpCtor, pattern, flags);
     });
     this.RegExpPrototype = new JSObject(this.ObjectPrototype, this.RegExpCtor);
     this.RegExpCtor.SetDataProp("prototype", this.RegExpPrototype, false, false, false);
 }
예제 #3
0
 public JSGlobalScope(JSEnvRec Parent, JSObject ScopeObject)
     : base(Parent, ScopeObject)
 {
 }
예제 #4
0
 private void AddFunction()
 {
     this.FunctionCtor = new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         string argNames;
         string sBody;
         if (args.Count > 1)
         {
             string[] ar = new string[args.Count - 1];
             for (int i = 0; i < (args.Count - 1); i++)
             {
                 ar[i] = args[i].StringValue();
             }
             argNames = string.Join(",", ar);
         }
         else
         {
             argNames = "";
         }
         if (args.Count == 0)
         {
             sBody = "";
         }
         else
         {
             sBody = args[args.Count - 1].StringValue();
         }
         JSFunctionObject r = CompiledScript.Compile("(function (" + argNames + ") {" + sBody + "})", false).Run() as JSFunctionObject;
         r.Scope = JSContext.CurrentGlobalContext.LexicalEnv;
         return r;
     }, 1);
     this.FunctionPrototype = new JSFunctionBase();
     this.FunctionPrototype.SetDataProp("constructor", this.FunctionCtor, true, false, true);
     this.FunctionPrototype.SetDataProp("call", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSArgs newArgs;
         if (AsConstructor)
         {
             throw new JSRuntimeException("TypeError", "Function.call called as constructor");
         }
         JSFunctionBase fnc = InternalUtilities.JSFunctionCast(ThisObj);
         if (args.Count == 0)
         {
             newArgs = args;
         }
         else
         {
             JSValue[] newAr = new JSValue[args.Count - 1];
             Array.Copy(args.ArgValues, 1, newAr, 0, args.Count - 1);
             newArgs = new JSArgs(ThisObj, newAr);
         }
         return fnc.Call(Scope, args[0], newArgs);
     }, 1), true, false, true);
     this.FunctionPrototype.SetDataProp("apply", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         if (AsConstructor)
         {
             throw new JSRuntimeException("TypeError", "Function.apply called as constructor");
         }
         JSFunctionBase fnc = InternalUtilities.JSFunctionCast(ThisObj);
         JSValue argArray = args[1];
         if ((argArray is JSUndefined) || (argArray is JSNull))
         {
             return fnc.Call(Scope, args[0], new JSArgs(ThisObj, new JSValue[0]));
         }
         if (!(argArray is JSObject))
         {
             throw new JSRuntimeException("TypeError", "Invalid argument to Function.apply");
         }
         JSValue olen = argArray["length"];
         if (!olen.CheckCoercible())
         {
             throw new JSRuntimeException("TypeError", "Invalid argument to Function.apply");
         }
         double nlen = olen.NumberValue();
         uint len = nlen.JSToUInt32();
         if (len != nlen)
         {
             throw new JSRuntimeException("TypeError", "Invalid argument to Function.apply");
         }
         JSValue[] newAr = new JSValue[len];
         for (int i = 0; i < len; i++)
         {
             newAr[i] = argArray[i.ToString()];
         }
         return fnc.Call(Scope, args[0], new JSArgs(ThisObj, newAr));
     }, 2), true, false, true);
     this.FunctionPrototype.SetDataProp("toString", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         return InternalUtilities.JSFunctionCast(ThisObj).GenerateString();
     }), true, false, true);
     this.FunctionPrototype.SetDataProp("length", 0.0, true, false, true);
     this.FunctionCtor.SetDataProp("prototype", this.FunctionPrototype, false, false, false);
 }
예제 #5
0
 private void AddArray()
 {
     this.ArrayCtor = new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs Args, bool AsConstructor)
     {
         if ((Args.Count == 1) && (Args[0] is JSNumber))
         {
             double n = Args[0].NumberValue();
             uint i = n.JSToUInt32();
             if (n != i)
             {
                 throw new JSRuntimeException("RangeError", "invalid array length");
             }
             return new JSArray(i);
         }
         return new JSArray(Args.ArgValues);
     }, 1);
     this.ArrayPrototype = new JSArray(this.ObjectPrototype, this.ArrayCtor);
     this.ArrayCtor.SetDataProp("prototype", this.ArrayPrototype, false, false, false);
 }
예제 #6
0
 public JSObjectScope(JSEnvRec Parent, JSObject ScopeObject)
     : base(Parent)
 {
     this.ScopeObject = ScopeObject;
 }
예제 #7
0
 private static void UpdatePropertyDescriptor(JSObject O, string P, JSObject desc)
 {
     JSValue tmp;
     JSValue value = JSUndefined.Instance;
     JSFunctionBase getter = null;
     JSFunctionBase setter = null;
     bool enumerable = true;
     bool configurable = true;
     bool writable = true;
     bool hasValue = false;
     bool hasGet = false;
     bool hasSet = false;
     bool hasEnumerable = false;
     bool hasConfigurable = false;
     bool hasWritable = false;
     if (desc.TryGetPropertyValue("enumerable", out tmp))
     {
         enumerable = tmp.BoolValue();
         hasEnumerable = true;
     }
     if (desc.TryGetPropertyValue("configurable", out tmp))
     {
         configurable = tmp.BoolValue();
         hasConfigurable = true;
     }
     if (desc.TryGetPropertyValue("value", out tmp))
     {
         value = tmp;
         hasValue = true;
     }
     if (desc.TryGetPropertyValue("writable", out tmp))
     {
         writable = tmp.BoolValue();
         hasWritable = true;
     }
     if (desc.TryGetPropertyValue("get", out tmp))
     {
         if (tmp is JSUndefined)
         {
             getter = null;
         }
         else
         {
             if (!(tmp is JSFunctionBase))
             {
                 throw new JSRuntimeException("TypeError", "invalid 'get' property in property descriptor");
             }
             getter = (JSFunctionBase)tmp;
         }
         hasGet = true;
     }
     if (desc.TryGetPropertyValue("set", out tmp))
     {
         if (tmp is JSUndefined)
         {
             setter = null;
         }
         else
         {
             if (!(tmp is JSFunctionBase))
             {
                 throw new JSRuntimeException("TypeError", "invalid 'set' property in property descriptor");
             }
             setter = (JSFunctionBase)tmp;
         }
         hasSet = true;
     }
     if (hasValue || hasGet || hasSet || hasEnumerable || hasConfigurable || hasWritable)
     {
         PropWrapper newProp;
         bool bIsAccessor;
         if (!(hasGet || hasSet))
         {
             bIsAccessor = false;
         }
         else
         {
             if (hasValue || hasWritable)
             {
                 throw new JSRuntimeException("TypeError", "property descriptor contained values for both data and accessor");
             }
             bIsAccessor = true;
         }
         PropWrapper oldProp = O.GetOwnPropertyRef(P);
         if (oldProp == null)
         {
             if (!O.IsExtensible)
             {
                 throw new JSRuntimeException("TypeError", "object is not extensible");
             }
             if (bIsAccessor)
             {
                 newProp = new AccessorProperty(getter, setter, writable, enumerable, configurable);
             }
             else
             {
                 newProp = new DataProperty(value, writable, enumerable, configurable);
             }
         }
         else
         {
             if (oldProp is DataProperty)
             {
                 DataProperty _o = oldProp as DataProperty;
                 if ((((!hasValue || JSValue.JSEqualsExact(value, _o.Value)) && (!hasEnumerable || (writable == oldProp.Writable))) && (!hasConfigurable || (enumerable == oldProp.Enumerable))) && (!hasWritable || (configurable == oldProp.Configurable)))
                 {
                     return;
                 }
             }
             else if (oldProp is AccessorProperty)
             {
                 AccessorProperty _o = oldProp as AccessorProperty;
                 if ((((!hasEnumerable || (writable == oldProp.Writable)) && (!hasConfigurable || (enumerable == oldProp.Enumerable))) && (!hasGet || (getter == _o.Getter))) && (!hasSet || (setter == _o.Setter)))
                 {
                     return;
                 }
             }
             if (!oldProp.Configurable)
             {
                 throw new JSRuntimeException("TypeError", "property is not configurable");
             }
             if ((bIsAccessor && (oldProp is AccessorProperty)) || (!bIsAccessor && (oldProp is DataProperty)))
             {
                 newProp = oldProp;
             }
             else if (bIsAccessor)
             {
                 newProp = new AccessorProperty(getter, setter);
             }
             else
             {
                 newProp = new DataProperty(value);
             }
             if (hasConfigurable)
             {
                 newProp.Configurable = configurable;
             }
             if (hasEnumerable)
             {
                 newProp.Enumerable = enumerable;
             }
             if (bIsAccessor)
             {
                 if (hasGet)
                 {
                     ((AccessorProperty)newProp).Getter = getter;
                 }
                 if (hasSet)
                 {
                     ((AccessorProperty)newProp).Setter = setter;
                 }
             }
             else
             {
                 if (hasWritable)
                 {
                     ((DataProperty)newProp).Value = value;
                 }
                 if (hasValue)
                 {
                     newProp.Set(O, value);
                 }
             }
         }
         O.SetProp(P, newProp);
     }
 }
예제 #8
0
 private void AddObjectProperties()
 {
     this.Global.SetDataProp("Object", this.ObjectCtor, false, false, false);
     this.ObjectCtor.SetDataProp("getPrototypeOf", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "getPrototypeOf argument not an object");
         }
         JSValue r = arg.Prototype;
         if (r == null)
         {
             return JSNull.Instance;
         }
         return r;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("getOwnPropertyNames", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "getOwnPropertyNames argument not an object");
         }
         IList<KeyValuePair<string, PropWrapper>> c = arg.GetOwnProperties();
         List<JSValue> ar = new List<JSValue>();
         foreach (KeyValuePair<string, PropWrapper> p in c)
         {
             if (p.Value.Enumerable)
             {
                 ar.Add(p.Key);
             }
         }
         return new JSArray(ar.ToArray());
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("create", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSValue arg = args[0];
         if (!((arg is JSObject) || (arg is JSNull)))
         {
             throw new JSRuntimeException("TypeError", "invalid prototype passed to Object.create");
         }
         if (arg is JSNull)
         {
             arg = null;
         }
         JSObject obj = new JSObject(arg);
         if (args.Count > 1)
         {
             throw new NotImplementedException();
         }
         return obj;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("defineProperty", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject O = args[0] as JSObject;
         if (O == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.defineProperty");
         }
         string P = args[1].StringValue();
         JSObject desc = args[2].ToJSObject();
         UpdatePropertyDescriptor(O, P, desc);
         return O;
     }, 3), true, false, true);
     this.ObjectCtor.SetDataProp("defineProperties", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         throw new Exception();
     }), true, false, true);
     this.ObjectCtor.SetDataProp("seal", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.seal");
         }
         foreach (KeyValuePair<string, PropWrapper> p in arg.GetOwnProperties())
         {
             p.Value.Configurable = false;
         }
         arg.IsExtensible = false;
         return arg;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("freeze", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.freeze");
         }
         foreach (KeyValuePair<string, PropWrapper> p in arg.GetOwnProperties())
         {
             if (p.Value is DataProperty)
             {
                 p.Value.Writable = false;
             }
             p.Value.Configurable = false;
         }
         arg.IsExtensible = false;
         return arg;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("preventExtensions", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.preventExtensions");
         }
         arg.IsExtensible = false;
         return arg;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("isSealed", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.isSealed");
         }
         if (arg.IsExtensible)
         {
             return JSBool.False;
         }
         foreach (KeyValuePair<string, PropWrapper> p in arg.GetOwnProperties())
         {
             if (p.Value.Configurable)
             {
                 return JSBool.False;
             }
         }
         return JSBool.True;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("isFrozen", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.isFrozen");
         }
         if (arg.IsExtensible)
         {
             return JSBool.False;
         }
         foreach (KeyValuePair<string, PropWrapper> p in arg.GetOwnProperties())
         {
             if ((p.Value is DataProperty) && p.Value.Writable)
             {
                 return JSBool.False;
             }
             if (p.Value.Configurable)
             {
                 return JSBool.False;
             }
         }
         return JSBool.True;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("isExtensible", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.isExtensible");
         }
         return arg.IsExtensible;
     }, 1), true, false, true);
     this.ObjectCtor.SetDataProp("keys", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSObject arg = args[0] as JSObject;
         if (arg == null)
         {
             throw new JSRuntimeException("TypeError", "invalid argument passed to Object.keys");
         }
         IList<KeyValuePair<string, PropWrapper>> ar = arg.GetOwnProperties();
         List<JSValue> ar2 = new List<JSValue>();
         for (int i = 0; i < ar.Count; i++)
         {
             KeyValuePair<string, PropWrapper> p = ar[i];
             if (p.Value.Enumerable)
             {
                 ar2.Add(p.Key);
             }
         }
         return new JSArray(ar2.ToArray());
     }, 1), true, false, true);
     this.ObjectPrototype.SetDataProp("toString", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         return "[object " + ThisObj.ClassString + "]";
     }), true, false, true);
     this.ObjectPrototype.SetDataProp("toLocaleString", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         return ((JSFunctionBase)ThisObj.ToJSObject()["toString"]).Call(Scope, ThisObj, args);
     }), true, false, true);
     this.ObjectPrototype.SetDataProp("valueOf", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         return ThisObj;
     }), true, false, true);
     this.ObjectPrototype.SetDataProp("hasOwnProperty", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         return ThisObj.HasOwnProperty(args[0].StringValue());
     }, 1), true, false, true);
     this.ObjectPrototype.SetDataProp("isPrototypeOf", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSValue v = args[0];
         while (true)
         {
             v = v.Prototype;
             if (v == null)
             {
                 return JSBool.False;
             }
             if (v == ThisObj)
             {
                 return JSBool.True;
             }
         }
     }, 1), true, false, true);
     this.ObjectPrototype.SetDataProp("propertyIsEnumerable", new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         string v = args[0].StringValue();
         PropWrapper r = ThisObj.ToJSObject().GetOwnPropertyRef(v);
         if (r == null)
         {
             return JSBool.False;
         }
         return r.Enumerable;
     }, 1), true, false, true);
 }
예제 #9
0
 private void AddObject()
 {
     this.ObjectCtor = new JSDelegateWrapper(delegate(JSContext Scope, JSValue ThisObj, JSArgs args, bool AsConstructor)
     {
         JSValue arg = args[0];
         if ((arg is JSUndefined) || (arg is JSNull))
         {
             return new JSObject(this.ObjectPrototype, this.ObjectCtor);
         }
         return arg.ToJSObject();
     }, 1);
     this.ObjectPrototype = new JSObject(null, this.ObjectCtor);
     this.ObjectCtor.SetDataProp("prototype", this.ObjectPrototype, false, false, false);
 }
예제 #10
0
 public virtual JSValue Construct(JSContext Scope, JSArgs Args)
 {
     JSObject o = new JSObject(this["prototype"], this);
     JSValue r = this.Call(Scope, o, Args);
     if (r is JSObject)
     {
         return r;
     }
     return o;
 }
예제 #11
0
        public JSRegExp(JSObject o, JSValue ctor, string pattern, string flags)
            : base(o, ctor)
        {
            bool ignoreCase = false;
            bool multiline = false;
            foreach (char c in flags)
            {
                switch (c)
                {
                    case 'g':
                        this.global = true;
                        break;

                    case 'i':
                        ignoreCase = true;
                        break;

                    case 'm':
                        multiline = true;
                        break;
                }
            }
            RegexOptions opt = RegexOptions.ECMAScript;
            if (ignoreCase)
            {
                opt |= RegexOptions.IgnoreCase;
            }
            if (multiline)
            {
                opt |= RegexOptions.Multiline;
            }
            try
            {
                this.CLRRegex = new Regex(pattern, opt);
            }
            catch(Exception ex)
            {
                throw new JSRuntimeException("SyntaxError", ex.Message);
            }
            this.src = pattern.Replace("/", @"\/");
            this["source"] = this.src;
            this["global"] = this.global;
            this["ignoreCase"] = ignoreCase;
            this["multiline"] = multiline;
        }
예제 #12
0
 public JSWithScope(JSEnvRec Parent, JSObject ScopeObject)
     : base(Parent, ScopeObject)
 {
 }