private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: return(((BooleanConstructor)thisObj).Construct(false)); default: return(((BooleanConstructor)thisObj).Construct(TypeUtilities.IsUndefined(args[0]) ? false : TypeConverter.ToBoolean(args[0]))); } }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal PromiseInstance(ObjectInstance prototype, FunctionInstance executor) : this(prototype) { try { executor.Call(Undefined.Value, resolveFunction, rejectFunction); } catch (JavaScriptException ex) { rejectFunction.Call(Undefined.Value, ex.ErrorObject); } }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: throw new JavaScriptException(ErrorType.TypeError, "undefined cannot be converted to an object"); default: return(((PromiseConstructor)thisObj).Construct(TypeConverter.ToObject <FunctionInstance>(engine, args[0]))); } }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: return(((WeakMapConstructor)thisObj).Construct(Undefined.Value)); default: return(((WeakMapConstructor)thisObj).Construct(args[0])); } }
public PromiseInstance Reject(object reason) { ClrStubFunction func = new ClrStubFunction(this.Engine.FunctionInstancePrototype, (engine, thisObj, args) => { FunctionInstance resolve = (FunctionInstance)args[0]; FunctionInstance reject = (FunctionInstance)args[1]; reject.Call(thisObj, reason); return(Undefined.Value); }); return(this.Construct(func)); }
public void ForEach(FunctionInstance callback, object thisArg) { foreach (var keyValue in TypeUtilities.Iterate(Engine, Entries())) { var keyValueObj = keyValue as ObjectInstance; if (keyValueObj == null) { throw new JavaScriptException(Engine, ErrorType.TypeError, "Invalid iterator return value."); } callback.Call(thisArg, keyValueObj[0], keyValueObj[1], this); } }
public TypedArrayInstance From(object source, FunctionInstance mapFn = null, object thisArg = null) { var items = TypeConverter.ToObject(Engine, source); var iterator = TypeUtilities.GetIterator(Engine, items); if (iterator != null) { // Loop. var values = new List <object>(); foreach (var value in TypeUtilities.Iterate(Engine, iterator)) { // Collect the values. values.Add(value); } // Convert the values into a typed array instance. var result = new TypedArrayInstance(this.InstancePrototype, this.type, Engine.ArrayBuffer.Construct(values.Count * BytesPerElement), 0, values.Count); for (int i = 0; i < values.Count; i++) { if (mapFn != null) { result[i] = mapFn.Call(thisArg, values[i], i); } else { result[i] = values[i]; } } return(result); } else { // There was no iterator symbol value, so fall back on the alternate method. int length = TypeConverter.ToInt32(items["length"]); var result = new TypedArrayInstance(this.InstancePrototype, this.type, Engine.ArrayBuffer.Construct(length * BytesPerElement), 0, length); for (int i = 0; i < length; i++) { if (mapFn != null) { result[i] = mapFn.Call(thisArg, items[i], i); } else { result[i] = items[i]; } } return(result); } }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: return(((RegExpConstructor)thisObj).Construct(newTarget, Undefined.Value, null)); case 1: return(((RegExpConstructor)thisObj).Construct(newTarget, args[0], null)); default: return(((RegExpConstructor)thisObj).Construct(newTarget, args[0], TypeUtilities.IsUndefined(args[1]) ? null : TypeConverter.ToString(args[1]))); } }
/// <summary> /// Calls the given user-defined function once per element in the array. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> public void ForEach(FunctionInstance callbackFunction, ObjectInstance context) { for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. callbackFunction.CallFromNative("forEach", context, elementValue, i, WrappedInstance); } } }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> internal PromiseInstance(ObjectInstance prototype) : base(prototype) { resolveFunction = new ClrStubFunction(Engine.FunctionInstancePrototype, "", 1, (engine, thisObj, args) => { Resolve(args.Length >= 1 ? args[0] : Undefined.Value); return(Undefined.Value); }); rejectFunction = new ClrStubFunction(Engine.FunctionInstancePrototype, "", 1, (engine, thisObj, args) => { Reject(args.Length >= 1 ? args[0] : Undefined.Value); return(Undefined.Value); }); }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: return(((DataViewConstructor)thisObj).Construct(null, 0, null)); case 1: return(((DataViewConstructor)thisObj).Construct(TypeUtilities.IsUndefined(args[0]) ? null : TypeConverter.ToObject <ArrayBufferInstance>(engine, args[0]), 0, null)); case 2: return(((DataViewConstructor)thisObj).Construct(TypeUtilities.IsUndefined(args[0]) ? null : TypeConverter.ToObject <ArrayBufferInstance>(engine, args[0]), TypeUtilities.IsUndefined(args[1]) ? 0 : TypeConverter.ToInteger(args[1]), null)); default: return(((DataViewConstructor)thisObj).Construct(TypeUtilities.IsUndefined(args[0]) ? null : TypeConverter.ToObject <ArrayBufferInstance>(engine, args[0]), TypeUtilities.IsUndefined(args[1]) ? 0 : TypeConverter.ToInteger(args[1]), TypeUtilities.IsUndefined(args[2]) ? (int?)null : TypeConverter.ToInteger(args[2]))); } }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new instance of a user-defined function. /// </summary> /// <param name="prototype"> The next object in the prototype chain. </param> /// <param name="targetFunction"> The function that was bound. </param> /// <param name="boundThis"> The value of the "this" parameter when the target function is called. </param> /// <param name="boundArguments"> Zero or more bound argument values. </param> internal BoundFunction(FunctionInstance targetFunction, object boundThis, object[] boundArguments) : base(targetFunction.Prototype) { if (targetFunction == null) throw new ArgumentNullException("targetFunction"); if (boundArguments == null) boundArguments = new object[0]; this.TargetFunction = targetFunction; this.BoundThis = boundThis; this.BoundArguments = boundArguments; // Add function properties. this.FastSetProperty("name", targetFunction.Name); this.FastSetProperty("length", Math.Max(targetFunction.Length - boundArguments.Length, 0)); this.FastSetProperty("prototype", this.Engine.Object.Construct(), PropertyAttributes.Writable); this.InstancePrototype.FastSetProperty("constructor", this, PropertyAttributes.NonEnumerable); }
protected virtual void ResetScriptEngine(ScriptSource source, IJinxBotClient client) { _jsEngine = new ScriptEngine(); _host = new JsHost(_jsEngine, client); _jsEngine.Execute(source); __accountCreated = GetFunc("accountCreated"); __accountCreationFailed = GetFunc("accountCreationFailed"); __adChanged = GetFunc("adChanged"); __channelDidNotExist = GetFunc("channelDidNotExist"); __channelListReceived = GetFunc("channelListReceived"); __channelWasFull = GetFunc("channelWasFull"); __channelWasRestricted = GetFunc("channelWasRestricted"); __clientCheckFailed = GetFunc("clientCheckFailed"); __clientCheckPassed = GetFunc("clientCheckPassed"); __commandSent = GetFunc("commandSent"); __connected = GetFunc("connected"); __disconnected = GetFunc("disconnected"); __enteredChat = GetFunc("enteredChat"); __error = GetFunc("error"); __friendAdded = GetFunc("friendAdded"); __friendListReceived = GetFunc("friendListReceived"); __friendMoved = GetFunc("friendMoved"); __friendRemoved = GetFunc("friendRemoved"); __friendUpdated = GetFunc("friendUpdated"); __information = GetFunc("information"); __informationReceived = GetFunc("informationReceived"); __joinedChannel = GetFunc("joinedChannel"); __loginFailed = GetFunc("loginFailed"); __loginSucceeded = GetFunc("loginSucceeded"); __messageSent = GetFunc("messageSent"); __profileLookupFailed = GetFunc("profileLookupFailed"); __serverBroadcast = GetFunc("serverBroadcast"); __serverErrorReceived = GetFunc("serverErrorReceived"); __serverNews = GetFunc("serverNews"); __userEmoted = GetFunc("userEmoted"); __userFlagsChanged = GetFunc("userFlagsChanged"); __userJoined = GetFunc("userJoined"); __userLeft = GetFunc("userLeft"); __userProfileReceived = GetFunc("userProfileReceived"); __userShown = GetFunc("userShown"); __userSpoke = GetFunc("userSpoke"); __warcraftProfileReceived = GetFunc("warcraftProfileReceived"); __whisperReceived = GetFunc("whisperReceived"); __whisperSent = GetFunc("whisperSent"); }
/// <summary> /// Determines if at least one element of the array matches criteria defined by the given /// user-defined function. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. The function should /// return <c>true</c> or <c>false</c>. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> <c>true</c> if at least one element of the array matches criteria defined by /// the given user-defined function; <c>false</c> otherwise. </returns> public bool Some(FunctionInstance callbackFunction, ObjectInstance context) { for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. if (TypeConverter.ToBoolean(callbackFunction.CallFromNative("some", context, elementValue, i, WrappedInstance)) == true) { return(true); } } } return(false); }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal PromiseInstance(ObjectInstance prototype, FunctionInstance executor) : base(prototype) { FunctionInstance resolveFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return(Undefined.Value); }); FunctionInstance rejectFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return(Undefined.Value); }); try { executor.Call(Undefined.Value, resolveFunc, rejectFunc); } catch (JavaScriptException ex) { rejectFunc.Call(Undefined.Value, ex.ErrorObject); } }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal PromiseInstance(ObjectInstance prototype, FunctionInstance executor) : base(prototype) { FunctionInstance resolveFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return Undefined.Value; }); FunctionInstance rejectFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return Undefined.Value; }); try { executor.Call(Undefined.Value, resolveFunc, rejectFunc); } catch (JavaScriptException ex) { rejectFunc.Call(Undefined.Value, ex.ErrorObject); } }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new instance of a user-defined function. /// </summary> /// <param name="prototype"> The next object in the prototype chain. </param> /// <param name="targetFunction"> The function that was bound. </param> /// <param name="boundThis"> The value of the "this" parameter when the target function is called. </param> /// <param name="boundArguments"> Zero or more bound argument values. </param> internal BoundFunction(FunctionInstance targetFunction, object boundThis, object[] boundArguments) : base(targetFunction.Prototype) { if (targetFunction == null) { throw new ArgumentNullException("targetFunction"); } if (boundArguments == null) { boundArguments = new object[0]; } this.TargetFunction = targetFunction; this.BoundThis = boundThis; this.BoundArguments = boundArguments; // Add function properties. this.FastSetProperty("name", targetFunction.Name); this.FastSetProperty("length", Math.Max(targetFunction.Length - boundArguments.Length, 0)); this.FastSetProperty("prototype", this.Engine.Object.Construct(), PropertyAttributes.Writable); this.InstancePrototype.FastSetProperty("constructor", this, PropertyAttributes.NonEnumerable); }
/// <summary> /// Returns a copy of this string with text replaced using a replacement function. /// </summary> /// <param name="thisObject"> The string that is being operated on. </param> /// <param name="substr"> The text to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced. </returns> public static string Replace(string thisObject, string substr, FunctionInstance replaceFunction) { // Find the first occurrance of substr. int start = thisObject.IndexOf(substr, StringComparison.Ordinal); if (start == -1) { return(thisObject); } int end = start + substr.Length; // Get the replacement text from the provided function. var replaceText = TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, substr, start, thisObject)); // Replace only the first match. var result = new System.Text.StringBuilder(thisObject.Length + (replaceText.Length - substr.Length)); result.Append(thisObject, 0, start); result.Append(replaceText); result.Append(thisObject, end, thisObject.Length - end); return(result.ToString()); }
/// <summary> /// Creates an object, using this function as the constructor. /// </summary> /// <param name="newTarget"> The value of 'new.target'. </param> /// <param name="argumentValues"> An array of argument values to pass to the function. </param> /// <returns> The object that was created. </returns> public override ObjectInstance ConstructLateBound(FunctionInstance newTarget, params object[] argumentValues) { // Append the provided argument values to the end of the existing bound argument values. var resultingArgumentValues = argumentValues; if (this.BoundArguments.Length > 0) { if (argumentValues == null || argumentValues.Length == 0) { resultingArgumentValues = this.BoundArguments; } else { resultingArgumentValues = new object[this.BoundArguments.Length + argumentValues.Length]; Array.Copy(this.BoundArguments, resultingArgumentValues, this.BoundArguments.Length); Array.Copy(argumentValues, 0, resultingArgumentValues, this.BoundArguments.Length, argumentValues.Length); } } // Call the target function. return(this.TargetFunction.ConstructLateBound(newTarget, resultingArgumentValues)); }
/// <summary> /// Accumulates a single value by calling a user-defined function for each element /// (starting with the last element in the array). /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element /// in the array. This function is called with four arguments: the current accumulated /// value, the value of the element, the index of the element, and the array that is being /// operated on. The return value for this function is the new accumulated value and is /// passed to the next invocation of the function. </param> /// <param name="initialValue"> The initial accumulated value. </param> /// <returns> The accumulated value returned from the last invocation of the callback /// function. </returns> public object ReduceRight(FunctionInstance callbackFunction, object initialValue) { // If an initial value is not provided, the initial value is the last (defined) element. int i = Length - 1; object accumulatedValue = initialValue; if (accumulatedValue == null) { // Scan for a defined element. for (; i >= 0; i--) { if (this[i] != null) { accumulatedValue = this[i--]; break; } } if (accumulatedValue == null) { throw new JavaScriptException(ErrorType.TypeError, "Reduce of empty array with no initial value"); } } // Scan from high to to low. for (; i >= 0; i--) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. accumulatedValue = callbackFunction.CallFromNative("reduceRight", Undefined.Value, accumulatedValue, elementValue, i, WrappedInstance); } } return(accumulatedValue); }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new instance of a user-defined function. /// </summary> /// <param name="prototype"> The next object in the prototype chain. </param> /// <param name="targetFunction"> The function that was bound. </param> /// <param name="boundThis"> The value of the "this" parameter when the target function is called. </param> /// <param name="boundArguments"> Zero or more bound argument values. </param> internal BoundFunction(FunctionInstance targetFunction, object boundThis, object[] boundArguments) : base(targetFunction.Prototype) { if (targetFunction == null) throw new ArgumentNullException("targetFunction"); if (boundArguments == null) boundArguments = new object[0]; this.TargetFunction = targetFunction; this.BoundThis = boundThis; this.BoundArguments = boundArguments; // Add function properties. this.FastSetProperty("name", targetFunction.Name); this.FastSetProperty("length", Math.Max(targetFunction.Length - boundArguments.Length, 0)); this.FastSetProperty("prototype", this.Engine.Object.Construct(), PropertyAttributes.Writable); this.InstancePrototype.FastSetProperty("constructor", this, PropertyAttributes.NonEnumerable); // Caller and arguments cannot be accessed. var thrower = new ThrowTypeErrorFunction(this.Engine.Function, "The 'caller' or 'arguments' properties cannot be accessed on a bound function."); var accessor = new PropertyAccessorValue(thrower, thrower); this.FastSetProperty("caller", accessor, PropertyAttributes.IsAccessorProperty, overwriteAttributes: true); this.FastSetProperty("arguments", accessor, PropertyAttributes.IsAccessorProperty, overwriteAttributes: true); }
/// <summary> /// Creates an object, using this function as the constructor. /// </summary> /// <param name="newTarget"> The value of 'new.target'. </param> /// <param name="argumentValues"> An array of argument values. </param> /// <returns> The object that was created. </returns> public override ObjectInstance ConstructLateBound(FunctionInstance newTarget, params object[] argumentValues) { object result; if (argumentValues.Length == 0 && this.WrappedType.IsValueType) { result = Activator.CreateInstance(this.WrappedType); } else { if (this.constructBinder == null) { throw new JavaScriptException(ErrorType.TypeError, string.Format("The type '{0}' has no public constructors", this.WrappedType)); } result = this.constructBinder.Call(this.Engine, this, argumentValues); } if (result is ObjectInstance) { return((ObjectInstance)result); } return(new ClrInstanceWrapper(this.Engine, result)); }
private RegExpInstance Construct(FunctionInstance newTarget, object patternOrRegExp, string flags = null) { var prototype = (newTarget["prototype"] as ObjectInstance) ?? this.InstancePrototype; if (patternOrRegExp is RegExpInstance regExp) { // new RegExp(regExp, flags) if (flags != null) { return(new RegExpInstance(prototype, regExp.Source, flags)); } return(new RegExpInstance(prototype, regExp)); } else if (patternOrRegExp is ObjectInstance regExpLike && TypeConverter.ToBoolean(regExpLike[Symbol.Match])) { // new RegExp(regExp-like, flags) var pattern = TypeConverter.ToString(regExpLike["source"], string.Empty); if (flags == null) { flags = TypeConverter.ToString(regExpLike["flags"], null); } return(new RegExpInstance(prototype, pattern, flags)); }
/// <summary> /// Creates an object, using this function as the constructor. /// </summary> /// <param name="newTarget"> The value of 'new.target'. </param> /// <param name="argumentValues"> An array of argument values. </param> /// <returns> The object that was created. </returns> public override ObjectInstance ConstructLateBound(FunctionInstance newTarget, params object[] argumentValues) { // Create a new object and set the prototype to the instance prototype of the function. var newObject = ObjectInstance.CreateRawObject(newTarget.InstancePrototype); // Run the function, with the new object as the "this" keyword. var context = ExecutionContext.CreateConstructContext( engine: this.Engine, parentScope: this.ParentScope, thisValue: newObject, executingFunction: this, newTarget: newTarget, functionContainer: null); var result = this.body(context, argumentValues); // Return the result of the function if it is an object. if (result is ObjectInstance) { return((ObjectInstance)result); } // Otherwise, return the new object. return(newObject); }
/// <summary> /// Creates a new array with the results of calling the given function on every element in /// this array. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element /// in the array. This function is called with three arguments: the value of the element, /// the index of the element, and the array that is being operated on. The value that is /// returned from this function is stored in the resulting array. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> A new array with the results of calling the given function on every element /// in the array. </returns> public ObjectInstance Map(FunctionInstance callbackFunction, ObjectInstance context) { // Create a new array to hold the new values. // The length of the output array is always equal to the length of the input array. var resultArray = new T[Length]; for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. object result = callbackFunction.CallFromNative("map", context, elementValue, i, WrappedInstance); // Store the result. resultArray[i] = ConvertValue(result); } } return(ConstructArray(resultArray)); }
/// <summary> /// Returns an index in the typed array, if an element in the typed array satisfies the /// provided testing function. Otherwise -1 is returned. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. The function should /// return <c>true</c> or <c>false</c>. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> The first element that results in the callback returning <c>true</c>. </returns> public int FindIndex(FunctionInstance callbackFunction, ObjectInstance context) { for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. bool result = TypeConverter.ToBoolean(callbackFunction.CallFromNative("findIndex", context, elementValue, i, WrappedInstance)); // Return if the result was true. if (result == true) { return(i); } } } // No matches, return undefined. return(-1); }
/// <summary> /// Returns a copy of the given string with text replaced using a regular expression. /// </summary> /// <param name="input"> The string on which to perform the search. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of the given string with text replaced using a regular expression. </returns> public string Replace(string input, FunctionInstance replaceFunction) { return(this.value.Replace(input, match => { // Set the deprecated RegExp properties. this.Engine.RegExp.SetDeprecatedProperties(input, match); object[] parameters = new object[match.Groups.Count + 2]; for (int i = 0; i < match.Groups.Count; i++) { if (match.Groups[i].Success == false) { parameters[i] = Undefined.Value; } else { parameters[i] = match.Groups[i].Value; } } parameters[match.Groups.Count] = match.Index; parameters[match.Groups.Count + 1] = input; return TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, parameters)); }, this.Global == true ? int.MaxValue : 1)); }
public void Load(string url, FunctionInstance callback) { new Thread((ThreadStart)delegate { string data = null; try { data = webClient.DownloadString(url); } catch (Exception e) { scriptRunner.Execute(callback, data, new JavaScriptException(Engine, "Error", "Error in download", e)); } }) { Name = "JsLoader" }.Start(); }
/// <summary> /// Creates a new PropertyAccessorValue instance. /// </summary> /// <param name="getter"> The getter function, or <c>null</c> if no getter was provided. </param> /// <param name="setter"> The setter function, or <c>null</c> if no setter was provided. </param> public PropertyAccessorValue(FunctionInstance getter, FunctionInstance setter) { this.getter = getter; this.setter = setter; }
/// <summary> /// Creates a new PropertyDescriptor instance with a getter function and, optionally, a /// setter function. /// </summary> /// <param name="getter"> The function to call to retrieve the property value. </param> /// <param name="setter"> The function to call to set the property value. </param> /// <param name="attributes"> The property attributes (whether the property is writable or /// not is implied by whether there is a setter function). </param> public PropertyDescriptor(FunctionInstance getter, FunctionInstance setter, PropertyAttributes attributes) : this(new PropertyAccessorValue(getter, setter), attributes) { }
public TypedArrayInstance From(object source, FunctionInstance mapFn = null, object thisArg = null) { var items = TypeConverter.ToObject(Engine, source); var iterator = TypeUtilities.GetIterator(Engine, items); if (iterator != null) { // Loop. var values = new List<object>(); foreach (var value in TypeUtilities.Iterate(Engine, iterator)) { // Collect the values. values.Add(value); } // Convert the values into a typed array instance. var result = new TypedArrayInstance(this.InstancePrototype, this.type, Engine.ArrayBuffer.Construct(values.Count * BytesPerElement), 0, values.Count); for (int i = 0; i < values.Count; i++) { if (mapFn != null) result[i] = mapFn.Call(thisArg, values[i], i); else result[i] = values[i]; } return result; } else { // There was no iterator symbol value, so fall back on the alternate method. int length = TypeConverter.ToInt32(items["length"]); var result = new TypedArrayInstance(this.InstancePrototype, this.type, Engine.ArrayBuffer.Construct(length * BytesPerElement), 0, length); for (int i = 0; i < length; i++) { if (mapFn != null) result[i] = mapFn.Call(thisArg, items[i], i); else result[i] = items[i]; } return result; } }
private void SetInterval(int id, FunctionInstance function, double delay, DateTime previous) { var self = this; var finnishTime = previous.AddMilliseconds(delay); Task.Factory.StartNew(() => { self.cancellationTokenSource.Token.ThrowIfCancellationRequested(); TimeSpan timeout = finnishTime - DateTime.Now; if (timeout < TimeSpan.Zero) timeout = TimeSpan.Zero; self.cancellationTokenSource.Token.WaitHandle.WaitOne(timeout); self.cancellationTokenSource.Token.ThrowIfCancellationRequested(); lock (self) { if (!self.intervals.Contains(id)) return; } self.scriptRunner.BeginInvoke(delegate { function.Call(self.Engine.Global); }); SetInterval(id, function, delay, finnishTime); }, self.cancellationTokenSource.Token); }
public static int SetInterval(ScriptEngine engine, FunctionInstance function, double delay) { var self = timeoutHandlers[engine]; int id; lock (self) { do { id = self.nextId++; } while (self.timeouts.Contains(id) || self.intervals.Contains(id)); self.intervals.Add(id); } self.SetInterval(id, function, delay, DateTime.Now); return id; }
public static ArrayInstance From(ScriptEngine engine, ObjectInstance iterable, FunctionInstance mapFunction, object thisArg) { var result = new List <object>(); var iterator = TypeUtilities.GetIterator(engine, iterable); if (iterator != null) { // Initialize the array from an iterator. int index = 0; foreach (var item in TypeUtilities.Iterate(engine, iterator)) { object mappedValue = mapFunction?.Call(thisArg ?? Undefined.Value, item, index) ?? item; result.Add(mappedValue); index++; } } else { // Initialize the array from an array-like object. uint length = ArrayInstance.GetLength(iterable); for (int i = 0; i < length; i++) { object mappedValue = mapFunction?.Call(thisArg ?? Undefined.Value, iterable[i], i) ?? iterable[i]; result.Add(mappedValue); } } return(engine.Array.New(result.ToArray())); }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: return(((FunctionConstructor)thisObj).Construct(new string[0])); default: return(((FunctionConstructor)thisObj).Construct(TypeConverter.ConvertParameterArrayTo <string>(engine, args, 0))); } }
public static ArrayInstance Map(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); // Create a new array to hold the new values. // The length of the output array is always equal to the length of the input array. var resultArray = new ArrayInstance(thisObj.Engine.Array.InstancePrototype, arrayLength, arrayLength); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. object result = callbackFunction.CallLateBound(context, elementValue, i, thisObj); // Store the result. resultArray[(uint)i] = result; } } return resultArray; }
public static object ReduceRight(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] object initialValue = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); // If an initial value is not provided, the initial value is the last (defined) element. int i = (int)arrayLength - 1; object accumulatedValue = initialValue; if (accumulatedValue == null) { // Scan for a defined element. for (; i >= 0; i--) { if (thisObj[(uint)i] != null) { accumulatedValue = thisObj[(uint)(i--)]; break; } } if (accumulatedValue == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Reduce of empty array with no initial value"); } // Scan from high to to low. for (; i >= 0; i--) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. accumulatedValue = callbackFunction.CallLateBound(Undefined.Value, accumulatedValue, elementValue, i, thisObj); } } return accumulatedValue; }
public void Exists(string path, FunctionInstance callback) { ThreadPool.QueueUserWorkItem(new WaitCallback(ExistsAsync), new object[] { path, callback }); }
/// <summary> /// Returns a copy of this string with text replaced using a replacement function. /// </summary> /// <param name="substr"> The text to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced. </returns> public static string Replace(string thisObject, string substr, FunctionInstance replaceFunction) { // Find the first occurrance of substr. int start = thisObject.IndexOf(substr, StringComparison.Ordinal); if (start == -1) return thisObject; int end = start + substr.Length; // Get the replacement text from the provided function. var replaceText = TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, substr, start, thisObject)); // Replace only the first match. var result = new System.Text.StringBuilder(thisObject.Length + (replaceText.Length - substr.Length)); result.Append(thisObject, 0, start); result.Append(replaceText); result.Append(thisObject, end, thisObject.Length - end); return result.ToString(); }
public static void ForEach(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. callbackFunction.CallFromNative("forEach", context, elementValue, i, thisObj); } } }
public BinHeapInstance Construct(FunctionInstance func) { return new BinHeapInstance(InstancePrototype, func); }
public FuncExe(FunctionInstance instance) { _instance = instance; }
/// <summary> /// Returns a copy of this string with text replaced using a regular expression and a /// replacement function. /// </summary> /// <param name="thisObject"> The string that is being operated on. </param> /// <param name="regExp"> The regular expression to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced using a regular expression. </returns> public static string Replace(string thisObject, RegExpInstance regExp, FunctionInstance replaceFunction) { return(regExp.Replace(thisObject, replaceFunction)); }
public static int SetTimeout(ScriptEngine engine, FunctionInstance function, double delay) { var self = timeoutHandlers[engine]; var finnishTime = DateTime.Now.AddMilliseconds(delay); int id; lock (self) { do { id = self.nextId++; } while (self.timeouts.Contains(id) || self.intervals.Contains(id)); self.timeouts.Add(id); } Task.Factory.StartNew(() => { self.cancellationTokenSource.Token.ThrowIfCancellationRequested(); TimeSpan timeout = finnishTime - DateTime.Now; if (timeout < TimeSpan.Zero) timeout = TimeSpan.Zero; self.cancellationTokenSource.Token.WaitHandle.WaitOne(timeout); self.cancellationTokenSource.Token.ThrowIfCancellationRequested(); lock (self) { if (!self.timeouts.Contains(id)) return; self.timeouts.Remove(id); } self.scriptRunner.BeginInvoke(delegate { function.Call(self.Engine.Global); }); }, self.cancellationTokenSource.Token); return id; }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { return(((SymbolConstructor)thisObj).Construct()); }
private static ObjectInstance __STUB__Construct(ScriptEngine engine, FunctionInstance thisObj, FunctionInstance newTarget, object[] args) { switch (args.Length) { case 0: return(((ArrayConstructor)thisObj).Construct(newTarget, new object[0])); default: return(((ArrayConstructor)thisObj).Construct(newTarget, args)); } }
public void Listen(string eventName, FunctionInstance fn) { if (!events.ContainsKey(eventName)) events.Add(eventName, new List<FunctionInstance>()); events[eventName].Add(fn); }
private void Initialize() { Require = new RequireFunction(this); }
/// <summary> /// Returns a copy of the given string with text replaced using a regular expression. /// </summary> /// <param name="input"> The string on which to perform the search. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of the given string with text replaced using a regular expression. </returns> public string Replace(string input, FunctionInstance replaceFunction) { return this.value.Replace(input, match => { // Set the deprecated RegExp properties. this.Engine.RegExp.SetDeprecatedProperties(input, match); object[] parameters = new object[match.Groups.Count + 2]; for (int i = 0; i < match.Groups.Count; i++) { if (match.Groups[i].Success == false) parameters[i] = Undefined.Value; else parameters[i] = match.Groups[i].Value; } parameters[match.Groups.Count] = match.Index; parameters[match.Groups.Count + 1] = input; return TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, parameters)); }, this.Global == true ? int.MaxValue : 1); }
public BinHeapInstance(ObjectInstance prototype, FunctionInstance func) : base(prototype) { _heap = new List<ObjectInstance>(); _func = func; }
/// <summary> /// Creates a new PropertyDescriptor instance with a getter function and, optionally, a /// setter function. /// </summary> /// <param name="getter"> The function to call to retrieve the property value. </param> /// <param name="setter"> The function to call to set the property value. </param> /// <param name="attributes"> The property attributes (whether the property is writable or /// not is implied by whether there is a setter function). </param> public PropertyDescriptor(FunctionInstance getter, FunctionInstance setter, PropertyAttributes attributes) : this(new PropertyAccessorValue(getter, setter), attributes) { }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new Function object. /// </summary> /// <param name="prototype"> The next object in the prototype chain. </param> /// <param name="instancePrototype"> The prototype for instances created by this function. </param> internal FunctionConstructor(ObjectInstance prototype, FunctionInstance instancePrototype) : base(prototype, "Function", instancePrototype) { }
public void NextTick(FunctionInstance callback) { // node.js actually performs these callbacks at the end of the current tick, which // is nearly as fast as calling them synchronous regarding reaction time. We could // also do this with a seperate queue, though for now it's just an immediate. (Context.GetModule("timers") as Timers).SetImmediate(callback, new object[] { }); }
// OBJECT SERIALIZATION AND DESERIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a property descriptor from an object containing any of the following /// properties: configurable, writable, enumerable, value, get, set. /// </summary> /// <param name="obj"> The object to get the property values from. </param> /// <param name="defaults"> The values to use if the relevant value is not specified. </param> /// <returns> A PropertyDescriptor that corresponds to the object. </returns> public static PropertyDescriptor FromObject(ObjectInstance obj, PropertyDescriptor defaults) { if (obj == null) { return(PropertyDescriptor.Undefined); } // Read configurable attribute. bool configurable = defaults.IsConfigurable; if (obj.HasProperty("configurable")) { configurable = TypeConverter.ToBoolean(obj["configurable"]); } // Read writable attribute. bool writable = defaults.IsWritable; if (obj.HasProperty("writable")) { writable = TypeConverter.ToBoolean(obj["writable"]); } // Read enumerable attribute. bool enumerable = defaults.IsEnumerable; if (obj.HasProperty("enumerable")) { enumerable = TypeConverter.ToBoolean(obj["enumerable"]); } // Read property value. object value = defaults.Value; if (obj.HasProperty("value")) { value = obj["value"]; } // The descriptor is an accessor if get or set is present. bool isAccessor = false; // Read get accessor. FunctionInstance getter = defaults.Getter; if (obj.HasProperty("get")) { if (obj.HasProperty("value")) { throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors cannot have both 'get' and 'value' set"); } if (obj.HasProperty("writable")) { throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors with 'get' or 'set' defined must not have 'writable' set"); } if (obj["get"] is FunctionInstance) { getter = (FunctionInstance)obj["get"]; } else if (TypeUtilities.IsUndefined(obj["get"]) == true) { getter = null; } else { throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptor 'get' must be a function"); } isAccessor = true; } // Read set accessor. FunctionInstance setter = defaults.Setter; if (obj.HasProperty("set")) { if (obj.HasProperty("value")) { throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors cannot have both 'set' and 'value' set"); } if (obj.HasProperty("writable")) { throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors with 'get' or 'set' defined must not have 'writable' set"); } if (obj["set"] is FunctionInstance) { setter = (FunctionInstance)obj["set"]; } else if (TypeUtilities.IsUndefined(obj["set"]) == true) { setter = null; } else { throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptor 'set' must be a function"); } isAccessor = true; } // Build up the attributes enum. PropertyAttributes attributes = PropertyAttributes.Sealed; if (configurable == true) { attributes |= PropertyAttributes.Configurable; } if (writable == true) { attributes |= PropertyAttributes.Writable; } if (enumerable == true) { attributes |= PropertyAttributes.Enumerable; } // Either a value or an accessor is possible. object descriptorValue = value; if (isAccessor == true) { descriptorValue = new PropertyAccessorValue(getter, setter); } // Create the new property descriptor. return(new PropertyDescriptor(descriptorValue, attributes)); }
public static bool Some(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. if (TypeConverter.ToBoolean(callbackFunction.CallLateBound(context, elementValue, i, thisObj)) == true) return true; } } return false; }
public static ObjectInstance Sort([JSParameter(JSParameterFlags.Mutated)] ObjectInstance thisObj, FunctionInstance comparisonFunction = null) { // Get the length of the array. uint arrayLength = GetLength(thisObj); // An array of size 1 or less is already sorted. if (arrayLength <= 1) return thisObj; // Create a comparer delegate. Func<object, object, double> comparer; if (comparisonFunction == null) comparer = (a, b) => { if (a == null && b == null) return 0f; if (a == null) return 1f; if (b == null) return -1f; if (a == Undefined.Value && b == Undefined.Value) return 0f; if (a == Undefined.Value) return 1f; if (b == Undefined.Value) return -1f; return string.Compare(TypeConverter.ToString(a), TypeConverter.ToString(b), StringComparison.Ordinal); }; else comparer = (a, b) => { if (a == null && b == null) return 0f; if (a == null) return 1f; if (b == null) return -1f; if (a == Undefined.Value && b == Undefined.Value) return 0f; if (a == Undefined.Value) return 1f; if (b == Undefined.Value) return -1f; return TypeConverter.ToNumber(comparisonFunction.CallLateBound(thisObj.Engine.Global, a, b)); }; try { // Sort the array. QuickSort(thisObj, comparer, 0, arrayLength - 1); } catch (IndexOutOfRangeException) { throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid comparison function"); } return thisObj; }
void Xhr(ObjectInstance href, ObjectInstance type, FunctionInstance callback, FunctionInstance errorCallback) { var filename = href.ToString(); var referencingFile = currentFiles.Peek(); try { var file = referencingFile.Directory.GetFile(filename); var content = file.OpenRead().ReadToEnd(); callback.Call(Null.Value, content, DateTime.MinValue); } catch (FileNotFoundException ex) { throw FileNotFoundExceptionWithSourceFilename(referencingFile, ex); } catch (DirectoryNotFoundException ex) { throw DirectoryNotFoundExceptionWithSourceFilename(referencingFile, ex); } }
public void Ignore(string eventName, FunctionInstance fn) { if (events.ContainsKey(eventName)) events[eventName].Remove(fn); }
/// <summary> /// Returns a copy of this string with text replaced using a regular expression and a /// replacement function. /// </summary> /// <param name="regExp"> The regular expression to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced using a regular expression. </returns> public static string Replace(string thisObject, RegExpInstance regExp, FunctionInstance replaceFunction) { return regExp.Replace(thisObject, replaceFunction); }
public static ArrayInstance Filter(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); // Create a new array to hold the new values. var result = thisObj.Engine.Array.New(); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. bool includeInArray = TypeConverter.ToBoolean(callbackFunction.CallLateBound(context, elementValue, i, thisObj)); // Store the result if the callback function returned true. if (includeInArray == true) result.Push(elementValue); } } return result; }