private MethodCandidate MakeByRefReducedMethodTarget(MethodBase method) { List <ParameterWrapper> parameters = new List <ParameterWrapper>(); int argIndex = 0; ArgBuilder instanceBuilder; if (!CompilerHelpers.IsStatic(method)) { parameters.Add(new ParameterWrapper(_binder, method.DeclaringType, true)); instanceBuilder = new SimpleArgBuilder(argIndex++, parameters[0].Type); } else { instanceBuilder = new NullArgBuilder(); } List <ArgBuilder> argBuilders = new List <ArgBuilder>(); List <int> returnArgs = new List <int>(); if (CompilerHelpers.GetReturnType(method) != typeof(void)) { returnArgs.Add(-1); } int paramCount = 0; foreach (ParameterInfo pi in method.GetParameters()) { if (pi.ParameterType == typeof(CodeContext) && paramCount == 0) { argBuilders.Add(new ContextArgBuilder()); continue; } paramCount++; int newIndex = 0, kwIndex = -1; if (!CompilerHelpers.IsOutParameter(pi)) { kwIndex = GetKeywordIndex(pi); if (kwIndex == -1) { newIndex = argIndex++; } } ArgBuilder ab; if (CompilerHelpers.IsOutParameter(pi)) { returnArgs.Add(argBuilders.Count); ab = new OutArgBuilder(pi); } else if (pi.ParameterType.IsByRef) { returnArgs.Add(argBuilders.Count); ParameterWrapper param = new ParameterWrapper(_binder, pi.ParameterType.GetElementType(), SymbolTable.StringToId(pi.Name)); parameters.Add(param); ab = new ReturnReferenceArgBuilder(newIndex, pi.ParameterType.GetElementType()); } else { ParameterWrapper param = new ParameterWrapper(_binder, pi); parameters.Add(param); ab = new SimpleArgBuilder(newIndex, param.Type, pi); } if (kwIndex == -1) { argBuilders.Add(ab); } else { argBuilders.Add(new KeywordArgBuilder(ab, _kwArgs.Length, kwIndex)); } } ReturnBuilder returnBuilder = MakeKeywordReturnBuilder( new ByRefReturnBuilder(_binder, returnArgs), method.GetParameters(), parameters); return(MakeMethodCandidate(method, parameters, instanceBuilder, argBuilders, returnBuilder)); }
private void MapParameterReduceByRef(ParameterInfo pi) { Debug.Assert(_returnArgs != null); // See KeywordArgBuilder.BuilderExpectsSingleParameter int indexForArgBuilder = 0; int nameIndex = -1; if (!CompilerHelpers.IsOutParameter(pi)) { nameIndex = _argNames.IndexOf(pi.Name); if (nameIndex == -1) { indexForArgBuilder = _argIndex++; } } ArgBuilder ab; if (CompilerHelpers.IsOutParameter(pi)) { _returnArgs.Add(_arguments.Count); ab = new OutArgBuilder(pi); } else if (pi.ParameterType.IsByRef) { // if the parameter is marked as [In] it is not returned. if ((pi.Attributes & (ParameterAttributes.In | ParameterAttributes.Out)) != ParameterAttributes.In) { _returnArgs.Add(_arguments.Count); } _parameters.Add(new ParameterWrapper(pi, pi.ParameterType.GetElementType(), pi.Name, false, false, false, false)); ab = new ReturnReferenceArgBuilder(pi, indexForArgBuilder); } else if (BinderHelpers.IsParamDictionary(pi)) { _paramsDict = new ParameterWrapper(pi); ab = new SimpleArgBuilder(pi, indexForArgBuilder); } else { _parameters.Add(new ParameterWrapper(pi)); ab = new SimpleArgBuilder(pi, indexForArgBuilder); } if (nameIndex == -1) { _arguments.Add(ab); } else { Debug.Assert(KeywordArgBuilder.BuilderExpectsSingleParameter(ab)); _arguments.Add(new KeywordArgBuilder(ab, _argNames.Count, nameIndex)); } }
/// <summary> /// Maps out parameters to return args and ref parameters to ones that don't accept StrongBox. /// </summary> private void MapParameterReduceByRef(ParameterInfo pi) { Debug.Assert(_returnArgs != null); // TODO: // Is this reduction necessary? What if // 1) we had an implicit conversion StrongBox<T> -> T& and // 2) all out parameters were treated as optional StrongBox<T> parameters? (if not present we return the result in a return value) int indexForArgBuilder = 0; int nameIndex = -1; if (!pi.IsOutParameter()) { nameIndex = _argNames.IndexOf(pi.Name); if (nameIndex == -1) { indexForArgBuilder = _argIndex++; } } ArgBuilder ab; if (pi.IsOutParameter()) { _returnArgs.Add(_arguments.Count); ab = new OutArgBuilder(pi); } else if (pi.ParameterType.IsByRef) { // if the parameter is marked as [In] it is not returned. if ((pi.Attributes & (ParameterAttributes.In | ParameterAttributes.Out)) != ParameterAttributes.In) { _returnArgs.Add(_arguments.Count); } _parameters.Add(new ParameterWrapper(pi, pi.ParameterType.GetElementType(), pi.Name, ParameterBindingFlags.None)); ab = new ReturnReferenceArgBuilder(pi, indexForArgBuilder); } else { ab = AddSimpleParameterMapping(pi, indexForArgBuilder); } if (nameIndex == -1) { _arguments.Add(ab); } else { Debug.Assert(KeywordArgBuilder.BuilderExpectsSingleParameter(ab)); _arguments.Add(new KeywordArgBuilder(ab, _argNames.Count, nameIndex)); } }