示例#1
0
        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));
        }