1 /*
   2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package vm.mlvm.meth.share.transform.v2;
  25 
  26 import vm.mlvm.meth.share.Argument;
  27 import vm.mlvm.meth.share.Arguments;
  28 
  29 public abstract class MHEnvelopeArgTFPair extends MHTFPair {
  30 
  31     private final String _tag;
  32     private final int _argNum;
  33     protected final Argument _envelopeArg;
  34     protected final Argument _envelopeLocatorArg;
  35     private final Argument _componentArg;
  36 
  37     public MHEnvelopeArgTFPair(MHCall outboundTarget, String tag, int argNum, Argument envelope, Argument envelopeLocator) {
  38         super(outboundTarget);
  39 
  40         _tag = tag;
  41         _argNum = argNum;
  42 
  43         envelopeLocator.setPreserved(true);
  44         envelopeLocator.setTag(tag + "_Locator");
  45         _envelopeLocatorArg = envelopeLocator;
  46 
  47         Argument arg = outboundTarget.getArgs()[argNum];
  48         _componentArg = arg;
  49 
  50         envelope.setTag(tag + "_Envelope");
  51         envelope.setPreserved(true);
  52         _envelopeArg = envelope;
  53     }
  54 
  55     @Override
  56     public MHTF getOutboundTF() {
  57         try {
  58             MHMacroTF mTF = new MHMacroTF("envelope arg outbound");
  59             mTF.addOutboundCall(outboundTarget);
  60 
  61             Argument[] outArgs = outboundTarget.getArgs();
  62 
  63             mTF.addTransformation(new MHPermuteTF(
  64                     mTF.addTransformation(new MHFoldTF(
  65                             mTF.addTransformation(new MHPermuteTF(outboundTarget,
  66                                     MHPermuteTF.moveArgsInPermuteArray(MHPermuteTF.getIdentityPermuteArray(outArgs.length), 0, 1, _argNum)
  67                             )),
  68                             mTF.addTransformation(computeGetTF(_envelopeArg, _envelopeLocatorArg))
  69                     )),
  70                     MHPermuteTF.moveArgsInPermuteArray(MHPermuteTF.getIdentityPermuteArray(outArgs.length + 1), _argNum, 2, 0)
  71             ));
  72 
  73             return mTF;
  74         } catch ( Exception e ) {
  75             throw (IllegalArgumentException) (new IllegalArgumentException("Exception when creating TF")).initCause(e);
  76         }
  77     }
  78 
  79     protected abstract MHTF computeGetTF(Argument envelopeArg2, Argument envelopeLocatorArg2);
  80 
  81     @Override
  82     public MHTF getInboundTF(MHCall target) {
  83         try {
  84             Argument[] outArgs = target.getArgs();
  85 
  86             int[] arrayArgIdxs = Arguments.findTag(outArgs, _tag + "_Envelope");
  87             if ( arrayArgIdxs.length != 1 )
  88                 throw new IllegalArgumentException("There should be only one argument tagged [" + _tag + "_Envelope], but there are " + arrayArgIdxs);
  89             int arrayArgIdx = arrayArgIdxs[0];
  90 
  91             int[] idxArgIdxs = Arguments.findTag(outArgs, _tag + "_Locator");
  92             if ( idxArgIdxs.length != 1 )
  93                 throw new IllegalArgumentException("There should be only one argument tagged [" + _tag + "_Locator], but there are " + idxArgIdxs);
  94             int idxArgIdx = idxArgIdxs[0];
  95 
  96             MHMacroTF mTF = new MHMacroTF("envelope arg inbound");
  97             mTF.addOutboundCall(target);
  98 
  99             int[] innerPermuteArray = MHPermuteTF.getIdentityPermuteArray(outArgs.length);
 100 
 101             if ( arrayArgIdx < idxArgIdx )
 102                 innerPermuteArray = MHPermuteTF.moveArgsInPermuteArray(MHPermuteTF.moveArgsInPermuteArray(innerPermuteArray, 0, 1, arrayArgIdx), 0, 1, idxArgIdx);
 103             else
 104                 innerPermuteArray = MHPermuteTF.moveArgsInPermuteArray(MHPermuteTF.moveArgsInPermuteArray(innerPermuteArray, 0, 1, idxArgIdx), 0, 1, arrayArgIdx);
 105 
 106             mTF.addTransformation(new MHPermuteTF(
 107                     mTF.addTransformation(new MHInsertTF(
 108                             mTF.addTransformation(new MHFoldTF(
 109                                     mTF.addTransformation(new MHPermuteTF(target, innerPermuteArray)),
 110                                     mTF.addTransformation(computeSetTF(_envelopeArg, _envelopeLocatorArg, _componentArg))
 111                             )),
 112                             0, new Argument[] { _envelopeArg, _envelopeLocatorArg }, true
 113                     )),
 114                     MHPermuteTF.moveArgsInPermuteArray(MHPermuteTF.getIdentityPermuteArray(outArgs.length), arrayArgIdx, 1, 0)
 115             ));
 116 
 117             return mTF;
 118         } catch ( Exception e ) {
 119             throw (IllegalArgumentException) (new IllegalArgumentException("Exception when creating TF")).initCause(e);
 120         }
 121     }
 122 
 123     protected abstract MHTF computeSetTF(Argument envelopeArg2, Argument envelopeLocatorArg2, Argument componentArg2);
 124 }