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)); }
private LambdaForm MakeArgumentCombinationForm(int pos, MethodType combinerType, bool keepArguments, bool dropResult) { LambdaFormBuffer buf = Buffer(); buf.StartEdit(); int combinerArity = combinerType.ParameterCount(); int resultArity = (dropResult ? 0 : 1); assert(pos <= MethodType.MAX_JVM_ARITY); assert(pos + resultArity + (keepArguments ? combinerArity : 0) <= LambdaForm.Arity_Renamed); assert(pos > 0); // cannot filter the MH arg itself assert(combinerType == combinerType.BasicType()); assert(combinerType.ReturnType() != typeof(void) || dropResult); 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 getCombiner = new Name(newData.GetterFunction(oldData.FieldCount()), newBaseAddress); Object[] combinerArgs = new Object[1 + combinerArity]; combinerArgs[0] = getCombiner; Name[] newParams; if (keepArguments) { newParams = new Name[0]; System.Array.Copy(LambdaForm.Names, pos + resultArity, combinerArgs, 1, combinerArity); } else { newParams = new Name[combinerArity]; BasicType[] newTypes = basicTypes(combinerType.ParameterList()); for (int i = 0; i < newTypes.Length; i++) { newParams[i] = new Name(pos + i, newTypes[i]); } System.Array.Copy(newParams, 0, combinerArgs, 1, combinerArity); } Name callCombiner = new Name(combinerType, combinerArgs); // insert the two new expressions int exprPos = LambdaForm.Arity(); buf.InsertExpression(exprPos + 0, getCombiner); buf.InsertExpression(exprPos + 1, callCombiner); // insert new arguments, if needed int argPos = pos + resultArity; // skip result parameter foreach (Name newParam in newParams) { buf.InsertParameter(argPos++, newParam); } assert(buf.LastIndexOf(callCombiner) == exprPos + 1 + newParams.Length); if (!dropResult) { buf.ReplaceParameterByCopy(pos, exprPos + 1 + newParams.Length); } return(buf.EndEdit()); }
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)); }