예제 #1
0
        /// Editing methods for lambda forms.
        // Each editing method can (potentially) cache the edited LF so that it can be reused later.

        internal virtual LambdaForm BindArgumentForm(int pos)
        {
            Transform  key  = Transform.Of(Transform.Kind.BIND_ARG, pos);
            LambdaForm form = GetInCache(key);

            if (form != null)
            {
                assert(form.ParameterConstraint(0) == NewSpeciesData(LambdaForm.ParameterType(pos)));
                return(form);
            }
            LambdaFormBuffer buf = Buffer();

            buf.StartEdit();

            BoundMethodHandle.SpeciesData oldData = OldSpeciesData();
            BoundMethodHandle.SpeciesData newData = NewSpeciesData(LambdaForm.ParameterType(pos));
            Name          oldBaseAddress          = LambdaForm.Parameter(0);// BMH holding the values
            Name          newBaseAddress;
            NamedFunction getter = newData.GetterFunction(oldData.FieldCount());

            if (pos != 0)
            {
                // The newly created LF will run with a different BMH.
                // Switch over any pre-existing BMH field references to the new BMH class.
                buf.ReplaceFunctions(oldData.GetterFunctions(), newData.GetterFunctions(), oldBaseAddress);
                newBaseAddress = oldBaseAddress.withConstraint(newData);
                buf.RenameParameter(0, newBaseAddress);
                buf.ReplaceParameterByNewExpression(pos, new Name(getter, newBaseAddress));
            }
            else
            {
                // cannot bind the MH arg itself, unless oldData is empty
                assert(oldData == BoundMethodHandle.SpeciesData.EMPTY);
                newBaseAddress = (new Name(L_TYPE)).withConstraint(newData);
                buf.ReplaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
                buf.InsertParameter(0, newBaseAddress);
            }

            form = buf.EndEdit();
            return(PutInCache(key, form));
        }
예제 #2
0
        internal virtual LambdaForm FilterArgumentForm(int pos, BasicType newType)
        {
            Transform  key  = Transform.Of(Transform.Kind.FILTER_ARG, pos, newType.ordinal());
            LambdaForm form = GetInCache(key);

            if (form != null)
            {
                assert(form.Arity_Renamed == LambdaForm.Arity_Renamed);
                assert(form.ParameterType(pos) == newType);
                return(form);
            }

            BasicType  oldType    = LambdaForm.ParameterType(pos);
            MethodType filterType = MethodType.MethodType(oldType.basicTypeClass(), newType.basicTypeClass());

            form = MakeArgumentCombinationForm(pos, filterType, false, false);
            return(PutInCache(key, form));
        }
예제 #3
0
        internal virtual LambdaForm AddArgumentForm(int pos, BasicType type)
        {
            Transform  key  = Transform.Of(Transform.Kind.ADD_ARG, pos, type.ordinal());
            LambdaForm form = GetInCache(key);

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

            buf.StartEdit();

            buf.InsertParameter(pos, new Name(type));

            form = buf.EndEdit();
            return(PutInCache(key, form));
        }