< prev index next >

jdk/src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.experimental.bytecode;
  27 


  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodType;
  30 import java.util.ArrayList;
  31 import java.util.HashMap;
  32 import java.util.Iterator;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Map.Entry;
  36 import java.util.Vector;
  37 import java.util.function.Consumer;
  38 import java.util.function.Supplier;
  39 
  40 public class TypedCodeBuilder<S, T, E, C extends TypedCodeBuilder<S, T, E, C>> extends MacroCodeBuilder<S, T, E, C> {
  41 
  42     State lastStackMapState;
  43     int lastStackMapPc = -1;
  44     Map<CharSequence, LocalVarInfo> lvarOffsets = new HashMap<>();
  45     protected State state;
  46     int depth = 0;
  47     int currLocalOffset = 0;
  48 




  49     class StatefulPendingJump extends PendingJump {
  50 
  51         State state;
  52 
  53         StatefulPendingJump(CharSequence label, int pc, State state) {
  54             super(label, pc);
  55             this.state = state;
  56         }
  57 
  58         @Override
  59         boolean resolve(CharSequence label, int pc) {
  60             boolean b = super.resolve(label, pc);
  61             if (b) {
  62                 TypedCodeBuilder.this.state = TypedCodeBuilder.this.state.merge(state);
  63             }
  64             return b;
  65         }
  66     }
  67 
  68     class LocalVarInfo {


 225             state.pop(tag);
 226             state.push(typeHelper.nullType());
 227             state.push(typeHelper.nullType());
 228             return op.get();
 229         }
 230     }
 231 
 232     public class State {
 233         public final ArrayList<T> stack;
 234         public final Vector<T> locals;
 235 
 236         State(ArrayList<T> stack, Vector<T> locals) {
 237             this.stack = stack;
 238             this.locals = locals;
 239         }
 240 
 241         State() {
 242             this(new ArrayList<>(), new Vector<>());
 243         }
 244 
 245         void push(TypeTag tag) {

 246             switch (tag) {
 247                 case A:
 248                 case V:
 249                     throw new IllegalStateException("Bad type tag");
 250                 default:
 251                     push(typeHelper.fromTag(tag));
 252             }
 253         }
 254 
 255         void push(T t) {

 256             stack.add(t);
 257             if (width(t) == 2) {
 258                 stack.add(null);
 259             }
 260             if (stack.size() > stacksize) {
 261                 stacksize = stack.size();
 262             }
 263         }
 264 
 265         T peek() {
 266             return stack.get(stack.size() - 1);
 267         }
 268 
 269         T tosType() {
 270             T tos = peek();
 271             if (tos == null) {
 272                 //double slot
 273                 tos = stack.get(stack.size() - 2);
 274             }
 275             return tos;
 276         }
 277 
 278         T popInternal() {
 279             return stack.remove(stack.size() - 1);
 280         }
 281 

 282         @SuppressWarnings("unchecked")
 283         T pop() {
 284             if (stack.size() == 0 || peek() == null) throw new IllegalStateException();
 285             return popInternal();
 286         }
 287 
 288         T pop2() {
 289             T o = stack.get(stack.size() - 2);
 290             TypeTag t = typeHelper.tag(o);
 291             if (t.width != 2) throw new IllegalStateException();
 292             popInternal();
 293             popInternal();
 294             return o;
 295         }
 296 
 297         T pop(TypeTag t) {
 298             return (t.width() == 2) ?
 299                 pop2() : pop();
 300         }
 301 
 302         void load(TypeTag tag, int index) {
 303             if (tag == TypeTag.A) throw new IllegalStateException("Bad type tag");


 955     }
 956 
 957     T ldcType(Object o) {
 958         if (o instanceof Double) {
 959             return typeHelper.fromTag(TypeTag.D);
 960         } else if (o instanceof Long) {
 961             return typeHelper.fromTag(TypeTag.J);
 962         } else if (o instanceof Float) {
 963             return typeHelper.fromTag(TypeTag.F);
 964         } else if (o instanceof Integer) {
 965             return typeHelper.fromTag(TypeTag.I);
 966         } else if (o instanceof Class<?>) {
 967             return typeHelper.type(typeHelper.symbolFrom("java/lang/Class"));
 968         } else if (o instanceof String) {
 969             return typeHelper.type(typeHelper.symbolFrom("java/lang/String"));
 970         } else if (o instanceof MethodHandle) {
 971             return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle"));
 972         } else if (o instanceof MethodType) {
 973             return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodType"));
 974         } else {
 975             throw new IllegalStateException();
 976         }
 977     }
 978 
 979     public C load(int index) {
 980         return load(typeHelper.tag(state.locals.get(index)), index);
 981     }
 982 
 983     public C store(int index) {
 984         return store(typeHelper.tag(state.tosType()), index);
 985     }
 986 
 987     @Override
 988     public C withLocalSize(int localsize) {
 989         throw new IllegalStateException("Local size automatically computed");
 990     }
 991 
 992     @Override
 993     public C withStackSize(int stacksize) {
 994         throw new IllegalStateException("Stack size automatically computed");
 995     }




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.experimental.bytecode;
  27 
  28 import jdk.experimental.value.MethodHandleBuilder;
  29 
  30 import java.lang.invoke.MethodHandle;
  31 import java.lang.invoke.MethodType;
  32 import java.util.ArrayList;
  33 import java.util.HashMap;
  34 import java.util.Iterator;
  35 import java.util.List;
  36 import java.util.Map;
  37 import java.util.Map.Entry;
  38 import java.util.Vector;
  39 import java.util.function.Consumer;
  40 import java.util.function.Supplier;
  41 
  42 public class TypedCodeBuilder<S, T, E, C extends TypedCodeBuilder<S, T, E, C>> extends MacroCodeBuilder<S, T, E, C> {
  43 
  44     State lastStackMapState;
  45     int lastStackMapPc = -1;
  46     Map<CharSequence, LocalVarInfo> lvarOffsets = new HashMap<>();
  47     protected State state;
  48     int depth = 0;
  49     int currLocalOffset = 0;
  50 
  51     public State state() {
  52         return state;
  53     }
  54 
  55     class StatefulPendingJump extends PendingJump {
  56 
  57         State state;
  58 
  59         StatefulPendingJump(CharSequence label, int pc, State state) {
  60             super(label, pc);
  61             this.state = state;
  62         }
  63 
  64         @Override
  65         boolean resolve(CharSequence label, int pc) {
  66             boolean b = super.resolve(label, pc);
  67             if (b) {
  68                 TypedCodeBuilder.this.state = TypedCodeBuilder.this.state.merge(state);
  69             }
  70             return b;
  71         }
  72     }
  73 
  74     class LocalVarInfo {


 231             state.pop(tag);
 232             state.push(typeHelper.nullType());
 233             state.push(typeHelper.nullType());
 234             return op.get();
 235         }
 236     }
 237 
 238     public class State {
 239         public final ArrayList<T> stack;
 240         public final Vector<T> locals;
 241 
 242         State(ArrayList<T> stack, Vector<T> locals) {
 243             this.stack = stack;
 244             this.locals = locals;
 245         }
 246 
 247         State() {
 248             this(new ArrayList<>(), new Vector<>());
 249         }
 250 
 251         // FIXME should be package-private
 252         public void push(TypeTag tag) {
 253             switch (tag) {
 254                 case A:
 255                 case V:
 256                     throw new IllegalStateException("Bad type tag");
 257                 default:
 258                     push(typeHelper.fromTag(tag));
 259             }
 260         }
 261 
 262         // FIXME should be package-private
 263         public void push(T t) {
 264             stack.add(t);
 265             if (width(t) == 2) {
 266                 stack.add(null);
 267             }
 268             if (stack.size() > stacksize) {
 269                 stacksize = stack.size();
 270             }
 271         }
 272 
 273         T peek() {
 274             return stack.get(stack.size() - 1);
 275         }
 276 
 277         T tosType() {
 278             T tos = peek();
 279             if (tos == null) {
 280                 //double slot
 281                 tos = stack.get(stack.size() - 2);
 282             }
 283             return tos;
 284         }
 285 
 286         T popInternal() {
 287             return stack.remove(stack.size() - 1);
 288         }
 289 
 290         // FIXME should be package-private
 291         @SuppressWarnings("unchecked")
 292         public T pop() {
 293             if (stack.size() == 0 || peek() == null) throw new IllegalStateException();
 294             return popInternal();
 295         }
 296 
 297         T pop2() {
 298             T o = stack.get(stack.size() - 2);
 299             TypeTag t = typeHelper.tag(o);
 300             if (t.width != 2) throw new IllegalStateException();
 301             popInternal();
 302             popInternal();
 303             return o;
 304         }
 305 
 306         T pop(TypeTag t) {
 307             return (t.width() == 2) ?
 308                 pop2() : pop();
 309         }
 310 
 311         void load(TypeTag tag, int index) {
 312             if (tag == TypeTag.A) throw new IllegalStateException("Bad type tag");


 964     }
 965 
 966     T ldcType(Object o) {
 967         if (o instanceof Double) {
 968             return typeHelper.fromTag(TypeTag.D);
 969         } else if (o instanceof Long) {
 970             return typeHelper.fromTag(TypeTag.J);
 971         } else if (o instanceof Float) {
 972             return typeHelper.fromTag(TypeTag.F);
 973         } else if (o instanceof Integer) {
 974             return typeHelper.fromTag(TypeTag.I);
 975         } else if (o instanceof Class<?>) {
 976             return typeHelper.type(typeHelper.symbolFrom("java/lang/Class"));
 977         } else if (o instanceof String) {
 978             return typeHelper.type(typeHelper.symbolFrom("java/lang/String"));
 979         } else if (o instanceof MethodHandle) {
 980             return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle"));
 981         } else if (o instanceof MethodType) {
 982             return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodType"));
 983         } else {
 984             return typeHelper.type(typeHelper.symbolFrom("java/lang/Object")); // CP patching support
 985         }
 986     }
 987 
 988     public C load(int index) {
 989         return load(typeHelper.tag(state.locals.get(index)), index);
 990     }
 991 
 992     public C store(int index) {
 993         return store(typeHelper.tag(state.tosType()), index);
 994     }
 995 
 996     @Override
 997     public C withLocalSize(int localsize) {
 998         throw new IllegalStateException("Local size automatically computed");
 999     }
1000 
1001     @Override
1002     public C withStackSize(int stacksize) {
1003         throw new IllegalStateException("Stack size automatically computed");
1004     }


< prev index next >