/// <summary> /// By default, and expression can have upto only one user. For multiple users, we will need to introduce temporary WriteIndentifier expressions. /// We might have statements (e.g. if) that use the result, so type should be Node and not Expression /// </summary> public override void AddUser(Node newUser) { if (User == null) { base.AddUser(newUser); } else { var currUser = User; var writeTemp = currUser as WriteTemporaryExpression; if (writeTemp == null) { base.RemoveUser(currUser); //next line will call this.AddUser again, so should null it beforehand writeTemp = new WriteTemporaryExpression(this); Debug.Assert(User == writeTemp, "Invalid situation!"); currUser.Replace(this, writeTemp); writeTemp.AddUser(currUser); } else { //already a temporary is assigned } newUser.Replace(this, writeTemp); writeTemp.AddUser(newUser); } }
/// <summary> /// By default, and expression can have upto only one user. For multiple users, we will need to introduce temporary WriteIndentifier expressions. /// We might have statements (e.g. if) that use the result, so type should be Node and not Expression /// </summary> public override void AddUser(Node newUser) { if (User == null) base.AddUser(newUser); else { var currUser = User; var writeTemp = currUser as WriteTemporaryExpression; if (writeTemp == null) { base.RemoveUser(currUser); //next line will call this.AddUser again, so should null it beforehand writeTemp = new WriteTemporaryExpression(this); Debug.Assert(User == writeTemp, "Invalid situation!"); currUser.Replace(this, writeTemp); writeTemp.AddUser(currUser); } else { //already a temporary is assigned } newUser.Replace(this, writeTemp); writeTemp.AddUser(newUser); } }
public Temporary Declare(WriteTemporaryExpression node) { Temporary temp; for (var i = TemporariesCount - 1; i >= 0; --i) { temp = Temporaries[i]; if (temp.Node == node) return temp; } //Did not find it, so need to declare it if (Temporaries == null) Temporaries = new Temporary[5]; if (TemporariesCount >= Temporaries.Length) Array.Resize(ref Temporaries, TemporariesCount * 2); temp = Temporaries[TemporariesCount]; if (temp == null) Temporaries[TemporariesCount] = temp = new Temporary(); else temp.Node = null; //This is to signal the node it should recalculate ++TemporariesCount; return temp; }
public override void Visit(WriteTemporaryExpression node) { var local = _localVars.Get(node); if (local == null) { //First visit Debug.Assert(node.Users != null && node.Users.Count > 1, "Invalid situation, temporary must have more than one user!"); VisitNode(node.Value); _ilGen.Dup(); if (_result.ValueType == mdr.ValueTypes.DValueRef) { local = _localVars.Declare(mdr.ValueTypes.DValue, node); _ilGen.Ldloca(local); _ilGen.Call(Types.Operations.Assign.Get(_result.ValueType)); } else if (_result.ValueType == mdr.ValueTypes.Unknown || _result.ValueType == mdr.ValueTypes.Any) { local = _localVars.Declare(_result.Type, node); _ilGen.Stloc(local); } else { local = _localVars.Declare(_result.ValueType, node); _ilGen.Stloc(local); } } else { //this was already visited if (local.LocalType == Types.DValue.TypeOf) { _ilGen.Ldloca(local); _result.ValueType = mdr.ValueTypes.DValueRef; } else { _ilGen.Ldloc(local); _result.Type = local.LocalType; } } }
public override void Visit(WriteTemporaryExpression node) { Visit((Reference)node); VisitNode(node.Value); }
public override void Visit(WriteTemporaryExpression node) { if (!VisitedWriteTemporaries.Contains(node)) { base.Visit(node); node.ValueType = GetType(node); VisitedWriteTemporaries.Add(node); } }
internal static mdr.ValueTypes GetType(WriteTemporaryExpression expression) { return expression.Value.ValueType; }
public override void Visit(WriteTemporaryExpression node) { Debug.Assert(node.Users.Count > 1, "Invalid situation, temporary must have more than one user!"); WriteTemporaryInfo info; if (_writeTemporaries.TryGetValue(node, out info)) { //this was already visited info.Readers.Add(new WriteTemporaryInfo.ReaderInfo() { ReaderICIndex = ReserveNewICIndex(), DestinationValueIndex = _stackModel.StackPointer, }); _stackModel.Push(1); } else { //First visit VisitNode(node.Value); info = new WriteTemporaryInfo() { WriterICIndex = ReserveNewICIndex(), SourceValueIndex = _stackModel.StackPointer - 1, //load the top item, but no pop or push }; _writeTemporaries.Add(node, info); } }
public override void Visit(WriteTemporaryExpression node) { Visit((Reference)node); }
public abstract void Visit(WriteTemporaryExpression node);
public override void Visit(WriteTemporaryExpression node) { Debug.Assert(node.Users.Count > 1, "Invalid situation, temporary must have more than one user!"); var local = _localVars.Get(node); if (local != null) { //this was already visited _ilGen.Ldloca(local); Call(Types.Operations.Stack.LoadDValue, 0, 1); } else { //First visit VisitNode(node.Value); local = _localVars.Declare(mdr.ValueTypes.DValue, node); LoadStackItem(-1); //load the top item, but no pop or push _ilGen.Ldloca(local); _ilGen.Call(Types.Operations.Assign.Get(mdr.ValueTypes.DValueRef)); } }
public override void Visit(WriteTemporaryExpression node) { AssignToImplicitReturn(node); }