public static void ImportType(IScriptable scope, Type type) { if (!type.IsPublic) { return; } if (ScriptRuntime.IsNativeRuntimeType(type)) { return; } // Cannot define 'Object' if (type.Name == "Object") { return; } string [] ns = type.FullName.Split('.'); IScriptable parent = scope; for (int i = 0; i < ns.Length - 1; i++) { IScriptable obj = (parent.Get(ns [i], parent) as IScriptable); if (obj == null) { obj = new BuiltinObject(); parent.Put(ns [i], parent, obj); } parent = obj; } object thisObj = null; if (type.IsEnum) { thisObj = new CliEnum((Enum)Activator.CreateInstance(type)); } else { thisObj = CliType.GetNativeCliType(type); } // Define as toplevel object scope.Put(ns [ns.Length - 1], scope, thisObj); // Define as full qualified name parent.Put(ns [ns.Length - 1], parent, thisObj); }
internal void Set(int id, IScriptable start, object value) { if (value == UniqueTag.NotFound) { throw new ArgumentException(); } EnsureId(id); int attr = attributeArray [id - 1]; if ((attr & ScriptableObject.READONLY) == 0) { if (start == obj) { if (value == null) { value = UniqueTag.NullValue; } int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT; lock (this) { valueArray [valueSlot] = value; } } else { int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT; string name = (string)valueArray [nameSlot]; start.Put(name, start, value); } } }
public override object Put(string name, IScriptable start, object value) { int info = FindInstanceIdInfo(name); if (info != 0) { if (start == this && Sealed) { throw Context.ReportRuntimeErrorById("msg.modify.sealed", name); } int attr = (int)((uint)info >> 16); if ((attr & READONLY) == 0) { if (start == this) { int id = (info & 0xFFFF); SetInstanceIdValue(id, value); } else { return(start.Put(name, start, value)); } } else { ReadOnlyPropertyChanged(name); } return(value); } if (prototypeValues != null) { int id = prototypeValues.FindId(name); if (id != 0) { if (start == this && Sealed) { throw Context.ReportRuntimeErrorById("msg.modify.sealed", name); } prototypeValues.Set(id, start, value); return(value); } } return(base.Put(name, start, value)); }
public static void ImportType(IScriptable scope, Type type) { if (!type.IsPublic) return; if (ScriptRuntime.IsNativeRuntimeType (type)) return; // Cannot define 'Object' if (type.Name == "Object") return; string [] ns = type.FullName.Split ('.'); IScriptable parent = scope; for (int i = 0; i < ns.Length - 1; i++) { IScriptable obj = (parent.Get (ns [i], parent) as IScriptable); if (obj == null) { obj = new BuiltinObject (); parent.Put (ns [i], parent, obj); } parent = obj; } object thisObj = null; if (type.IsEnum) { thisObj = new CliEnum ((Enum)Activator.CreateInstance (type)); } else { thisObj = CliType.GetNativeCliType (type); } // Define as toplevel object scope.Put (ns [ns.Length - 1], scope, thisObj); // Define as full qualified name parent.Put (ns [ns.Length - 1], parent, thisObj); }
/// <summary> Utility method to add properties to arbitrary Scriptable object. /// If destination is instance of ScriptableObject, calls /// defineProperty there, otherwise calls put in destination /// ignoring attributes /// </summary> public static void DefineProperty (IScriptable destination, string propertyName, object value, int attributes) { if (!(destination is ScriptableObject)) { destination.Put (propertyName, destination, value); return; } ScriptableObject so = (ScriptableObject)destination; so.DefineProperty (propertyName, value, attributes); }
/// <summary> Sets the value of the indexed property, creating it if need be. /// /// </summary> /// <param name="index">the numeric index for the property /// </param> /// <param name="start">the object whose property is being set /// </param> /// <param name="value">value to set the property to /// </param> public virtual object Put (int index, IScriptable start, object value) { Slot slot = GetSlot (null, index); if (slot == null) { if (start != this) { return start.Put (index, start, value); } slot = AddSlot (null, index, null); } if (start == this && Sealed) { throw Context.ReportRuntimeErrorById ("msg.modify.sealed", Convert.ToString (index)); } if ((slot.attributes & ScriptableObject.READONLY) != 0) { return slot.GetValue (null, start, start); // TODO: ??? } if (this == start) { return slot.SetValue (null, start, start, value); } else { return start.Put (index, start, value); } }
/// <summary> Sets the value of the named property, creating it if need be. /// /// If the property was created using defineProperty, the /// appropriate setter method is called. <p> /// /// If the property's attributes include READONLY, no action is /// taken. /// This method will actually set the property in the start /// object. /// /// </summary> /// <param name="name">the name of the property /// </param> /// <param name="start">the object whose property is being set /// </param> /// <param name="value">value to set the property to /// </param> public virtual object Put (string name, IScriptable start, object value) { Slot slot = lastAccess; // Get local copy if ((object)name != (object)slot.stringKey || slot.wasDeleted != 0) { int hash = name.GetHashCode (); slot = GetSlot (name, hash); if (slot == null) { if (start != this) { start.Put (name, start, value); return value; } slot = AddSlot (name, hash, null); } // Note: cache is not updated in put } if (start == this && Sealed) { throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name); } if ((slot.attributes & ScriptableObject.READONLY) != 0) { // FINDME Context cx = Context.CurrentContext; if (cx.Version == Context.Versions.JS1_2) { throw Context.ReportRuntimeErrorById ("msg.read-only", name); } else { if (cx.HasFeature (Context.Features.Strict)) { Context.ReportWarningById ("msg.read-only", name); } } return value; } if (this == start) { return slot.SetValue (null, start, start, value); } else { if (slot.setter != null) { Slot newSlot = (Slot)slot.Clone (); ((ScriptableObject)start).AddSlotImpl (newSlot.stringKey, newSlot.intKey, newSlot); return newSlot.SetValue (null, start, start, value); } else { return start.Put (name, start, value); } } return value; }
public override object Put (string name, IScriptable start, object value) { int info = FindInstanceIdInfo (name); if (info != 0) { if (start == this && Sealed) { throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name); } int attr = (int)((uint)info >> 16); if ((attr & READONLY) == 0) { if (start == this) { int id = (info & 0xFFFF); SetInstanceIdValue (id, value); } else { return start.Put (name, start, value); } } else { ReadOnlyPropertyChanged (name); } return value; } if (prototypeValues != null) { int id = prototypeValues.FindId (name); if (id != 0) { if (start == this && Sealed) { throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name); } prototypeValues.Set (id, start, value); return value; } } return base.Put (name, start, value); }
internal void Set (int id, IScriptable start, object value) { if (value == UniqueTag.NotFound) throw new ArgumentException (); EnsureId (id); int attr = attributeArray [id - 1]; if ((attr & ScriptableObject.READONLY) == 0) { if (start == obj) { if (value == null) { value = UniqueTag.NullValue; } int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT; lock (this) { valueArray [valueSlot] = value; } } else { int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT; string name = (string)valueArray [nameSlot]; start.Put (name, start, value); } } }
public static void Init(Context cx, IScriptable scope, bool zealed) { BuiltinGlobal obj = new BuiltinGlobal(); for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) { string name; int arity = 1; switch (id) { case Id_decodeURI: name = "decodeURI"; break; case Id_decodeURIComponent: name = "decodeURIComponent"; break; case Id_encodeURI: name = "encodeURI"; break; case Id_encodeURIComponent: name = "encodeURIComponent"; break; case Id_escape: name = "escape"; break; case Id_eval: name = "eval"; break; case Id_isFinite: name = "isFinite"; break; case Id_isNaN: name = "isNaN"; break; case Id_isXMLName: name = "isXMLName"; break; case Id_parseFloat: name = "parseFloat"; break; case Id_parseInt: name = "parseInt"; arity = 2; break; case Id_unescape: name = "unescape"; break; case Id_uneval: name = "uneval"; break; default: throw Context.CodeBug(); } IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name, arity, scope); if (zealed) { f.SealObject(); } f.ExportAsScopeProperty(); } ScriptableObject.DefineProperty(scope, "NaN", (object)double.NaN, ScriptableObject.DONTENUM); ScriptableObject.DefineProperty(scope, "Infinity", (System.Double.PositiveInfinity), ScriptableObject.DONTENUM); ScriptableObject.DefineProperty(scope, "undefined", Undefined.Value, ScriptableObject.DONTENUM); string [] errorMethods = new string [] { "ConversionError", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "InternalError", "JavaException" }; /* * Each error constructor gets its own Error object as a prototype, * with the 'name' property set to the name of the error. */ for (int i = 0; i < errorMethods.Length; i++) { string name = errorMethods [i]; IScriptable errorProto = ScriptRuntime.NewObject(cx, scope, "Error", ScriptRuntime.EmptyArgs); errorProto.Put("name", errorProto, name); if (zealed) { if (errorProto is ScriptableObject) { ((ScriptableObject)errorProto).SealObject(); } } IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_new_CommonError, name, 1, scope); ctor.MarkAsConstructor(errorProto); if (zealed) { ctor.SealObject(); } ctor.ExportAsScopeProperty(); } }
/// <summary> Sets the value of the named property, creating it if need be. /// /// If the property was created using defineProperty, the /// appropriate setter method is called. <p> /// /// If the property's attributes include READONLY, no action is /// taken. /// This method will actually set the property in the start /// object. /// /// </summary> /// <param name="name">the name of the property /// </param> /// <param name="start">the object whose property is being set /// </param> /// <param name="value">value to set the property to /// </param> public virtual object Put (string name, IScriptable start, object value) { Slot slot = lastAccess; // Get local copy if ((object)name != (object)slot.stringKey || slot.wasDeleted != 0) { int hash = name.GetHashCode (); slot = GetSlot (name, hash); if (slot == null) { if (start != this) { start.Put (name, start, value); return value; } slot = AddSlot (name, hash, null); } // Note: cache is not updated in put } if (start == this && Sealed) { throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name); } if ((slot.attributes & ScriptableObject.READONLY) != 0) { ReadOnlyPropertyChanged (name); return value; } if (this == start) { return slot.SetValue (null, start, start, value); } else { if (slot.setter != null) { Slot newSlot = (Slot)slot.Clone (); ((ScriptableObject)start).AddSlotImpl (newSlot.stringKey, newSlot.intKey, newSlot); return newSlot.SetValue (null, start, start, value); } else { return start.Put (name, start, value); } } return value; }
private static object doScriptableIncrDecr(IScriptable target, string id, IScriptable protoChainStart, object value, int incrDecrMask) { bool post = ((incrDecrMask & Node.POST_FLAG) != 0); double number; if (CliHelper.IsNumber (value)) { number = Convert.ToDouble (value); } else { number = ScriptConvert.ToNumber (value); if (post) { // convert result to number value = number; } } if ((incrDecrMask & Node.DECR_FLAG) == 0) { ++number; } else { --number; } object result = number; target.Put (id, protoChainStart, result); if (post) { return value; } else { return result; } }
public static object setName(IScriptable bound, object value, Context cx, IScriptable scope, string id) { if (bound != null) { if (bound is XMLObject) { XMLObject xmlObject = (XMLObject)bound; xmlObject.EcmaPut (cx, id, value); } else { ScriptableObject.PutProperty (bound, id, value); } } else { // "newname = 7;", where 'newname' has not yet // been defined, creates a new property in the // top scope unless strict mode is specified. if (cx.HasFeature (Context.Features.StrictVars)) { throw Context.ReportRuntimeErrorById ("msg.assn.create.strict", id); } // Find the top scope by walking up the scope chain. bound = ScriptableObject.GetTopLevelScope (scope); if (cx.useDynamicScope) { bound = checkDynamicScope (cx.topCallScope, bound); } bound.Put (id, bound, value); } return value; }
public static void initFunction(Context cx, IScriptable scope, BuiltinFunction function, int type, bool fromEvalCode) { if (type == FunctionNode.FUNCTION_STATEMENT) { string name = function.FunctionName; if (name != null && name.Length != 0) { if (!fromEvalCode) { // ECMA specifies that functions defined in global and // function scope outside eval should have DONTDELETE set. ScriptableObject.DefineProperty (scope, name, function, ScriptableObject.PERMANENT); } else { scope.Put (name, scope, function); } } } else if (type == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) { string name = function.FunctionName; if (name != null && name.Length != 0) { // Always put function expression statements into initial // activation object ignoring the with statement to follow // SpiderMonkey while (scope is BuiltinWith) { scope = scope.ParentScope; } scope.Put (name, scope, function); } } else { throw Context.CodeBug (); } }
/* * See ECMA 15.5.4.8. Modified to match JS 1.2 - optionally takes * a limit argument and accepts a regular expression as the split * argument. */ private static object ImplSplit(Context cx, IScriptable scope, string target, object [] args) { // create an empty Array to return; IScriptable top = GetTopLevelScope(scope); IScriptable result = ScriptRuntime.NewObject(cx, top, "Array", null); // return an array consisting of the target if no separator given // don't check against undefined, because we want // 'fooundefinedbar'.split(void 0) to split to ['foo', 'bar'] if (args.Length < 1) { result.Put(0, result, target); return(result); } // Use the second argument as the split limit, if given. bool limited = (args.Length > 1) && (args [1] != Undefined.Value); long limit = 0; // Initialize to avoid warning. if (limited) { /* Clamp limit between 0 and 1 + string length. */ limit = ScriptConvert.ToUint32(args [1]); if (limit > target.Length) { limit = 1 + target.Length; } } string separator = null; int [] matchlen = new int [1]; IScriptable re = null; RegExpProxy reProxy = null; if (args [0] is IScriptable) { reProxy = cx.RegExpProxy; if (reProxy != null) { IScriptable test = (IScriptable)args [0]; if (reProxy.IsRegExp(test)) { re = test; } } } if (re == null) { separator = ScriptConvert.ToString(args [0]); matchlen [0] = separator.Length; } // split target with separator or re int [] ip = new int [] { 0 }; int match; int len = 0; bool [] matched = new bool [] { false }; string [] [] parens = new string [] [] { null }; Context.Versions version = cx.Version; while ((match = find_split(cx, scope, target, separator, version, reProxy, re, ip, matchlen, matched, parens)) >= 0) { if ((limited && len >= limit) || (match > target.Length)) { break; } string substr; if (target.Length == 0) { substr = target; } else { substr = target.Substring(ip [0], (match) - (ip [0])); } result.Put(len, result, substr); len++; /* * Imitate perl's feature of including parenthesized substrings * that matched part of the delimiter in the new array, after the * split substring that was delimited. */ // CB, 02.01.2007: Don't do this, causes bug #287630 // https://bugzilla.mozilla.org/show_bug.cgi?query_format=specific&order=relevance+desc&bug_status=__open__&id=287630 /* * if (re != null && matched [0] == true) { * int size = parens [0].Length; * for (int num = 0; num < size; num++) { * if (limited && len >= limit) * break; * result.Put (len, result, parens [0] [num]); * len++; * } * matched [0] = false; * } */ ip [0] = match + matchlen [0]; if (version < Context.Versions.JS1_3 && version != Context.Versions.Default) { /* * Deviate from ECMA to imitate Perl, which omits a final * split unless a limit argument is given and big enough. */ if (!limited && ip [0] == target.Length) { break; } } } return(result); }
public virtual object Put(string name, IScriptable start, object value) { return(obj.Put(name, start, value)); }