Exemplo n.º 1
0
        public LogicalOrExpression(Expression left, Expression right, TernaryExpression implementation)
            : base(left, right)
        {
            Implementation = implementation;

            //Implementation.AddUser(this.User);
        }
Exemplo n.º 2
0
    public LogicalAndExpression(Expression left, Expression right, TernaryExpression implementation)
      : base(left, right)
    {
      Implementation = implementation;

      //Implementation.AddUser(this.User);
    }
Exemplo n.º 3
0
      //#region Binary Logical Operators; ECMA 11.11 -------------------------------------------------------------------------------------

      //public override void Visit(LogicalAndExpression node) {}

      //public override void Visit(LogicalOrExpression node) {}

      //#endregion

      #region Conditional Operators; ECMA 11.12 -------------------------------------------------------------------------------------

      public override void Visit(TernaryExpression node)
      {
        PushLocation(node);

        var elseLabel = _ilGen.DefineLabel();
        var endLabel = _ilGen.DefineLabel();

        VisitNode(node.Left);
        AsBoolean();
        _ilGen.Brfalse(elseLabel);

        ///We don't know if the type of left & right are different or not, we start by assuming they are the same type
        ///and then if not, patch the code

        var stackState1 = _localVars.GetTemporaryStackState();
        VisitNode(node.Middle);
        _localVars.PopTemporariesAfter(stackState1);
        var middleValueType = _result.ValueType;
        var middleValue = _localVars.PushTemporary(middleValueType);
        _ilGen.Stloc(middleValue);
        _ilGen.Br(endLabel);

        _ilGen.MarkLabel(elseLabel);
        var stackState2 = _localVars.GetTemporaryStackState();
        VisitNode(node.Right);
        _localVars.PopTemporariesAfter(stackState2);
        var rightValueType = _result.ValueType;

        if (middleValueType == rightValueType)
        {
          ///Hopefully this is the common case with the least complication
          _ilGen.Stloc(middleValue);

          _ilGen.MarkLabel(endLabel);
          _ilGen.Ldloc(middleValue);
          _result.ValueType = middleValueType;
        }
        else
        {
          _localVars.PopTemporariesAfter(stackState1); //release middle middleValue temporary, it is ok if we reuse the variable here
          var resultValueType = TypeCalculator.ResolveType(middleValueType, rightValueType);
          if (resultValueType == mdr.ValueTypes.DValueRef)
          {
            var resultValue = _localVars.PushTemporary(Types.DValue.TypeOf);
            _ilGen.Ldloca(resultValue);
            _ilGen.Call(Types.Operations.Assign.Get(rightValueType));
            var endPatchLabel = _ilGen.DefineLabel();
            _ilGen.Br(endPatchLabel);

            _ilGen.MarkLabel(endLabel);
            _ilGen.Ldloc(middleValue);
            _ilGen.Ldloca(resultValue);
            _ilGen.Call(Types.Operations.Assign.Get(middleValueType));

            _ilGen.MarkLabel(endPatchLabel);
            _ilGen.Ldloca(resultValue);
            _result.ValueType = mdr.ValueTypes.DValueRef;
          }
          else
          {
            var needConvertion = false;
            if (resultValueType == mdr.ValueTypes.Object)
            {
              Debug.Assert(
                (mdr.ValueTypesHelper.IsObject(middleValueType) || middleValueType == mdr.ValueTypes.Null)
                && (mdr.ValueTypesHelper.IsObject(rightValueType) || rightValueType == mdr.ValueTypes.Null)
                , "Invalid situation! result type {0} does not match {1} and {2}", resultValueType, middleValueType, rightValueType);
            }
            else
            {
              Debug.Assert(
                mdr.ValueTypesHelper.IsNumber(resultValueType)
                && (mdr.ValueTypesHelper.IsNumber(middleValueType) || middleValueType == mdr.ValueTypes.Boolean)
                && (mdr.ValueTypesHelper.IsNumber(rightValueType) || rightValueType == mdr.ValueTypes.Boolean)
                , "Invalid situation! result type {0} does not match {1} and {2}", resultValueType, middleValueType, rightValueType);
              needConvertion = true;
            }

            var resultValue = _localVars.PushTemporary(resultValueType);
            if (needConvertion)
              _ilGen.Call(Types.ClrSys.Convert.Get(rightValueType, resultValueType));
            _ilGen.Stloc(resultValue);
            var endPatchLabel = _ilGen.DefineLabel();
            _ilGen.Br(endPatchLabel);

            _ilGen.MarkLabel(endLabel);
            _ilGen.Ldloc(middleValue);
            if (needConvertion)
              _ilGen.Call(Types.ClrSys.Convert.Get(middleValueType, resultValueType));
            _ilGen.Stloc(resultValue);

            _ilGen.MarkLabel(endPatchLabel);
            _ilGen.Ldloc(resultValue);
            _result.ValueType = resultValueType;
          }
        }

        //var trueValueType = node.Middle.ValueType;
        //var falseValueType = node.Right.ValueType;
        //if (trueValueType == falseValueType)
        //{
        //  //We can optioally just generate code in each BB and leave it on stack, but then
        //  //in debug mode, the source generator will think that stuff is left on the stack and generate wrong code
        //  //So, we just always store into a local variable

        //  var result = _localVars.PushTemporary(trueValueType);

        //  VisitNode(node.Middle);
        //  Debug.Assert(_resultType == trueValueType, "actual type {0} differ from expected type {1}", _resultType, trueValueType);
        //  _ilGen.Stloc(result);
        //  _ilGen.Br(endLabel);

        //  _ilGen.MarkLabel(elseLabel);
        //  VisitNode(node.Right);
        //  Debug.Assert(_resultType == falseValueType, "actual type {0} differ from expected type {1}", _resultType, falseValueType);
        //  _ilGen.Stloc(result);

        //  _ilGen.MarkLabel(endLabel);
        //  _ilGen.Ldloc(result);
        //  _resultType = trueValueType;
        //}
        //else
        //{
        //  var result = _localVars.PushTemporary(Types.DValue.TypeOf);

        //  var stackState = _localVars.GetTemporaryStackState();
        //  _ilGen.Ldloca(result);
        //  VisitNode(node.Middle);
        //  Debug.Assert(_resultType == trueValueType, "actual type {0} differ from expected type {1}", _resultType, trueValueType);
        //  _ilGen.Call(Types.DValue.Set(trueValueType));
        //  _localVars.PopTemorariesAfter(stackState);
        //  _ilGen.Br(endLabel);

        //  _ilGen.MarkLabel(elseLabel);
        //  stackState = _localVars.GetTemporaryStackState();
        //  _ilGen.Ldloca(result);
        //  VisitNode(node.Right);
        //  Debug.Assert(_resultType == falseValueType, "actual type {0} differ from expected type {1}", _resultType, falseValueType);
        //  _ilGen.Call(Types.DValue.Set(falseValueType));
        //  _localVars.PopTemorariesAfter(stackState);

        //  _ilGen.MarkLabel(endLabel);
        //  _ilGen.Ldloca(result);
        //  _resultType = mdr.ValueTypes.DValueRef;
        //}

        PopLocation();
      }
Exemplo n.º 4
0
 public override void Visit(TernaryExpression node)
 {
   VisitNode(node.Left);
   VisitNode(node.Middle);
   VisitNode(node.Right);
   Visit((Expression)node);
 }
Exemplo n.º 5
0
 public override void Visit(TernaryExpression node) { base.Visit(node); node.ValueType = GetType(node); }
Exemplo n.º 6
0
 internal static mdr.ValueTypes GetType(TernaryExpression expression) { return ResolveType(expression.Middle.ValueType, expression.Right.ValueType); }
Exemplo n.º 7
0
 public override void Visit(TernaryExpression node) { Visit((Expression)node); }
Exemplo n.º 8
0
      public override void Visit(TernaryExpression node)
      {
        PushLocation(node);

        VisitNode(node.Left);
        _stackModel.Pop(1);
        var conditionIndex = _stackModel.StackPointer;

        var gotoRightIndex = ReserveNewICIndex();

        VisitNode(node.Middle);
        _stackModel.Pop(1);
        var gotoEndIndex = ReserveNewICIndex();

        BeginICMethod(node);
        Brfalse(conditionIndex, GetCurrentICIndex() + 1);
        EndICMethod(gotoRightIndex);

        VisitNode(node.Right);

        BeginICMethod(node);
        Br(GetCurrentICIndex() + 1);
        EndICMethod(gotoEndIndex);

        PopLocation();
      }
Exemplo n.º 9
0
 public override void Visit(TernaryExpression node)
 {
     Visit((Expression)node);
 }
Exemplo n.º 10
0
 public abstract void Visit(TernaryExpression node);
Exemplo n.º 11
0
      public override void Visit(TernaryExpression node)
      {
        PushLocation(node);
        var secondChoice = _ilGen.DefineLabel();
        var done = _ilGen.DefineLabel();

        VisitNode(node.Left);
        AsBoolean();
        _ilGen.Brfalse(secondChoice);
        VisitNode(node.Middle);
        _ilGen.Br(done);
        _ilGen.MarkLabel(secondChoice);
        VisitNode(node.Right);
        _ilGen.MarkLabel(done);

        _stackModel.Pop(2);
        _stackModel.Push(1);
        PopLocation();
      }
Exemplo n.º 12
0
 public override void Visit(TernaryExpression node) { AssignToImplicitReturn(node); }