Ejemplo n.º 1
0
        /// <summary>
        /// Resolves a function instance via the .NET stack.
        /// </summary>
        private static UserDefinedFunction ResolveFunctionInstance(int count)
        {
            // First, get the stack:
            System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(5 + count, true);

            for (int i = 0; i < trace.FrameCount; i++)
            {
                System.Diagnostics.StackFrame frame = trace.GetFrame(i);

                UserDefinedFunction func = MethodLookup.Search(frame.GetMethod() as MethodInfo);

                if (func != null)
                {
                    return(func);
                }
            }

            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a new function instance.
        /// </summary>
        /// <param name="argumentsAndBody"> The argument names plus the function body. </param>
        /// <returns> A new function instance. </returns>
        public static FunctionInstance OnConstruct(ScriptEngine engine, params string[] argumentsAndBody)
        {
            // Passing no arguments results in an empty function.
            if (argumentsAndBody.Length == 0)
            {
                return(UserDefinedFunction.Create(engine, "anonymous", null, string.Empty));
            }

            // Split any comma-delimited names.
            List <ArgVariable> args = new List <ArgVariable>();

            args.Add(new ArgVariable("this"));

            for (int i = 0; i < argumentsAndBody.Length - 1; i++)
            {
                var splitNames = argumentsAndBody[i].Split(',');

                for (int j = 0; j < splitNames.Length; j++)
                {
                    // Trim any whitespace from the start and end of the argument name.
                    string argumentName = Nitrassic.Library.String.Trim(splitNames[j]);
                    if (argumentName == string.Empty)
                    {
                        throw new JavaScriptException(engine, "SyntaxError", "Unexpected ',' in argument");
                    }

                    // Check the name is valid and resolve any escape sequences.
                    argumentName = Compiler.Lexer.ResolveIdentifier(engine, argumentName);
                    if (argumentName == null)
                    {
                        throw new JavaScriptException(engine, "SyntaxError", "Expected identifier");
                    }

                    args.Add(new ArgVariable(argumentName));
                }
            }

            // Create a new function.
            return(UserDefinedFunction.Create(engine, "anonymous", args, argumentsAndBody[argumentsAndBody.Length - 1]));
        }
Ejemplo n.º 3
0
        //	 OVERRIDES
        //_________________________________________________________________________________________

        /// <summary>
        /// Calls this function, passing in the given "this" value and zero or more arguments.
        /// </summary>
        /// <param name="thisObj"> The value of the "this" keyword within the function. </param>
        /// <param name="argumentValues"> An array of argument values to pass to the function. </param>
        /// <returns> The value that was returned from the function. </returns>
        public override object CallLateBound(ScriptEngine engine, params object[] thisAndArgumentValues)
        {
            // Call the function, passing the hoisted values too.
            int hoisted  = HoistValues.Length;
            int argCount = thisAndArgumentValues.Length;

            object[] set = new object[hoisted + argCount];

            // Transfer 'this':
            set[0] = thisAndArgumentValues;

            // Copy hoist values in:
            System.Array.Copy(HoistValues, 0, set, 1, hoisted);

            // Copy arg values in:
            System.Array.Copy(thisAndArgumentValues, 1, set, hoisted + 1, argCount - 1);

            // Need to find the correct compiled version of the host:
            UserDefinedFunction udf = Host.GetCompiled(engine, set);

            return(udf.body.Invoke(null, set));
        }