Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Compiler / VariableBinder.cs / 1305376 / VariableBinder.cs
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions.Compiler { ////// Determines if variables are closed over in nested lambdas and need to /// be hoisted. /// internal sealed class VariableBinder : ExpressionVisitor { private readonly AnalyzedTree _tree = new AnalyzedTree(); private readonly Stack_scopes = new Stack (); private readonly Stack _constants = new Stack (); private bool _inQuote; internal static AnalyzedTree Bind(LambdaExpression lambda) { var binder = new VariableBinder(); binder.Visit(lambda); return binder._tree; } private VariableBinder() { } protected internal override Expression VisitConstant(ConstantExpression node) { // If we're in Quote, we can ignore constants completely if (_inQuote) { return node; } // Constants that can be emitted into IL don't need to be stored on // the delegate if (ILGen.CanEmitConstant(node.Value, node.Type)) { return node; } _constants.Peek().AddReference(node.Value, node.Type); return node; } protected internal override Expression VisitUnary(UnaryExpression node) { if (node.NodeType == ExpressionType.Quote) { bool savedInQuote = _inQuote; _inQuote = true; Visit(node.Operand); _inQuote = savedInQuote; } else { Visit(node.Operand); } return node; } protected internal override Expression VisitLambda (Expression node) { _scopes.Push(_tree.Scopes[node] = new CompilerScope(node, true)); _constants.Push(_tree.Constants[node] = new BoundConstants()); Visit(MergeScopes(node)); _constants.Pop(); _scopes.Pop(); return node; } protected internal override Expression VisitInvocation(InvocationExpression node) { LambdaExpression lambda = node.LambdaOperand; // optimization: inline code for literal lambda's directly if (lambda != null) { // visit the lambda, but treat it more like a scope _scopes.Push(_tree.Scopes[lambda] = new CompilerScope(lambda, false)); Visit(MergeScopes(lambda)); _scopes.Pop(); // visit the invoke's arguments Visit(node.Arguments); return node; } return base.VisitInvocation(node); } protected internal override Expression VisitBlock(BlockExpression node) { if (node.Variables.Count == 0) { Visit(node.Expressions); return node; } _scopes.Push(_tree.Scopes[node] = new CompilerScope(node, false)); Visit(MergeScopes(node)); _scopes.Pop(); return node; } protected override CatchBlock VisitCatchBlock(CatchBlock node) { if (node.Variable == null) { Visit(node.Body); return node; } _scopes.Push(_tree.Scopes[node] = new CompilerScope(node, false)); Visit(node.Body); _scopes.Pop(); return node; } // If the immediate child is another scope, merge it into this one // This is an optimization to save environment allocations and // array accesses. private ReadOnlyCollection MergeScopes(Expression node) { ReadOnlyCollection body; var lambda = node as LambdaExpression; if (lambda != null) { body = new ReadOnlyCollection (new[] { lambda.Body }); } else { body = ((BlockExpression)node).Expressions; } var currentScope = _scopes.Peek(); // A block body is mergeable if the body only contains one single block node containing variables, // and the child block has the same type as the parent block. while (body.Count == 1 && body[0].NodeType == ExpressionType.Block) { var block = (BlockExpression)body[0]; if (block.Variables.Count > 0) { // Make sure none of the variables are shadowed. If any // are, we can't merge it. foreach (var v in block.Variables) { if (currentScope.Definitions.ContainsKey(v)) { return body; } } // Otherwise, merge it if (currentScope.MergedScopes == null) { currentScope.MergedScopes = new Set
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CultureData.cs
- RenderData.cs
- SByteStorage.cs
- OpenFileDialog.cs
- NamespaceDisplay.xaml.cs
- ContentTextAutomationPeer.cs
- TypeRestriction.cs
- AndCondition.cs
- XPathMultyIterator.cs
- LazyTextWriterCreator.cs
- SchemaRegistration.cs
- AvTraceFormat.cs
- NativeRightsManagementAPIsStructures.cs
- ContourSegment.cs
- ComplexType.cs
- ServiceModelConfigurationSectionGroup.cs
- SimpleWorkerRequest.cs
- PopOutPanel.cs
- TableColumnCollectionInternal.cs
- Compress.cs
- Int32CAMarshaler.cs
- FlowchartDesigner.Helpers.cs
- MbpInfo.cs
- FrameworkTextComposition.cs
- ParserHooks.cs
- WebBrowserDocumentCompletedEventHandler.cs
- SafeNativeMethods.cs
- TraceUtility.cs
- IntellisenseTextBox.cs
- EntityDataSourceMemberPath.cs
- DBDataPermission.cs
- SharedDp.cs
- DataGridViewComboBoxColumn.cs
- EngineSiteSapi.cs
- SafeSecurityHandles.cs
- BooleanToSelectiveScrollingOrientationConverter.cs
- TextContainerHelper.cs
- ObjectContextServiceProvider.cs
- XmlSchemaSimpleTypeUnion.cs
- IIS7UserPrincipal.cs
- TileBrush.cs
- XmlSchemaElement.cs
- DoubleAnimationUsingPath.cs
- BaseHashHelper.cs
- EditorPart.cs
- KoreanLunisolarCalendar.cs
- DynamicValueConverter.cs
- DataGridTablesFactory.cs
- BinaryNode.cs
- InvalidDataException.cs
- X509CertificateRecipientServiceCredential.cs
- ClientOperation.cs
- __ConsoleStream.cs
- HtmlFormWrapper.cs
- TextTreeUndoUnit.cs
- WebPartConnectionsCloseVerb.cs
- PostBackOptions.cs
- datacache.cs
- GeometryCombineModeValidation.cs
- SynchronizationFilter.cs
- PersonalizablePropertyEntry.cs
- RegexWriter.cs
- TraceContextEventArgs.cs
- UdpDiscoveryMessageFilter.cs
- EdmItemCollection.cs
- WebHttpSecurityElement.cs
- Inline.cs
- AutoGeneratedField.cs
- DataRowChangeEvent.cs
- GridToolTip.cs
- MessagingDescriptionAttribute.cs
- ConfigurationSectionGroupCollection.cs
- InternalPermissions.cs
- Border.cs
- FieldNameLookup.cs
- DataBoundLiteralControl.cs
- HtmlTable.cs
- XmlSerializerFaultFormatter.cs
- BamlReader.cs
- BindingValueChangedEventArgs.cs
- XmlNullResolver.cs
- OleServicesContext.cs
- HTTP_SERVICE_CONFIG_URLACL_KEY.cs
- EdmItemError.cs
- InvalidEnumArgumentException.cs
- WebPartVerbCollection.cs
- RegularExpressionValidator.cs
- UnsafeNativeMethods.cs
- UserPreferenceChangingEventArgs.cs
- Ref.cs
- WebPart.cs
- TypeSystem.cs
- WinCategoryAttribute.cs
- ECDsaCng.cs
- PathGeometry.cs
- BoundPropertyEntry.cs
- BulletedListEventArgs.cs
- DPAPIProtectedConfigurationProvider.cs
- NativeMethods.cs
- InternalBufferOverflowException.cs