public void VisitNode(JSResultReferenceExpression rre)
        {
            var invocation = (rre.Referent as JSInvocationExpression);

            // When passing a packed array element directly to a function, use a proxy instead.
            // This allows hoisting to operate when the call is inside a loop, and it reduces GC pressure (since we basically make the struct unpack occur on-demand).
            if (
                (ParentNode is JSInvocationExpression) &&
                (invocation != null) &&
                (invocation.JSMethod != null) &&
                invocation.JSMethod.Reference.FullName.Contains("JSIL.Runtime.IPackedArray") &&
                invocation.JSMethod.Reference.FullName.Contains("get_Item(") &&
                Configuration.CodeGenerator.AggressivelyUseElementProxies.GetValueOrDefault(false)
                )
            {
                var elementType = invocation.GetActualType(TypeSystem);
                var replacement = new JSNewPackedArrayElementProxy(
                    invocation.ThisReference, invocation.Arguments.First(),
                    elementType
                    );

                ParentNode.ReplaceChild(rre, replacement);
                VisitReplacement(replacement);
                return;
            }

            VisitChildren(rre);
        }
        public void VisitNode(JSNewPackedArrayElementProxy npaep)
        {
            var isInsideLoop     = (Stack.Any((node) => node is JSLoopStatement));
            var parentInvocation = Stack.OfType <JSInvocationExpression>().FirstOrDefault();
            var doesValueEscape  = (parentInvocation != null) &&
                                   DoesValueEscapeFromInvocation(parentInvocation, npaep, true);

            if (
                isInsideLoop &&
                (
                    (parentInvocation == null) ||
                    !doesValueEscape
                )
                )
            {
                var replacement = CreateHoistedVariable(
                    (hoistedVariable) =>
                    new JSRetargetPackedArrayElementProxy(
                        hoistedVariable, npaep.Array, npaep.Index
                        ),
                    npaep.GetActualType(TypeSystem),
                    npaep.Array,
                    npaep.Index,
                    npaep.MakeUntargeted()
                    );

                ParentNode.ReplaceChild(npaep, replacement);
                VisitReplacement(replacement);
            }

            VisitChildren(npaep);
        }
        public void VisitNode (JSResultReferenceExpression rre) {
            var invocation = (rre.Referent as JSInvocationExpression);

            // When passing a packed array element directly to a function, use a proxy instead.
            // This allows hoisting to operate when the call is inside a loop, and it reduces GC pressure (since we basically make the struct unpack occur on-demand).
            if (
                (ParentNode is JSInvocationExpression) &&
                (invocation != null) &&
                (invocation.JSMethod != null) &&
                invocation.JSMethod.Reference.FullName.Contains("JSIL.Runtime.IPackedArray") &&
                invocation.JSMethod.Reference.FullName.Contains("get_Item(") &&
                Configuration.CodeGenerator.AggressivelyUseElementProxies.GetValueOrDefault(false)
            ) {
                var elementType = invocation.GetActualType(TypeSystem);
                var replacement = new JSNewPackedArrayElementProxy(
                    invocation.ThisReference, invocation.Arguments.First(),
                    elementType
                );

                ParentNode.ReplaceChild(rre, replacement);
                VisitReplacement(replacement);
                return;
            }

            VisitChildren(rre);
        }
Beispiel #4
0
        public void VisitNode (JSNewPackedArrayElementProxy npaep) {
            var isInsideLoop = (Stack.Any((node) => node is JSLoopStatement));
            var parentInvocation = Stack.OfType<JSInvocationExpression>().FirstOrDefault();
            var doesValueEscape = (parentInvocation != null) && 
                DoesValueEscapeFromInvocation(parentInvocation, npaep, true);

            if (
                isInsideLoop &&
                (
                    (parentInvocation == null) ||
                    !doesValueEscape
                )
            ) {
                var replacement = CreateHoistedVariable(
                    (hoistedVariable) => 
                        new JSRetargetPackedArrayElementProxy(
                            hoistedVariable, npaep.Array, npaep.Index
                        ),
                    npaep.GetActualType(TypeSystem),
                    npaep.Array,
                    npaep.Index,
                    npaep.MakeUntargeted()
                );

                ParentNode.ReplaceChild(npaep, replacement);
                VisitReplacement(replacement);
            }

            VisitChildren(npaep);
        }