internal void EmitVariableAccess(LambdaCompiler lc, ReadOnlyCollection <ParameterExpression> vars)
        {
            if (NearestHoistedLocals != null)
            {
                // Find what array each variable is on & its index
                var indexes = new List <long>(vars.Count);

                foreach (var variable in vars)
                {
                    // For each variable, find what array it's defined on
                    ulong parents = 0;
                    var   locals  = NearestHoistedLocals;
                    while (!locals.Indexes.ContainsKey(variable))
                    {
                        parents++;
                        locals = locals.Parent;
                        Debug.Assert(locals != null);
                    }

                    // combine the number of parents we walked, with the
                    // real index of variable to get the index to emit.
                    var index = (parents << 32) | (uint)locals.Indexes[variable];

                    indexes.Add((long)index);
                }

                if (indexes.Count > 0)
                {
                    EmitGet(NearestHoistedLocals.SelfVariable);
                    lc.EmitConstantArray(indexes.ToArray());
                    lc.IL.Emit(OpCodes.Call, typeof(RuntimeOps).GetMethod("CreateRuntimeVariables", new[] { typeof(object[]), typeof(long[]) }));
                    return;
                }
            }

            // No visible variables
            lc.IL.Emit(OpCodes.Call, typeof(RuntimeOps).GetMethod("CreateRuntimeVariables", Type.EmptyTypes));
        }
示例#2
0
        private void EmitDelegateConstruction(LambdaCompiler inner)
        {
            var delegateType  = inner._lambda.Type;
            var dynamicMethod = inner._method as DynamicMethod;

            if (dynamicMethod != null)
            {
                var types          = new[] { typeof(Type), typeof(object) };
                var createDelegate = typeof(DynamicMethod).GetMethod("CreateDelegate", types);
                if (createDelegate != null)
                {
                    _boundConstants.EmitConstant(this, dynamicMethod, typeof(DynamicMethod));
                    _ilg.EmitType(delegateType);
                    EmitClosureCreation(inner);
                    _ilg.Emit(OpCodes.Callvirt, createDelegate);
                    _ilg.Emit(OpCodes.Castclass, delegateType);
                }
                else
                {
                    // Emit MethodInfo.CreateDelegate instead because DynamicMethod is not in Windows 8 Profile
                    _boundConstants.EmitConstant(this, dynamicMethod, typeof(MethodInfo));
                    _ilg.EmitType(delegateType);
                    EmitClosureCreation(inner);
                    _ilg.Emit(OpCodes.Callvirt,
                              typeof(MethodInfo).GetMethod("CreateDelegate", types));
                    _ilg.Emit(OpCodes.Castclass, delegateType);
                }
            }
            else
            {
                // new DelegateType(closure)
                EmitClosureCreation(inner);
                _ilg.Emit(OpCodes.Ldftn, inner._method);
                _ilg.Emit(OpCodes.Newobj, (ConstructorInfo)(delegateType.GetMember(".ctor")[0]));
            }
        }
示例#3
0
        /// <summary>
        /// Emits a delegate to the method generated for the LambdaExpression.
        /// May end up creating a wrapper to match the requested delegate type.
        /// </summary>
        /// <param name="lambda">Lambda for which to generate a delegate</param>
        ///
        private void EmitDelegateConstruction(LambdaExpression lambda)
        {
            // 1. Create the new compiler
            LambdaCompiler impl;

            if (_method is DynamicMethod)
            {
                impl = new LambdaCompiler(_tree, lambda);
            }
            else
            {
                // When the lambda does not have a name or the name is empty, generate a unique name for it.
                var name = string.IsNullOrEmpty(lambda.Name) ? GetUniqueMethodName() : lambda.Name;
                var mb   = _typeBuilder.DefineMethod(name, MethodAttributes.Private | MethodAttributes.Static);
                impl = new LambdaCompiler(_tree, lambda, mb);
            }

            // 2. emit the lambda
            // Since additional ILs are always emitted after the lambda's body, should not emit with tail call optimization.
            impl.EmitLambdaBody(_scope, false, CompilationFlags.EmitAsNoTail);

            // 3. emit the delegate creation in the outer lambda
            EmitDelegateConstruction(impl);
        }
 internal void AddLocal(LambdaCompiler gen, ParameterExpression variable)
 {
     _locals.Add(variable, new LocalStorage(gen, variable));
 }
示例#5
0
 internal ArgumentStorage(LambdaCompiler compiler, ParameterExpression p)
     : base(compiler, p)
 {
     _argument = compiler.GetLambdaArgument(compiler.Parameters.IndexOf(p));
 }
示例#6
0
 protected Storage(LambdaCompiler compiler, ParameterExpression variable)
 {
     Compiler = compiler;
     Variable = variable;
 }