public override bool VisitInstructionExpression(CilInstructionExpression expression) { if (expression.Instructions.Count == 1 && expression.Instructions[0].OpCode.Code == CilCode.Unbox_Any && IsBoxExpression(expression.Arguments[0], out var argument, out var boxedType) && expression.Instructions[0].Operand is ITypeDefOrRef type && type.FullName == boxedType.FullName) { argument.ExpectedType = expression.ExpectedType; expression.ReplaceWith(argument.Remove()); } return(base.VisitInstructionExpression(expression)); }
private void ReplaceWithLdlen(CilInstructionExpression expression, SzArrayTypeSignature arrayType) { var arrayExpr = expression.Arguments[0]; arrayExpr.ExpectedType = arrayType; var arrayLengthExpr = new CilInstructionExpression(CilOpCodes.Ldlen, null, (CilExpression)arrayExpr.Remove()) { ExpressionType = _context.TargetModule.CorLibTypeFactory.Int32 }; expression.ReplaceWith(arrayLengthExpr); }
private void ReplaceWithLdlen(CilInstructionExpression expression, SzArrayTypeSignature arrayType) { var arrayExpr = expression.Arguments[0]; arrayExpr.ExpectedType = arrayType; var arrayLoadExpr = new CilInstructionExpression(CilOpCodes.Ldlen, null, (CilExpression)arrayExpr.Remove()) { ExpressionType = arrayType.BaseType }; expression.ReplaceWith(arrayLoadExpr); }
private void ReplaceWithLdelema(CilInstructionExpression expression, SzArrayTypeSignature arrayType) { var arrayExpr = expression.Arguments[0]; var indexExpr = expression.Arguments[1]; arrayExpr.ExpectedType = arrayType; var elementTypeRef = _context.ReferenceImporter .ImportType(arrayType.BaseType.ToTypeDefOrRef()); var arrayLoadExpr = new CilInstructionExpression(CilOpCodes.Ldelema, elementTypeRef, (CilExpression)arrayExpr.Remove(), (CilExpression)indexExpr.Remove()) { ExpressionType = new ByReferenceTypeSignature(arrayType.BaseType) }; expression.ReplaceWith(arrayLoadExpr); }
private void ReplaceWithStelem(CilInstructionExpression expression, SzArrayTypeSignature arrayType) { var arrayExpr = expression.Arguments[0]; var valueExpr = expression.Arguments[1]; var indexExpr = expression.Arguments[2]; arrayExpr.ExpectedType = arrayType; // Select appropriate opcode. CilOpCode opCode; object operand = null; switch (arrayType.BaseType.ElementType) { case ElementType.I1: case ElementType.U1: opCode = CilOpCodes.Stelem_I1; break; case ElementType.Char: case ElementType.I2: case ElementType.U2: opCode = CilOpCodes.Stelem_I2; break; case ElementType.Boolean: case ElementType.I4: case ElementType.U4: opCode = CilOpCodes.Stelem_I4; break; case ElementType.I8: case ElementType.U8: opCode = CilOpCodes.Stelem_I8; break; case ElementType.R4: opCode = CilOpCodes.Stelem_R4; break; case ElementType.R8: opCode = CilOpCodes.Stelem_R8; break; case ElementType.I: case ElementType.U: opCode = CilOpCodes.Stelem_I; break; case ElementType.ValueType: opCode = CilOpCodes.Stelem; operand = _context.ReferenceImporter .ImportType(arrayType.BaseType.ToTypeDefOrRef()); break; default: opCode = CilOpCodes.Stelem_Ref; break; } valueExpr.ExpectedType = arrayType.BaseType; var arrayStoreExpr = new CilInstructionExpression(opCode, operand, (CilExpression)arrayExpr.Remove(), (CilExpression)indexExpr.Remove(), (CilExpression)valueExpr.Remove()); expression.ReplaceWith(arrayStoreExpr); }
private void ReplaceWithLdelem(CilInstructionExpression expression, SzArrayTypeSignature arrayType) { var arrayExpr = expression.Arguments[0]; var indexExpr = expression.Arguments[1]; arrayExpr.ExpectedType = arrayType; var elementTypeRef = _context.ReferenceImporter .ImportType(arrayType.BaseType.ToTypeDefOrRef()); // Select appropriate opcode. CilOpCode opCode; object operand = null; switch (arrayType.BaseType.ElementType) { case ElementType.I1: opCode = CilOpCodes.Ldelem_I1; break; case ElementType.U1: opCode = CilOpCodes.Ldelem_U1; break; case ElementType.I2: opCode = CilOpCodes.Ldelem_I2; break; case ElementType.Char: case ElementType.U2: opCode = CilOpCodes.Ldelem_U2; break; case ElementType.Boolean: case ElementType.I4: opCode = CilOpCodes.Ldelem_I4; break; case ElementType.U4: opCode = CilOpCodes.Ldelem_U4; break; case ElementType.I8: case ElementType.U8: opCode = CilOpCodes.Ldelem_I8; break; case ElementType.R4: opCode = CilOpCodes.Ldelem_R4; break; case ElementType.R8: opCode = CilOpCodes.Ldelem_R8; break; case ElementType.I: case ElementType.U: opCode = CilOpCodes.Ldelem_I; break; case ElementType.ValueType: opCode = CilOpCodes.Ldelem; operand = elementTypeRef; break; default: opCode = CilOpCodes.Ldelem_Ref; break; } // Create the ldelem expression var arrayLoadExpr = new CilInstructionExpression(opCode, operand, (CilExpression)arrayExpr.Remove(), (CilExpression)indexExpr.Remove()) { ExpressionType = arrayType.BaseType }; if (arrayType.BaseType.IsValueType) { // Array.GetValue boxes value typed values. arrayLoadExpr = new CilInstructionExpression(CilOpCodes.Box, elementTypeRef, arrayLoadExpr) { ExpectedType = expression.ExpectedType, ExpressionType = expression.ExpressionType }; } expression.ReplaceWith(arrayLoadExpr); }