internal virtual LambdaForm CollectArgumentsForm(int pos, MethodType collectorType) { int collectorArity = collectorType.ParameterCount(); bool dropResult = (collectorType.ReturnType() == typeof(void)); if (collectorArity == 1 && !dropResult) { return(FilterArgumentForm(pos, basicType(collectorType.ParameterType(0)))); } BasicType[] newTypes = BasicType.basicTypes(collectorType.ParameterList()); Transform.Kind kind = (dropResult ? Transform.Kind.COLLECT_ARGS_TO_VOID : Transform.Kind.COLLECT_ARGS); if (dropResult && collectorArity == 0) // pure side effect { pos = 1; } Transform key = Transform.Of(kind, pos, collectorArity, BasicType.basicTypesOrd(newTypes)); LambdaForm form = GetInCache(key); if (form != null) { assert(form.Arity_Renamed == LambdaForm.Arity_Renamed - (dropResult ? 0 : 1) + collectorArity); return(form); } form = MakeArgumentCombinationForm(pos, collectorType, false, dropResult); return(PutInCache(key, form)); }
internal virtual LambdaForm FoldArgumentsForm(int foldPos, bool dropResult, MethodType combinerType) { int combinerArity = combinerType.ParameterCount(); Transform.Kind kind = (dropResult ? Transform.Kind.FOLD_ARGS_TO_VOID : Transform.Kind.FOLD_ARGS); Transform key = Transform.Of(kind, foldPos, combinerArity); LambdaForm form = GetInCache(key); if (form != null) { assert(form.Arity_Renamed == LambdaForm.Arity_Renamed - (kind == Transform.Kind.FOLD_ARGS ? 1 : 0)); return(form); } form = MakeArgumentCombinationForm(foldPos, combinerType, true, dropResult); return(PutInCache(key, form)); }
internal virtual LambdaForm FilterReturnForm(BasicType newType, bool constantZero) { Transform.Kind kind = (constantZero ? Transform.Kind.FILTER_RETURN_TO_ZERO : Transform.Kind.FILTER_RETURN); Transform key = Transform.Of(kind, newType.ordinal()); LambdaForm form = GetInCache(key); if (form != null) { assert(form.Arity_Renamed == LambdaForm.Arity_Renamed); assert(form.ReturnType() == newType); return(form); } LambdaFormBuffer buf = Buffer(); buf.StartEdit(); int insPos = LambdaForm.Names.Length; Name callFilter; if (constantZero) { // Synthesize a constant zero value for the given type. if (newType == V_TYPE) { callFilter = null; } else { callFilter = new Name(constantZero(newType)); } } else { BoundMethodHandle.SpeciesData oldData = OldSpeciesData(); BoundMethodHandle.SpeciesData newData = NewSpeciesData(L_TYPE); // The newly created LF will run with a different BMH. // Switch over any pre-existing BMH field references to the new BMH class. Name oldBaseAddress = LambdaForm.Parameter(0); // BMH holding the values buf.ReplaceFunctions(oldData.GetterFunctions(), newData.GetterFunctions(), oldBaseAddress); Name newBaseAddress = oldBaseAddress.withConstraint(newData); buf.RenameParameter(0, newBaseAddress); Name getFilter = new Name(newData.GetterFunction(oldData.FieldCount()), newBaseAddress); buf.InsertExpression(insPos++, getFilter); BasicType oldType = LambdaForm.ReturnType(); if (oldType == V_TYPE) { MethodType filterType = MethodType.MethodType(newType.basicTypeClass()); callFilter = new Name(filterType, getFilter); } else { MethodType filterType = MethodType.MethodType(newType.basicTypeClass(), oldType.basicTypeClass()); callFilter = new Name(filterType, getFilter, LambdaForm.Names[LambdaForm.Result]); } } if (callFilter != null) { buf.InsertExpression(insPos++, callFilter); } buf.Result = callFilter; form = buf.EndEdit(); return(PutInCache(key, form)); }
internal virtual LambdaForm CollectArgumentArrayForm(int pos, MethodHandle arrayCollector) { MethodType collectorType = arrayCollector.Type(); int collectorArity = collectorType.ParameterCount(); assert(arrayCollector.IntrinsicName() == Intrinsic.NEW_ARRAY); Class arrayType = collectorType.ReturnType(); Class elementType = arrayType.ComponentType; BasicType argType = basicType(elementType); int argTypeKey = argType.ordinal(); if (argType.basicTypeClass() != elementType) { // return null if it requires more metadata (like String[].class) if (!elementType.Primitive) { return(null); } argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal(); } assert(collectorType.ParameterList().Equals(Collections.NCopies(collectorArity, elementType))); Transform.Kind kind = Transform.Kind.COLLECT_ARGS_TO_ARRAY; Transform key = Transform.Of(kind, pos, collectorArity, argTypeKey); LambdaForm form = GetInCache(key); if (form != null) { assert(form.Arity_Renamed == LambdaForm.Arity_Renamed - 1 + collectorArity); return(form); } LambdaFormBuffer buf = Buffer(); buf.StartEdit(); assert(pos + 1 <= LambdaForm.Arity_Renamed); assert(pos > 0); // cannot filter the MH arg itself Name[] newParams = new Name[collectorArity]; for (int i = 0; i < collectorArity; i++) { newParams[i] = new Name(pos + i, argType); } Name callCombiner = new Name(arrayCollector, (Object[])newParams); //... // insert the new expression int exprPos = LambdaForm.Arity(); buf.InsertExpression(exprPos, callCombiner); // insert new arguments int argPos = pos + 1; // skip result parameter foreach (Name newParam in newParams) { buf.InsertParameter(argPos++, newParam); } assert(buf.LastIndexOf(callCombiner) == exprPos + newParams.Length); buf.ReplaceParameterByCopy(pos, exprPos + newParams.Length); form = buf.EndEdit(); return(PutInCache(key, form)); }