CallFromNative() private method

Calls this function, passing in the given "this" value and zero or more arguments.
private CallFromNative ( string function, object thisObject ) : object
function string The name of the caller function.
thisObject object The value of the "this" keyword within the function.
return object
Example #1
0
        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.CallFromNative("from", 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.CallFromNative("from", thisArg, items[i], i);
                    }
                    else
                    {
                        result[i] = items[i];
                    }
                }
                return(result);
            }
        }
Example #2
0
        /// <summary>
        /// Creates a new array with the elements from this array that pass the test implemented by
        /// the given 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> A copy of this array but with only those elements which produce <c>true</c>
        /// when passed to the provided function. </returns>
        public ObjectInstance Filter(FunctionInstance callbackFunction, ObjectInstance context)
        {
            // Create a new array to hold the new values.
            var result = new List <T>(Length / 2);

            for (int i = 0; i < Length; i++)
            {
                // Get the value of the array element.
                T elementValue = this[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.CallFromNative("filter", context, elementValue, i, WrappedInstance));

                    // Store the result if the callback function returned true.
                    if (includeInArray == true)
                    {
                        result.Add(elementValue);
                    }
                }
            }
            return(ConstructArray(result.ToArray()));
        }
        public TypedArrayInstance Sort(FunctionInstance comparisonFunction = null)
        {
            Comparison <object> comparer;

            if (comparisonFunction == null)
            {
                // Default comparer.
                comparer = (a, b) =>
                {
                    double x = TypeConverter.ToNumber(a);
                    double y = TypeConverter.ToNumber(b);
                    if (x < y)
                    {
                        return(-1);
                    }
                    if (x > y)
                    {
                        return(1);
                    }
                    if (double.IsNaN(x) && double.IsNaN(y))
                    {
                        return(0);
                    }
                    if (double.IsNaN(x))
                    {
                        return(1);
                    }
                    if (double.IsNaN(y))
                    {
                        return(-1);
                    }
                    if (TypeUtilities.IsNegativeZero(x) && TypeUtilities.IsPositiveZero(y))
                    {
                        return(-1);
                    }
                    if (TypeUtilities.IsPositiveZero(x) && TypeUtilities.IsNegativeZero(y))
                    {
                        return(1);
                    }
                    return(0);
                };
            }
            else
            {
                // Custom comparer.
                comparer = (a, b) =>
                {
                    var v = TypeConverter.ToNumber(comparisonFunction.CallFromNative("sort", null, a, b));
                    if (double.IsNaN(v))
                    {
                        return(0);
                    }
                    return(Math.Sign(v));
                };
            }

            return((TypedArrayInstance) new TypedArrayAdapter(this).Sort(comparer));
        }
Example #4
0
        /// <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);
                }
            }
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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);
        }
Example #7
0
        /// <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());
        }
Example #8
0
        /// <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);
        }
Example #9
0
        /// <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));
        }
Example #10
0
        /// <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));
        }
Example #11
0
        /// <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();
        }
Example #12
0
        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.CallFromNative("reduceRight", Undefined.Value, accumulatedValue, elementValue, i, thisObj);
                }
            }

            return accumulatedValue;
        }
Example #13
0
        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.CallFromNative("filter", context, elementValue, i, thisObj));

                    // Store the result if the callback function returned true.
                    if (includeInArray == true)
                        result.Push(elementValue);
                }
            }
            return result;
        }
Example #14
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.CallFromNative("map", context, elementValue, i, thisObj);

                    // Store the result.
                    resultArray[(uint)i] = result;
                }
            }

            return resultArray;
        }
Example #15
0
        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);
                }
            }
        }
Example #16
0
        /// <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);
        }