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)"); }
/// * 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)"); }
/// <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)) + ")"); }
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); }