private void Emit(Expression exp) { OpCode op; switch (exp) { case BinaryExpression be: if (exp.NodeType == ExpressionType.Assign) { EmitAssign(be); break; } Emit(be.Left); Emit(be.Right); switch (exp.NodeType) { case ExpressionType.ArrayIndex: _ilg.Ldelem(be.Left.Type.GetElementType()); break; case ExpressionType.RightShift: _ilg.Emit( new Instruction(be.Left.Type.IsUnsigned() ? OpCodes.Shr_Un : OpCodes.Shr)); break; default: if (Expr2Op.TryGetValue(exp.NodeType, out op)) { _ilg.Emit(new Instruction(op)); } else { throw new NotSupportedException(); } break; } break; case IndexExpression ie: Emit(ie.Object); break; case UnaryExpression ue: Emit(ue.Operand); if (Expr2Op.TryGetValue(exp.NodeType, out op)) { _ilg.Emit(new Instruction(op)); } else { throw new NotSupportedException(); } break; case ConstantExpression ce: _ilg.Const(ce.Value, ce.Type); break; case ParameterExpression pe: var local = ParameterResolver?.Invoke(pe); if (local != null) { _ilg.Emit(Instruction.Create(OpCodes.Ldloc, local)); } // else assume parameter is on stack and do nothing break; default: throw new NotSupportedException(); } }
public override void Load(IILEmitter emitter) { Array.Load(emitter); emitter.Const(Index); emitter.Ldelem(Array.Type.Next); }