Exemplo n.º 1
0
        private WriteBack AddressOfWriteBackCore(IndexExpression node)
        {
            // emit instance, if any
            LocalBuilder?instanceLocal = null;
            Type?        instanceType  = null;

            if (node.Object != null)
            {
                EmitInstance(node.Object, out instanceType);

                // store in local
                IL.Emit(OpCodes.Dup);
                IL.Emit(OpCodes.Stloc, instanceLocal = GetInstanceLocal(instanceType));
            }

            // Emit indexes. We don't allow byref args, so no need to worry
            // about write-backs or EmitAddress
            var n    = node.ArgumentCount;
            var args = new LocalBuilder[n];

            for (var i = 0; i < n; i++)
            {
                var arg = node.GetArgument(i);
                EmitExpression(arg);

                var argLocal = GetLocal(arg.Type);
                IL.Emit(OpCodes.Dup);
                IL.Emit(OpCodes.Stloc, argLocal);
                args[i] = argLocal;
            }

            // emit the get
            EmitGetIndexCall(node, instanceType);

            // emit the address of the value
            var valueLocal = GetLocal(node.Type);

            IL.Emit(OpCodes.Stloc, valueLocal);
            IL.Emit(OpCodes.Ldloca, valueLocal);

            // Set the property after the method call
            // don't re-evaluate anything
            return(@this =>
            {
                if (instanceLocal != null)
                {
                    @this.IL.Emit(OpCodes.Ldloc, instanceLocal);
                    @this.FreeLocal(instanceLocal);
                }
                foreach (var arg in args)
                {
                    @this.IL.Emit(OpCodes.Ldloc, arg);
                    @this.FreeLocal(arg);
                }
                @this.IL.Emit(OpCodes.Ldloc, valueLocal);
                @this.FreeLocal(valueLocal);

                @this.EmitSetIndexCall(node, instanceLocal?.LocalType);
            });
        }
Exemplo n.º 2
0
        private void AddressOf(IndexExpression node, Type type)
        {
            if (!TypeUtils.AreEquivalent(type, node.Type) || node.Indexer != null)
            {
                EmitExpressionAddress(node, type);
                return;
            }

            if (node.Object == null)
            {
                throw new ArgumentException(string.Empty, nameof(node));
            }

            if (node.ArgumentCount == 1)
            {
                EmitExpression(node.Object);
                EmitExpression(node.GetArgument(0));
                IL.Emit(OpCodes.Ldelema, node.Type);
            }
            else
            {
                var address = node.Object.Type.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance);
                EmitMethodCall(node.Object, address, node);
            }
        }
Exemplo n.º 3
0
        protected override Expression VisitIndex(IndexExpression node)
        {
            if (node.Object != null)
            {
                Visit(node.Object);
            }
            else
            {
                Debug.Assert(node.Indexer != null);
                Out(node.Indexer.DeclaringType.Name);
            }
            if (node.Indexer != null)
            {
                Out('.');
                Out(node.Indexer.Name);
            }

            Out('[');
            for (int i = 0, n = node.ArgumentCount(); i < n; i++)
            {
                if (i > 0)
                {
                    Out(", ");
                }
                Visit(node.GetArgument(i));
            }
            Out(']');

            return(node);
        }
        private WriteBack AddressOfWriteBackCore(IndexExpression node)
        {
            // emit instance, if any
            LocalBuilder instanceLocal = null;
            Type instanceType = null;
            if (node.Object != null)
            {
                EmitInstance(node.Object, out instanceType);

                // store in local
                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, instanceLocal = GetInstanceLocal(instanceType));
            }

            // Emit indexes. We don't allow byref args, so no need to worry
            // about write-backs or EmitAddress
            int n = node.ArgumentCount;
            var args = new LocalBuilder[n];
            for (var i = 0; i < n; i++)
            {
                Expression arg = node.GetArgument(i);
                EmitExpression(arg);

                LocalBuilder argLocal = GetLocal(arg.Type);
                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, argLocal);
                args[i] = argLocal;
            }

            // emit the get
            EmitGetIndexCall(node, instanceType);

            // emit the address of the value
            LocalBuilder valueLocal = GetLocal(node.Type);
            _ilg.Emit(OpCodes.Stloc, valueLocal);
            _ilg.Emit(OpCodes.Ldloca, valueLocal);

            // Set the property after the method call
            // don't re-evaluate anything
            return @this =>
            {
                if (instanceLocal != null)
                {
                    @this._ilg.Emit(OpCodes.Ldloc, instanceLocal);
                    @this.FreeLocal(instanceLocal);
                }
                foreach (LocalBuilder arg in args)
                {
                    @this._ilg.Emit(OpCodes.Ldloc, arg);
                    @this.FreeLocal(arg);
                }
                @this._ilg.Emit(OpCodes.Ldloc, valueLocal);
                @this.FreeLocal(valueLocal);

                @this.EmitSetIndexCall(node, instanceLocal?.LocalType);
            };
        }
        private void AddressOf(IndexExpression node, Type type)
        {
            if (!TypeUtils.AreEquivalent(type, node.Type) || node.Indexer != null)
            {
                EmitExpressionAddress(node, type);
                return;
            }

            if (node.ArgumentCount == 1)
            {
                EmitExpression(node.Object);
                EmitExpression(node.GetArgument(0));
                _ilg.Emit(OpCodes.Ldelema, node.Type);
            }
            else
            {
                MethodInfo address = node.Object.Type.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance);
                EmitMethodCall(node.Object, address, node);
            }
        }
        private WriteBack AddressOfWriteBack(IndexExpression node)
        {
            if (node.Indexer == null || !node.Indexer.CanWrite)
            {
                return null;
            }

            // emit instance, if any
            LocalBuilder instanceLocal = null;
            Type instanceType = null;
            if (node.Object != null)
            {
                EmitInstance(node.Object, instanceType = node.Object.Type);

                // store in local
                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, instanceLocal = GetInstanceLocal(instanceType));
            }

            // Emit indexes. We don't allow byref args, so no need to worry
            // about write-backs or EmitAddress
            var n = node.ArgumentCount;
            List<LocalBuilder> args = new List<LocalBuilder>(n);
            for (var i = 0; i < n; i++)
            {
                var arg = node.GetArgument(i);
                EmitExpression(arg);

                var argLocal = GetLocal(arg.Type);
                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, argLocal);
                args.Add(argLocal);
            }

            // emit the get
            EmitGetIndexCall(node, instanceType);

            // emit the address of the value
            var valueLocal = GetLocal(node.Type);
            _ilg.Emit(OpCodes.Stloc, valueLocal);
            _ilg.Emit(OpCodes.Ldloca, valueLocal);

            // Set the property after the method call
            // don't re-evaluate anything
            return delegate ()
            {
                if (instanceLocal != null)
                {
                    _ilg.Emit(OpCodes.Ldloc, instanceLocal);
                    FreeLocal(instanceLocal);
                }
                foreach (var arg in args)
                {
                    _ilg.Emit(OpCodes.Ldloc, arg);
                    FreeLocal(arg);
                }
                _ilg.Emit(OpCodes.Ldloc, valueLocal);
                FreeLocal(valueLocal);

                EmitSetIndexCall(node, instanceType);
            };
        }
Exemplo n.º 7
0
        private WriteBack AddressOfWriteBack(IndexExpression node)
        {
            if (node.Indexer == null || !node.Indexer.CanWrite)
            {
                return(null);
            }

            // emit instance, if any
            LocalBuilder instanceLocal = null;
            Type         instanceType  = null;

            if (node.Object != null)
            {
                EmitInstance(node.Object, instanceType = node.Object.Type);

                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, instanceLocal = GetLocal(instanceType));
            }

            // Emit indexes. We don't allow byref args, so no need to worry
            // about write-backs or EmitAddress
            var n = node.ArgumentCount;
            List <LocalBuilder> args = new List <LocalBuilder>(n);

            for (var i = 0; i < n; i++)
            {
                var arg = node.GetArgument(i);
                EmitExpression(arg);

                var argLocal = GetLocal(arg.Type);
                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, argLocal);
                args.Add(argLocal);
            }

            // emit the get
            EmitGetIndexCall(node, instanceType);

            // emit the address of the value
            var valueLocal = GetLocal(node.Type);

            _ilg.Emit(OpCodes.Stloc, valueLocal);
            _ilg.Emit(OpCodes.Ldloca, valueLocal);

            // Set the property after the method call
            // don't re-evaluate anything
            return(delegate()
            {
                if (instanceLocal != null)
                {
                    _ilg.Emit(OpCodes.Ldloc, instanceLocal);
                    FreeLocal(instanceLocal);
                }
                foreach (var arg in args)
                {
                    _ilg.Emit(OpCodes.Ldloc, arg);
                    FreeLocal(arg);
                }
                _ilg.Emit(OpCodes.Ldloc, valueLocal);
                FreeLocal(valueLocal);

                EmitSetIndexCall(node, instanceType);
            });
        }