Esempio n. 1
0
        public void VisitNode(JSFunctionExpression fn)
        {
            // Create a new visitor for nested function expressions
            if (Stack.OfType <JSFunctionExpression>().Skip(1).FirstOrDefault() != null)
            {
                new IntroduceVariableReferences(JSIL, fn.AllVariables, new HashSet <string>(from p in fn.Parameters select p.Name)).Visit(fn);
                return;
            }

            VisitChildren(fn);

            foreach (var r in ReferencesToTransform)
            {
                var cr = GetConstructedReference(r);

                if (cr == null)
                {
                    // We have already done the variable transform for this variable in the past.
                    continue;
                }

                // For 'ref this', we need to replace each individual expression, because we can't
                //  rename the this-variable.
                if (cr.IsThis)
                {
                    var refThis = JSIL.NewReference(Variables["this"]);
                    fn.ReplaceChildRecursive(r, refThis);
                    continue;
                }

                var parameter = (from p in fn.Parameters
                                 where p.Identifier == cr.Identifier
                                 select p).FirstOrDefault();

                if (parameter != null)
                {
                    TransformParameterIntoReference(parameter, fn.Body);
                }
                else
                {
                    var declaration = (from kvp in Declarations
                                       let vds = kvp.Key
                                                 from ivd in vds.Declarations.Select((vd, i) => new { vd = vd, i = i })
                                                 where MatchesConstructedReference(ivd.vd.Left, cr)
                                                 select new { vds = vds, vd = ivd.vd, i = ivd.i, block = kvp.Value }).FirstOrDefault();

                    if (declaration == null)
                    {
                        throw new InvalidOperationException(String.Format("Could not locate declaration for {0}", cr));
                    }

                    TransformVariableIntoReference(
                        (JSVariable)declaration.vd.Left,
                        declaration.vds,
                        declaration.i,
                        declaration.block
                        );
                }
            }
        }
Esempio n. 2
0
        public void VisitNode(JSFunctionExpression fn)
        {
            // Create a new visitor for nested function expressions
            if (Stack.OfType<JSFunctionExpression>().Skip(1).FirstOrDefault() != null) {
                new IntroduceVariableReferences(JSIL, fn.AllVariables, new HashSet<string>(from p in fn.Parameters select p.Name)).Visit(fn);
                return;
            }

            VisitChildren(fn);

            foreach (var r in ReferencesToTransform) {
                var cr = GetConstructedReference(r);

                if (cr == null) {
                    // We have already done the variable transform for this variable in the past.
                    continue;
                }

                // For 'ref this', we need to replace each individual expression, because we can't
                //  rename the this-variable.
                if (cr.IsThis) {
                    var refThis = JSIL.NewReference(Variables["this"]);
                    fn.ReplaceChildRecursive(r, refThis);
                    continue;
                }

                var parameter = (from p in fn.Parameters
                                 where p.Identifier == cr.Identifier
                                 select p).FirstOrDefault();

                if (parameter != null) {
                    TransformParameterIntoReference(parameter, fn.Body);
                } else {
                    var declaration = (from kvp in Declarations
                                       let vds = kvp.Key
                                       from ivd in vds.Declarations.Select((vd, i) => new { vd = vd, i = i })
                                       where MatchesConstructedReference(ivd.vd.Left, cr)
                                       select new { vds = vds, vd = ivd.vd, i = ivd.i, block = kvp.Value }).FirstOrDefault();

                    if (declaration == null)
                        throw new InvalidOperationException(String.Format("Could not locate declaration for {0}", cr));

                    TransformVariableIntoReference(
                        (JSVariable)declaration.vd.Left,
                        declaration.vds,
                        declaration.i,
                        declaration.block
                    );
                }
            }
        }
Esempio n. 3
0
        public void VisitNode(JSFunctionExpression fn)
        {
            var existingDeclarations = new HashSet <string>(
                fn.AllChildrenRecursive.OfType <JSVariableDeclarationStatement>()
                .SelectMany(
                    (vds) =>
                    from vd in vds.Declarations
                    select((JSVariable)vd.Left).Identifier
                    ).Union(
                    from tcb in fn.AllChildrenRecursive.OfType <JSTryCatchBlock>()
                    where tcb.CatchVariable != null
                    select tcb.CatchVariable.Identifier
                    )
                );

            foreach (var v_ in from v in Variables.Values
                     where !v.IsParameter &&
                     !existingDeclarations.Contains(v.Identifier)
                     select v)
            {
                ToDeclare.Add(v_);
            }

            VisitChildren(fn);

            foreach (var kvp in ToReplace)
            {
                fn.ReplaceChildRecursive(kvp.Key, kvp.Value);
            }

            if (ToDeclare.Count > 0)
            {
                fn.Body.Statements.Insert(
                    0, new JSVariableDeclarationStatement(
                        (from v in ToDeclare
                         select new JSBinaryOperatorExpression(
                             JSOperator.Assignment, v,
                             v.DefaultValue,
                             v.IdentifierType
                             )).ToArray()
                        )
                    );
            }
        }
        public void VisitNode (JSFunctionExpression fn) {
            var existingDeclarations = new HashSet<string>(
                fn.AllChildrenRecursive.OfType<JSVariableDeclarationStatement>()
                .SelectMany(
                    (vds) => 
                        from vd in vds.Declarations 
                        select ((JSVariable)vd.Left).Identifier
                ).Union(
                    from tcb in fn.AllChildrenRecursive.OfType<JSTryCatchBlock>()
                    where tcb.CatchVariable != null
                    select tcb.CatchVariable.Identifier
                )
            );

            foreach (var v_ in from v in Variables.Values
                               where !v.IsParameter &&
                                     !existingDeclarations.Contains(v.Identifier)
                               select v) 
            {
                ToDeclare.Add(v_);
            }

            VisitChildren(fn);

            foreach (var kvp in ToReplace)
                fn.ReplaceChildRecursive(kvp.Key, kvp.Value);

            if (ToDeclare.Count > 0)
                fn.Body.Statements.Insert(
                    0, new JSVariableDeclarationStatement(
                        (from v in ToDeclare
                         select new JSBinaryOperatorExpression(
                            JSOperator.Assignment, v,
                            v.DefaultValue, 
                            v.IdentifierType
                        )).ToArray()
                    )
                );
        }
        public void VisitNode(JSFunctionExpression fn)
        {
            VisitChildren(fn);

            foreach (var p in fn.Parameters) {
                if (!p.IsReference)
                    continue;

                var vrat = new VariableReferenceAccessTransformer(JSIL, p);
                vrat.Visit(fn);
            }

            /*
            if (!fn.Method.Method.IsStatic) {
                var vrat = new VariableReferenceAccessTransformer(JSIL, Variables["this"]);
                vrat.Visit(fn);
            }
             */

            foreach (var r in ReferencesToTransform) {
                var cr = GetConstructedReference(r);

                if (cr == null) {
                    // We have already done the variable transform for this variable in the past.
                    continue;
                }

                // For 'ref this', we need to replace each individual expression, because we can't
                //  rename the this-variable.
                if (cr.IsThis) {
                    var refThis = JSIL.NewReference(Variables["this"]);
                    fn.ReplaceChildRecursive(r, refThis);
                    continue;
                }

                var parameter = (from p in fn.Parameters
                                 where p.Identifier == cr.Identifier
                                 select p).FirstOrDefault();

                if (parameter != null) {
                    TransformParameterIntoReference(parameter, fn.Body);
                } else {
                    var declaration = (from kvp in Declarations
                                       let vds = kvp.Key
                                       from ivd in vds.Declarations.Select((vd, i) => new { vd = vd, i = i })
                                       where MatchesConstructedReference(ivd.vd.Left, cr)
                                       select new { vds = vds, vd = ivd.vd, i = ivd.i, block = kvp.Value }).FirstOrDefault();

                    if (declaration == null)
                        throw new InvalidOperationException(String.Format("Could not locate declaration for {0}", cr));

                    TransformVariableIntoReference(
                        (JSVariable)declaration.vd.Left,
                        declaration.vds,
                        declaration.i,
                        declaration.block
                    );
                }

                var vrat = new VariableReferenceAccessTransformer(JSIL, cr);
                vrat.Visit(fn);
            }
        }
        public void VisitNode(JSFunctionExpression fn)
        {
            VisitChildren(fn);

            foreach (var p in fn.Parameters)
            {
                if (!p.IsReference)
                {
                    continue;
                }

                var vrat = new VariableReferenceAccessTransformer(JSIL, p);
                vrat.Visit(fn);
            }

            /*
             * if (!fn.Method.Method.IsStatic) {
             *  var vrat = new VariableReferenceAccessTransformer(JSIL, Variables["this"]);
             *  vrat.Visit(fn);
             * }
             */

            foreach (var r in ReferencesToTransform)
            {
                var cr = GetConstructedReference(r);

                if (cr == null)
                {
                    // We have already done the variable transform for this variable in the past.
                    continue;
                }

                // For 'ref this', we need to replace each individual expression, because we can't
                //  rename the this-variable.
                if (cr.IsThis)
                {
                    var refThis = JSIL.NewReference(Variables["this"]);
                    fn.ReplaceChildRecursive(r, refThis);
                    continue;
                }

                var parameter = (from p in fn.Parameters
                                 where p.Identifier == cr.Identifier
                                 select p).FirstOrDefault();

                if (parameter != null)
                {
                    TransformParameterIntoReference(parameter, fn.Body);
                }
                else
                {
                    var declaration = (from kvp in Declarations
                                       let vds = kvp.Key
                                                 from ivd in vds.Declarations.Select((vd, i) => new { vd = vd, i = i })
                                                 where MatchesConstructedReference(ivd.vd.Left, cr)
                                                 select new { vds = vds, vd = ivd.vd, i = ivd.i, block = kvp.Value }).FirstOrDefault();

                    if (declaration == null)
                    {
                        throw new InvalidOperationException(String.Format("Could not locate declaration for {0}", cr));
                    }

                    TransformVariableIntoReference(
                        (JSVariable)declaration.vd.Left,
                        declaration.vds,
                        declaration.i,
                        declaration.block
                        );
                }

                var vrat = new VariableReferenceAccessTransformer(JSIL, cr);
                vrat.Visit(fn);
            }
        }
Esempio n. 7
0
        public void VisitNode(JSSwitchStatement ss)
        {
            IndexLookup indexLookup;
            Initializer initializer;
            NullCheck   nullCheck;

            // Detect switch statements using a lookup dictionary
            var switchVar = ss.Condition as JSVariable;

            // HACK: Fixup reference read-throughs
            var switchRefRead = ss.Condition as JSReadThroughReferenceExpression;

            if (switchRefRead != null)
            {
                switchVar = switchRefRead.Variable;
            }

            if (
                (switchVar != null) &&
                IndexLookups.TryGetValue(switchVar, out indexLookup) &&
                Initializers.TryGetValue(indexLookup.Field, out initializer)
                )
            {
                if (NullChecks.TryGetValue(indexLookup.SwitchVariable, out nullCheck))
                {
                    CurrentFunction.ReplaceChildRecursive(nullCheck.Statement, new JSNullStatement());
                }

                CurrentFunction.ReplaceChildRecursive(initializer.Statement, new JSNullStatement());

                if (indexLookup.IsInverted)
                {
                    CurrentFunction.ReplaceChildRecursive(indexLookup.Statement, new JSNullStatement());
                }

                var            switchCases = new List <JSSwitchCase>();
                JSExpression[] values;
                foreach (var cse in ss.Cases)
                {
                    var body = cse.Body;

                    if (cse.Values == null)
                    {
                        values = null;
                        body   = new JSBlockStatement(body.Statements.ToArray());
                    }
                    else
                    {
                        values = (from v in cse.Values
                                  let il = v as JSIntegerLiteral
                                           where il != null
                                           select initializer.Values[(int)il.Value]).ToArray();
                    }

                    switchCases.Add(new JSSwitchCase(
                                        values, body, cse.IsDefault
                                        ));
                }

                var newSwitch = new JSSwitchStatement(
                    indexLookup.SwitchVariable, switchCases.ToArray()
                    );

                SwitchStatementsDeoptimized += 1;

                ParentNode.ReplaceChild(ss, newSwitch);

                var outVar = indexLookup.OutputVariable;
                foreach (var fn in Stack.OfType <JSFunctionExpression>())
                {
                    foreach (var vds in fn.Body.AllChildrenRecursive.OfType <JSVariableDeclarationStatement>().ToArray())
                    {
                        for (int i = 0, c = vds.Declarations.Count; i < c; i++)
                        {
                            var leftVar = vds.Declarations[i].Left as JSVariable;

                            if ((leftVar != null) && (leftVar.Identifier == outVar.Identifier))
                            {
                                vds.Declarations.RemoveAt(i);
                                i--;
                                c--;
                            }
                        }
                    }

                    fn.AllVariables.Remove(outVar.Identifier);
                }

                VisitReplacement(newSwitch);
            }

            VisitChildren(ss);
        }