void ImplementRegularICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);

            IParameter[] parameters = signature.Parameters;
            for (int i = 0; i < parameters.Length; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(
                    CodeBuilder.CreateReference(call.Parameters[0]),
                    i);
                mie.Arguments.Add(slice);
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
            }
            else
            {
                call.Body.Add(new ReturnStatement(mie));
            }
        }
Пример #2
0
        override public void OnClassDefinition(ClassDefinition node)
        {
            Visit(node.Members, NodeType.ClassDefinition);

            InternalCallableType type = node.Entity as InternalCallableType;

            if (null != type)
            {
                ImplementICallableCall(type, node);
            }
        }
		void ImplementICallableCall(InternalCallableType type, ClassDefinition node)
		{
			Method call = (Method)node.Members["Call"];
			Debug.Assert(null != call);
			Debug.Assert(call.Body.IsEmpty);
						
			CallableSignature signature = type.GetSignature();
			int byRefCount = GetByRefParamCount(signature);
			if (byRefCount > 0)
			{
				ImplementByRefICallableCall(call, type, node, signature, byRefCount);
			}
			else
			{
				ImplementRegularICallableCall(call, type, node, signature);
			}
		}
Пример #4
0
        void ImplementRegularICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);

            IParameter[] parameters            = signature.Parameters;
            int          fixedParametersLength = signature.AcceptVarArgs ? parameters.Length - 1 : parameters.Length;

            for (int i = 0; i < fixedParametersLength; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(
                    CodeBuilder.CreateReference(call.Parameters[0]),
                    i);
                mie.Arguments.Add(slice);
            }

            if (signature.AcceptVarArgs)
            {
                if (parameters.Length == 1)
                {
                    mie.Arguments.Add(CodeBuilder.CreateReference(call.Parameters[0]));
                }
                else
                {
                    mie.Arguments.Add(
                        CodeBuilder.CreateMethodInvocation(
                            RuntimeServices_GetRange1,
                            CodeBuilder.CreateReference(call.Parameters[0]),
                            CodeBuilder.CreateIntegerLiteral(fixedParametersLength)));
                }
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
            }
            else
            {
                call.Body.Add(new ReturnStatement(mie));
            }
            CheckMethodGenerics(call, node);
        }
Пример #5
0
        void ImplementICallableCall(InternalCallableType type, ClassDefinition node)
        {
            Method call = (Method)node.Members["Call"];

            Debug.Assert(null != call);
            Debug.Assert(0 == call.Body.Statements.Count);

            CallableSignature signature = type.GetSignature();
            int byRefCount = GetByRefParamCount(signature);

            if (byRefCount > 0)
            {
                ImplementByRefICallableCall(call, type, node, signature, byRefCount);
            }
            else
            {
                ImplementRegularICallableCall(call, type, node, signature);
            }
        }
Пример #6
0
        void ImplementByRefICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature,
            int byRefCount)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);

            IParameter[]        parameters = signature.Parameters;
            ReferenceExpression args       = CodeBuilder.CreateReference(call.Parameters[0]);

            InternalLocal[] temporaries = new InternalLocal[byRefCount];

            int byRefIndex = 0;

            for (int i = 0; i < parameters.Length; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

                IParameter parameter = parameters[i];
                if (parameter.IsByRef)
                {
                    IType tempType = parameter.Type;
                    if (tempType.IsByRef)
                    {
                        tempType = tempType.GetElementType();
                    }
                    temporaries[byRefIndex] = CodeBuilder.DeclareLocal(call,
                                                                       "__temp_" + parameter.Name,
                                                                       tempType);

                    call.Body.Add(
                        CodeBuilder.CreateAssignment(
                            CodeBuilder.CreateReference(temporaries[byRefIndex]),
                            CodeBuilder.CreateCast(
                                tempType,
                                slice)));

                    mie.Arguments.Add(
                        CodeBuilder.CreateReference(
                            temporaries[byRefIndex]));

                    ++byRefIndex;
                }
                else
                {
                    mie.Arguments.Add(slice);
                }
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
                PropagateByRefParameterChanges(call, parameters, temporaries);
            }
            else
            {
                InternalLocal invokeReturnValue = CodeBuilder.DeclareLocal(call,
                                                                           "__returnValue", signature.ReturnType);
                call.Body.Add(
                    CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateReference(invokeReturnValue),
                        mie));
                PropagateByRefParameterChanges(call, parameters, temporaries);
                call.Body.Add(
                    new ReturnStatement(
                        CodeBuilder.CreateReference(invokeReturnValue)));
            }
        }
Пример #7
0
 MethodInvocationExpression CreateInvokeInvocation(InternalCallableType type)
 {
     return(CodeBuilder.CreateMethodInvocation(
                CodeBuilder.CreateSelfReference(type),
                type.GetInvokeMethod()));
 }
        void ImplementICallableCall(InternalCallableType type, ClassDefinition node)
        {
            Method call = (Method)node.Members["Call"];

            Debug.Assert(null != call);
            Debug.Assert(0 == call.Body.Statements.Count);

            CallableSignature          signature = type.GetSignature();
            MethodInvocationExpression mie       = CodeBuilder.CreateMethodInvocation(
                CodeBuilder.CreateSelfReference(type),
                type.GetInvokeMethod());

            int          byrefcount    = 0;
            ILocalEntity invokeresults = null;

            ILocalEntity[]      tempvals;
            IParameter[]        parameters = signature.Parameters;
            ReferenceExpression args       = null;

            foreach (IParameter param in parameters)
            {
                if (param.IsByRef)
                {
                    ++byrefcount;
                }
            }

            tempvals = new InternalLocal[byrefcount];

            if (parameters.Length > 0)
            {
                args = CodeBuilder.CreateReference(call.Parameters[0]);
            }

            int byrefindex = 0;

            for (int i = 0; i < parameters.Length; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

                if (parameters[i].IsByRef)
                {
                    tempvals[byrefindex] = CodeBuilder.DeclareLocal(call,
                                                                    "__temp_" + parameters[i].Name,
                                                                    parameters[i].Type);

                    call.Body.Add(
                        CodeBuilder.CreateAssignment(
                            CodeBuilder.CreateReference(tempvals[byrefindex]),
                            CodeBuilder.CreateCast(
                                parameters[i].Type,
                                slice)));

                    mie.Arguments.Add(CodeBuilder.CreateReference(tempvals[byrefindex]));

                    ++byrefindex;
                }
                else
                {
                    mie.Arguments.Add(slice);
                }
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
            }
            else if (byrefcount > 0)
            {
                invokeresults = CodeBuilder.DeclareLocal(call,
                                                         "__result", signature.ReturnType);
                call.Body.Add(
                    CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateReference(invokeresults),
                        mie));
            }

            byrefindex = 0;
            for (int i = 0; i < parameters.Length; ++i)
            {
                if (parameters[i].IsByRef)
                {
                    SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

                    call.Body.Add(
                        CodeBuilder.CreateAssignment(
                            slice,
                            CodeBuilder.CreateReference(tempvals[byrefindex])));

                    ++byrefindex;
                }
            }

            if (TypeSystemServices.VoidType != signature.ReturnType)
            {
                if (byrefcount > 0)
                {
                    call.Body.Add(new ReturnStatement(
                                      CodeBuilder.CreateReference(invokeresults)));
                }
                else
                {
                    call.Body.Add(new ReturnStatement(mie));
                }
            }
        }
		void ImplementByRefICallableCall(
									Method call,
									InternalCallableType type,
									ClassDefinition node,
									CallableSignature signature,
									int byRefCount)
		{			
			MethodInvocationExpression mie = CreateInvokeInvocation(type);
			IParameter[] parameters = signature.Parameters;			
			ReferenceExpression args = CodeBuilder.CreateReference(call.Parameters[0]);
			InternalLocal[] temporaries = new InternalLocal[byRefCount];
			
			int byRefIndex = 0;
			for (int i=0; i<parameters.Length; ++i)
			{				
				SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

				IParameter parameter = parameters[i];				
				if (parameter.IsByRef)
				{
					IType tempType = parameter.Type;
					if (tempType.IsByRef)
					{
						tempType = tempType.ElementType;
					}
					temporaries[byRefIndex] = CodeBuilder.DeclareLocal(call,
								"__temp_" + parameter.Name,
								tempType);
								
					call.Body.Add(
						CodeBuilder.CreateAssignment(
						CodeBuilder.CreateReference(temporaries[byRefIndex]),
							CodeBuilder.CreateCast(
								tempType,
								slice)));
						
					mie.Arguments.Add(
						CodeBuilder.CreateReference(
							temporaries[byRefIndex]));
					
					++byRefIndex;
				}
				else
				{
					mie.Arguments.Add(slice);
				}
			}
			
			if (TypeSystemServices.VoidType == signature.ReturnType)
			{
				call.Body.Add(mie);
				PropagateByRefParameterChanges(call, parameters, temporaries);
			}
			else
			{
				InternalLocal invokeReturnValue = CodeBuilder.DeclareLocal(call,
							"__returnValue", signature.ReturnType);
				call.Body.Add(
					CodeBuilder.CreateAssignment(
						CodeBuilder.CreateReference(invokeReturnValue),
						mie));
				PropagateByRefParameterChanges(call, parameters, temporaries);
				call.Body.Add(
					new ReturnStatement(
						CodeBuilder.CreateReference(invokeReturnValue)));
			}
		}
		MethodInvocationExpression CreateInvokeInvocation(InternalCallableType type)
		{
			return CodeBuilder.CreateMethodInvocation(
								CodeBuilder.CreateSelfReference(type),
								type.GetInvokeMethod());
		}
		void ImplementRegularICallableCall(
									Method call,
									InternalCallableType type,
									ClassDefinition node,
									CallableSignature signature)
		{	
			MethodInvocationExpression mie = CreateInvokeInvocation(type);
			IParameter[] parameters = signature.Parameters;
			int fixedParametersLength = signature.AcceptVarArgs ? parameters.Length - 1 : parameters.Length;
			for (int i=0; i<fixedParametersLength; ++i)
			{
				SlicingExpression slice = CodeBuilder.CreateSlicing(
							CodeBuilder.CreateReference(call.Parameters[0]),
							i);
				mie.Arguments.Add(slice);
			}

			if (signature.AcceptVarArgs)
			{
				if (parameters.Length == 1)
				{
					mie.Arguments.Add(CodeBuilder.CreateReference(call.Parameters[0]));
				}
				else
				{
					mie.Arguments.Add(
						CodeBuilder.CreateMethodInvocation(
							RuntimeServices_GetRange1,
							CodeBuilder.CreateReference(call.Parameters[0]),
							CodeBuilder.CreateIntegerLiteral(fixedParametersLength)));
				}
			}
			
			if (TypeSystemServices.VoidType == signature.ReturnType)
			{
				call.Body.Add(mie);
			}
			else
			{
				call.Body.Add(new ReturnStatement(mie));
			}
		}