/// 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)); }