Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#

C# Scripts using DynamicMethod

Rate me:
Please Sign up or sign in to vote.
5.00/5 (22 votes)
10 May 2011CPOL3 min read 69.9K   3K   64   19
C# scripts using DynamicMethod

Introduction

I had the problem to host active content in my document files, which included small scripts for animations and object specific interactions, like JavaScripts in HTML.

C# offers the great possibility to compile your own assemblies at runtime. However, there is no possibility to unload such compilations, to unload dynamic generated assemblies at runtime. The only way to do this is to create such assemblies in your own Domain and to unload such Domains later on but the communication between Domains is slow like inter process communication. Additional, to load the C# compiler environment and the compilation itself is not very fast at runtime, not nice for documents with hundreds of small internal scripts.

There are already quite a few articles about dynamic code generation using .NET and how to ship around these problems, but nothing was good enough for my case. The idea was to write my own C# script compiler based on C# syntax and conventions and to use Dynamic Methods to generate IL for best performance.

I found out that this works well without any assembly generation. With such solution, it is possible to use all existing classes and value structures but it is not possible to define your own new classes. The reason for this is that a .NET class always needs an assembly and the related assembly information.
However, the script itself works like a unique class with member functions and variables.

Using the Demo

For demonstration purposes, I wrote a small and very limited test program, only three C# files:
Program.cs contains a very simple user interface and EditCtrl.cs a simple code editor control.
The file Script.cs contains the class Script and this class is easy to use in other C# projects.

The demo looks like this and can be used to check and debug functionality and speed, the directory Demos contains some demo scripts for this.

Image 1

Using the Code

To use the code in other C# projects, it is only necessary to import the class Script from Script.cs. After this is done, it’s possible to use the Script class like this:

C#
var script = new Script();
script.Code = "using System.Windows.Forms; MessageBox.Show(\"Hello World!\");";
script.Run(null);

The second line in Script.cs contains the expression #define TraceOpCode. If this is defined (currently only in DEBUG), the Debug Output window will show the current MSIL output.
For this simple example, it is only:

ldstr Hello World!
call System.Windows.Forms.DialogResult Show(System.String)
pop
ret

How It Works

The namespace System.Reflection.Emit contains the class DynamicMethod. This class exists since .NET FrameWork version 2.0.
It is possible to use the DynamicMethod class to generate and execute methods at run time, without having to generate a dynamic assembly and a dynamic type to contain the method. Dynamic methods are the most efficient way to generate and execute small amounts of code. A good reference of how to use and an example code can be found here.

The Script class encapsulates a simple array of Dynamic methods: DynamicMethod[] methods. Every script function and the script body as creator is compiled to one of the dynamic methods in this array.
For this, the Script class contains the private helper class Script.Compiler to translate the script code to MSIL instructions using the ILGenerator from DynamicMethod.
After this own compilation, the .NET Framework just-in-time (JIT) compiler can translate the MSIL instructions to native machine code.
In difference to script interpreters, we get fast machine code for each supported CPU architecture.

Restrictions

The current compiler version has no implementation for switch and while. However, the same functionality is possible with if and for statements. There is o support for native unsafe pointers. Alternatively, the compiler implemented in C# is easy to extend for such and other requirements.

Feedback

I would appreciate any feedback you can give me on the code, concept, or the article itself.
Also, I'm curious about your ideas for enhancements and if you implement this concept what was the result.

History

  • 10th May, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Question.. not return a value in the name o f method? Pin
Member 1298804619-Jul-20 7:23
Member 1298804619-Jul-20 7:23 
PraiseAwesome Pin
JohnWallis4231-Oct-18 8:46
JohnWallis4231-Oct-18 8:46 
Questionmy most genuine admiration Pin
serpiccio26-Apr-13 9:19
serpiccio26-Apr-13 9:19 
Questionunderscore is missing Pin
Vejen30-May-12 5:03
Vejen30-May-12 5:03 
AnswerRe: underscore is missing Pin
D. Christian Ohle30-May-12 20:34
D. Christian Ohle30-May-12 20:34 
GeneralRe: underscore is missing Pin
Vejen1-Jun-12 4:40
Vejen1-Jun-12 4:40 
QuestionImpressive. 2 questions. Hope you still work on this... Pin
Thomas Zeutschler20-Mar-12 9:30
Thomas Zeutschler20-Mar-12 9:30 
AnswerRe: Impressive. 2 questions. Hope you still work on this... Pin
D. Christian Ohle22-Mar-12 5:25
D. Christian Ohle22-Mar-12 5:25 
QuestionParameters Pin
rbacenetti9-Jan-12 8:05
rbacenetti9-Jan-12 8:05 
GeneralMy vote of 5 Pin
tohghua14-Oct-11 19:34
tohghua14-Oct-11 19:34 
GeneralMy vote of 2 Pin
User 202031323-May-11 5:03
User 202031323-May-11 5:03 
GeneralVery very interesting! Pin
pl.218-May-11 1:33
professionalpl.218-May-11 1:33 
GeneralMy vote of 3 Pin
Member 473373916-May-11 19:55
Member 473373916-May-11 19:55 
General@ All, Thanks Pin
D. Christian Ohle12-May-11 4:16
D. Christian Ohle12-May-11 4:16 
GeneralCool! Pin
ahmet_uzun10-May-11 23:45
ahmet_uzun10-May-11 23:45 
GeneralNice article & code Pin
wvd_vegt10-May-11 22:28
professionalwvd_vegt10-May-11 22:28 
GeneralMy vote of 3 Pin
JV999910-May-11 22:20
professionalJV999910-May-11 22:20 
GeneralSome details about the implementation, please Pin
John Brett10-May-11 21:23
John Brett10-May-11 21:23 
GeneralInteresting Pin
sam.hill10-May-11 12:38
sam.hill10-May-11 12:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.