예제 #1
0
        public void TestInvalidMain2()
        {
            using (var container = new Win64Container())
            {
                var voidType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Void);

                var mainFunc = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>()
                {
                }, voidType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.Return)
                });

                try
                {
                    container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(mainFunc));
                    Assert.Fail("Expected invalid main to not pass.");
                }
                catch (Exception e)
                {
                    Assert.AreEqual("Expected the main function to have the signature: 'main() Int'.", e.Message);
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Creates a list from a single function
 /// </summary>
 /// <param name="function">The function</param>
 public static IList <ManagedFunction> SingleFunction(ManagedFunction function)
 {
     return(new List <ManagedFunction>()
     {
         function
     });
 }
예제 #3
0
        public void TestNoMain()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);

                var testFunc = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>()
                {
                    intType
                }, intType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return)
                });

                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(testFunc));

                try
                {
                    container.Execute();
                    Assert.Fail("Expected no entry point to not pass.");
                }
                catch (Exception e)
                {
                    Assert.AreEqual("There is no entry point defined.", e.Message);
                }
            }
        }
예제 #4
0
        public void TestStoreField()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                (var pointType, var pointConstructor) = TestHelpers.DefinePointClass(container.VirtualMachine);

                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                    pointType
                },
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.NewObject, ".constructor", pointType, new List <BaseType>()),
                    new Instruction(OpCodes.StoreLocal, 0),
                    new Instruction(OpCodes.LoadLocal, 0),
                    new Instruction(OpCodes.LoadInt, 1337),
                    new Instruction(OpCodes.StoreField, "Point::x"),
                    new Instruction(OpCodes.LoadLocal, 0),
                    new Instruction(OpCodes.LoadField, "Point::x"),
                    new Instruction(OpCodes.Return)
                });

                container.VirtualMachine.LoadFunctionsAsAssembly(new List <ManagedFunction>()
                {
                    func,
                    pointConstructor
                });

                var result = container.Execute();
                Assert.AreEqual(1337, result);
            }
        }
예제 #5
0
        public void TestCreateArray()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);

                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadInt, 10),
                    new Instruction(OpCodes.NewArray, intType.Name),
                    new Instruction(OpCodes.Pop),
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return)
                });

                var functions = TestHelpers.SingleFunction(func);

                container.VirtualMachine.LoadFunctionsAsAssembly(functions);
                var result = container.Execute();
                Assert.AreEqual(0, result);
            }
        }
예제 #6
0
        public void TestDeallocationStack2()
        {
            using (var container = this.CreateContainer())
            {
                var gc = container.VirtualMachine.GarbageCollector;

                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                (var pointType, var pointConstructor) = TestHelpers.DefinePointClass(container.VirtualMachine);

                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                },
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.NewObject, ".constructor", pointType, new List <BaseType>()),
                    new Instruction(OpCodes.Call, "std.gc.collect", new List <BaseType>()),
                    new Instruction(OpCodes.Pop),
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return)
                });

                container.VirtualMachine.LoadFunctionsAsAssembly(new List <ManagedFunction>()
                {
                    func,
                    pointConstructor
                });

                var result = container.Execute();
                Assert.AreEqual(1, gc.Deallocations.Count);
                Assert.AreEqual(0, gc.Deallocations[0].Count);
            }
        }
예제 #7
0
        public void TestLocals1()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var funcDef = new FunctionDefinition("main", new List <BaseType>(), intType);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 100),
                    new Instruction(OpCodes.StoreLocal, 0),

                    new Instruction(OpCodes.LoadInt, 200),
                    new Instruction(OpCodes.StoreLocal, 1),

                    new Instruction(OpCodes.LoadInt, 300),
                    new Instruction(OpCodes.StoreLocal, 2),

                    new Instruction(OpCodes.LoadInt, 400),
                    new Instruction(OpCodes.StoreLocal, 3),

                    new Instruction(OpCodes.LoadLocal, 3),
                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(funcDef, Enumerable.Repeat(intType, 4).ToList(), instructions);
                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));
                Assert.AreEqual(400, container.Execute());
            }
        }
예제 #8
0
        public void TestVoidParameter()
        {
            using (var container = new Win64Container())
            {
                var voidType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Void);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>()
                {
                    voidType
                }, voidType),
                    new List <BaseType>(),
                    instructions);

                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));

                try
                {
                    container.Execute();
                    Assert.Fail("Expected void parameter to not pass.");
                }
                catch (VerificationException e)
                {
                    Assert.AreEqual("0: 'Void' is not a valid parameter type.", e.Message);
                }
            }
        }
예제 #9
0
        public void TestNotEndInReturn()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 0)
                };
                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>(),
                    instructions);

                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));

                try
                {
                    container.Execute();
                    Assert.Fail("Expected without return to not pass.");
                }
                catch (VerificationException e)
                {
                    Assert.AreEqual("0: Functions must end with a 'RET' instruction.", e.Message);
                }
            }
        }
예제 #10
0
 /// <summary>
 /// Creates a new verification exception
 /// </summary>
 /// <param name="message">The message</param>
 /// <param name="function">The function being verified</param>
 /// <param name="instruction">The instruction being verified</param>
 /// <param name="index">The index of the instruction</param>
 public VerificationException(string message, ManagedFunction function, Instruction instruction, int index)
     : base($"{index}: {message}")
 {
     this.Function         = function;
     this.Instruction      = instruction;
     this.InstructionIndex = index;
 }
예제 #11
0
        /// <summary>
        /// Returns the compilation data for the given function
        /// </summary>
        /// <param name="function">The function</param>
        /// <returns>The data or null if not compiled</returns>
        public AbstractCompilationData GetCompilationData(ManagedFunction function)
        {
            if (this.compiledFunctions.TryGetValue(function, out var compilationData))
            {
                return(compilationData);
            }

            return(null);
        }
예제 #12
0
        public void TestDeallocationClassFields3()
        {
            using (var container = this.CreateContainer())
            {
                var gc = container.VirtualMachine.GarbageCollector;

                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                (var pointType, var pointConstructor) = TestHelpers.DefinePointClass(container.VirtualMachine);

                var listMetadata = new ClassMetadata("List");
                listMetadata.DefineField(new FieldDefinition("head", pointType, AccessModifier.Public));
                listMetadata.CreateFields();
                container.VirtualMachine.ClassMetadataProvider.Add(listMetadata);
                var listType = container.VirtualMachine.TypeProvider.FindClassType("List");

                var listConstructorFunction = TestHelpers.CreateDefaultConstructor(container.VirtualMachine, listType);

                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                    listType
                },
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.NewObject, ".constructor", listType, new List <BaseType>()),
                    new Instruction(OpCodes.StoreLocal, 0),
                    new Instruction(OpCodes.LoadLocal, 0),
                    new Instruction(OpCodes.NewObject, ".constructor", pointType, new List <BaseType>()),
                    new Instruction(OpCodes.StoreField, "List::head"),
                    new Instruction(OpCodes.Call, "std.gc.collect", new List <BaseType>()),
                    new Instruction(OpCodes.LoadNull),
                    new Instruction(OpCodes.StoreLocal, 0),
                    new Instruction(OpCodes.Call, "std.gc.collect", new List <BaseType>()),
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return)
                });

                container.VirtualMachine.LoadFunctionsAsAssembly(new List <ManagedFunction>()
                {
                    func,
                    pointConstructor,
                    listConstructorFunction
                });

                var result = container.Execute();
                Assert.AreEqual(2, gc.Deallocations.Count);

                Assert.AreEqual(0, gc.Deallocations[0].Count);

                Assert.AreEqual(2, gc.Deallocations[1].Count);
                Assert.AreEqual(gc.Allocations[0], gc.Deallocations[1][0]);
                Assert.AreEqual(gc.Allocations[1], gc.Deallocations[1][1]);
            }
        }
예제 #13
0
        /// <summary>
        /// Compiles the given function
        /// </summary>
        /// <param name="function">The function to compile</param>
        /// <returns>A pointer to the start of the compiled function</returns>
        public IntPtr Compile(ManagedFunction function)
        {
            //Compile the function
            var compilationData = new CompilationData(function);

            this.compiledFunctions.Add(function, compilationData);
            this.codeGenerator.CompileFunction(compilationData);

            //Allocate native memory. The instructions will be copied later when all symbols has been resolved.
            var memory = this.MemoryManager.AllocateCode(function.GeneratedCode.Count);

            function.Definition.SetEntryPoint(memory);

            return(memory);
        }
예제 #14
0
        public void TestInvalidOverload()
        {
            using (var container = new Win64Container())
            {
                var intType   = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var floatType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Float);

                var func1 = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>()
                {
                    intType
                }, intType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return)
                });

                var func2 = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>()
                {
                    intType
                }, floatType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadFloat, 0.0f),
                    new Instruction(OpCodes.Return)
                });

                try
                {
                    container.VirtualMachine.LoadFunctionsAsAssembly(new List <ManagedFunction>()
                    {
                        func1, func2
                    });
                    Assert.Fail("Expected invalid overload to not pass.");
                }
                catch (Exception e)
                {
                    Assert.AreEqual("The function 'test(Int) Float' is already defined.", e.Message);
                }
            }
        }
예제 #15
0
        public void TestDiv()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var funcDef = new FunctionDefinition("main", new List <BaseType>(), intType);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 4),
                    new Instruction(OpCodes.LoadInt, 2),
                    new Instruction(OpCodes.DivInt),
                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(funcDef, new List <BaseType>(), instructions);
                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));
                Assert.AreEqual(4 / 2, container.Execute());
            }
        }
예제 #16
0
        public void TestMul()
        {
            using (var container = new Win64Container())
            {
                var floatType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Float);
                var funcDef   = new FunctionDefinition("floatMain", new List <BaseType>(), floatType);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadFloat, 2.5f),
                    new Instruction(OpCodes.LoadFloat, 1.35f),
                    new Instruction(OpCodes.MulFloat),
                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(funcDef, new List <BaseType>(), instructions);
                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));
                Assert.AreEqual(2.5f * 1.35f, ExecuteFloatProgram(container), 1E-4);
            }
        }
예제 #17
0
        public void TestDefinitionOrder()
        {
            using (var container = new Win64Container())
            {
                var intType           = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var assemblyFunctions = new List <ManagedFunction>();

                Action testFn = () =>
                {
                    var def = new FunctionDefinition("test", new List <BaseType>(), intType);

                    var instructions = new List <Instruction>
                    {
                        new Instruction(OpCodes.LoadInt, 1),
                        new Instruction(OpCodes.LoadInt, 2),
                        new Instruction(OpCodes.AddInt),
                        new Instruction(OpCodes.Return)
                    };
                    var func = new ManagedFunction(def, new List <BaseType>(), instructions);
                    assemblyFunctions.Add(func);
                };

                Action mainFn = () =>
                {
                    var def = new FunctionDefinition("main", new List <BaseType>(), intType);

                    var instructions = new List <Instruction>
                    {
                        new Instruction(OpCodes.Call, "test", new List <BaseType>()),
                        new Instruction(OpCodes.Return)
                    };

                    var func = new ManagedFunction(def, new List <BaseType>(), instructions);
                    assemblyFunctions.Add(func);
                };

                mainFn();
                testFn();
                container.VirtualMachine.LoadFunctionsAsAssembly(assemblyFunctions);
                Assert.AreEqual(3, container.Execute());
            }
        }
예제 #18
0
        public void TestMixedArguments()
        {
            using (var container = new Win64Container())
            {
                var intType    = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var floatType  = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Float);
                var parameters = new List <BaseType>()
                {
                    intType, floatType, intType, floatType, intType, floatType
                };

                container.VirtualMachine.Binder.Define(FunctionDefinition.NewExternal <FuncIntArgIntFloatIntFloatIntFloat>(
                                                           "add",
                                                           parameters,
                                                           intType,
                                                           MixedAdd));

                var def = new FunctionDefinition("main", new List <BaseType>(), intType);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 1),
                    new Instruction(OpCodes.LoadFloat, 2.0f),
                    new Instruction(OpCodes.LoadInt, 3),
                    new Instruction(OpCodes.LoadFloat, 4.0f),
                    new Instruction(OpCodes.LoadInt, 5),
                    new Instruction(OpCodes.LoadFloat, 6.0f),

                    new Instruction(
                        OpCodes.Call,
                        "add",
                        parameters),

                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(def, new List <BaseType>(), instructions);
                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));

                Assert.AreEqual(1 + 2 + 3 + 4 + 5 + 6, container.Execute());
            }
        }
예제 #19
0
        public void TestFloatDefaultValue()
        {
            using (var container = new Win64Container())
            {
                var floatType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Float);
                var funcDef   = new FunctionDefinition("floatMain", new List <BaseType>(), floatType);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadLocal, 0),
                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(funcDef, Enumerable.Repeat(floatType, 1).ToList(), instructions);
                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));
                container.VirtualMachine.Compile();
                var mainFunc = Marshal.GetDelegateForFunctionPointer <FloatMain>(
                    container.VirtualMachine.Binder.GetFunction("floatMain()").EntryPoint);

                Assert.AreEqual(0.0f, mainFunc());
            }
        }
예제 #20
0
        /// <summary>
        /// Verifies that given function has the correct semantics
        /// </summary>
        /// <param name="function">The function</param>
        public void VerifyFunction(ManagedFunction function)
        {
            var verifierData = new VerifierData(function);

            if (function.Instructions.Count == 0)
            {
                this.ThrowError(
                    verifierData,
                    new Instruction(),
                    0,
                    "Empty functions are not allowed.");
            }

            this.VerifyDefinition(verifierData);

            for (int i = 0; i < function.Instructions.Count; i++)
            {
                var instruction = function.Instructions[i];

                //Calculate the maximum size of the operand stack
                function.OperandStackSize = Math.Max(function.OperandStackSize, verifierData.OperandStack.Count);

                this.Handle(verifierData, instruction, i);

                if (i == function.Instructions.Count - 1)
                {
                    if (instruction.OpCode != OpCodes.Return)
                    {
                        this.ThrowError(
                            verifierData,
                            instruction,
                            i,
                            "Functions must end with a 'RET' instruction.");
                    }
                }
            }

            this.VerifyBranches(verifierData);
        }
예제 #21
0
        public void TestStackArguments()
        {
            using (var container = new Win64Container())
            {
                var intType    = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var parameters = Enumerable.Repeat(intType, 9).ToList();

                container.VirtualMachine.Binder.Define(FunctionDefinition.NewExternal <FuncIntArgIntIntIntIntIntIntIntIntInt>(
                                                           "add",
                                                           parameters,
                                                           intType,
                                                           StackAdd));

                var def = new FunctionDefinition("main", new List <BaseType>(), intType);

                var instructions = new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 1),
                    new Instruction(OpCodes.LoadInt, 2),
                    new Instruction(OpCodes.LoadInt, 3),
                    new Instruction(OpCodes.LoadInt, 4),
                    new Instruction(OpCodes.LoadInt, 5),
                    new Instruction(OpCodes.LoadInt, 6),
                    new Instruction(OpCodes.LoadInt, 7),
                    new Instruction(OpCodes.LoadInt, 8),
                    new Instruction(OpCodes.LoadInt, 9),

                    new Instruction(
                        OpCodes.Call,
                        "add",
                        parameters),

                    new Instruction(OpCodes.Return)
                };
                var func = new ManagedFunction(def, new List <BaseType>(), instructions);
                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));
                Assert.AreEqual(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, container.Execute());
            }
        }
예제 #22
0
        public void TestOverload()
        {
            using (var container = new Win64Container())
            {
                var intType   = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var floatType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Float);

                var func1 = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>()
                {
                    intType
                }, intType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return)
                });

                var func2 = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>()
                {
                    floatType
                }, floatType),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadFloat, 0.0f),
                    new Instruction(OpCodes.Return)
                });

                container.VirtualMachine.LoadFunctionsAsAssembly(new List <ManagedFunction>()
                {
                    func1, func2
                });
            }
        }
예제 #23
0
        public void TestEmpty()
        {
            using (var container = new Win64Container())
            {
                var intType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);

                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>(),
                    new List <Instruction>());

                container.VirtualMachine.LoadFunctionsAsAssembly(TestHelpers.SingleFunction(func));

                try
                {
                    container.Execute();
                    Assert.Fail("Expected empty functions to not pass.");
                }
                catch (VerificationException e)
                {
                    Assert.AreEqual("0: Empty functions are not allowed.", e.Message);
                }
            }
        }
예제 #24
0
 /// <summary>
 /// Creates new verifier data
 /// </summary>
 /// <param name="function">The function</param>
 public VerifierData(ManagedFunction function)
 {
     this.Function     = function;
     this.OperandStack = new Stack <BaseType>();
     this.Branches     = new List <BranchCheck>();
 }
예제 #25
0
 /// <summary>
 /// Creates a new stack frame for the given function
 /// </summary>
 /// <param name="basePointer">The base pointer</param>
 /// <param name="function">The function</param>
 /// <param name="instructionIndex">The index of the current instruction</param>
 public StackFrame(IntPtr basePointer, ManagedFunction function, int instructionIndex)
 {
     this.BasePointer      = basePointer;
     this.Function         = function;
     this.InstructionIndex = instructionIndex;
 }
 /// <summary>
 /// Creates new compilation data
 /// </summary>
 /// <param name="function">The function</param>
 public AbstractCompilationData(ManagedFunction function)
 {
     this.Function = function;
 }
예제 #27
0
        public void TestConstructor()
        {
            using (var container = new Win64Container())
            {
                var intType  = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var voidType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Void);

                var pointMetadata = new ClassMetadata("Point");
                pointMetadata.DefineField(new FieldDefinition("x", intType, AccessModifier.Public));
                pointMetadata.DefineField(new FieldDefinition("y", intType, AccessModifier.Public));
                pointMetadata.CreateFields();

                container.VirtualMachine.ClassMetadataProvider.Add(pointMetadata);

                var pointType = container.VirtualMachine.TypeProvider.FindClassType("Point");

                var pointConstructor = new ManagedFunction(
                    new FunctionDefinition(".constructor", new List <BaseType>()
                {
                    intType, intType
                }, voidType, pointType, true),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadArgument, 0),
                    new Instruction(OpCodes.LoadArgument, 1),
                    new Instruction(OpCodes.StoreField, "Point::x"),
                    new Instruction(OpCodes.LoadArgument, 0),
                    new Instruction(OpCodes.LoadArgument, 2),
                    new Instruction(OpCodes.StoreField, "Point::y"),
                    new Instruction(OpCodes.Return)
                });

                var func = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                    pointType
                },
                    new List <Instruction>()
                {
                    new Instruction(OpCodes.LoadInt, 1337),
                    new Instruction(OpCodes.LoadInt, 4711),
                    new Instruction(OpCodes.NewObject, ".constructor", pointType, new List <BaseType>()
                    {
                        intType, intType
                    }),
                    new Instruction(OpCodes.StoreLocal, 0),
                    new Instruction(OpCodes.LoadLocal, 0),
                    new Instruction(OpCodes.LoadField, "Point::x"),
                    new Instruction(OpCodes.LoadLocal, 0),
                    new Instruction(OpCodes.LoadField, "Point::y"),
                    new Instruction(OpCodes.AddInt),
                    new Instruction(OpCodes.Return)
                });

                container.VirtualMachine.LoadFunctionsAsAssembly(new List <ManagedFunction>()
                {
                    func,
                    pointConstructor
                });

                var result = container.Execute();
                Assert.AreEqual(1337 + 4711, result);
            }
        }
예제 #28
0
        static void Main(string[] args)
        {
            var config = new VirtualMachineConfiguration(
                true,
                true,
                true,
                true,
                true);

            using (var container = new Win64Container(config))
            {
                var intType  = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var voidType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Void);

                var pointMetadata = new ClassMetadata("Point");
                pointMetadata.DefineField(new FieldDefinition("x", intType, AccessModifier.Public));
                pointMetadata.DefineField(new FieldDefinition("y", intType, AccessModifier.Public));
                pointMetadata.CreateFields();
                container.VirtualMachine.ClassMetadataProvider.Add(pointMetadata);
                var pointType = container.VirtualMachine.TypeProvider.FindClassType("Point");

                var pointArrayType = container.VirtualMachine.TypeProvider.FindArrayType(pointType);

                void Println(long objectReference)
                {
                    Console.WriteLine($"0x{objectReference.ToString("x8")}");
                }

                container.VirtualMachine.Binder.Define(FunctionDefinition.NewExternal <PrintlnPoint>(
                                                           "std.println",
                                                           new List <BaseType>()
                {
                    pointType
                },
                                                           voidType,
                                                           Println));

                var constructorFunction = new ManagedFunction(
                    new FunctionDefinition(".constructor", new List <BaseType>(), voidType, pointType, true),
                    new List <BaseType>(),
                    new List <Instruction>()
                {
                    //new Instruction(OpCodes.LoadArgument, 0),
                    //new Instruction(OpCodes.LoadInt, 1337),
                    //new Instruction(OpCodes.StoreField, "Point::x"),
                    new Instruction(OpCodes.Return)
                });

                var mainFunction = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                    pointArrayType
                },
                    //new List<BaseType>() { pointType },
                    new List <Instruction>
                {
                    //new Instruction(OpCodes.LoadInt, 10),
                    //new Instruction(OpCodes.NewArray, pointType.Name),
                    //new Instruction(OpCodes.StoreLocal, 0),
                    //new Instruction(OpCodes.LoadLocal, 0),
                    //new Instruction(OpCodes.LoadInt, 0),
                    //new Instruction(OpCodes.NewObject, ".constructor", pointType, new List<BaseType>()),
                    //new Instruction(OpCodes.StoreElement, pointType.Name),
                    //new Instruction(OpCodes.Call, "std.gc.collect", new List<BaseType>()),
                    //new Instruction(OpCodes.LoadInt, 0),
                    //new Instruction(OpCodes.Return),

                    new Instruction(OpCodes.LoadInt, 10),
                    new Instruction(OpCodes.NewArray, pointType.Name),
                    new Instruction(OpCodes.StoreLocal, 0),
                    new Instruction(OpCodes.NewObject, ".constructor", pointType, new List <BaseType>()),
                    new Instruction(OpCodes.Pop),
                    new Instruction(OpCodes.Call, "std.gc.collect", new List <BaseType>()),
                    new Instruction(OpCodes.Call, "std.gc.collect", new List <BaseType>()),
                    new Instruction(OpCodes.LoadInt, 0),
                    new Instruction(OpCodes.Return),
                });

                var functions = new List <ManagedFunction>()
                {
                    mainFunction,
                    constructorFunction
                };

                container.VirtualMachine.LoadFunctionsAsAssembly(functions);
                container.VirtualMachine.Compile();

                foreach (var function in functions)
                {
                    var disassembler = new Disassembler(
                        container.VirtualMachine.Compiler.GetCompilationData(function),
                        x => new Compiler.Win64.Disassembler(x));
                    Console.WriteLine(disassembler.Disassemble());
                }

                int returnValue = container.VirtualMachine.GetEntryPoint()();
                Console.WriteLine(returnValue);
            }

            Console.ReadLine();
        }
예제 #29
0
        static void Main2(string[] args)
        {
            using (var container = new Win64Container())
            {
                var intType   = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Int);
                var floatType = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Float);
                var voidType  = container.VirtualMachine.TypeProvider.FindPrimitiveType(PrimitiveTypes.Void);

                var intArrayType = container.VirtualMachine.TypeProvider.FindArrayType(intType);

                var pointMetadata = new ClassMetadata("Point");
                pointMetadata.DefineField(new FieldDefinition("x", intType, AccessModifier.Public));
                pointMetadata.DefineField(new FieldDefinition("y", intType, AccessModifier.Public));
                pointMetadata.CreateFields();
                container.VirtualMachine.ClassMetadataProvider.Add(pointMetadata);
                var pointType = container.VirtualMachine.TypeProvider.FindClassType("Point");

                //var constructorFunction = new ManagedFunction(
                //    new FunctionDefinition(".constructor", new List<BaseType>(), voidType, pointType, true),
                //    new List<BaseType>(),
                //    new List<Instruction>()
                //    {
                //        new Instruction(OpCodes.Return)
                //    });

                //var mainFunction = new ManagedFunction(
                //    new FunctionDefinition("main", new List<BaseType>(), intType),
                //    new List<BaseType>() { },
                //    new List<Instruction>
                //    {
                //        new Instruction(OpCodes.NewObject, ".constructor", pointType, new List<BaseType>()),
                //        new Instruction(OpCodes.LoadField, "Point::x"),
                //        new Instruction(OpCodes.Return)
                //    });

                //var functions = new List<ManagedFunction>()
                //{
                //    mainFunction,
                //    constructorFunction
                //};

                var testFunction2 = new ManagedFunction(
                    new FunctionDefinition("test2", new List <BaseType>()
                {
                    intType
                }, intType),
                    new List <BaseType>()
                {
                    intType, floatType, pointType, intArrayType
                },
                    new List <Instruction>
                {
                    new Instruction(OpCodes.LoadFloat, 13.37f),
                    new Instruction(OpCodes.StoreLocal, 1),
                    new Instruction(OpCodes.LoadInt, 10),
                    new Instruction(OpCodes.NewArray, intType.Name),
                    new Instruction(OpCodes.StoreLocal, 3),
                    new Instruction(OpCodes.LoadArgument, 0),
                    new Instruction(OpCodes.LoadInt, 2),
                    new Instruction(OpCodes.AddInt),
                    new Instruction(OpCodes.Return)
                });

                var testFunction = new ManagedFunction(
                    new FunctionDefinition("test", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                },
                    new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 4711),
                    new Instruction(OpCodes.Call, "test2", new List <BaseType>()
                    {
                        intType
                    }),
                    new Instruction(OpCodes.Return)
                });

                var mainFunction = new ManagedFunction(
                    new FunctionDefinition("main", new List <BaseType>(), intType),
                    new List <BaseType>()
                {
                },
                    new List <Instruction>
                {
                    new Instruction(OpCodes.LoadInt, 4711),
                    new Instruction(OpCodes.Pop),
                    new Instruction(OpCodes.Call, "test", new List <BaseType>()),
                    new Instruction(OpCodes.Return)
                });

                var functions = new List <ManagedFunction>()
                {
                    mainFunction,
                    testFunction,
                    testFunction2
                };

                container.VirtualMachine.LoadFunctionsAsAssembly(functions);
                container.VirtualMachine.Compile();

                foreach (var function in functions)
                {
                    var disassembler = new Disassembler(
                        container.VirtualMachine.Compiler.GetCompilationData(function),
                        x => new Compiler.Win64.Disassembler(x));
                    Console.WriteLine(disassembler.Disassemble());
                }

                int returnValue = container.VirtualMachine.GetEntryPoint()();
                Console.WriteLine(returnValue);
            }

            Console.ReadLine();
        }
예제 #30
0
 /// <summary>
 /// Creates a new operand stack
 /// </summary>
 /// <param name="function">The function</param>
 /// <param name="assembler">The assembler</param>
 public OperandStack(ManagedFunction function, Assembler assembler)
 {
     this.function        = function;
     this.assembler       = assembler;
     this.operandTopIndex = -1;
 }