Mercurial > pub > Jint1
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; + } } }