# 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