Exemplo n.º 1
0
        internal virtual LambdaForm SpreadArgumentsForm(int pos, Class arrayType, int arrayLength)
        {
            Class elementType     = arrayType.ComponentType;
            Class erasedArrayType = arrayType;

            if (!elementType.Primitive)
            {
                erasedArrayType = typeof(Object[]);
            }
            BasicType bt             = basicType(elementType);
            int       elementTypeKey = bt.ordinal();

            if (bt.basicTypeClass() != elementType)
            {
                if (elementType.Primitive)
                {
                    elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
                }
            }
            Transform  key  = Transform.Of(Transform.Kind.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
            LambdaForm form = GetInCache(key);

            if (form != null)
            {
                assert(form.Arity_Renamed == LambdaForm.Arity_Renamed - arrayLength + 1);
                return(form);
            }
            LambdaFormBuffer buf = Buffer();

            buf.StartEdit();

            assert(pos <= MethodType.MAX_JVM_ARITY);
            assert(pos + arrayLength <= LambdaForm.Arity_Renamed);
            assert(pos > 0);             // cannot spread the MH arg itself

            Name spreadParam = new Name(L_TYPE);
            Name checkSpread = new Name(MethodHandleImpl.Lazy.NF_checkSpreadArgument, spreadParam, arrayLength);

            // insert the new expressions
            int exprPos = LambdaForm.Arity();

            buf.InsertExpression(exprPos++, checkSpread);
            // adjust the arguments
            MethodHandle aload = MethodHandles.ArrayElementGetter(erasedArrayType);

            for (int i = 0; i < arrayLength; i++)
            {
                Name loadArgument = new Name(aload, spreadParam, i);
                buf.InsertExpression(exprPos + i, loadArgument);
                buf.ReplaceParameterByCopy(pos + i, exprPos + i);
            }
            buf.InsertParameter(pos, spreadParam);

            form = buf.EndEdit();
            return(PutInCache(key, form));
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        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());
        }
Exemplo n.º 4
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));
        }