Imports System Imports System.Reflection Imports System.Reflection.Emit Public Class SimVM Private Delegate Function tmplP1(Of TReturn, TParameter0) (ByVal p0 As TParameter0) As TReturn Structure VMI Dim opcode as String Dim operand as Integer Sub New(ByVal _opcode as String, _operand as Integer) opcode = _opcode operand = _operand End Sub End Structure Public Shared Sub Main() Dim ops() as VMI = { _ new VMI("ldi",0), _ new VMI("sto",0), _ new VMI("ldi",0), _ new VMI("sto",1), _ new VMI("jmp",26), _ new VMI("ldi",0), _ new VMI("sto",2), _ new VMI("jmp",18), _ new VMI("ldr",0), _ new VMI("ldr",1), _ new VMI("ldr",2), _ new VMI("mul",0), _ new VMI("add",0), _ new VMI("sto",0), _ new VMI("ldr",2), _ new VMI("ldi",1), _ new VMI("add",0), _ new VMI("sto",2), _ new VMI("ldr",2), _ new VMI("ldi",10000), _ new VMI("cmp",0), _ new VMI("blt",8), _ new VMI("ldr",1), _ new VMI("ldi",1), _ new VMI("add",0), _ new VMI("sto",1), _ new VMI("ldr",1), _ new VMI("ldi",10000), _ new VMI("cmp",0), _ new VMI("blt",5), _ new VMI("eof",0) _ } Dim methodArgs as Type() = { GetType(Integer) } Dim program as New DynamicMethod("program", GetType(Long), methodArgs, GetType(SimVM).Module) Dim il As ILGenerator = program.GetILGenerator() Dim r0 As LocalBuilder = il.DeclareLocal(GetType(Integer)) Dim r1 As LocalBuilder = il.DeclareLocal(GetType(Integer)) Dim r2 As LocalBuilder = il.DeclareLocal(GetType(Integer)) Dim r3 As LocalBuilder = il.DeclareLocal(GetType(Integer)) Dim jmp(ops.Length) as Label Dim ip as Integer = 0 For ip = 0 to ops.Length - 1 jmp(ip) = il.DefineLabel() Next For ip = 0 to ops.Length - 1 Dim i as VMI = ops(ip) il.MarkLabel(jmp(ip)) Select Case i.Opcode Case "ldi" il.Emit(Opcodes.Ldc_i4, i.Operand) Case "ldr" il.Emit(Opcodes.Ldloc, i.Operand) Case "sto" il.Emit(Opcodes.Stloc, i.Operand) Case "jmp" il.Emit(Opcodes.Br_S, jmp(i.operand)) Case "mul" il.Emit(Opcodes.Mul) Case "add" il.Emit(Opcodes.Add) Case "eof" il.Emit(Opcodes.Ldloc, 0) il.Emit(Opcodes.Ret) Case "cmp" Select Case (ops(ip+1).opcode) Case "blt" il.Emit(Opcodes.Blt, jmp(ops(ip+1).operand)) Case Else Console.WriteLine("unsupported branch: {0}", ops(ip+1).opcode) End Select ip = ip + 1 Case Else Console.WriteLine("unsupported opcode: {0}", i.Opcode) End Select Next Console.WriteLine("{0}", _ CType(program.CreateDelegate(GetType(tmplP1(Of Long, Integer))), tmplP1(Of Long, Integer))(0)) End Sub End Class