view Jint.Runtime/VM/Frame.cs @ 8:5b2302d3ac4f default tip

Слияние
author cin
date Wed, 30 Oct 2013 20:44:42 +0400
parents a6329b092499
children
line wrap: on
line source

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];
        }

        /// <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];
            }
            set {
                m_registers[index] = value;
            }
        }

        /// <summary>
        /// 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 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;
        }

        /// <summary>
        /// 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 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 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))
                m_registers[index] = m_runtime.BoxValue(value);
            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>();
        }
    }
}