Example #1
0
        public static void CreateArgumentsObject(ref mdr.CallFrame callFrame, int argumentsIndex)
        {
            var arguments = JSFunctionArguments.CreateArgumentsObject(ref callFrame, GetContext(ref callFrame));

            callFrame.Values[argumentsIndex].Set(arguments);
            SetArguments(ref callFrame, arguments);
        }
Example #2
0
        static void ReadArguments(ref mdr.CallFrame callerFrame, int firstArgIndex, int argsCount, ref mdr.CallFrame calleeFrame)
        {
            var values = callerFrame.Values;

            calleeFrame.PassedArgsCount = argsCount;
            var argIndex = argsCount - 1;
            var sp       = firstArgIndex + argIndex;

            switch (argsCount)
            {
            case 0:
                break;

            case 1:
                calleeFrame.Arg0 = values[sp];
                calleeFrame.Signature.InitArgType(argIndex--, calleeFrame.Arg0.ValueType);
                goto case 0;

            case 2:
                calleeFrame.Arg1 = values[sp--];
                calleeFrame.Signature.InitArgType(argIndex--, calleeFrame.Arg1.ValueType);
                goto case 1;

            case 3:
                calleeFrame.Arg2 = values[sp--];
                calleeFrame.Signature.InitArgType(argIndex--, calleeFrame.Arg2.ValueType);
                goto case 2;

            case 4:
                calleeFrame.Arg3 = values[sp--];
                calleeFrame.Signature.InitArgType(argIndex--, calleeFrame.Arg3.ValueType);
                goto case 3;

            default:
            {
                var remainintArgsCount = argsCount - mdr.CallFrame.InlineArgsCount;
                calleeFrame.Arguments = JSFunctionArguments.Allocate(remainintArgsCount);
                for (var i = remainintArgsCount - 1; i >= 0; --i)
                {
                    calleeFrame.Arguments[i] = values[sp--];
                    calleeFrame.Signature.InitArgType(argIndex--, calleeFrame.Arguments[i].ValueType);
                }
            }
                goto case 4;
            }
        }
Example #3
0
        public JSFunction()
            : base(mdr.Runtime.Instance.DFunctionPrototype, "Function")
        {
            JittedCode = (ref mdr.CallFrame callFrame) =>
            {
                //ECMA 15.3.2.1
                Debug.WriteLine("calling new Function");
                StringBuilder properFunctionDeclaration = new StringBuilder("return function ");
                int           argsCount = 0;
                string        body;
                if (callFrame.PassedArgsCount == 0)
                {
                    argsCount = 0;
                    body      = "";
                }
                else
                if (callFrame.PassedArgsCount == 1)
                {
                    argsCount = 0;
                    body      = callFrame.Arg(0).AsString();
                }
                else
                {
                    argsCount = callFrame.PassedArgsCount - 1;
                    body      = callFrame.Arg(callFrame.PassedArgsCount - 1).AsString();
                }

                properFunctionDeclaration.Append("(");
                for (int i = 0; i < argsCount; i++)
                {
                    properFunctionDeclaration.Append(callFrame.Arg(i).AsString());
                    if (i < argsCount - 1)
                    {
                        properFunctionDeclaration.Append(",");
                    }
                }
                properFunctionDeclaration.Append(")");

                properFunctionDeclaration.Append("{").Append(body).Append("}");
                string properFunctionDecString = properFunctionDeclaration.ToString();
                Debug.WriteLine("new Function: {0}", properFunctionDecString);
                JSGlobalObject.EvalString(properFunctionDecString, ref callFrame.Return);
                if (IsConstrutor)
                {
                    callFrame.This = callFrame.Return.AsDFunction();
                }
            };

            // toString is implementd in DObject
            //TargetPrototype.DefineOwnProperty("toString", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            //{
            //    Debug.WriteLine("calling JSFunction.toString");
            //    var function = callFrame.This as mdr.DFunction;
            //    if (function == null)
            //        Trace.Fail("TypeError");
            //    var funcStream = new System.IO.StringWriter();
            //    funcStream.WriteLine("{0} {{", Declaration(function));
            //    var astWriter = new mjr.Expressions.AstWriter(funcStream);
            //    astWriter.Execute((JSFunctionMetadata)function.Metadata);
            //    funcStream.WriteLine("}");
            //    callFrame.Return.Set(funcStream.ToString());
            //    //callFrame.Return.Set(function.ToString());
            //}), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);
            TargetPrototype.DefineOwnProperty("apply", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("calling JSFunction.apply");
                var tmpCallFrame      = new mdr.CallFrame();
                tmpCallFrame.Function = callFrame.This.ToDFunction();
                if (tmpCallFrame.Function == null)
                {
                    throw new InvalidOperationException(".apply should be called on a Function object");
                }
                if (mdr.ValueTypesHelper.IsDefined(callFrame.Arg0.ValueType))
                {
                    tmpCallFrame.This = Operations.Convert.ToObject.Run(ref callFrame.Arg0);
                }
                else
                {
                    tmpCallFrame.This = mdr.Runtime.Instance.GlobalContext;
                }
                if (callFrame.PassedArgsCount > 1)
                {
                    if (callFrame.Arg1.ValueType != mdr.ValueTypes.Array)
                    {
                        throw new InvalidOperationException("second argument of .apply should be an array");
                    }
                    var args = callFrame.Arg1.AsDArray();
                    tmpCallFrame.PassedArgsCount = args.Length;
                    switch (tmpCallFrame.PassedArgsCount)
                    {  //putting goto case x will crash the mono on linux
                    case 0:
                        break;

                    case 1:
                        tmpCallFrame.Arg0 = args.Elements[0];
                        break;

                    case 2:
                        tmpCallFrame.Arg1 = args.Elements[1];
                        goto case 1;

                    //tmpCallFrame.Arg0 = args.Elements[0];
                    //break;
                    case 3:
                        tmpCallFrame.Arg2 = args.Elements[2];
                        goto case 2;

                    //tmpCallFrame.Arg1 = args.Elements[1];
                    //tmpCallFrame.Arg0 = args.Elements[0];
                    //break;
                    case 4:
                        tmpCallFrame.Arg3 = args.Elements[3];
                        goto case 3;

                    //tmpCallFrame.Arg2 = args.Elements[2];
                    //tmpCallFrame.Arg1 = args.Elements[1];
                    //tmpCallFrame.Arg0 = args.Elements[0];
                    //break;
                    default:
                        tmpCallFrame.Arguments = JSFunctionArguments.Allocate(tmpCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount);
                        Array.Copy(args.Elements, mdr.CallFrame.InlineArgsCount, tmpCallFrame.Arguments, 0, tmpCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount);
                        goto case 4;
                        //tmpCallFrame.Arg3 = args.Elements[3];
                        //tmpCallFrame.Arg2 = args.Elements[2];
                        //tmpCallFrame.Arg1 = args.Elements[1];
                        //tmpCallFrame.Arg0 = args.Elements[0];
                        //break;
                    }
                    tmpCallFrame.Signature = new mdr.DFunctionSignature(args.Elements, tmpCallFrame.PassedArgsCount);
                }
                else
                {
                    tmpCallFrame.PassedArgsCount = 0;
                }
                tmpCallFrame.Function.Call(ref tmpCallFrame);
                if (tmpCallFrame.Arguments != null)
                {
                    JSFunctionArguments.Release(tmpCallFrame.Arguments);
                }

                callFrame.Return = tmpCallFrame.Return;
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            TargetPrototype.DefineOwnProperty("call", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("calling JSFunction.call");
                var tmpCallFrame      = new mdr.CallFrame();
                tmpCallFrame.Function = callFrame.This.ToDFunction();
                if (tmpCallFrame.Function == null)
                {
                    throw new InvalidOperationException(".call should be called on a Function object");
                }

                switch (callFrame.PassedArgsCount)
                {
                case 0:
                    tmpCallFrame.PassedArgsCount = 0;
                    tmpCallFrame.This            = mdr.Runtime.Instance.GlobalContext;
                    //throw new InvalidOperationException(".call should be called with at least one parameter");
                    break;

                case 1:
                    //tmpCallFrame.This = callFrame.Arg0;
                    if (mdr.ValueTypesHelper.IsDefined(callFrame.Arg0.ValueType))
                    {
                        tmpCallFrame.This = Operations.Convert.ToObject.Run(ref callFrame.Arg0);
                    }
                    else
                    {
                        tmpCallFrame.This = mdr.Runtime.Instance.GlobalContext;
                    }
                    tmpCallFrame.PassedArgsCount = callFrame.PassedArgsCount - 1;
                    break;

                case 2:
                    tmpCallFrame.Arg0 = callFrame.Arg1;
                    goto case 1;

                //tmpCallFrame.This = callFrame.Arg0;
                //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1;
                //break;
                case 3:
                    tmpCallFrame.Arg1 = callFrame.Arg2;
                    goto case 2;

                //tmpCallFrame.Arg0 = callFrame.Arg1;
                //tmpCallFrame.This = callFrame.Arg0;
                //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1;
                //break;
                case 4:
                    tmpCallFrame.Arg2 = callFrame.Arg3;
                    goto case 3;

                //tmpCallFrame.Arg1 = callFrame.Arg2;
                //tmpCallFrame.Arg0 = callFrame.Arg1;
                //tmpCallFrame.This = callFrame.Arg0;
                //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1;
                //break;
                case 5:
                    tmpCallFrame.Arg3 = callFrame.Arguments[0];
                    goto case 4;

                //tmpCallFrame.Arg2 = callFrame.Arg3;
                //tmpCallFrame.Arg1 = callFrame.Arg2;
                //tmpCallFrame.Arg0 = callFrame.Arg1;
                //tmpCallFrame.This = callFrame.Arg0;
                //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1;
                //break;
                default:
                    tmpCallFrame.Arguments = JSFunctionArguments.Allocate(tmpCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount);
                    Array.Copy(tmpCallFrame.Arguments, 0, callFrame.Arguments, 1, callFrame.PassedArgsCount - 1 - mdr.CallFrame.InlineArgsCount);
                    tmpCallFrame.Arg3 = callFrame.Arguments[0];
                    goto case 5;
                    //tmpCallFrame.Arg2 = callFrame.Arg3;
                    //tmpCallFrame.Arg1 = callFrame.Arg2;
                    //tmpCallFrame.Arg0 = callFrame.Arg1;
                    //tmpCallFrame.This = callFrame.Arg0;
                    //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1;
                    //break;
                }
                tmpCallFrame.Signature = new mdr.DFunctionSignature(ref tmpCallFrame, tmpCallFrame.PassedArgsCount);
                tmpCallFrame.Function.Call(ref tmpCallFrame);
                if (tmpCallFrame.Arguments != null)
                {
                    JSFunctionArguments.Release(tmpCallFrame.Arguments);
                }

                callFrame.Return = tmpCallFrame.Return;
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            /*TargetPrototype.DefineOwnProperty("bind", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
             * {
             *  Debug.WriteLine("calling JSFunction.bind");
             *  Trace.Fail("Unimplemented");
             * }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);*/
        }