Пример #1
0
        private ReadIndexerExpression MakeReadIndexerExpression(Expression container, Expression index)
        {
            StringLiteral         constIndex = index as StringLiteral;
            int                   integerIndex;
            ReadIndexerExpression n;

            //We need to make sure that the string is not an integer, because in the case of Arrays integer strings are equivalent to integers!!
            if (constIndex != null && !int.TryParse(constIndex.Value, out integerIndex))
            {
                n = new ReadPropertyExpression(MakeToObject((Expression)container), constIndex);
            }
            else
            {
                n = new ReadIndexerExpression(MakeToObject((Expression)container), (Expression)index);
            }
            return(n);
        }
Пример #2
0
      protected override void PerformLookup(ReadIndexerExpression node, LocalBuilder obj, mdr.ValueTypes objType, mdr.ValueTypes indexType, LocalBuilder value)
      {
        if (objType == mdr.ValueTypes.Array && indexType == mdr.ValueTypes.Int32)
          base.PerformLookup(node, obj, objType, indexType, value);
        else
        {
          _ilGen.Callvirt(Types.DObject.GetPropertyDescriptor.Get(_result.ValueType));
          //_ilGen.Callvirt(Types.DObject.GetField(_result.ValueType));

          int profIndex = _currFuncMetadata.GetProfileIndex(node);
          _ilGen.Ldloc(_profiler);
          _ilGen.Ldc_I4(profIndex);
          _ilGen.Ldloc(obj);
          _ilGen.Call(Types.DObject.GetMap);
          _ilGen.Call(Types.Operations.Internals.UpdateMapProfile);

          _ilGen.Ldloc(obj);
          _ilGen.Ldloca(value);
          _ilGen.Callvirt(Types.PropertyDescriptor.Get_DObject_DValueRef);
        }
      }
Пример #3
0
      protected virtual void PerformLookup(ReadIndexerExpression node, LocalBuilder obj, mdr.ValueTypes objType, mdr.ValueTypes indexType, LocalBuilder value)
      {
        if (objType == mdr.ValueTypes.Array && indexType == mdr.ValueTypes.Int32)
        {
          var index = _localVars.PushTemporary(indexType);
          _ilGen.Stloc(index);

          var slowPath = _ilGen.DefineLabel();
          var exitPath = _ilGen.DefineLabel();
          _ilGen.Pop();
          _ilGen.Ldloc(index);
          _ilGen.Ldc_I4_0();
          _ilGen.Blt(slowPath);
          _ilGen.Ldloc(index);
          _ilGen.Ldloc(obj);
          _ilGen.Ldfld(Types.DArray.ElementsLength);
          _ilGen.Bge(slowPath);

          _ilGen.Ldloc(obj);
          _ilGen.Ldfld(Types.DArray.Elements);
          _ilGen.Ldloc(index);
          _ilGen.Ldelema(Types.DValue.TypeOf);
          _ilGen.Ldobj(Types.DValue.TypeOf);
          _ilGen.Stloc(value);
          _ilGen.Br(exitPath);

          _localVars.PopTemporary(index);

          _ilGen.MarkLabel(slowPath);
          _ilGen.Ldloc(obj);
          _ilGen.Ldloc(index);
          _ilGen.Callvirt(Types.DObject.GetPropertyDescriptor.Get(_result.ValueType));
          _ilGen.Ldloc(obj);
          _ilGen.Ldloca(value);
          _ilGen.Callvirt(Types.PropertyDescriptor.Get_DObject_DValueRef);

          _ilGen.MarkLabel(exitPath);
        }
        else
        {
          _ilGen.Callvirt(Types.DObject.GetPropertyDescriptor.Get(_result.ValueType));
          //_ilGen.Callvirt(Types.DObject.GetField(_result.ValueType));
          _ilGen.Ldloc(obj);
          _ilGen.Ldloca(value);
          _ilGen.Callvirt(Types.PropertyDescriptor.Get_DObject_DValueRef);
        }
      }
Пример #4
0
      public override void Visit(ReadIndexerExpression node)
      {
        PushLocation(node);
        //TODO: how should we add typed array acces to this? 
        //  If we know the actual type is DArray with some type data, we can potentially use that. But that should be done at run time
        //  So, we should generate code to do that. Or is it more complicated than that?

        ///Any read or write in this situation must consider that the results might a Prototype, and so getter/setter should be called as well

        ///In the case of Usages.ReadWrite:
        ///We should execute the read side then the write side. If object itself does not have field, it will
        ///use its prototype chain for read. If we do the reverse order, the field is first added to the object.
        ///Also, 
        ///  if the object does have the field, the result ref for read and write will be point to two different objects
        ///  if the object has the filed, both refs will point to the same thing. So, we should be ok in terms of dangling refs

        ///Note:
        ////GetField... does not have any side effects, so we don't need to call it!
        ///SetField... or GetOrAddField... may have side effects, so we should call it as well no matter what, but if we are in Write or ReadWrite mode, the User cannot be null

        //We push this first since we don't want to pop it later, before pushing/poping more 
        var value = _localVars.PushTemporary(Types.DValue.TypeOf);

        var stackState = _localVars.GetTemporaryStackState();

        VisitNode(node.Container);
        AsDObject();
        var objType = _result.ValueType;
        var obj = _localVars.PushTemporary(objType);

        _ilGen.Stloc(obj);
        _ilGen.Ldloc(obj);

        //TODO: we need to insert the inline cache here
        VisitNode(node.Index);

        var indexType = _result.ValueType;

        PerformLookup(node, obj, objType, indexType, value);

        _localVars.PopTemporariesAfter(stackState);

        _ilGen.Ldloca(value);
        _result.ValueType = mdr.ValueTypes.DValueRef;

        PopLocation();
      }
Пример #5
0
 public override void Visit(ReadIndexerExpression node) { Visit((Indexer)node); }
Пример #6
0
 public override void Visit(ReadIndexerExpression node) { base.Visit(node); node.ValueType = GetType(node); }
Пример #7
0
 internal static mdr.ValueTypes GetType(ReadIndexerExpression expression) { return mdr.ValueTypes.DValueRef; }
      public override void Visit(ReadIndexerExpression node)
      {
        /*var nodeProfile = _currProfiler.GetNodeProfile(node);
        
        if (_currFuncMetadata.EnableInlineCache
          && nodeProfile != null
          && nodeProfile.Map != null
          && nodeProfile.PD == JSRuntime.Instance.GetArrayItemAccessor())
        {
          PushLocation(node);
          var value = _localVars.PushTemporary(Types.DValue.TypeOf);

          var stackState = _localVars.GetTemporaryStackState();

          VisitNode(node.Container);
          AsDObject();
          var objType = _result.ValueType;
          var obj = _localVars.PushTemporary(objType);

          _ilGen.Stloc(obj);
          _ilGen.Ldloc(obj);

          //TODO: we need to insert the inline cache here
          VisitNode(node.Index);

          var indexType = _result.ValueType;
          if (indexType != mdr.ValueTypes.Int32)
          {
            AsInt32();
          }
          PerformLookup(node, obj, mdr.ValueTypes.Array, mdr.ValueTypes.Int32, value);

          _localVars.PopTemporariesAfter(stackState);

          _ilGen.Ldloca(value);
          _result.ValueType = mdr.ValueTypes.DValueRef;

          PopLocation();
        }        
        else*/
          base.Visit(node);
      }
Пример #9
0
      public override void Visit(ReadIndexerExpression node)
      {
        PushLocation(node);

        VisitNode(node.Container);
        VisitNode(node.Index);

        _stackModel.Pop(2);

        BeginICMethod(node);
        _ilGen.Ldarg_CallFrame();
        _ilGen.Ldc_I4(_stackModel.StackPointer);
        _ilGen.Call(Types.Operations.ICMethods.ReadIndexer);
        EndICMethod();

        _stackModel.Push(1);

        PopLocation();
      }
Пример #10
0
 public override void Visit(ReadIndexerExpression node)
 {
     Visit((Indexer)node);
 }
Пример #11
0
    private ReadIndexerExpression MakeReadIndexerExpression(Expression container, Expression index)
    {
      StringLiteral constIndex = index as StringLiteral;
      int integerIndex;
      ReadIndexerExpression n;

      //We need to make sure that the string is not an integer, because in the case of Arrays integer strings are equivalent to integers!!
      if (constIndex != null && !int.TryParse(constIndex.Value, out integerIndex))
        n = new ReadPropertyExpression(MakeToObject((Expression)container), constIndex);
      else
        n = new ReadIndexerExpression(MakeToObject((Expression)container), (Expression)index);
      return n;
    }
Пример #12
0
 public abstract void Visit(ReadIndexerExpression node);
Пример #13
0
      public override void Visit(ReadIndexerExpression node)
      {
        PushLocation(node);
        //TODO: how should we add typed array acces to this? 
        //  If we know the actual type is DArray with some type data, we can potentially use that. But that should be done at run time
        //  So, we should generate code to do that. Or is it more complicated than that?

        ///Any read or write in this situation must consider that the results might a Prototype, and so getter/setter should be called as well

        ///In the case of Usages.ReadWrite:
        ///We should execute the read side then the write side. If object itself does not have field, it will
        ///use its prototype chain for read. If we do the reverse order, the field is first added to the object.
        ///Also, 
        ///  if the object does have the field, the result ref for read and write will be point to two different objects
        ///  if the object has the filed, both refs will point to the same thing. So, we should be ok in terms of dangling refs

        ///Note:
        ////GetField... does not have any side effects, so we don't need to call it!
        ///SetField... or GetOrAddField... may have side effects, so we should call it as well no matter what, but if we are in Write or ReadWrite mode, the User cannot be null

        VisitNode(node.Container);
        VisitNode(node.Index);

        // TODO: Commented since canPopOperand is unused.
        /*var canPopOperand = true;// !expression.UserIsFunction;*/
        var popOperandCount = 2;// expression.UserIsFunction ? 1 : 2; //remove index, but leave object for This if user is function
        _ilGen.Ldc_I4(popOperandCount);
        Call(Types.Operations.Stack.LoadField, popOperandCount, 1);
        PopLocation();
      }
Пример #14
0
    internal void PopLocation(ReadIndexerExpression node, mdr.DObject obj, mdr.PropertyDescriptor pd)
    {
      if (_currProfiler != null)
      {

        if (mdr.Runtime.Instance.Configuration.ProfileStats)
        {
          mdr.Runtime.Instance.Counters.GetCounter("Prop lookup").Count++;
          if (pd.IsDataDescriptor && !pd.IsInherited)
          {
            mdr.Runtime.Instance.Counters.GetCounter("Prop lookup owndata").Count++;
          }
          if (pd.IsDataDescriptor && pd.IsInherited)
          {
            mdr.Runtime.Instance.Counters.GetCounter("Prop lookup inherited").Count++;
          }
          MapNodeProfile mapProfile = _currProfiler.GetOrAddNodeProfile(node);
          if (mapProfile != null)
          {
            if (mapProfile.Map == obj.Map) 
            {
              mdr.Runtime.Instance.Counters.GetCounter("Prop lookup map hit").Count++;
              if (mapProfile.PD == pd)
              {
                mdr.Runtime.Instance.Counters.GetCounter("Prop lookup map/pd hit").Count++;
                if (pd.HasAttributes(mdr.PropertyDescriptor.Attributes.Data) && !pd.HasAttributes(mdr.PropertyDescriptor.Attributes.Inherited))
                {
                  mdr.Runtime.Instance.Counters.GetCounter("Prop lookup map/pd owndata hit").Count++;
                }
                if (pd.HasAttributes(mdr.PropertyDescriptor.Attributes.Inherited))
                {
                  mdr.Runtime.Instance.Counters.GetCounter("Prop lookup map/pd inherited hit").Count++;
                }
              }
            }
          }
        }
        _currProfiler.GetOrAddNodeProfile(node).UpdateNodeProfile(obj.Map, pd);
        //NodeProfile nProfile = _currProfiler.GetNodeProfile(node);
        //if (nProfile != null)
        //{
        //  (nProfile as MapNodeProfile).UpdateNodeProfile(obj.Map, pd);
        //}
        //else
        //{
        //  _currProfiler.CreateNewProfile(node, obj.Map, pd);
        //}
      }
    }
Пример #15
0
 public override void Visit(ReadIndexerExpression node)
 {
   throw new NotImplementedException();
 }
Пример #16
0
 public override void Visit(ReadIndexerExpression node) { AssignToImplicitReturn(node); }