Assembling and Executing MSIL from C# Code

C

carl.manaster

Hi,

I'd like to take a string containing MSIL code, assemble it, execute
it, and receive the result all from my running C# application.

So far I've managed to manually create some MSIL code that I can
successfully assemble with ilasm and execute at the DOS prompt, and
I've read up on System.Reflection.Emit and CodeDom, but I don't see how
to do this. It looks like I would have to write a whole
System.CodeDom.Compiler.CodeCompiler; I hope I'm wrong about that,
since it seems that the whole purpose of that class is to generate the
MSIL from a source language, but I've already got the MSIL.
Thanks in advance for any pointers.

Peace,
--Carl
 
D

Daniel O'Connell [C# MVP]

Hi,

I'd like to take a string containing MSIL code, assemble it, execute
it, and receive the result all from my running C# application.

So far I've managed to manually create some MSIL code that I can
successfully assemble with ilasm and execute at the DOS prompt, and
I've read up on System.Reflection.Emit and CodeDom, but I don't see how
to do this. It looks like I would have to write a whole
System.CodeDom.Compiler.CodeCompiler; I hope I'm wrong about that,
since it seems that the whole purpose of that class is to generate the
MSIL from a source language, but I've already got the MSIL.
Thanks in advance for any pointers.

I don't believe the framework has an IL parser+assembler class, which is
what you'd need. You might be able to find a third party one or you write a
rudimentary assembler yourself(the SDK includes an il grammar file). The
last option wiould be to launch ilasm from your project and let it assemble
the code.

I've got a class like you are talking about slated on my todo list, but it
will be a while yet.
 
J

Jon Shemitz

I'd like to take a string containing MSIL code, assemble it, execute
it, and receive the result all from my running C# application.

So far I've managed to manually create some MSIL code that I can
successfully assemble with ilasm and execute at the DOS prompt, and
I've read up on System.Reflection.Emit and CodeDom, but I don't see how
to do this. It looks like I would have to write a whole
System.CodeDom.Compiler.CodeCompiler; I hope I'm wrong about that,
since it seems that the whole purpose of that class is to generate the
MSIL from a source language, but I've already got the MSIL.

Does the CIL [Common Intermediate Language - the now-old replacement
name for MSIL] have to come from a string? You say you're creating
code to pass to ILASM - could the process that creates that code just
call Emit directly?

Emit is reasonably straightforward, but if you have to read a string,
you have to write an assembler, which IS a full-blown compiler, albeit
a very rudimentary one. You have to tokenize, detect bad syntax, &c.
 
C

carl.manaster

Thanks, Daniel,
I've got a class like you are talking about slated on my todo
list, but it will be a while yet.
I'd sure be interested to see that when you get to it.

Peace,
--Carl
 
C

carl.manaster

Hi, Jon,
Does the CIL [Common Intermediate Language - the now-old replacement
name for MSIL] have to come from a string? You say you're creating
code to pass to ILASM - could the process that creates that code just
call Emit directly?

Emit is reasonably straightforward, but if you have to read a string,
you have to write an assembler, which IS a full-blown compiler, albeit
a very rudimentary one. You have to tokenize, detect bad syntax, &c.

I'm looking at some Emit examples now. I could probably use that, but
I'm trying to start simple. Since generating the CIL [thanks] seemed
simple, for the _very_ simple code I'm starting with, I was trying not
to introduce all of the structure of emitters and code generators and
the like. Expecting to get there eventually, if the project goes
anywhere, but wanting to start out with the simplest thing (something I
could understand immediately) and work my way up.

Thanks,
--Carl
 
E

Eyeawanda Pondicherry

When you create the dynamic assembly, with the AssemblyBuilder, there is
a SaveAndRun method.

Without knowing the nature of the receiving application, it's hard to
say exactly how to set it up, but the answer to your question should be
/yes/ .
 
C

carl.manaster

Thanks, Eyeawanda,

But I can't find SaveAndRun. Could my version of C# or of the .net
library be out of date? I also couldn't find a reference for
SaveAndRun on the web.

As far as the nature of the receiving application - I am trying to
further explore the notion of "zero button testing", like this:
<http://s92417348.onlinehome.us/software/zbt/>

I want to take very simple functions, starting with this:

one:
~~expect returns 1
~~return 1

and generate and execute code that tests whether the expectation
passes. Here's what I hand-generated for the above:

..method static int32 one() cil managed
~~{
~~.maxstack 1
~~ldc.i4.1
~~ret
~~}

..namespace __TEST
~~{
~~.method static bool __TEST.one() cil managed
~~~~{
~~~~.maxstack 2
~~~~.locals init (int32)
~~~~.try
~~~~~~{
~~~~~~call int32 one()
~~~~~~stloc.0
~~~~~~leave.s CALL_SUCCEEDED
~~~~~~}
~~~~catch [mscorlib] System.Exception
~~~~~~{
~~~~~~pop
~~~~~~leave.s FAIL
~~~~~~}
~~CALL_SUCCEEDED:
~~~~ldloc.0
~~~~ldc.i4.1
~~~~bne.un.s FAIL
~~~~ldc.i4.1
~~~~br.s FINISH
~~FAIL:
~~~~ldc.i4.0
~~FINISH:
~~~~ret
~~~~}
~~}

I want to develop this incrementally, with tests the whole way along.
So I want to be able to test that appropriate CIL is generated, and
that it executes. And (for instance) that if the function itself
(one() in this example) is malformed, the __TEST code nevertheless runs
and still indicates a failure.

That desire for incremental development is scaring me away from the big
Compiler classes - I could of course just stub out everything, but I'd
rather work with smaller pieces.

Thanks,
--Carl
 
J

Jon Shemitz

I'm looking at some Emit examples now. I could probably use that, but
I'm trying to start simple. Since generating the CIL [thanks] seemed
simple, for the _very_ simple code I'm starting with, I was trying not
to introduce all of the structure of emitters and code generators and
the like. Expecting to get there eventually, if the project goes
anywhere, but wanting to start out with the simplest thing (something I
could understand immediately) and work my way up.

That makes sense. You do need to setup quite a stack of xBuilder
objects before you can Emit the first instruction. Otoh, the second
method or the second class is a lot easier than the first, because it
can use much of the same stack. I got started by copying an example,
and broadened my understanding as I needed to do different things. (I
think "tackle the immediate problem" generally beats "understand every
detail before you start" as a design and problem solving strategy.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top