changeset 5:cb13da6e3349

simple loop test
author cin
date Mon, 28 Oct 2013 00:49:15 +0400
parents 1ae5b10f7a10
children a6329b092499 17543aa3aced
files Jint.Runtime/Jint.Runtime.csproj Jint.Runtime/Main.cs Jint.Runtime/VM/AbstractBox.cs Jint.Runtime/VM/Box.cs Jint.Runtime/VM/Frame.cs Jint.Runtime/VM/OpCodes/ConditionOp.cs Jint.Runtime/VM/OpCodes/GteCmp.cs Jint.Runtime/VM/OpCodes/Loop.cs Jint.Runtime/VM/OpCodes/LteCmp.cs Jint.Runtime/VM/RuntimeContext.cs Jint.suo
diffstat 11 files changed, 167 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/Jint.Runtime/Jint.Runtime.csproj	Sun Oct 27 21:20:59 2013 +0400
+++ b/Jint.Runtime/Jint.Runtime.csproj	Mon Oct 28 00:49:15 2013 +0400
@@ -45,7 +45,9 @@
     <Compile Include="VM\Machine.cs" />
     <Compile Include="VM\OpCodes\BinaryOp.cs" />
     <Compile Include="VM\OpCodes\Codes.cs" />
-    <Compile Include="VM\OpCodes\Loop.cs" />
+    <Compile Include="VM\OpCodes\ConditionOp.cs" />
+    <Compile Include="VM\OpCodes\LteCmp.cs" />
+    <Compile Include="VM\OpCodes\GteCmp.cs" />
     <Compile Include="VM\OperationDelegates.cs" />
     <Compile Include="VM\RuntimeContext.cs" />
   </ItemGroup>
--- a/Jint.Runtime/Main.cs	Sun Oct 27 21:20:59 2013 +0400
+++ b/Jint.Runtime/Main.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -12,12 +12,25 @@
         {
             RuntimeContext runtime = new RuntimeContext();
             runtime.DefineBinaryOperation<int>(Codes.Add, (x, y) => x + y);
+            runtime.DefineCompareOperation<int>((x, y) => x.CompareTo(y));
 
-            var frame = new Frame(4,runtime);
+            var frame = new Frame(5,runtime);
+            frame.SetValue(1, 10000000);
             frame.SetValue(2,0);
             frame.SetValue(3,1);
 
-            var op = new BinaryOp(Codes.Add, 2, 3, 2);
+
+            var code = new LteCmp(2, 1, 4);
+            var body = new BinaryOp(Codes.Add, 2, 3, 2);
+            body.Chain(code);
+            code.Chain(
+                new ConditionOp(
+                    4,
+                    body,
+                    null
+                )
+            );
+                        
 
 			var t = Environment.TickCount;
 
@@ -25,38 +38,33 @@
              *          mov r1, 10 000 000
              *          mov r2, 0
              *          mov r3, 1
-             *          loop
-             *              condition:
-             *                  gte r2, r1
-             *              body:
-             *                  add r2,r3,r2
+             *          lte r2, r1, r4
+             * cmp:
+             *          test r4 { success => body, fail => end }
+             * body:
+             *          add r2,r3,r2
+             *          goto cmp
+             * end:
              */
 
-            for (int i = 0; i < 10000000; i++)
-                op.Invoke(frame);
+            for (IInstruction op = code; op != null; op = op.Invoke(frame))
+                ;
 
-			Console.WriteLine ("vm: {0}, int {1} ms", frame.GetValue<int>(2), Environment.TickCount - t );
+			Console.WriteLine ("vm: {0}, int {1} ms", frame.GetConverted<int>(2), Environment.TickCount - t );
 
             t = Environment.TickCount;
 
-            /*
-             *          mov r1, 10 000 000
-             *          mov r2, 0
-             *          mov r3, 1
-             *          loop
-             *              condition:
-             *                  gte r2, r1
-             *              body:
-             *                  add r2,r3,r2
-             */
-            object count = 0, inc = 1;
+            object count = 0, inc = 1, max = 10000000;
             
-            for (int i = 0; i < 10000000; i++)
+            while(Compare(count,max) <= 0)
                 count = Add(count,inc);
 
             Console.WriteLine("native: {0}, int {1} ms", frame.GetValue<int>(2), Environment.TickCount - t);
 
-			t = Environment.TickCount;
+        }
+
+        public static int Compare(object arg1, object arg2) {
+            return ((int)arg1).CompareTo((int)arg2);
         }
 
         public static object Add(object arg1, object arg2) {
--- a/Jint.Runtime/VM/AbstractBox.cs	Sun Oct 27 21:20:59 2013 +0400
+++ b/Jint.Runtime/VM/AbstractBox.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -16,7 +16,8 @@
 
         public abstract void InvokeBinaryOperation(Codes code, int arg2, int dest, Frame frame);
         public abstract void InvokeUnaryOperation(Codes code, int dest, Frame frame);
-        public abstract void InvokeCompareOperation(int arg2, int dest, Frame frame);
-        public abstract void InvokeEqualityOperation(int arg2, int dest, Frame frame);
+        public abstract int InvokeCompareOperation(int arg2, Frame frame);
+        public abstract bool InvokeEqualityOperation(int arg2, Frame frame);
+        public abstract T Convert<T>();
     }
 }
--- a/Jint.Runtime/VM/Box.cs	Sun Oct 27 21:20:59 2013 +0400
+++ b/Jint.Runtime/VM/Box.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -3,6 +3,7 @@
 using System.Linq;
 using System.Text;
 using Jint.Runtime.VM.OpCodes;
+using System.ComponentModel;
 
 namespace Jint.Runtime.VM {
     class Box<T>: AbstractBox, IGettter<T>, ISetter<T> {
@@ -10,6 +11,7 @@
         public T holdingValue;
         object[] m_impl;
         RuntimeContext m_runtime;
+        TypeConverter m_converter;
 
         public Box(T value, RuntimeContext runtime): base(typeof(T)) {
             if (runtime == null)
@@ -27,6 +29,14 @@
             }
         }
 
+        TypeConverter TypeConverter {
+            get {
+                if (m_converter == null)
+                    m_converter = TypeDescriptor.GetConverter(typeof(T));
+                return m_converter;
+            }
+        }
+
         public T Get() {
             return holdingValue;
         }
@@ -45,14 +55,18 @@
             frame.SetValue(dest, op(holdingValue));
         }
 
-        public override void InvokeCompareOperation(int arg2, int dest, Frame frame) {
+        public override int InvokeCompareOperation(int arg2, Frame frame) {
             var op = (CompareOperation<T>)Impl[(int)Codes.Cmp];
-            frame.SetValue(dest, op(holdingValue, frame.GetValue<T>(arg2)));
+            return op(holdingValue, frame.GetValue<T>(arg2));
         }
 
-        public override void InvokeEqualityOperation(int arg2, int dest, Frame frame) {
+        public override bool InvokeEqualityOperation(int arg2, Frame frame) {
             var op = (EqualityOperation<T>)Impl[(int)Codes.Cmp];
-            frame.SetValue(dest, op(holdingValue, frame.GetValue<T>(arg2)));
+            return op(holdingValue, frame.GetValue<T>(arg2));
+        }
+
+        public override T2 Convert<T2>() {
+            return (T2)TypeConverter.ConvertTo(holdingValue, typeof(T2));
         }
     }
 }
--- a/Jint.Runtime/VM/Frame.cs	Sun Oct 27 21:20:59 2013 +0400
+++ b/Jint.Runtime/VM/Frame.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -17,6 +17,11 @@
             m_registers = new AbstractBox[size];
         }
 
+        /// <summary>
+        /// Return register at the specified index.
+        /// </summary>
+        /// <param name="index">The index of the register</param>
+        /// <returns>The register.</returns>
         public AbstractBox this[int index] {
             get {
                 return m_registers[index];
@@ -27,12 +32,12 @@
         }
 
         /// <summary>
-        /// Extracts value stored in the registry specified by the index.
+        /// Extracts value stored in the register specified by the index.
         /// </summary>
         /// <remarks>This method doesn't do any cast, if the specified type isn't the same as the type of the stored value a type cast exception will occur.</remarks>
-        /// <typeparam name="T">The type of the value stored in the registry.</typeparam>
-        /// <param name="index">The index of the registry.</param>
-        /// <returns>The value stored in the registry.</returns>
+        /// <typeparam name="T">The type of the value stored in the register.</typeparam>
+        /// <param name="index">The index of the register.</param>
+        /// <returns>The value stored in the register.</returns>
         public T GetValue<T>(int index) {
             return ((Box<T>)m_registers[index]).holdingValue;
         }
@@ -41,13 +46,13 @@
         /// Stores a new value in the register specified by the index.
         /// </summary>
         /// <remarks>
-        /// If the previous value has the same type as the value being stored in the registry,
-        /// the new value will replace the old one, otherwise the registry will be reallocated to
+        /// If the previous value has the same type as the value being stored in the register,
+        /// the new value will replace the old one, otherwise the register will be reallocated to
         /// store the new value.
         /// </remarks>
         /// <typeparam name="T">The type of the value being stored</typeparam>
-        /// <param name="index">The index of the registry where the value will be stored</param>
-        /// <param name="value">The value to be stored in the registry</param>
+        /// <param name="index">The index of the register where the value will be stored</param>
+        /// <param name="value">The value to be stored in the register</param>
         public void SetValue<T>(int index, T value) {
             var reg = m_registers[index] as Box<T>;
             if (reg == null || reg.holdingType != typeof(T))
@@ -55,5 +60,14 @@
             else
                 reg.holdingValue = value;
         }
+
+        public T GetConverted<T>(int index) {
+            var reg = m_registers[index];
+
+            if (reg.holdingType == typeof(T))
+                return ((Box<T>)reg).holdingValue;
+            else
+                return reg.Convert<T>();
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Jint.Runtime/VM/OpCodes/ConditionOp.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jint.Runtime.VM.OpCodes {
+    class ConditionOp: IInstruction {
+        int m_test;
+        IInstruction m_success;
+        IInstruction m_fail;
+
+        public ConditionOp(int test, IInstruction success, IInstruction fail) {
+            m_test = test;
+            m_success = success;
+            m_fail = fail;
+        }
+
+        public IInstruction Invoke(Frame frame) {
+            return frame.GetConverted<bool>(m_test) ? m_success : m_fail;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Jint.Runtime/VM/OpCodes/GteCmp.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jint.Runtime.VM.OpCodes {
+    class GteCmp: IInstruction {
+        int m_arg1;
+        int m_arg2;
+        int m_dest;
+        IInstruction m_next;
+
+        public GteCmp(int arg1, int arg2, int dest) {
+            m_arg1 = arg1;
+            m_arg2 = arg2;
+            m_dest = dest;
+        }
+
+        public IInstruction Chain(IInstruction next) {
+            return m_next = next;
+        }
+
+        public IInstruction Invoke(Frame frame) {
+            frame.SetValue(m_dest, frame[m_arg1].InvokeCompareOperation(m_arg2, frame) >= 0);
+            return m_next;
+        }
+    }
+}
--- a/Jint.Runtime/VM/OpCodes/Loop.cs	Sun Oct 27 21:20:59 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Jint.Runtime.VM.OpCodes {
-    class Loop {
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Jint.Runtime/VM/OpCodes/LteCmp.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Jint.Runtime.VM.OpCodes {
+    class LteCmp: IInstruction {
+        int m_arg1;
+        int m_arg2;
+        int m_dest;
+        IInstruction m_next;
+
+        public LteCmp(int arg1, int arg2, int dest) {
+            m_arg1 = arg1;
+            m_arg2 = arg2;
+            m_dest = dest;
+        }
+
+        public IInstruction Chain(IInstruction next) {
+            return m_next = next;
+        }
+
+        public IInstruction Invoke(Frame frame) {
+            frame.SetValue(m_dest, frame[m_arg1].InvokeCompareOperation(m_arg2, frame) <= 0);
+            return m_next;
+        }
+    }
+}
--- a/Jint.Runtime/VM/RuntimeContext.cs	Sun Oct 27 21:20:59 2013 +0400
+++ b/Jint.Runtime/VM/RuntimeContext.cs	Mon Oct 28 00:49:15 2013 +0400
@@ -20,12 +20,21 @@
             return new Box<T>(value, this);
         }
 
-        public void DefineBinaryOperation<T>(Codes code, BinaryOperation<T> op) {
+        object[] GetOrCreateOps(Type type) {
             object[] ops;
-            if (!m_impls.TryGetValue(typeof(T), out ops))
-                ops = m_impls[typeof(T)] = new object[(int)Codes.MaxOp];
+            if (!m_impls.TryGetValue(type, out ops))
+                ops = m_impls[type] = new object[(int)Codes.MaxOp];
+            return ops;
+        }
 
+        public void DefineBinaryOperation<T>(Codes code, BinaryOperation<T> op) {
+            object[] ops = GetOrCreateOps(typeof(T));
             ops[(int)code] = op;
         }
+
+        public void DefineCompareOperation<T>(CompareOperation<T> op) {
+            object[] ops = GetOrCreateOps(typeof(T));
+            ops[(int)Codes.Cmp] = op;
+        }
     }
 }
Binary file Jint.suo has changed