c# - Add objects to list in loop in IL Emit - Common Language Runtime detected an invalid program -
the following c# code:
list<int> list = new list<int>(); for(int count = 0; count < 5; count++) list.add(count); return list;
my corresponding emitted code follows:
localbuilder list = ilout.declarelocal(typeof(list<int>)); localbuilder count = ilout.declarelocal(typeof(int)); localbuilder cmpres = ilout.declarelocal(typeof(bool)); constructorinfo dictconstrctor = typeof(list<int>).getconstructor(new type[] { }); methodinfo methodinfo_add = typeof(list<int>).getmethod("add", new[] { typeof(int) }); label il_001c = ilout.definelabel(); label il_000b = ilout.definelabel(); ilout.emit(opcodes.newobj, dictconstrctor); ilout.emit(opcodes.stloc_0, list); ilout.emit(opcodes.ldc_i4_0); ilout.emit(opcodes.stloc_1, count); ilout.emit(opcodes.br_s, il_001c); ilout.marklabel(il_000b); ilout.emit(opcodes.ldloc_0, list); ilout.emit(opcodes.ldloc_1, count); ilout.emit(opcodes.call, methodinfo_add); ilout.emit(opcodes.ldloc_1, count); ilout.emit(opcodes.ldc_i4_1); ilout.emit(opcodes.add); ilout.emit(opcodes.stloc_1, count); ilout.marklabel(il_001c); ilout.emit(opcodes.ldloc_1, count); ilout.emit(opcodes.ldc_i4_2); ilout.emit(opcodes.clt); ilout.emit(opcodes.stloc_3, cmpres); ilout.emit(opcodes.ldloc_3, cmpres); ilout.emit(opcodes.brtrue_s, il_000b); ilout.emit(opcodes.ldloc_0, list); ilout.emit(opcodes.ret);
it throwing exception - "common language runtime detected invalid program.".
what doing wrong here? appreciated.
ilout.emit(opcodes.stloc_1, count);
and
ilout.emit(opcodes.ldloc_1, count);
make no sense. no additional parameter needed if explicitly saying "use local 1"
likewise:
ilout.emit(opcodes.stloc_3, cmpres); ilout.emit(opcodes.ldloc_3, cmpres);
although frankly i'm not sure cmpres
serves useful purpose; no point storing , loading - leave on stack
note: if count
"local 1", cmpres
"local 2"; there no "local 3", stloc_3
, ldloc_3
malformed.
and again here:
ilout.emit(opcodes.ldloc_0, list); ilout.emit(opcodes.ldloc_1, count);
--
next call; you're doing static call:
ilout.emit(opcodes.call, methodinfo_add);
but instance method on object, should virtual call.
and again local fumble here:
ilout.emit(opcodes.ldloc_1, count);
and here:
ilout.emit(opcodes.stloc_1, count);
and here:
ilout.emit(opcodes.ldloc_0, list);
however, have severe doubts loop (even if fixed) expect - if read right, actually:
var list = new list<int>(); for(int [= 0] ; < 2 ; i++) // note 0 here implicit not explicit { list.add(i); } return list;
Comments
Post a Comment