# HG changeset patch # User cin # Date 1383140315 -14400 # Node ID a6329b09249934d7d4e25b31a0bbe442c82db977 # Parent cb13da6e3349abc9c945baa15465a333b88abcbf Added scopes, function builder diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/Jint.Runtime.csproj --- a/Jint.Runtime/Jint.Runtime.csproj Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.Runtime/Jint.Runtime.csproj Wed Oct 30 17:38:35 2013 +0400 @@ -50,6 +50,10 @@ + + + + @@ -60,4 +64,7 @@ + + + \ No newline at end of file diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/AbstractBox.cs --- a/Jint.Runtime/VM/AbstractBox.cs Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.Runtime/VM/AbstractBox.cs Wed Oct 30 17:38:35 2013 +0400 @@ -1,23 +1,24 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Jint.Runtime.VM { - using OpCodes; - - abstract class AbstractBox { - - protected AbstractBox(Type type) { - holdingType = type; - } - - public readonly Type holdingType; - - public abstract void InvokeBinaryOperation(Codes code, int arg2, int dest, Frame frame); - public abstract void InvokeUnaryOperation(Codes code, int dest, Frame frame); - public abstract int InvokeCompareOperation(int arg2, Frame frame); - public abstract bool InvokeEqualityOperation(int arg2, Frame frame); - public abstract T Convert(); - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Jint.Runtime.VM { + using OpCodes; + + abstract class AbstractBox { + + protected AbstractBox(Type type) { + holdingType = type; + } + + public readonly Type holdingType; + + public abstract void InvokeBinaryOperation(Codes code, int arg2, int dest, Frame frame); + public abstract void InvokeUnaryOperation(Codes code, int dest, Frame frame); + public abstract int InvokeCompareOperation(int arg2, Frame frame); + public abstract bool InvokeEqualityOperation(int arg2, Frame frame); + public abstract T Convert(); + public abstract void CopyTo (Frame frame, int dest); + } +} diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/Box.cs --- a/Jint.Runtime/VM/Box.cs Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.Runtime/VM/Box.cs Wed Oct 30 17:38:35 2013 +0400 @@ -1,72 +1,77 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Jint.Runtime.VM.OpCodes; -using System.ComponentModel; - -namespace Jint.Runtime.VM { - class Box: AbstractBox, IGettter, ISetter { - - public T holdingValue; - object[] m_impl; - RuntimeContext m_runtime; - TypeConverter m_converter; - - public Box(T value, RuntimeContext runtime): base(typeof(T)) { - if (runtime == null) - throw new ArgumentNullException("runtime"); - - holdingValue = value; - m_runtime = runtime; - } - - object[] Impl { - get { - if (m_impl == null) - m_impl = m_runtime.GetImpl(typeof(T)); - return m_impl; - } - } - - TypeConverter TypeConverter { - get { - if (m_converter == null) - m_converter = TypeDescriptor.GetConverter(typeof(T)); - return m_converter; - } - } - - public T Get() { - return holdingValue; - } - - public void Set(T value) { - holdingValue = value; - } - - public override void InvokeBinaryOperation(Codes code, int arg2, int dest, Frame frame) { - var op = (BinaryOperation)Impl[(int)code]; - frame.SetValue(dest, op(holdingValue, frame.GetValue(arg2))); - } - - public override void InvokeUnaryOperation(Codes code, int dest, Frame frame) { - var op = (UnaryOperation)Impl[(int)code]; - frame.SetValue(dest, op(holdingValue)); - } - - public override int InvokeCompareOperation(int arg2, Frame frame) { - var op = (CompareOperation)Impl[(int)Codes.Cmp]; - return op(holdingValue, frame.GetValue(arg2)); - } - - public override bool InvokeEqualityOperation(int arg2, Frame frame) { - var op = (EqualityOperation)Impl[(int)Codes.Cmp]; - return op(holdingValue, frame.GetValue(arg2)); - } - - public override T2 Convert() { - return (T2)TypeConverter.ConvertTo(holdingValue, typeof(T2)); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Jint.Runtime.VM.OpCodes; +using System.ComponentModel; + +namespace Jint.Runtime.VM { + class Box: AbstractBox, IGettter, ISetter { + + public T holdingValue; + object[] m_impl; + RuntimeContext m_runtime; + TypeConverter m_converter; + + public Box(T value, RuntimeContext runtime): base(typeof(T)) { + if (runtime == null) + throw new ArgumentNullException("runtime"); + + holdingValue = value; + m_runtime = runtime; + } + + object[] Impl { + get { + if (m_impl == null) + m_impl = m_runtime.GetImpl(typeof(T)); + return m_impl; + } + } + + TypeConverter TypeConverter { + get { + if (m_converter == null) + m_converter = TypeDescriptor.GetConverter(typeof(T)); + return m_converter; + } + } + + public T Get() { + return holdingValue; + } + + public void Set(T value) { + holdingValue = value; + } + + public override void InvokeBinaryOperation(Codes code, int arg2, int dest, Frame frame) { + var op = (BinaryOperation)Impl[(int)code]; + frame.SetValue(dest, op(holdingValue, frame.GetValue(arg2))); + } + + public override void InvokeUnaryOperation(Codes code, int dest, Frame frame) { + var op = (UnaryOperation)Impl[(int)code]; + frame.SetValue(dest, op(holdingValue)); + } + + public override int InvokeCompareOperation(int arg2, Frame frame) { + var op = (CompareOperation)Impl[(int)Codes.Cmp]; + return op(holdingValue, frame.GetValue(arg2)); + } + + public override bool InvokeEqualityOperation(int arg2, Frame frame) { + var op = (EqualityOperation)Impl[(int)Codes.Cmp]; + return op(holdingValue, frame.GetValue(arg2)); + } + + public override T2 Convert() { + return (T2)TypeConverter.ConvertTo(holdingValue, typeof(T2)); + } + + public override void CopyTo (Frame frame, int dest) + { + frame.SetValue (dest, holdingValue); + } + } +} diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/Frame.cs --- a/Jint.Runtime/VM/Frame.cs Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.Runtime/VM/Frame.cs Wed Oct 30 17:38:35 2013 +0400 @@ -1,73 +1,77 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Jint.Runtime.VM { - class Frame { - AbstractBox[] m_registers; - RuntimeContext m_runtime; - - public Frame(int size, RuntimeContext runtime) { - if (runtime == null) - throw new ArgumentNullException("runtime"); - if (size < 0) - throw new ArgumentOutOfRangeException("size"); - m_runtime = runtime; - 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]; - } - set { - m_registers[index] = value; - } - } - - /// - /// 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 register. - /// The index of the register. - /// The value stored in the register. - public T GetValue(int index) { - return ((Box)m_registers[index]).holdingValue; - } - - /// - /// 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 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 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)) - m_registers[index] = m_runtime.BoxValue(value); - 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(); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Jint.Runtime.VM { + class Frame { + AbstractBox[] m_registers; + RuntimeContext m_runtime; + + public const int ThisRegister = 0; + public const int ScopeRegister = 1; + public const int FirstVarRegsiter = 2; + + public Frame(int size, RuntimeContext runtime) { + if (runtime == null) + throw new ArgumentNullException("runtime"); + if (size < 0) + throw new ArgumentOutOfRangeException("size"); + m_runtime = runtime; + 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]; + } + set { + m_registers[index] = value; + } + } + + /// + /// 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 register. + /// The index of the register. + /// The value stored in the register. + public T GetValue(int index) { + return ((Box)m_registers[index]).holdingValue; + } + + /// + /// 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 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 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)) + m_registers[index] = m_runtime.BoxValue(value); + 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 cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/FunctionBuilder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Jint.Runtime/VM/FunctionBuilder.cs Wed Oct 30 17:38:35 2013 +0400 @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; + +namespace Jint.Runtime.VM +{ + class FunctionBuidler + { + Scope m_parentScope; + + /// + /// maps local variable names to the registers + /// + Dictionary m_locals; + + /// + /// maps formal parameters to local variables + /// + int[] m_formalParameters; + + int m_frameSize; + + IInstruction m_code; + + RuntimeContext m_runtime; + + public FunctionBuilder (string[] argumentNames, RuntimeContext runtime, Scope parentScope) + { + m_parentScope; + m_frameSize = 2; // reserve for this and scope + + m_locals = new Dictionary(); + + if (argumentNames!= null) { + m_formalParameters = new int[argumentNames.Length]; + for(int i = 0; i < argumentNames.Length; i++) + m_formalParameters[i] = AllocVariable(argumentNames[i]); + } + } + + // all vars should be allocated before temp registers + public int AllocVariable(string name) { + int id; + + if (m_locals.TryGetValue (name, out id)) + return id; + + id = m_frameSize++; + m_locals [name] = id; + return id; + } + + public int AllocateRegister() { + return m_frameSize++; + } + + public void Invoke (object that, object[] args) { + var frame = new Frame (m_frameSize, m_runtime); + var scope = new Scope (m_locals, frame, m_declaringScope); + frame.SetValue (Frame.ThisRegister, that); + frame.SetValue (Frame.ScopeRegister, scope); + + var paramLen = Math.Min (m_formalParameters.Length, args.Length); + + for (int i=0; i< paramLen; i++) + frame.SetValue (m_formalParameters [i], args [i]); + } + + } +} + diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/IReference.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Jint.Runtime/VM/IReference.cs Wed Oct 30 17:38:35 2013 +0400 @@ -0,0 +1,12 @@ +using System; + +namespace Jint.Runtime.VM +{ + interface IReference + { + T Get(); + void Put(T value); + void CopyTo (Frame frame, int dest); + } +} + diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/Machine.cs --- a/Jint.Runtime/VM/Machine.cs Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.Runtime/VM/Machine.cs Wed Oct 30 17:38:35 2013 +0400 @@ -1,15 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Jint.Runtime.VM { - class Machine { - Frame m_frame; - - public void Run(IInstruction prog) { - while (prog != null) - prog = prog.Invoke(m_frame); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Jint.Runtime.VM { + class Machine { + Frame m_frame; + + public void Run(IInstruction prog) { + while (prog != null) + prog = prog.Invoke(m_frame); + } + } +} diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/OpCodes/BinaryOp.cs --- a/Jint.Runtime/VM/OpCodes/BinaryOp.cs Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.Runtime/VM/OpCodes/BinaryOp.cs Wed Oct 30 17:38:35 2013 +0400 @@ -1,36 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Jint.Runtime.VM.OpCodes { - delegate void BinaryInstructionImpl(int arg1, int arg2, int dest, Frame frame); - - class BinaryOp: IInstruction { - - int m_dest; - int m_arg1; - int m_arg2; - Codes m_code; - IInstruction m_next; - - public BinaryOp(Codes code, int arg1, int arg2, int dest) { - m_code = code; - m_arg1 = arg1; - m_arg2 = arg2; - m_dest = dest; - } - - public IInstruction Chain(IInstruction next) { - m_next = next; - return next; - } - - public IInstruction Invoke(Frame frame) { - //frame[m_arg1].GetBinaryImpl(m_code)(m_arg1, m_arg2, m_dest, frame); - frame[m_arg1].InvokeBinaryOperation(m_code, m_arg2, m_dest, frame); - - return m_next; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Jint.Runtime.VM.OpCodes { + delegate void BinaryInstructionImpl(int arg1, int arg2, int dest, Frame frame); + + class BinaryOp: IInstruction { + + int m_dest; + int m_arg1; + int m_arg2; + Codes m_code; + IInstruction m_next; + + public BinaryOp(Codes code, int arg1, int arg2, int dest) { + m_code = code; + m_arg1 = arg1; + m_arg2 = arg2; + m_dest = dest; + } + + public IInstruction Chain(IInstruction next) { + m_next = next; + return next; + } + + public IInstruction Invoke(Frame frame) { + //frame[m_arg1].GetBinaryImpl(m_code)(m_arg1, m_arg2, m_dest, frame); + frame[m_arg1].InvokeBinaryOperation(m_code, m_arg2, m_dest, frame); + + return m_next; + } + } +} diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/Scope.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Jint.Runtime/VM/Scope.cs Wed Oct 30 17:38:35 2013 +0400 @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace Jint.Runtime.VM +{ + class Scope + { + Frame m_frame; + Dictionary m_vars; + Scope m_parent; + + public const int ThisRegister = 0; + public const int ScopeRegister = 1; + public const int FirstVarRegsiter = 2; + + public Scope (IDictionary vars, Frame frame, Scope parent) + { + if (vars == null) + throw new ArgumentNullException ("vars"); + if (frame == null) + throw new ArgumentNullException ("frame"); + + m_vars = new Dictionary (vars); + m_frame = frame; + m_parent = parent; + } + + public IReference Resolve(string name) { + if (String.IsNullOrEmpty (name)) + throw new ArgumentException ("The specified variable name is invalid"); + + int index; + if (m_vars.TryGetValue (name, out index)) + return new ScopeReference (this, index); + + if (m_parent != null) + return m_parent.Resolve (name); + else + throw new KeyNotFoundException (String.Format("The specified variable '{0}' isn't found",name)); + } + } +} + diff -r cb13da6e3349 -r a6329b092499 Jint.Runtime/VM/ScopeReference.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Jint.Runtime/VM/ScopeReference.cs Wed Oct 30 17:38:35 2013 +0400 @@ -0,0 +1,35 @@ +using System; + +namespace Jint.Runtime.VM +{ + public class ScopeReference: IReference + { + Frame m_frame; + int m_index; + public ScopeReference (Frame frame, int index) + { + if (frame == null) + throw new ArgumentNullException("frame"); + + m_index = index; + m_frame = frame; + } + + + #region IReference implementation + public T Get () + { + return m_frame.GetValue(m_index); + } + public void Put (T value) + { + m_frame.SetValue(m_index); + } + public void CopyTo (Frame frame, int dest) + { + m_frame[m_index].CopyTo(frame,dest); + } + #endregion + } +} + diff -r cb13da6e3349 -r a6329b092499 Jint.userprefs --- a/Jint.userprefs Mon Oct 28 00:49:15 2013 +0400 +++ b/Jint.userprefs Wed Oct 30 17:38:35 2013 +0400 @@ -1,16 +1,12 @@  - + - - - - - - - - - + + + + + @@ -19,11 +15,8 @@ + - - - -