internal virtual void FinishBind(PythonNameBinder binder) { List<ClosureInfo> closureVariables = null; if (FreeVariables != null && FreeVariables.Count > 0) { LocalParentTuple = Ast.Parameter(Parent.GetClosureTupleType(), "$tuple"); foreach (var variable in _freeVars) { var parentClosure = Parent._closureVariables; Debug.Assert(parentClosure != null); for (int i = 0; i < parentClosure.Length; i++) { if (parentClosure[i].Variable == variable) { _variableMapping[variable] = new ClosureExpression(variable, Ast.Property(LocalParentTuple, String.Format("Item{0:D3}", i)), null); break; } } Debug.Assert(_variableMapping.ContainsKey(variable)); if (closureVariables == null) { closureVariables = new List<ClosureInfo>(); } closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition))); } } if (Variables != null) { foreach (PythonVariable variable in Variables.Values) { if (!HasClosureVariable(closureVariables, variable) && !variable.IsGlobal && (variable.AccessedInNestedScope || ExposesLocalVariable(variable))) { if (closureVariables == null) { closureVariables = new List<ClosureInfo>(); } closureVariables.Add(new ClosureInfo(variable, true)); } if (variable.Kind == VariableKind.Local) { Debug.Assert(variable.Scope == this); if (variable.AccessedInNestedScope || ExposesLocalVariable(variable)) { _variableMapping[variable] = new ClosureExpression(variable, Ast.Parameter(typeof(ClosureCell), variable.Name), null); } else { _variableMapping[variable] = Ast.Parameter(typeof(object), variable.Name); } } } } if (closureVariables != null) { _closureVariables = closureVariables.ToArray(); } // no longer needed _references = null; }
internal void CreateVariables(ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals, List <MSAst.Expression> init) { if (Variables != null) { foreach (PythonVariable variable in Variables.Values) { if (variable.Kind != VariableKind.Global) { ClosureExpression closure = GetVariableExpression(variable) as ClosureExpression; if (closure != null) { init.Add(closure.Create()); locals.Add((MSAst.ParameterExpression)closure.ClosureCell); } else if (variable.Kind == VariableKind.Local) { locals.Add((MSAst.ParameterExpression)GetVariableExpression(variable)); if (variable.ReadBeforeInitialized) { init.Add( AssignValue( GetVariableExpression(variable), MSAst.Expression.Field(null, typeof(Uninitialized).GetField(nameof(Uninitialized.Instance))) ) ); } } } } } if (IsClosure) { Type tupleType = Parent.GetClosureTupleType(); Debug.Assert(tupleType != null); init.Add( MSAst.Expression.Assign( LocalParentTuple, MSAst.Expression.Convert( GetParentClosureTuple(), tupleType ) ) ); locals.Add(LocalParentTuple); } }
private static void CompileAssignment(LightCompiler compiler, MSAst.Expression variable, Action <LightCompiler> compileValue) { var instructions = compiler.Instructions; ClosureExpression closure = variable as ClosureExpression; if (closure != null) { compiler.Compile(closure.ClosureCell); } LookupGlobalVariable lookup = variable as LookupGlobalVariable; if (lookup != null) { compiler.Compile(lookup.CodeContext); instructions.EmitLoad(lookup.Name); } compileValue(compiler); if (closure != null) { instructions.EmitStoreField(ClosureExpression._cellField); return; } if (lookup != null) { var setter = typeof(PythonOps).GetMethod(lookup.IsLocal ? nameof(PythonOps.SetLocal) : nameof(PythonOps.SetGlobal)); instructions.Emit(CallInstruction.Create(setter)); return; } MSAst.ParameterExpression functionValueParam = variable as MSAst.ParameterExpression; if (functionValueParam != null) { instructions.EmitStoreLocal(compiler.Locals.GetLocalIndex(functionValueParam)); return; } var globalVar = variable as PythonGlobalVariableExpression; if (globalVar != null) { instructions.Emit(new PythonSetGlobalInstruction(globalVar.Global)); instructions.EmitPop(); return; } Debug.Assert(false, "Unsupported variable type for light compiling function"); }
internal ClosureExpression/*!*/ LiftedParameter(PythonVariable variable, string name) { ParameterExpression result = Ast.Variable(typeof(object), name); _params.Add(result); ClosureExpression closureVar = new ClosureExpression(variable, HiddenVariable(typeof(ClosureCell), name), result); EnsureLiftedVars(); _liftedVars.Add(new DefinitionClosureInfo(closureVar, true)); return closureVar; }
internal ClosureExpression/*!*/ LiftedVariable(PythonVariable/*!*/ variable, string/*!*/ name, bool accessInNestedScope) { ParameterExpression result = HiddenVariable(typeof(ClosureCell), name); ClosureExpression closureVar = new ClosureExpression(variable, result, null); EnsureLiftedVars(); _liftedVars.Add(new DefinitionClosureInfo(closureVar, true)); return closureVar; }
internal virtual void FinishBind(PythonNameBinder binder) { List<ClosureInfo> closureVariables = null; if (FreeVariables != null && FreeVariables.Count > 0) { _localParentTuple = Ast.Parameter(Parent.GetClosureTupleType(), "$tuple"); foreach (var variable in _freeVars) { var parentClosure = Parent._closureVariables; Debug.Assert(parentClosure != null); for (int i = 0; i < parentClosure.Length; i++) { if (parentClosure[i].Variable == variable) { _variableMapping[variable] = new ClosureExpression(variable, Ast.Property(_localParentTuple, String.Format("Item{0:D3}", i)), null); break; } } Debug.Assert(_variableMapping.ContainsKey(variable)); if (closureVariables == null) { closureVariables = new List<ClosureInfo>(); } closureVariables.Add(new ClosureInfo(variable, !(this is ClassDefinition))); } } if (Variables != null) { foreach (PythonVariable variable in Variables.Values) { if (!HasClosureVariable(closureVariables, variable) && !variable.IsGlobal && (variable.AccessedInNestedScope || ExposesLocalVariable(variable))) { if (closureVariables == null) { closureVariables = new List<ClosureInfo>(); } closureVariables.Add(new ClosureInfo(variable, true)); } if (variable.Kind == VariableKind.Local) { Debug.Assert(variable.Scope == this); if (variable.AccessedInNestedScope || ExposesLocalVariable(variable)) { _variableMapping[variable] = new ClosureExpression(variable, Ast.Parameter(typeof(ClosureCell), variable.Name), null); } else { _variableMapping[variable] = Ast.Parameter(typeof(object), variable.Name); } } } } if (closureVariables != null) { _closureVariables = closureVariables.ToArray(); } // no longer needed _references = null; }