K reseni 5. DU pouzijte Mono.Cecil (otestovanou verzi si muzete stahnout z webu predmetu). Dale je zde par hintu, ktere budete asi potrebovat: 1) Pokud chcete volat z assembly kod (metodu), na kterou se assembly jeste neodkazovala, tak je treba do ni "dogenerovat" odkaz na takovou metodu (abyste se pak na ni mohli odkazat v generovanem CIL kodu [napr. jako argument instrukce CALL]). To lze nejjednoduseji udelat napriklad takto: MethodDefinition mDef = ... (metoda v jejimz kontextu se chci odkazovat na jinou metodu X.m) MethodInfo mInfo = (standardni reflection ziskany popis metody X.m) MethodReference mRef = mDef.Module.Import(mInfo); mRef (MethodReference) potom slouzi jako odkaz na metodu X.m, ktery mohu pouzit jako argument napr. instrukce CALL: ilProc.Append(ilProc.Create(OpCodes.Call, mRef)); 2) S lokalnimi promennymi mohu pracovat pomoci: mDef.Body.Variables kde mDef je MethodDefinition metody o jejiz promenne se zajimam (kolekce Variables je kolekce VariableDefinition, ktere mohu studovat nebo vytvaret nove - pouziva se jako argument instrukce LDLOC a STLOC): VariableDefinition v = ... ilProc.Append(ilProc.Create(OpCodes.Stloc, v)); 3) Zakladni veci tykajici se generovani kodu v Cecilu jsou ve jmenych prostorech: using Mono.Cecil; using Mono.Cecil.Cil; ale navic ve jmenem prostoru Rocks je nekolik zajimavych extension metod, ktere se mohou hodit - tedy se muze hodit: using Mono.Cecil.Rocks; coz mi pridava napr.: mDef.Body.SimplifyMacros() ktera rozepise vsechny CIL instrukce do jejich nejobecnejsi formy, tj. napr. z ldarg.0 to udela ldarg 0, nebo ldc.i4.s 5 to udela ldc.i4 5, nebo z br.s to udela br !!! mDef.Body.OptimizeMacros() vsechny CIL instrukce se snazi prepsat na jejich nejuspornejsi variantu na zaklade skutecnych parametru a jejich rozsahu (tedy je vlastne opakem SimplifyMacros) - tedy napr. starg 0 prepise na starg.0, nebo br prepise na br.s pokud je cil skoku dostatecne blizko. 4) Pokud modifikujete stavajici kod, tak Cecil automaticky opravuje vsechny branch instrukce tak, ze stale odkazuji na puvodni instrukci jako pred tim. Tedy pokud napr. mate kod, kde +XX je offset k instrukci add (tj. skok na instrukci add): br +XX ldloc.0 add ktery opravite na nasledujici vlozenim instrukci stloc a ldc pred puvodni ldloc: br +XX stloc.1 ldc.i4.1 ldloc.0 add tak se automaticky offset +XX opravi tak, ze br +XX stale skace na puvodni instrukci add. Ale POZOR: nikdy Cecil sam nemeni druh/opcode instrukce - tj. pokud byl puvodni skok short branch (tj. br.s +XX), a mezi nej a instrukci add jste pridali tolik bytu CIL kodu, ze je instrukce add mimo rozsah short branch, tak se offset +XX sice opravi, ale SPATNE (tj. zustane vam jen spodnich 7/8 bitu spravne hodnoty!)