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 
MHEnvelopeArgTFPair(MHCall outboundTarget, String tag, int argNum, Argument envelope, Argument envelopeLocator)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
getOutboundTF()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 
computeGetTF(Argument envelopeArg2, Argument envelopeLocatorArg2)79     protected abstract MHTF computeGetTF(Argument envelopeArg2, Argument envelopeLocatorArg2);
80 
81     @Override
getInboundTF(MHCall target)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 
computeSetTF(Argument envelopeArg2, Argument envelopeLocatorArg2, Argument componentArg2)123     protected abstract MHTF computeSetTF(Argument envelopeArg2, Argument envelopeLocatorArg2, Argument componentArg2);
124 }
125