public LogicalOrExpression(Expression left, Expression right, TernaryExpression implementation) : base(left, right) { Implementation = implementation; //Implementation.AddUser(this.User); }
public LogicalAndExpression(Expression left, Expression right, TernaryExpression implementation) : base(left, right) { Implementation = implementation; //Implementation.AddUser(this.User); }
//#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(); }
public override void Visit(TernaryExpression node) { VisitNode(node.Left); VisitNode(node.Middle); VisitNode(node.Right); Visit((Expression)node); }
public override void Visit(TernaryExpression node) { base.Visit(node); node.ValueType = GetType(node); }
internal static mdr.ValueTypes GetType(TernaryExpression expression) { return ResolveType(expression.Middle.ValueType, expression.Right.ValueType); }
public override void Visit(TernaryExpression node) { Visit((Expression)node); }
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(); }
public abstract void Visit(TernaryExpression node);
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(); }
public override void Visit(TernaryExpression node) { AssignToImplicitReturn(node); }