Example #1
0
 public static bool CallProperty(mdr.DObject input, string propName, out mdr.DValue output)
 {
     if (input != null)
     {
         var propDesc = input.GetPropertyDescriptor(propName);
         var prop     = new mdr.DValue();
         propDesc.Get(input, ref prop);
         mdr.DFunction func = null;
         if (prop.ValueType == mdr.ValueTypes.Function)
         {
             func = prop.AsDFunction();
             //if (toString != null)
             //{
             mdr.CallFrame callFrame = new mdr.CallFrame();
             callFrame.This     = (input);
             callFrame.Function = func;
             func.Call(ref callFrame);
             if (ValueTypesHelper.IsPrimitive(callFrame.Return.ValueType))
             {
                 output = callFrame.Return;
                 return(true);
             }
         }
     }
     output = new mdr.DValue();
     output.SetUndefined();
     return(false);
 }
Example #2
0
        public DValue Get(DObject obj)
        {
            DValue tmp = new DValue();

            Get(obj, ref tmp);
            return(tmp);
        }
Example #3
0
        private PropertyMap DeleteOwnPropertyDescriptor(DObject obj, PropertyMap currMap, PropertyMap delMap)
        {
            Debug.Assert(delMap != null, "Invalid situation!");
            ///In this function, we recursively add all the properties between the delMap, and this to the delMap.Parent
            ///currMap==this would be the end of recursion
            ///at the end we need to propagate the deletion to all objects whose prototype is obj

            var newMap = (delMap == currMap.Parent || delMap == currMap) ? delMap.Parent : DeleteOwnPropertyDescriptor(obj, currMap.Parent, delMap);

            if (delMap != this)
            {
                var currPropDesc = currMap.Property;
                newMap = newMap.AddOwnProperty(currPropDesc.Name, currPropDesc.NameId, currPropDesc.GetAttributes());
            }
            if (currMap == this)
            {
                Debug.Assert(this.Property.Index == newMap.Property.Index + 1, "Invalid situation, we should delete on one field here!");
                obj.Map = newMap;
                if (delMap != this) //otherwise it is just the last field so no need to copy
                {
                    Array.Copy(obj.Fields, delMap.Property.Index + 1, obj.Fields, delMap.Property.Index, this.Property.Index - delMap.Property.Index);
                }

                var mapMetadata = Metadata.GetMapMetadataOfPrototype(obj, false);
                if (mapMetadata != null)
                {
                    mapMetadata.PropagateDeletionDownPrototypeChain(obj, delMap.Property);
                }
            }
            return(newMap);
        }
Example #4
0
 public PropertyMapMetadata GetMapMetadataOfPrototype(DObject prototype)
 {
     if (prototype == null)
     {
         return(EmptyPropertyMapMetadata);
     }
     return(prototype.Map.Metadata.GetMapMetadataOfPrototype(prototype));
 }
Example #5
0
 public virtual void SetGlobalContext(mdr.DObject globalContext)
 {
     Debug.Assert(globalContext != null, "Global Context cannot be null");
     GlobalContext = globalContext;
     //if (globalContext == null)
     //    GlobalContext = new mdr.DObject();
     //GlobalContext = new mdr.DObject(GlobalDObject);
 }
Example #6
0
 public void CopyTo(DObject obj)
 {
     if (!DType.IsParentOf(obj.DType))
     {
         throw new Exception(string.Format("Type {0} is not a parent of type {1} and so cannot be extended", DType, obj.DType));
     }
     Array.Copy(Fields, obj.Fields, Fields.Length);
 }
Example #7
0
        public static bool Run(mdr.DObject i0, mdr.DFunction i1)
        {
            //var prototype = func.GetFieldByFieldIndex(mdr.DType.PrototypeIndex);
            var prototype = new mdr.DValue();

            i1.PrototypePropertyDescriptor.Get(i1, ref prototype);
            return(i0.Prototype == prototype.AsDObject());
        }
Example #8
0
//#if __MonoCS__
//    [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
//#endif
        public void Get(DObject obj, ref DValue value)
        {
            /*if (mdr.Runtime.Instance.Configuration.ProfileStats)
             * {
             * mdr.Runtime.Instance.Counters.GetCounter("PD.GET").Count++;
             * mdr.Runtime.Instance.Counters.GetCounter("PD.GET[" + _flags + "]").Count++;
             * } */
            _getter(this, obj, ref value);
        }
Example #9
0
        public static mdr.DObject CreateFunctionContext(ref mdr.CallFrame callFrame)
        {
            //this function will or may change its context, so create a new one; this is the safest option

            ///If callFrame.Function.ContextMap is null, it means it is the first time that function object is called
            ///in this case, we create a new PropertyMap and add all necessary fields to it. Then assign it to the .ContextMap.
            ///We don't add them one-by-one to the context itself to avoid resizing context.Fields several times.
            ///Also we first add all of them, so that we can use the reference of the context.Fields[i]
            //TODO: if we had the function object here, we could technically do the addition to map here and generate code that directly uses the indexes

            mdr.DObject context;
            var         contextMap = callFrame.Function.Metadata.ContextMap;

            if (contextMap == null)
            {
                var outerContext = callFrame.Function.OuterContext;
                context = new mdr.DObject(outerContext); //We do this first to get the root of the map first

                contextMap = context.Map;
                var scope = ((JSFunctionMetadata)callFrame.Function.Metadata).Scope;
                if (scope.HasClosedOnSymbol)
                {
                    var symbols = scope.Symbols;
                    for (var i = symbols.Count - 1; i >= 0; --i)
                    {
                        var symbol = symbols[i];
                        if (symbol.SymbolType == JSSymbol.SymbolTypes.ClosedOnLocal)
                        {
                            if (scope.HasArgumentsSymbol && symbol.IsParameter)
                            {
                                contextMap = contextMap.AddOwnProperty(symbol.Name, symbol.FieldId, PropertyDescriptor.Attributes.Accessor | PropertyDescriptor.Attributes.NotConfigurable);
                            }
                            else
                            {
                                contextMap = contextMap.AddOwnProperty(symbol.Name, symbol.FieldId, PropertyDescriptor.Attributes.Data | PropertyDescriptor.Attributes.NotConfigurable);
                            }
                        }
                    }
                }

                if (scope.HasEval)
                {
                    //Eval may use the arguments
                    Debug.Assert(scope.HasArgumentsSymbol, "Exected arguments in the context for a function with eval");
                    contextMap = contextMap.AddOwnProperty(JSFunctionArguments.Name, mdr.Runtime.Instance.GetFieldId(JSFunctionArguments.Name), PropertyDescriptor.Attributes.Data | PropertyDescriptor.Attributes.NotConfigurable);
                }

                context.Map = contextMap; //This will update the fields size
                callFrame.Function.Metadata.ContextMap = contextMap;
            }
            else
            {
                context = new mdr.DObject(contextMap);
            }
            return(context);
        }
Example #10
0
 public DFunction(DFunctionMetadata funcMetadata, DObject outerContext)
     : base(Runtime.Instance.DFunctionMap)
 {
     Metadata = funcMetadata;
     if (funcMetadata != null)
     {
         JittedCode = Metadata.Execute;
     }
     OuterContext = outerContext;
 }
Example #11
0
 public void Set(DObject v)
 {
     if (v == null)
     {
         Object = DObject.Undefined;
     }
     else
     {
         v.CopyTo(this);
     }
 }
Example #12
0
 public void Set(DObject obj, DObject value)
 {
     if (_setter == Own_Data_Set) //This is the most common case, and we can make it faster this way
     {
         obj.Fields[Index].Set(value);
     }
     else
     {
         var tmp = new DValue();
         tmp.Set(value);
         Set(obj, ref tmp);
     }
 }
Example #13
0
        internal PropertyDescriptor AddOwnProperty(DObject obj, string field, int fieldId, PropertyDescriptor.Attributes attributes)
        {
            PropertyMap newMap = AddOwnProperty(field, fieldId, attributes);

            obj.Map = newMap;

            var mapMetadata = Metadata.GetMapMetadataOfPrototype(obj, false);

            if (mapMetadata != null)
            {
                mapMetadata.PropagateAdditionDownPrototypeChain(obj, newMap.Property); //obj is some other objects' prototype
            }
            return(newMap.Property);
        }
Example #14
0
 public void SetNullable(DObject v)
 {
     // XXX: Presumably the separation of Set(DObject) and CheckNull(DObject) existed because
     // sometimes we know for sure that the DObject is not null and we can elide the check.
     // If that's not true, this method should be merged into Set(DObject).
     if (v == null)
     {
         SetNull();
     }
     else
     {
         Set(v);
     }
 }
Example #15
0
 public void Set(DObject obj, string value)
 {
     //if (IsDataDescriptor && !IsInherited)
     if (_setter == Own_Data_Set) //This is the most common case, and we can make it faster this way
     {
         obj.Fields[Index].Set(value);
     }
     else
     {
         var tmp = new DValue();
         tmp.Set(value);
         Set(obj, ref tmp);
     }
 }
Example #16
0
 public DObject Set(DObject This, bool v)
 {
     if (OnSetBoolean == null)
     {
         var tmp = new DValue();
         tmp.Set(v);
         return(Set(This, ref tmp));
     }
     else
     {
         OnSetBoolean(This, v);
         return(this);
     }
 }
Example #17
0
 public DObject Set(DObject This, DObject v)
 {
     if (OnSetDObject == null)
     {
         var tmp = new DValue();
         tmp.Set(v);
         return(Set(This, ref tmp));
     }
     else
     {
         OnSetDObject(This, v);
         return(this);
     }
 }
 public DForwardingProperty(DObject receiver, string field)
 {
     Receiver   = receiver;
     ReceiverPD = Receiver.Map.GetPropertyDescriptor(field);
     Debug.Assert(ReceiverPD != null, "receiver field has null descriptor: " + field);
     OnGetDValue = (DObject This, ref DValue v) =>
     {
         ReceiverPD.Get(Receiver, ref v);
     };
     OnSetDValue = (DObject This, ref DValue v) =>
     {
         ReceiverPD.Set(Receiver, ref v);
     };
 }
        public PropertyMapMetadata(DObject prototype)
        {
            Prototype = prototype;
            if (Prototype == null)
            {
                Level = 0;
            }
            else
            {
                Level = Prototype.Map.Metadata.Level + 1;
            }

            //We create an empty ProperyDescriptor to avoid checking for null all the time
            Root = new PropertyMap(this, null, new PropertyDescriptor(null, Runtime.InvalidFieldId, Runtime.InvalidFieldIndex, PropertyDescriptor.Attributes.NotEnumerable | PropertyDescriptor.Attributes.Undefined), null);
        }
Example #20
0
        public void SetArg(int i, DObject v)
        {
            switch (i)
            {
            case 0: Arg0.Set(v); break;

            case 1: Arg1.Set(v); break;

            case 2: Arg2.Set(v); break;

            case 3: Arg3.Set(v); break;

            default: Arguments[i - InlineArgsCount].Set(v); break;
            }
            //UpdateSignature(i);
        }
Example #21
0
 private static void AddSymbolsToContext(List <JSSymbol> symbols, mdr.DObject context)
 {
     //This is called when we are sharing the context, so should be careful not to add fields that are already there
     //Technically, this is the generic and safe way to do this.
     for (var i = symbols.Count - 1; i >= 0; --i)
     {
         var symbol = symbols[i];
         if (symbol.SymbolType == JSSymbol.SymbolTypes.ClosedOnLocal)
         {
             var pd = context.Map.GetPropertyDescriptorByFieldId(symbol.FieldId); //TODO: can this be made faster?
             if (pd == null)
             {
                 context.AddOwnPropertyDescriptorByFieldId(symbol.FieldId, PropertyDescriptor.Attributes.Data | PropertyDescriptor.Attributes.NotConfigurable);
             }
         }
     }
 }
 internal void PropagateDeletionDownPrototypeChain(DObject obj, PropertyDescriptor propDesc)
 {
     //We should only find at most one matching element
     foreach (var p in _inheritedProperties)
     {
         if (p.NameId == propDesc.NameId)
         {
             Debug.Assert(p.IsInherited, "{0} has invalid descriptor type {1}", p.Name, p.GetAttributes());
             if (p.Container.Map.Metadata.Level > obj.Map.Metadata.Level)
             {
                 //this property is inherited from an object lower in the property chain. So no longer need to propogate
                 return;
             }
             Debug.Assert(p.Container == obj, "Invalid situation!");
             //We check to see if the property exists in higher parts of protoype chain
             var upperPropDesc = obj.Map.Metadata.GetInheritedPropertyDescriptorByFieldId(propDesc.NameId);
             if (upperPropDesc == null || upperPropDesc.IsUndefined)
             {
                 p.Container = null;
                 p.Index     = propDesc.Index;
                 p.ResetAttributes(PropertyDescriptor.Attributes.Undefined);
             }
             else
             {
                 if (p.Container != upperPropDesc.Container)
                 {
                     if (p.ObjectCacheIndex != -1 && p.ObjectCacheIndex < Runtime._inheritPropertyObjectCache.Length)
                     {
                         Runtime._inheritPropertyObjectCache[p.ObjectCacheIndex] = null;
                     }
                 }
                 p.Container = upperPropDesc.Container;
                 p.Index     = upperPropDesc.Index;
                 p.ResetAttributes(upperPropDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited);
             }
         }
     }
     foreach (var child in _children)
     {
         if (child.IsAlive)
         {
             (child.Target as PropertyMapMetadata).PropagateDeletionDownPrototypeChain(obj, propDesc);
         }
     }
 }
Example #23
0
        public static Result Run(mdr.DObject i0, mdr.DObject i1, bool LeftFirst)
        {
            var pLeft  = new mdr.DValue();
            var pRight = new mdr.DValue();

            if (LeftFirst)
            {
                Convert.ToPrimitive.Run(i0, ref pLeft, false);
                Convert.ToPrimitive.Run(i1, ref pRight, false);
            }
            else
            {
                Convert.ToPrimitive.Run(i1, ref pRight, false);
                Convert.ToPrimitive.Run(i0, ref pLeft, false);
            }

            return(Run(ref pLeft, ref pRight));
        }
Example #24
0
        //#region ToX
        //public string ToString(DObject This) { return (OnGetString != null) ? OnGetString(This) : ToDValue().ToString(); }// base.ToString(); }
        //public double ToDouble(DObject This) { return (OnGetDouble != null) ? OnGetDouble(This) : ToDValue().ToDouble(); }// base.ToDouble(); }
        //public int ToInt(DObject This) { return (OnGetInt != null) ? OnGetInt(This) : ToDValue().ToInt32(); }// base.ToInt(); }
        //public bool ToBoolean(DObject This) { return (OnGetBoolean != null) ? OnGetBoolean(This) : ToDValue().ToBoolean(); }// base.ToBoolean(); }
        //public DObject ToDObject(DObject This) { return (OnGetDObject != null) ? OnGetDObject(This) : ToDValue().ToDObject(); }// base.ToDObject(); }
        //public DValue ToDValue(DObject This)
        //{
        //    if (OnGetDValue != null)
        //    {
        //        DValue temp = new DValue();
        //        OnGetDValue(This, ref temp);
        //        return temp;
        //    }
        //    else
        //    {
        //        return base.ToDValue();
        //    }
        //}
        //#endregion

        #region Get
        public void Get(DObject This, ref DValue v)
        {
            if (OnGetDValue != null)
            {
                OnGetDValue(This, ref v);
            }
            else if (Getter != null)
            {
                var callFrame = new CallFrame();
                callFrame.Function = Getter;
                callFrame.This     = (This);
                Getter.Call(ref callFrame);
                v = callFrame.Return;
            }
            else
            {
                v = base.ToDValue();
            }
        }
        internal void PropagateAdditionDownPrototypeChain(DObject obj, PropertyDescriptor propDesc)
        {
            //We should only find at most one matching element
            foreach (var p in _inheritedProperties)
            {
                if (p.NameId == propDesc.NameId)
                {
                    if (p.IsUndefined)
                    {
                        p.Container = obj;
                        p.Index     = propDesc.Index;
                        p.ResetAttributes(propDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited);
                    }
                    else
                    {
                        Debug.Assert(p.IsInherited, "{0} has invalid descriptor type {1}", p.Name, p.GetAttributes());
                        if (p.Container.Map.Metadata.Level > obj.Map.Metadata.Level)
                        {
                            //this property is inherited from an object lower in the property chain. So no longer need to propogate
                            return;
                        }

                        if (p.Container != obj && p.Container.Map.Metadata.Level < obj.Map.Metadata.Level)
                        {
                            p.Container = obj;
                            p.Index     = propDesc.Index;
                            p.ResetAttributes(propDesc.GetAttributes() | PropertyDescriptor.Attributes.Inherited);
                            if (p.ObjectCacheIndex != -1 && p.ObjectCacheIndex < Runtime._inheritPropertyObjectCache.Length)
                            {
                                Runtime._inheritPropertyObjectCache[p.ObjectCacheIndex] = null;
                            }
                        }
                    }
                }
            }
            foreach (var child in _children)
            {
                if (child.IsAlive)
                {
                    (child.Target as PropertyMapMetadata).PropagateAdditionDownPrototypeChain(obj, propDesc);
                }
            }
        }
Example #26
0
 public DObject Set(DObject This, ref DValue v)
 {
     if (OnSetDValue != null)
     {
         OnSetDValue(This, ref v);
     }
     else if (Setter != null)
     {
         var callFrame = new CallFrame();
         callFrame.Function        = Setter;
         callFrame.This            = (This);
         callFrame.PassedArgsCount = 1;
         callFrame.Arg0            = v;
         callFrame.Signature.InitArgType(0, v.ValueType);
         Setter.Call(ref callFrame);
     }
     else
     {
         Trace.Fail(new NotSupportedException(string.Format("Cannot find setter for {0}:{1} on property {2}", v, typeof(DValue), base.ToString())));
     }
     return(this);
 }
Example #27
0
        public DeleteStatus DeleteOwnPropertyDescriptor(DObject obj, string field)
        {
            Debug.Assert(obj.Map == this, "Invalid situation! this is the map of current object");
            Debug.Assert(field != null, "Cannot remove null field from object");

            for (var m = this; m != null; m = m.Parent)
            {
                if (m.Property.Name == field)
                {
                    if (m.Property.IsNotConfigurable)
                    {
                        return(DeleteStatus.NotDeletable);
                    }
                    else
                    {
                        DeleteOwnPropertyDescriptor(obj, this, m);
                        return(DeleteStatus.Deleted);
                    }
                }
            }
            return(DeleteStatus.NotFound);
        }
Example #28
0
        public static void DefaultValue(mdr.DObject input, out mdr.DValue output, bool stringHint = false)
        {
            if (input.PrimitiveValue.ValueType != mdr.ValueTypes.Undefined)
            {
                output = input.PrimitiveValue;
                return;
            }

            if (stringHint)
            {
                if (!CallToStringProperty(input, out output) && !CallValueOfProperty(input, out output))
                {
                    Trace.Fail(new InvalidOperationException(string.Format("TypeError: DefaultValue for {0} is unknown", input.ValueType)));
                }
            }
            else //assume number hint
            {
                if (!CallValueOfProperty(input, out output) && !CallToStringProperty(input, out output))
                {
                    Trace.Fail(new InvalidOperationException(string.Format("TypeError: DefaultValue for {0} is unknown", input.ValueType)));
                }
            }
        }
Example #29
0
 public PropertyMap GetRootMapOfPrototype(DObject prototype)
 {
     return(GetMapMetadataOfPrototype(prototype).Root);
 }
Example #30
0
        protected Runtime(RuntimeConfiguration configuration)
        {
            _inheritPropertyObjectCacheMaxIndex = 0;

            //We need to first set the Instance since the following constructors may use it!
            Runtime.Instance = this;

            Configuration = configuration;
            configuration.ParseArgs();//Do this now before anyone tries to read any configuration value.

            if (configuration.EnableTimers)
            {
                Timers = new m.Util.Timers();
                _timer = StartSimpleTimer(true, "MCJS");
            }

            if (configuration.EnableCounters)
            {
                Counters = new m.Util.Counters();
            }

            EmptyPropertyMapMetadata = new PropertyMapMetadata(null);

            ///We can initialize commong field Ids to save lookups later
            ValueOfFieldId   = GetFieldId("valueOf");
            ToStringFieldId  = GetFieldId("toString");
            PrototypeFieldId = GetFieldId("prototype");
            LengthFieldId    = GetFieldId("length");

            ///In each instance of Runtime we need to first reset prototypes in case a program has changed them

            //DUndefinedPrototype = new DObject(root.Root);

            DObjectPrototype = new DObject(EmptyPropertyMapMetadata.Root);
            DObjectMap       = GetRootMapOfPrototype(DObjectPrototype);

            DFunctionPrototype = new DObject(DObjectMap);
            DFunctionMap       = GetRootMapOfPrototype(DFunctionPrototype);

            DNumberPrototype = new DObject(DObjectMap);
            DNumberMap       = GetRootMapOfPrototype(DNumberPrototype);

            DStringPrototype = new DObject(DObjectMap);
            DStringMap       = GetRootMapOfPrototype(DStringPrototype);

            DBooleanPrototype = new DObject(DObjectMap);
            DBooleanMap       = GetRootMapOfPrototype(DBooleanPrototype);

            DArrayPrototype = new DObject(DObjectMap);
            DArrayMap       = GetRootMapOfPrototype(DArrayPrototype);

            DRegExpPrototype = new DObject(DObjectMap);
            DRegExpMap       = GetRootMapOfPrototype(DRegExpPrototype);


            //Now need to recreate default values based on fresh prototypes.
            DefaultDUndefined = new DUndefined();
            DefaultDNull      = new DNull();

            //DefaultDObject = new DObject();
            //DefaultDDouble = new DDouble(default(double));
            //DefaultDString = new DString(default(string));
            //DefaultDInt = new DInt(default(int));
            //DefaultDBoolean = new DBoolean(default(bool));
            //DefaultDFunction = new DFunction(null);
            //DefaultDArray = new DArray();
            //DefaultDProperty = new DProperty();

            ArrayItemAccessor = new PropertyDescriptor(null)
            {
                Getter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) =>
                {
                    value = (obj as DArray).Elements[pd.Index];

                    /*if (mdr.Runtime.Instance.Configuration.ProfileStats)
                     * {
                     * mdr.Runtime.Instance.Counters.GetCounter("ArrayItemAccessor").Count++;
                     * }*/
                },
                Setter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) =>
                {
                    (obj as DArray).Elements[pd.Index] = value;
                },
            };

            StringItemAccessor = new PropertyDescriptor(null)
            {
                Getter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) =>
                {
                    var strObj = obj.FirstInPrototypeChainAs <DString>();
                    value.Set(strObj.PrimitiveValue.AsString()[pd.Index]);
                },
                Setter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) =>
                {
                    var strObj = obj.FirstInPrototypeChainAs <DString>();
                    var chars  = strObj.PrimitiveValue.AsString().ToCharArray();
                    chars[pd.Index] = value.AsChar();
                    strObj.PrimitiveValue.Set(new String(chars));
                },
            };

            var lengthFieldName = GetFieldName(LengthFieldId);

            ProtoInitializer.InitDArrayPrototype(DArrayPrototype, lengthFieldName);
            ProtoInitializer.InitDStringPrototype(DStringPrototype, lengthFieldName);

            var protoFieldName = GetFieldName(PrototypeFieldId);

            ProtoInitializer.InitDFunctionPrototype(DFunctionPrototype,
                                                    protoFieldName,
                                                    PrototypeFieldId);
        }
Example #31
0
    public static mdr.DObject CreateFunctionContext(ref mdr.CallFrame callFrame)
    {
      //this function will or may change its context, so create a new one; this is the safest option

      ///If callFrame.Function.ContextMap is null, it means it is the first time that function object is called
      ///in this case, we create a new PropertyMap and add all necessary fields to it. Then assign it to the .ContextMap.
      ///We don't add them one-by-one to the context itself to avoid resizing context.Fields several times.
      ///Also we first add all of them, so that we can use the reference of the context.Fields[i]
      //TODO: if we had the function object here, we could technically do the addition to map here and generate code that directly uses the indexes

      mdr.DObject context;
      var contextMap = callFrame.Function.Metadata.ContextMap;
      if (contextMap == null)
      {
        var outerContext = callFrame.Function.OuterContext;
        context = new mdr.DObject(outerContext); //We do this first to get the root of the map first

        contextMap = context.Map;
        var scope = ((JSFunctionMetadata)callFrame.Function.Metadata).Scope;
        if (scope.HasClosedOnSymbol)
        {
          var symbols = scope.Symbols;
          for (var i = symbols.Count - 1; i >= 0; --i)
          {
            var symbol = symbols[i];
            if (symbol.SymbolType == JSSymbol.SymbolTypes.ClosedOnLocal)
            {
              if (scope.HasArgumentsSymbol && symbol.IsParameter)
                contextMap = contextMap.AddOwnProperty(symbol.Name, symbol.FieldId, PropertyDescriptor.Attributes.Accessor | PropertyDescriptor.Attributes.NotConfigurable);
              else
                contextMap = contextMap.AddOwnProperty(symbol.Name, symbol.FieldId, PropertyDescriptor.Attributes.Data | PropertyDescriptor.Attributes.NotConfigurable);
            }
          }
        }

        if (scope.HasEval)
        {
          //Eval may use the arguments
          Debug.Assert(scope.HasArgumentsSymbol, "Exected arguments in the context for a function with eval");
          contextMap = contextMap.AddOwnProperty(JSFunctionArguments.Name, mdr.Runtime.Instance.GetFieldId(JSFunctionArguments.Name), PropertyDescriptor.Attributes.Data | PropertyDescriptor.Attributes.NotConfigurable);
        }

        context.Map = contextMap; //This will update the fields size
        callFrame.Function.Metadata.ContextMap = contextMap;
      }
      else
      {
        context = new mdr.DObject(contextMap);
      }
      return context;
    }