# HG changeset patch # User cin # Date 1382906955 -14400 # Node ID cb13da6e3349abc9c945baa15465a333b88abcbf # Parent 1ae5b10f7a10bea0b1746802427983f577b2387a simple loop test diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/Jint.Runtime.csproj --- 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 @@ - + + + diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/Main.cs --- 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(Codes.Add, (x, y) => x + y); + runtime.DefineCompareOperation((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(2), Environment.TickCount - t ); + Console.WriteLine ("vm: {0}, int {1} ms", frame.GetConverted(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(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) { diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/AbstractBox.cs --- 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(); } } diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/Box.cs --- 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: AbstractBox, IGettter, ISetter { @@ -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)Impl[(int)Codes.Cmp]; - frame.SetValue(dest, op(holdingValue, frame.GetValue(arg2))); + return op(holdingValue, frame.GetValue(arg2)); } - public override void InvokeEqualityOperation(int arg2, int dest, Frame frame) { + public override bool InvokeEqualityOperation(int arg2, Frame frame) { var op = (EqualityOperation)Impl[(int)Codes.Cmp]; - frame.SetValue(dest, op(holdingValue, frame.GetValue(arg2))); + return op(holdingValue, frame.GetValue(arg2)); + } + + public override T2 Convert() { + return (T2)TypeConverter.ConvertTo(holdingValue, typeof(T2)); } } } diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/Frame.cs --- 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]; } + /// + /// Return register at the specified index. + /// + /// The index of the register + /// The register. public AbstractBox this[int index] { get { return m_registers[index]; @@ -27,12 +32,12 @@ } /// - /// Extracts value stored in the registry specified by the index. + /// Extracts value stored in the register specified by the index. /// /// 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. - /// The type of the value stored in the registry. - /// The index of the registry. - /// The value stored in the registry. + /// The type of the value stored in the register. + /// The index of the register. + /// The value stored in the register. public T GetValue(int index) { return ((Box)m_registers[index]).holdingValue; } @@ -41,13 +46,13 @@ /// Stores a new value in the register specified by the index. /// /// - /// 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. /// /// The type of the value being stored - /// The index of the registry where the value will be stored - /// The value to be stored in the registry + /// The index of the register where the value will be stored + /// The value to be stored in the register public void SetValue(int index, T value) { var reg = m_registers[index] as Box; if (reg == null || reg.holdingType != typeof(T)) @@ -55,5 +60,14 @@ else reg.holdingValue = value; } + + public T GetConverted(int index) { + var reg = m_registers[index]; + + if (reg.holdingType == typeof(T)) + return ((Box)reg).holdingValue; + else + return reg.Convert(); + } } } diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/OpCodes/ConditionOp.cs --- /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(m_test) ? m_success : m_fail; + } + } +} diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/OpCodes/GteCmp.cs --- /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; + } + } +} diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/OpCodes/Loop.cs --- 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 { - - } -} diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/OpCodes/LteCmp.cs --- /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; + } + } +} diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.Runtime/VM/RuntimeContext.cs --- 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(value, this); } - public void DefineBinaryOperation(Codes code, BinaryOperation 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(Codes code, BinaryOperation op) { + object[] ops = GetOrCreateOps(typeof(T)); ops[(int)code] = op; } + + public void DefineCompareOperation(CompareOperation op) { + object[] ops = GetOrCreateOps(typeof(T)); + ops[(int)Codes.Cmp] = op; + } } } diff -r 1ae5b10f7a10 -r cb13da6e3349 Jint.suo Binary file Jint.suo has changed