Пример #1
0
        public override Object Visit(InvocationExpression node, Object obj)
        {
            InheritedAttributes ia        = (InheritedAttributes)obj;
            Object     objArgs            = obj;
            MethodType actualMethodCalled = TypeExpression.As <MethodType>(node.ActualMethodCalled);

            if (actualMethodCalled != null)
            {
                objArgs = new InheritedAttributes(ia.CurrentMethod, ia.Assignment, ia.Reference, ia.ArrayAccessFound, actualMethodCalled, ia.IsParentNodeAnInvocation);
            }

            FieldAccessExpression fieldAccessExpression = node.Identifier as FieldAccessExpression;

            if (fieldAccessExpression != null)
            {
                // * A message has been sent with the syntax "obj.method(...)"
                Object o = node.Identifier.Accept(this, obj);
                node.Arguments.Accept(this, objArgs);
                if ((o is SynthesizedAttributes) && (((SynthesizedAttributes)o).IdentifierExpressionMode == IdentifierMode.Instance))
                {
                    TypeExpression klass = null; // * When the implicit object is a fresh var reference
                    if (actualMethodCalled != null)
                    {
                        klass = actualMethodCalled.MemberInfo.Class;
                    }
                    this.codeGenerator.CallVirt(this.indent, actualMethodCalled, klass, fieldAccessExpression.FieldName.Identifier, node.Arguments);
                }
                else
                {
                    this.codeGenerator.Call(this.indent, actualMethodCalled, actualMethodCalled.MemberInfo.Class, actualMethodCalled.MemberInfo.MemberIdentifier);
                }
            }
            else
            {
                // * A message is sent with without the implicit object "method(...)"
                if (node.Identifier is SingleIdentifierExpression)
                {
                    if ((((MethodType)node.Identifier.ExpressionType).MemberInfo.ModifierMask & Modifier.Static) == 0)
                    {
                        this.codeGenerator.ldarg(this.indent, 0);
                    }
                    node.Arguments.Accept(this, objArgs);
                    this.codeGenerator.Call(this.indent, actualMethodCalled, actualMethodCalled.MemberInfo.Class, ((SingleIdentifierExpression)node.Identifier).Identifier);
                }
                else
                {
                    if (node.Identifier is BaseExpression)
                    {
                        node.Arguments.Accept(this, objArgs);
                        this.codeGenerator.constructorCall(this.indent, actualMethodCalled, ((BaseExpression)node.Identifier).ExpressionType, ".ctor");
                    }
                }
            }
            //TODO: OJO AQUÏ: MIRAR DONDE SE CORRESPONDE CON CODEGENERATOR, PORQUE GENERAR UNA LÍNEA DESDE EL VISITOR
            // ES un poco chapuzaCHAPUZA
            this.codeGenerator.WriteLine();
            return(null);
        }
        protected override void InstrospectiveFieldInvocation(Expression node, string memberName, Object obj)
        {
            InheritedAttributes ia       = (InheritedAttributes)obj;
            GetMemberCallSite   callSite = GetCallSiteContainer(ia.CurrentMethod).AddGetMemberCallSite(memberName);

            this.codeGenerator.pop(indent);
            this.codeGenerator.WriteLine(indent, "ldsfld class " + callSite.CallSiteType + " " + callSite.FullName);
            this.codeGenerator.WriteLine(indent, "ldfld !0 class " + callSite.CallSiteType + "::Target");
            this.codeGenerator.WriteLine(indent, "ldsfld class " + callSite.CallSiteType + " " + callSite.FullName);
            node.Accept(this, obj);
            this.codeGenerator.WriteLine(indent, "callvirt instance !2 class " + callSite.CallSiteSubType + "::Invoke(!0,!1)");
        }
Пример #3
0
        ///  * ld       <implicit object>
        ///  * <for each method of UnionMethods>
        ///  *    // check the invocation reference
        ///  *    dup
        ///  *    isinst <class type of actualMethod>
        ///  *    brfalse <check NextMethod> (Unbox needed for value types (not Unbox.any))
        ///  *    // check arguments
        ///  *    <for each argument>
        ///  *       dup
        ///  *       isinst <current parameter of actualMethod> (If param is ValueType, is the argument of this type or can promote to this type?)
        ///  *       brfalse <NextMethod> (Box needed for value types)
        ///  *    call <current method>
        ///  *    br <EndLabel>
        ///  *    // check NextMethod
        ///  *    <NextMethod>
        ///  *    <clean elements on the stack>
        ///  *  // There are some mistakes
        ///  *  call <WrongMethodException>
        ///  *  <EndLabel>

        #endregion
        public override Object Visit(InvocationExpression node, Object obj)
        {
            InheritedAttributes ia = (InheritedAttributes)obj; //Simple cast to shorten thee expression
            Object objArgs         = obj;
            //Object o = null;
            InheritedAttributes objInv             = new InheritedAttributes(ia.CurrentMethod, ia.Assignment, ia.Reference, ia.ArrayAccessFound, ia.ActualMethodCalled, true);
            MethodType          actualMethodCalled = TypeExpression.As <MethodType>(node.ActualMethodCalled);

            if (actualMethodCalled != null)
            {
                objArgs = new InheritedAttributes(ia.CurrentMethod, ia.Assignment, ia.Reference, ia.ArrayAccessFound, actualMethodCalled, true);
            }

            return(node.Identifier.AcceptOperation(new CGILInvocationExpressionOperation <T>(this.indent, this, this.codeGenerator, node, ia, objInv, objArgs), null));
        }
        protected override void InstrospectiveFieldAssignation(Expression node, string memberName, Object obj)
        {
            InheritedAttributes ia       = (InheritedAttributes)obj;
            SetMemberCallSite   callSite = GetCallSiteContainer(ia.CurrentMethod).AddSetMemberCallSite(memberName);
            string id = GetAuxFielVar() + memberName;

            this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id, "object");
            this.codeGenerator.stloc(this.indent, id);
            this.codeGenerator.pop(this.indent);
            this.codeGenerator.WriteLine(indent, "ldsfld class " + callSite.CallSiteType + " class " + callSite.FullName);
            this.codeGenerator.WriteLine(indent, "ldfld !0 class " + callSite.CallSiteType + "::Target");
            this.codeGenerator.WriteLine(indent, "ldsfld class " + callSite.CallSiteType + " class " + callSite.FullName);
            node.Accept(this, obj);
            this.codeGenerator.ldloc(this.indent, id);
            this.codeGenerator.WriteLine(indent, "callvirt instance void class " + callSite.CallSiteSubType + "::Invoke(!0, !1, !2)");
        }
Пример #5
0
        /// <summary>
        /// Checks, at runtime, the type in the top of the stack
        /// </summary>
        /// <param name="endLabel">Label to go if the type is correct.</param>
        /// <param name="type">WriteType to check.</param>
        /// <param name="toDouble">True if it is necessary to convert to double.</param>
        // private void runtimeCheckTypeExpression(string endLabel, TypeExpression type, bool toDouble)
        //{
        //   type.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, endLabel, toDouble));
        //string notThisType = this.codeGenerator.NewLabel;

        //this.codeGenerator.dup(this.indent);
        //this.codeGenerator.isinst(this.indent, type);
        //this.codeGenerator.brfalse(this.indent, notThisType);
        //this.codeGenerator.UnboxAny(this.indent, type);
        //if ((toDouble) && (!(type is DoubleType)))
        //   this.codeGenerator.convToDouble(this.indent);
        //this.codeGenerator.br(this.indent, endLabel);
        //this.codeGenerator.WriteLabel(notThisType);
        //}

        #endregion



        #region IntrospectiveInvocation()
        /// <param name="node">The AST invocation expression node</param>
        /// <param name="obj">The visitor paramenter</param>
        /// <param name="inheritedAttributes">Inherited attributes</param>
        /// <param name="memberName">The name of the member</param>
        internal virtual void IntrospectiveInvocation(InvocationExpression node, Object obj, Object inheritedAttributes, string memberName)
        {
            InheritedAttributes ia = (InheritedAttributes)obj;

            ia.IsParentNodeAnInvocation = true;
            Object o = node.Identifier.Accept(this, ia);

            this.IntrospectiveGetMethod(node, ia, memberName);
            node.Identifier.Accept(this, ia);
            this.codeGenerator.ldci4(this.indent, node.Arguments.ExpressionCount);
            this.codeGenerator.newarr(this.indent, "[mscorlib]System.Object");
            for (int i = 0; i < node.Arguments.ExpressionCount; i++)
            {
                IntrospectiveInvocationMakeReadyArgument(node, ia, i);
            }
            this.codeGenerator.CallVirt(this.indent, "instance", "object", "[mscorlib]System.Reflection.MethodBase", "Invoke", new string[] { "object", "object[]" });
        }
        internal override void IntrospectiveInvocation(InvocationExpression node, Object obj, Object inheritedAttributes, string memberName)
        {
            InheritedAttributes ia         = (InheritedAttributes)obj;
            IList <String>      parameters = new List <string>();

            for (int i = 0; i < node.Arguments.ExpressionCount; i++)
            {
                parameters.Add(node.Arguments.GetExpressionElement(i).ILTypeExpression.ILType());
            }
            InvokeMemberCallSite callSite = GetCallSiteContainer(ia.CurrentMethod).AddInvokeMemberCallSite(memberName, parameters);

            this.codeGenerator.WriteLine(indent, "ldsfld class " + callSite.CallSiteType + " class " + callSite.FullName);
            this.codeGenerator.WriteLine(indent, "ldfld !0 class " + callSite.CallSiteType + "::Target");
            this.codeGenerator.WriteLine(indent, "ldsfld class " + callSite.CallSiteType + " class " + callSite.FullName);
            node.Identifier.Accept(this, ia);
            for (int i = 0; i < node.Arguments.ExpressionCount; i++)
            {
                node.Arguments.GetExpressionElement(i).Accept(this, inheritedAttributes);
            }
            this.codeGenerator.WriteLine(indent, "callvirt instance !" + (parameters.Count + 2) + " class " + callSite.CallSiteSubType + "::Invoke(" + String.Join(",", Enumerable.Range(0, node.Arguments.ExpressionCount + 2).Select((t, i) => "!" + i)) + ")");
        }
Пример #7
0
        private void IntrospectiveGetMethod(InvocationExpression node, InheritedAttributes ia, String memberName)
        {
            String end = this.codeGenerator.NewLabel;

            this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
            this.codeGenerator.ldstr(this.indent, memberName);
            this.codeGenerator.ldci4(this.indent, node.Arguments.ExpressionCount);
            this.codeGenerator.newarr(this.indent, "[mscorlib]System.Type");
            for (int i = 0; i < node.Arguments.ExpressionCount; i++)
            {
                TypeExpression argType = node.Arguments.GetExpressionElement(i).ILTypeExpression;
                this.IntropectiveInvocationLoadArgument(i, argType);
            }
            this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.MethodInfo", "[mscorlib]System.Type", "GetMethod", new string[] { "string", "class [mscorlib]System.Type[]" });
            this.codeGenerator.dup(this.indent);
            this.codeGenerator.brtrue(this.indent, end);
            this.codeGenerator.pop(this.indent);
            node.Identifier.Accept(this, ia);
            this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
            this.codeGenerator.ldstr(this.indent, memberName);
            this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.MethodInfo", "[mscorlib]System.Type", "GetMethod", new string[] { "string" });
            this.codeGenerator.WriteLabel(this.indent, end);
        }