private static IEnumerable<Variable> GetVariableUsage(Statement st) { if (st is AssignmentStatement) { foreach (Variable i in GetVariableUsage(((AssignmentStatement)st).Value)) yield return i; } }
static void ProcessStatement(Statement st) { if (st is AssignmentStatement) { var assign = (AssignmentStatement)st; assign.Target = ProcessExpression(assign.Target); assign.Value = ProcessExpression(assign.Value); } }
private static IEnumerable<Variable> GetVariableDefinition(Statement st) { if (st is AssignmentStatement) { foreach (Variable i in GetVariableDefinition(((AssignmentStatement)st).Target)) yield return i; } }
private static bool ProcessStatement(Statement st, StatementBlock block) { if (st is AssignmentStatement) { var assign = (AssignmentStatement)st; if (assign.Value is BinOpExpression) { var exp = (BinOpExpression)assign.Value; if ((exp.Left is BinOpExpression || exp.Right is BinOpExpression) && exp.Left != assign.Target) { block.Statements.Add(new AssignmentStatement { Target = assign.Target, Value = exp.Left }); block.Statements.Add(new AssignmentStatement { Target = assign.Target, Value = new BinOpExpression { Left = assign.Target, Operation = exp.Operation, Right = exp.Right } }); return true; } } } block.Statements.Add(st); return false; }
static Statement ReplaceVar(Statement st, Variable buff) { if (st is AssignmentStatement) { ((AssignmentStatement)st).Value = ReplaceVar(((AssignmentStatement)st).Value, buff); ((AssignmentStatement)st).Target = ReplaceVar(((AssignmentStatement)st).Target, buff); } return st; }
static int SearchDownwardKill(TransformContext context, Statement st, StatementBlock block, int startIndex) { Variable[] usage = context.Usages[st]; Variable[] definition = context.Definitions[st]; for (int i = startIndex + 1; i < block.Statements.Count; i++) { if (context.Usages[block.Statements[i]].Intersect(definition).Count() > 0 || context.Definitions[block.Statements[i]].Intersect(usage).Count() > 0) return i; } return block.Statements.Count - 1; }
public void GenerateCIL(Statement statement) { EmitStatement(statement); }
void EmitStatement(Statement statement) { if (statement is AssignmentStatement) { var assignment = (AssignmentStatement)statement; EmitStore(assignment.Target, assignment.Value); } else if (statement is LoopStatement) { var loop = (LoopStatement)statement; /* * ldc.i4 begin * br cmp * ldc.i4 dummy //hint for dnlib * lop: nop * ... * ... * ldc.i4.1 * add * cmp: dup * ldc.i4 limit * blt lop * pop */ Instruction lbl = Instruction.Create(OpCodes.Nop); Instruction dup = Instruction.Create(OpCodes.Dup); Emit(Instruction.CreateLdcI4(loop.Begin)); Emit(Instruction.Create(OpCodes.Br, dup)); Emit(Instruction.CreateLdcI4(loop.Begin)); Emit(lbl); foreach (Statement child in loop.Statements) EmitStatement(child); Emit(Instruction.CreateLdcI4(1)); Emit(Instruction.Create(OpCodes.Add)); Emit(dup); Emit(Instruction.CreateLdcI4(loop.Limit)); Emit(Instruction.Create(OpCodes.Blt, lbl)); Emit(Instruction.Create(OpCodes.Pop)); } else if (statement is StatementBlock) { foreach (Statement child in ((StatementBlock)statement).Statements) EmitStatement(child); } else throw new NotSupportedException(); }
public CipherGenContext Emit(Statement statement) { Block.Statements.Add(statement); return this; }
// Cannot go before the statements that use the variable defined at the statement // Cannot go further than the statements that override the variable used at the statement private static int SearchUpwardKill(TransformContext context, Statement st, StatementBlock block, int startIndex) { Variable[] usage = context.Usages[st]; Variable[] definition = context.Definitions[st]; for (int i = startIndex - 1; i >= 0; i--) { if (context.Usages[block.Statements[i]].Intersect(definition).Count() > 0 || context.Definitions[block.Statements[i]].Intersect(usage).Count() > 0) return i; } return 0; }