Esempio n. 1
0
        private VariableLocation GetLocation(Variable variable)
        {
            VariableLocation location;

            if (!locals.TryGetValue(variable, out location))
            {
                var localIndex = cil.DeclareLocal(variable.StaticRepr.CliType, variable.Name);
                location = VariableLocation.Local(localIndex);
                locals.Add(variable, location);
            }

            return(location);
        }
Esempio n. 2
0
        internal FunctionEmitter(IR.Function function, MethodFactory methodFactory, FunctionLookup functionLookup)
        {
            Contract.Requires(function != null);
            Contract.Requires(methodFactory != null);
            Contract.Requires(functionLookup != null);

            this.declaration    = function;
            this.functionLookup = functionLookup;
            var signature = new FunctionSignature(function.Inputs.Select(i => i.StaticRepr), function.Outputs.Select(o => o.StaticRepr));

            // Determine the method signature
            var parameterDescriptors = new List <ParameterDescriptor>();

            foreach (var input in function.Inputs)
            {
                locals.Add(input, VariableLocation.Parameter(parameterDescriptors.Count));
                parameterDescriptors.Add(new ParameterDescriptor(input.StaticCliType, ParameterAttributes.None, input.Name));
            }

            Type returnType = typeof(void);

            if (function.Outputs.Length == 1)
            {
                returnType = function.Outputs[0].StaticCliType;                 // 1 output, use return value
            }
            else if (function.Outputs.Length >= 2)
            {
                // 2 or more outputs, use 'out' parameters
                foreach (var output in function.Outputs)
                {
                    string name = output.Name;
                    if (locals.ContainsKey(output))
                    {
                        // inout parameter, rename not to clash with input
                        name += "$out";
                    }
                    else
                    {
                        locals.Add(output, VariableLocation.Parameter(parameterDescriptors.Count));
                    }

                    var parameterType = output.StaticCliType.MakeByRefType();
                    parameterDescriptors.Add(new ParameterDescriptor(parameterType, ParameterAttributes.Out, name));
                }
            }

            // Create the method and get its IL generator
            ILGenerator ilGenerator;
            var         methodInfo = methodFactory(function.Name, parameterDescriptors, returnType, out ilGenerator);

            this.method = new FunctionMethod(methodInfo, signature);

            cil = new ILGeneratorMethodBodyWriter(ilGenerator);
            cil = new MethodBodyVerifier(new MethodBodyVerificationContext
            {
                Method         = methodInfo,
                ParameterTypes = parameterDescriptors.Select(p => p.Type).ToArray(),
                ReturnType     = returnType,
                HasInitLocals  = true,
                MaxStackSize   = ushort.MaxValue
            }, cil);

            temporaryPool = new TemporaryLocalPool(cil, "$temp");

            if (function.Outputs.Length == 1)
            {
                // Declare a local variable for the return value
                var output     = function.Outputs[0];
                var localIndex = cil.DeclareLocal(output.StaticCliType, output.Name);
                if (!function.Inputs.Contains(output))
                {
                    locals.Add(output, VariableLocation.Local(localIndex));
                }
            }
        }