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; }
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); }
public JSGlobalScope(JSEnvRec Parent, JSObject ScopeObject) : base(Parent, ScopeObject) { }
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); }
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); }
public JSObjectScope(JSEnvRec Parent, JSObject ScopeObject) : base(Parent) { this.ScopeObject = ScopeObject; }
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); } }
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); }
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); }
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; }
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; }
public JSWithScope(JSEnvRec Parent, JSObject ScopeObject) : base(Parent, ScopeObject) { }