Archive for January, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE (Web hosting providers) 506

Thursday, January 31st, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE 506 THE ROLE OF DYNAMIC ASSEMBLIES In general, the types of the System.Reflection.Emit namespace allow you represent raw CIL tokens programmatically during the construction of your dynamic binary. You will see many of these members in the example that follows; however, the ILGenerator type is worth checking out straightaway. The Role of the System.Reflection.Emit.ILGenerator As its name implies, the ILGenerator type s role is to inject CIL opcodes into a given type member. Typically, you will not need to directly create ILGenerator objects, but rather receive a valid reference to the ILGenerator type using the builder-centric types (such as the MethodBuilder and ConstructorBuilder types), for example: // Obtain an ILGenerator from a ConstructorBuilder // object named ‘myCtorBuilder’. ConstructorBuilder myCtorBuilder = new ConstructorBuilder(/* …various args… */); ILGenerator myCILGen = myCtorBuilder.GetILGenerator(); Once you have an ILGenerator in your hands, you are then able to emit the raw CIL opcodes using any number of methods. Table 15-9 documents some (but not all) methods of ILGenerator. Table 15-9. Select Methods of ILGenerator Method Meaning in Life BeginCatchBlock() Begins a catch block BeginExceptionBlock() Begins an exception block for a nonfiltered exception BeginFinallyBlock() Begins a finally block BeginScope() Begins a lexical scope DeclareLocal() Declares a local variable DefineLabel() Declares a new label Emit() Is overloaded numerous times to allow you to emit CIL opcodes EmitCall() Pushes a call or callvirt opcode into the CIL stream EmitWriteLine() Emits a call to Console.WriteLine() with different types of values EndExceptionBlock() Ends an exception block EndScope() Ends a lexical scope ThrowException() Emits an instruction to throw an exception UsingNamespace() Specifies the namespace to be used in evaluating locals and watches for the current active lexical scope The key method of ILGenerator is Emit(), which works in conjunction with the System.Reflection. Emit.OpCodes class type. As mentioned earlier in this chapter, this type exposes a good number of read-only fields that map to raw CIL opcodes. The full set of these members are all documented within online help, and you will see various examples in the pages that follow. Emitting a Dynamic Assembly To illustrate the process of defining a .NET assembly at runtime, let s walk through the process of creating a single-file dynamic assembly named MyAssembly.dll. Within this module is a class named HelloWorld. The HelloWorld type supports a default constructor and a custom constructor that is used to assign the value of a private member variable (theMessage) of type string. In addition,
Check Tomcat Web Hosting services for best quality webspace to host your web application.

Web server iis - CHAPTER 15 UNDERSTANDING CIL AND THE ROLE

Wednesday, January 30th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES 505 A dynamic assembly, on the other hand, is created in memory on the fly using the types provided by the System.Reflection.Emit namespace. The System.Reflection.Emit namespace makes it possible to create an assembly and its modules, type definitions, and CIL implementation logic at runtime. Once you have done so, you are then free to save your in-memory binary to disk. This, of course, results in a new static assembly. To be sure, the process of building a dynamic assembly using the System.Reflection.Emit namespace does require some level of understanding regarding the nature of CIL opcodes. Although creating dynamic assemblies is a fairly advanced (and uncommon) programming task, they can be useful under various circumstances: You are building a .NET programming tool that needs to generate assemblies on demand based on user input. You are building a program that needs to generate proxies to remote types on the fly based on the obtained metadata. You wish to load a static assembly and dynamically insert new types into the binary image. This being said, let s check out the types within System.Reflection.Emit. Exploring the System.Reflection.Emit Namespace Creating a dynamic assembly requires you to have some familiarity with CIL opcodes, but the types of the System.Reflection.Emit namespace hide the complexity of CIL as much as possible. For example, rather than directly specifying the necessary CIL directives and attributes to define a class type, you can simply make use of the TypeBuilder class. Likewise, if you wish to define a new instance-level constructor, you have no need to emit the specialname, rtspecialname, or .ctor tokens; rather, you can make use of the ConstructorBuilder. Table 15-8 documents the key members of the System. Reflection.Emit namespace. Table 15-8. Select Members of the System.Reflection.Emit Namespace Members Meaning in Life AssemblyBuilder Used to create an assembly (*.dll or *.exe) at runtime. *.exes must call the ModuleBuilder.SetEntryPoint() method to set the method that is the entry point to the module. If no entry point is specified, a *.dll will be generated. ModuleBuilder Used to define the set of modules within the current assembly. EnumBuilder Used to create a .NET enumeration type. TypeBuilder May be used to create classes, interfaces, structures, and delegates within a module at runtime. MethodBuilder Used to create type members (such as methods, local variables, EventBuilder properties, constructors, and attributes) at runtime. LocalBuilder PropertyBuilder FieldBuilder ConstructorBuilder CustomAttributeBuilder ParameterBuilder ILGenerator Emits CIL opcodes into a given type member. OpCodes Provides numerous fields that map to CIL opcodes. This type is used in conjunction with the various members of System.Reflection. Emit.ILGenerator.
Check Tomcat Web Hosting services for best quality webspace to host your web application.

CHAPTER 15 UNDERSTANDING CIL AND THE (Web site translator) 504

Tuesday, January 29th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE 504 THE ROLE OF DYNAMIC ASSEMBLIES Figure 15-4. Your CILCar in action // Call Display() and pass in topmost value on stack. call void [CILCars] CILCars.CILCarInfo::Display( class [CILCars]CILCars.CILCar) ret } } } The one opcode that is important to point out is .entrypoint. Recall from the discussion earlier in this chapter that this opcode is used to mark which method of an *.exe functions as the entry point of the module. In fact, given that .entrypoint is how the CLR identifies the initial method to execute, this method can be called anything at all other than Main(). The remainder of the CIL code found in the Main() method is your basic pushing and popping of stack-based values. Do note, however, that the creation of CILCar involves the use of the .newobj opcode. On a related note, recall that when you wish to invoke a member of a type using raw CIL, you make use of the doublecolon syntax and, as always, make use of the fully qualified name of the type. With this, you can compile your new file with ilasm.exe, verify your assembly with peverify.exe, and execute your program: ilasm CilCarClient.il peverify CilCarClient.exe CilCarClient.exe Figure 15-5 shows the end result. That wraps up the CIL primer and the first goal of this chapter. At this point, I hope you feel confident that you can open a particular .NET assembly using ildasm.exe and gain a better understanding of what exactly is occurring behind the scenes. Understanding Dynamic Assemblies As you may have gathered, the process of building a complex .NET application in CIL would be quite the labor of love. On the one hand, CIL is an extremely expressive programming language that allows you to interact with all of the programming constructs allowed by the CTS. On the other hand, authoring raw CIL is tedious, error-prone, and painful. While it is true that knowledge is power, you may indeed wonder just how important it is to commit the laws of CIL syntax to memory. The answer is, It depends. To be sure, most of your .NET programming endeavors will not require you to view, edit, or author raw CIL code. However, with the CIL primer behind you, you are now ready investigate the world of dynamic assemblies (as opposed to static assemblies) and the role of the System.Reflection.Emit namespace. The first question you may have is, What exactly is the difference between static and dynamic assemblies? By definition, static assemblies are .NET binaries loaded directly from disk storage, meaning they are located somewhere on your hard drive in a physical file (or possibly a set of files in the case of a multifile assembly) at the time the CLR requests them. As you might guess, every time you compile your C# source code, you end up with a static assembly.
Please visit our professional web hosting services to find out about cheap and reliable webhost service that will surely answer all your demands.

Web hosting bandwidth - CHAPTER 15 UNDERSTANDING CIL AND THE ROLE

Monday, January 28th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES 503 Building CILCarClient.exe Now you can build a simple *.exe assembly that will Make a CILCar type. Pass the type into the static CILCarInfo.Display() method. Create a new *.il file and define external references to mscorlib.dll and CILCars.dll (don t forget to place a copy of this .NET assembly in the client s application directory!). Next, define a single type (Program) that manipulates the CILCars.dll assembly. Here s the complete code: // External assembly refs. .assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) .ver 2:0:0:0 } .assembly extern CILCars { .ver 1:0:0:0 } // Our executable assembly. .assembly CILCarClient { .hash algorithm 0×00008004 .ver 0:0:0:0 } .module CILCarClient.exe // Implementation of Program type .namespace CILCarClient { .class private auto ansi beforefieldinit Program extends [mscorlib]System.Object { .method private hidebysig static void Main(string[] args) cil managed { // Marks the entry point of the *.exe. .entrypoint .maxstack 8 // Declare a local CILCar type and push // values on the stack for ctor call. .locals init ([0] class [CILCars]CILCars.CILCar myCilCar) ldc.i4 55 ldstr “Junior” // Make new CilCar; store and load reference. newobj instance void [CILCars]CILCars.CILCar::.ctor(int32, string) stloc.0 ldloc.0
In case you need quality webspace to host and run your web applications, try our personal web hosting services.

Web hosting rating - CHAPTER 15 UNDERSTANDING CIL AND THE 502

Sunday, January 27th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE 502 THE ROLE OF DYNAMIC ASSEMBLIES .class public auto ansi beforefieldinit CILCarInfo extends [mscorlib]System.Object { .method public hidebysig static void Display(class CILCars.CILCar c) cil managed { .maxstack 8 // We need a local string variable. .locals init ([0] string caption) // Load string and the incoming CILCar onto the stack. ldstr “{0}’s speed is:” ldarg.0 // Now place the value of the CILCar’s petName on the // stack and call the static String.Format() method. ldfld string CILCars.CILCar::petName call string [mscorlib]System.String::Format(string, object) stloc.0 // Now load the value of the currSpeed field and get its string // representation (note call to ToString() ). ldarg.0 ldflda int32 CILCars.CILCar::currSpeed call instance string [mscorlib]System.Int32::ToString() ldloc.0 // Now call the MessageBox.Show() method with loaded values. call valuetype [System.Windows.Forms] System.Windows.Forms.DialogResult [System.Windows.Forms] System.Windows.Forms.MessageBox::Show(string, string) pop ret } } Although the amount of CIL code is a bit more than you see in the implementation of CILCar, things are still rather straightforward. First, given that you are defining a static method, you don t have to be concerned with the hidden object reference (thus, the ldarg.0 opcode really does load the incoming CILCar argument). The method begins by loading a string (”{0}’s speed is”) onto the stack, followed by the CILCar argument. Once these two values are in place, you load the value of the petName field and call the static System.String.Format() method to substitute the curly bracket placeholder with the CILCar s pet name. The same general procedure takes place when processing the currSpeed field, but note that you use the ldarga opcode, which loads the argument address onto the stack. At this point, you call System.Int32.ToString() to transform the value at said address into a string type. Finally, once both strings have been formatted as necessary, you call the MessageBox.Show() method. At this point, you are able to compile your new *.dll using ilasm.exe with the following command: ilasm /dll CILCars.il and verify the contained CIL using peverify.exe: peverify CILCars.dll
If you are searching for cheap webhost for your web application, please visit MySQL5 Web Hosting services.

Web site hosting - CHAPTER 15 UNDERSTANDING CIL AND THE ROLE

Saturday, January 26th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES 501 // Define the single-file assembly. .assembly CILCars { .hash algorithm 0×00008004 .ver 1:0:0:0 } .module CILCars.dll As mentioned, this assembly will contain two class types. The first type, CILCar, defines two points of field data and a custom constructor. The second type, CarInfoHelper, defines a single static method named DisplayCarInfo(), which takes CILCar as a parameter and returns void. Both types are in the CILCars namespace. In terms of CIL, CILCar can be implemented as so: // Implementation of CILCars.CILCar type. .namespace CILCars { .class public auto ansi beforefieldinit CILCar extends [mscorlib]System.Object { // The field data of the CILCar. .field public string petName .field public int32 currSpeed // The custom constructor simply allows the caller // to assign the field data. .method public hidebysig specialname rtspecialname instance void .ctor(int32 c, string p) cil managed { .maxstack 8 // Load first arg onto the stack and call base class ctor. ldarg.0 // ‘this’ object, not the int32! call instance void [mscorlib]System.Object::.ctor() // Now load first and second args onto the stack. ldarg.0 // ‘this’ object ldarg.1 // int32 arg // Store topmost stack (int 32) member in currSpeed field. stfld int32 CILCars.CILCar::currSpeed // Load string arg and store in petName field. ldarg.0 // ‘this’ object ldarg.2 // string arg stfld string CILCars.CILCar::petName ret } } } Keeping in mind that the real first argument for any nonstatic member is the current object reference, the first block of CIL simply loads the object reference and calls the base class constructor. Next, you push the incoming constructor arguments onto the stack and store them into the type s field data using the stfld (store in field) opcode. Next, you need to implement the second type in this namespace: CILCarInfo. The meat of the type is found within the static Display() method. In a nutshell, the role of this method is to take the incoming CILCar parameter, extract the values of its field data, and display it in aWindows Forms message box. Here is the complete implementation of CILCarInfo, with analysis to follow:
You need excellent and relaible webhost company to host your web applications? Then pay a visit to Inexpensive Web Hosting services.

Web site templates - CHAPTER 15 UNDERSTANDING CIL AND THE 500

Friday, January 25th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE 500 THE ROLE OF DYNAMIC ASSEMBLIES Now, as you may recall, the br opcodes (br, blt, and so on) are used to control a break in flow when some condition has been met. In this example, you have set up a condition in which the for loop should break out of its cycle when the local variable i is equal to the value of 10. With each pass, the value of 1 is added to i, at which point the test condition is yet again evaluated. Also recall that when you make use of any of the CIL branching opcodes, you will need to define a specific code label (or two) that marks the location to jump to when the condition is indeed true. Given these points, ponder the following (augmented) CIL code generated via ildasm.exe (including the autogenerated code labels): .method public hidebysig static void CountToTen() cil managed { .maxstack 2 .locals init ([0] int32 i) // Init the local integer ‘i’. IL_0000: ldc.i4.0 // Load this value onto the stack. IL_0001: stloc.0 // Store this value at index ‘0′. IL_0002: br.s IL_0008 // Jump to IL_0008. IL_0004: ldloc.0 // Load value of variable at index 0. IL_0005: ldc.i4.1 // Load the value ‘1′ on the stack. IL_0006: add // Add current value on the stack at index 0. IL_0007: stloc.0 IL_0008: ldloc.0 // Load value at index ‘0′. IL_0009: ldc.i4.s 10 // Load value of ‘10′ onto the stack. IL_000b: blt.s IL_0004 // Less than? If so, jump back to IL_0004 IL_000d: ret } In a nutshell, this CIL code begins by defining the local int32 and loading it onto the stack. At this point, you jump back and forth between code label IL_0008 and IL_0004, each time bumping the value of i by 1 and testing to see whether i is still less than the value 10. If so, you exit the method. Building a .NET Assembly with CIL Now that you ve taken a tour of the syntax and semantics of raw CIL, it s time to solidify your current understanding by building a .NET application using nothing but CIL and your text editor of choice. Specifically, your application will consist of a privately deployed, single-file *.dll that contains two class type definitions, and a console-based *.exe that interacts with these types. Building CILCars.dll The first order of business is to build the *.dll to be consumed by the client. Open a text editor and create a new *.il file named CILCars.il. This single-file assembly will make use of two external .NET binaries, and you can begin creating your CIL code file as so: // Reference mscorlib.dll and // System.Windows.Forms.dll .assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) .ver 2:0:0:0 } .assembly extern System.Windows.Forms { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) .ver 2:0:0:0 }
We recommend high quality webhost to host and run your jsp application: christian web host services.

CHAPTER 15 UNDERSTANDING (Web design software) CIL AND THE ROLE

Thursday, January 24th, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES 499 This innocent-looking method has a lot to say in terms of CIL. First, the incoming arguments (a and b) must be pushed onto the virtual execution stack using the ldarg (load argument) opcode. Next, the add opcode will be used to pop the next two values off the stack and find the summation, and store the value on the stack yet again. Finally, this sum is popped off the stack and returned to the caller via the ret opcode. If you were to disassemble this C# method using ildasm.exe, you would find numerous additional tokens injected by csc.exe, but the crux of the CIL code is quite simple: .method public hidebysig static int32 Add(int32 a, int32 b) cil managed { .maxstack 2 ldarg.0 // Load ‘a’ onto the stack. ldarg.1 // Load ‘b’ onto the stack. add // Add both values. ret } The Hidden this Reference Notice that the two incoming arguments (a and b) are referenced within the CIL code using their indexed position (index 0 and index 1), given that the virtual execution stack begins indexing at position 0. One thing to be very mindful of when you are examining or authoring raw CIL code is that every (nonstatic) method that takes incoming arguments automatically receives an implicit additional parameter, which is a reference to the current object (think the C# this keyword). Given this, if the Add() method were defined as nonstatic // No longer static! public int Add(int a, int b) { return a + b; } the incoming a and b arguments are loaded using ldarg.1 and ldarg.2 (rather than the expected ldarg.0 and ldarg.1 opcodes). Again, the reason is that slot 0 actually contains the implicit this reference. Consider the following pseudo-code: // This is JUST pseudo-code! .method public hidebysig static int32 AddTwoIntParams( MyClass_HiddenThisPointer this, int32 a, int32 b) cil managed { ldarg.0 // Load MyClass_HiddenThisPointer onto the stack. ldarg.1 // Load ‘a’ onto the stack. ldarg.2 // Load ‘b’ onto the stack. … } Representing Iteration Constructs in CIL Iteration constructs in the C# programming language are represented using the for, foreach, while, and do keywords, each of which has a specific representation in CIL. Consider the classic for loop: public static void CountToTen() { for(int i = 0; i < 10; i++) ; }
If you are looking for affordable and reliable webhost to host and run your business application visit our ftp web hosting services.

CHAPTER 15 UNDERSTANDING CIL (Starting a web site) AND THE 498

Wednesday, January 23rd, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE 498 THE ROLE OF DYNAMIC ASSEMBLIES Declaring Local Variables in CIL Let s first check out how to declare a local variable. Assume you wish to build a method in CIL named MyLocalVariables() that takes no arguments and returns void. Within the method, you wish to define three local variables of type System.String, System.Int32, and System.Object. In C#, this member would appear as so (recall that locally scoped variables do not receive a default value and should be set to an initial state before further use): public static void MyLocalVariables() { string myStr = “CIL me dude…”; int myInt = 33; object myObj = new object(); } If you were to construct MyLocalVariables() directly in CIL, you could author the following: .method public hidebysig static void MyLocalVariables() cil managed { .maxstack 8 // Define three local variables. .locals init ([0] string myStr, [1] int32 myInt, [2] object myObj) // Load a string onto the virtual execution stack. ldstr “CIL me dude…” // Pop off current value and store in local variable [0]. stloc.0 // Load a constant of type ‘i4′ // (shorthand for int32) set to the value 33. ldc.i4 33 // Pop off current value and store in local variable [1]. stloc.1 // Create a new object and place on stack. newobj instance void [mscorlib]System.Object::.ctor() // Pop off current value and store in local variable [2]. stloc.2 ret } As you can see, the first step taken to allocate local variables in raw CIL is to make use of the .locals directive, which is paired with the init attribute. Within the scope of the related parentheses, your goal is to associate a given numerical index to each variable (seen here as [0], [1], and [2]). As you can see, each index is identified by its data type and an optional variable name. Once the local variables have been defined, you load a value onto the stack (using the various load-centric opcodes) and store the value within the local variable (using the various storage-centric opcodes). Mapping Parameters to Local Variables in CIL You have already seen how to declare local variables in raw CIL using the .local init directive; however, you have yet to see exactly how to map incoming parameters to local methods. Consider the following static C# method: public static int Add(int a, int b) { return a + b; }
You need excellent and relaible webhost company to host your web applications? Then pay a visit to Inexpensive Web Hosting services.

CHAPTER 15 UNDERSTANDING CIL AND THE ROLE (How to cite a web site)

Tuesday, January 22nd, 2008

CHAPTER 15 UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES 497 Opcode Meaning in Life ldobj Obtains all the values gathered by a heap-based object and places them on the stack. ldstr Loads a string value onto the stack. In addition to the set of load-specific opcodes, CIL provides numerous opcodes that explicitly pop the topmost value off the stack. As shown over the first few examples in this chapter, popping a value off the stack typically involves storing the value into temporary local storage for further use (such as a parameter for an upcoming method invocation). Given this, note how many opcodes that pop the current value off the virtual execution stack take an st (store) prefix. Table 15-7 hits the highlights. Table 15-7. Various Pop-Centric Opcodes Opcode Meaning in Life pop Removes the value currently on top of the evaluation stack, but does not bother to store the value starg Stores the value on top of the stack into the method argument at a specified index stloc (with numerous variations) Pops the current value from the top of the evaluation stack and stores it in a local variable list at a specified index stobj Copies a value of a specified type from the evaluation stack into a supplied memory address stsfld Replaces the value of a static field with a value from the evaluation stack Do be aware that various CIL opcodes will implicitly pop values off the stack to perform the task at hand. For example, if you are attempting to subtract two numbers using the sub opcode, it should be clear that sub will have to pop off the next two available values before it can perform the calculation. Once the calculation is complete, the result of the value (surprise, surprise) is pushed onto the stack once again. Considering the .maxstack Directive When you write method implementations using raw CIL, you need to be mindful of a special directive named .maxstack. As its name suggests, .maxstack establishes the maximum number of variables that may be pushed onto the stack at any given time during the execution of the method. The good news is that the .maxstack directive has a default value (8), which should be safe for a vast majority of methods you may be authoring. However, if you wish to be very explicit, you are able to manually calculate the number of local variables on the stack and define this value explicitly: .method public hidebysig instance void Speak() cil managed { // During the scope of this method, exactly // 1 value (the string literal) is on the stack. .maxstack 1 ldstr “Hello there…” call void [mscorlib]System.Console::WriteLine(string) ret }
You want to have a cheap webhost for your apache application, then check apache web hosting services.