Mercurial > lasercutter
view src/clojure/asm/commons/AnalyzerAdapter.java @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line source
1 /***2 * ASM: a very small and fast Java bytecode manipulation framework3 * Copyright (c) 2000-2005 INRIA, France Telecom4 * All rights reserved.5 *6 * Redistribution and use in source and binary forms, with or without7 * modification, are permitted provided that the following conditions8 * are met:9 * 1. Redistributions of source code must retain the above copyright10 * notice, this list of conditions and the following disclaimer.11 * 2. Redistributions in binary form must reproduce the above copyright12 * notice, this list of conditions and the following disclaimer in the13 * documentation and/or other materials provided with the distribution.14 * 3. Neither the name of the copyright holders nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF28 * THE POSSIBILITY OF SUCH DAMAGE.29 */30 package clojure.asm.commons;32 import java.util.ArrayList;33 import java.util.HashMap;34 import java.util.List;35 import java.util.Map;37 import clojure.asm.Label;38 import clojure.asm.MethodAdapter;39 import clojure.asm.MethodVisitor;40 import clojure.asm.Opcodes;41 import clojure.asm.Type;43 /**44 * A {@link MethodAdapter} that keeps track of stack map frame changes between45 * {@link #visitFrame(int,int,Object[],int,Object[]) visitFrame} calls. This46 * adapter must be used with the47 * {@link clojure.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>XXX</i>48 * instruction delegates to the next visitor in the chain, if any, and then49 * simulates the effect of this instruction on the stack map frame, represented50 * by {@link #locals} and {@link #stack}. The next visitor in the chain can get51 * the state of the stack map frame <i>before</i> each instruction by reading52 * the value of these fields in its visit<i>XXX</i> methods (this requires a53 * reference to the AnalyzerAdapter that is before it in the chain).54 *55 * @author Eric Bruneton56 */57 public class AnalyzerAdapter extends MethodAdapter{59 /**60 * <code>List</code> of the local variable slots for current execution61 * frame. Primitive types are represented by {@link Opcodes#TOP},62 * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},63 * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or64 * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a65 * two elements, the second one being TOP). Reference types are represented66 * by String objects (representing internal names, or type descriptors for67 * array types), and uninitialized types by Label objects (this label68 * designates the NEW instruction that created this uninitialized value).69 * This field is <tt>null</tt> for unreacheable instructions.70 */71 public List locals;73 /**74 * <code>List</code> of the operand stack slots for current execution75 * frame. Primitive types are represented by {@link Opcodes#TOP},76 * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},77 * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or78 * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a79 * two elements, the second one being TOP). Reference types are represented80 * by String objects (representing internal names, or type descriptors for81 * array types), and uninitialized types by Label objects (this label82 * designates the NEW instruction that created this uninitialized value).83 * This field is <tt>null</tt> for unreacheable instructions.84 */85 public List stack;87 /**88 * The labels that designate the next instruction to be visited. May be89 * <tt>null</tt>.90 */91 private List labels;93 /**94 * Information about uninitialized types in the current execution frame.95 * This map associates internal names to Label objects. Each label96 * designates a NEW instruction that created the currently uninitialized97 * types, and the associated internal name represents the NEW operand, i.e.98 * the final, initialized type value.99 */100 private Map uninitializedTypes;102 /**103 * The maximum stack size of this method.104 */105 private int maxStack;107 /**108 * The maximum number of local variables of this method.109 */110 private int maxLocals;112 /**113 * Creates a new {@link AnalyzerAdapter}.114 *115 * @param owner the owner's class name.116 * @param access the method's access flags (see {@link Opcodes}).117 * @param name the method's name.118 * @param desc the method's descriptor (see {@link Type Type}).119 * @param mv the method visitor to which this adapter delegates calls. May120 * be <tt>null</tt>.121 */122 public AnalyzerAdapter(123 final String owner,124 final int access,125 final String name,126 final String desc,127 final MethodVisitor mv){128 super(mv);129 locals = new ArrayList();130 stack = new ArrayList();131 uninitializedTypes = new HashMap();133 if((access & Opcodes.ACC_STATIC) == 0)134 {135 if(name.equals("<init>"))136 {137 locals.add(Opcodes.UNINITIALIZED_THIS);138 }139 else140 {141 locals.add(owner);142 }143 }144 Type[] types = Type.getArgumentTypes(desc);145 for(int i = 0; i < types.length; ++i)146 {147 Type type = types[i];148 switch(type.getSort())149 {150 case Type.BOOLEAN:151 case Type.CHAR:152 case Type.BYTE:153 case Type.SHORT:154 case Type.INT:155 locals.add(Opcodes.INTEGER);156 break;157 case Type.FLOAT:158 locals.add(Opcodes.FLOAT);159 break;160 case Type.LONG:161 locals.add(Opcodes.LONG);162 locals.add(Opcodes.TOP);163 break;164 case Type.DOUBLE:165 locals.add(Opcodes.DOUBLE);166 locals.add(Opcodes.TOP);167 break;168 case Type.ARRAY:169 locals.add(types[i].getDescriptor());170 break;171 // case Type.OBJECT:172 default:173 locals.add(types[i].getInternalName());174 }175 }176 }178 public void visitFrame(179 final int type,180 final int nLocal,181 final Object[] local,182 final int nStack,183 final Object[] stack){184 if(type != Opcodes.F_NEW)185 { // uncompressed frame186 throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag");187 }189 if(mv != null)190 {191 mv.visitFrame(type, nLocal, local, nStack, stack);192 }194 if(this.locals != null)195 {196 this.locals.clear();197 this.stack.clear();198 }199 else200 {201 this.locals = new ArrayList();202 this.stack = new ArrayList();203 }204 visitFrameTypes(nLocal, local, this.locals);205 visitFrameTypes(nStack, stack, this.stack);206 maxStack = Math.max(maxStack, this.stack.size());207 }209 private void visitFrameTypes(210 final int n,211 final Object[] types,212 final List result){213 for(int i = 0; i < n; ++i)214 {215 Object type = types[i];216 result.add(type);217 if(type == Opcodes.LONG || type == Opcodes.DOUBLE)218 {219 result.add(Opcodes.TOP);220 }221 }222 }224 public void visitInsn(final int opcode){225 if(mv != null)226 {227 mv.visitInsn(opcode);228 }229 execute(opcode, 0, null);230 if((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)231 || opcode == Opcodes.ATHROW)232 {233 this.locals = null;234 this.stack = null;235 }236 }238 public void visitIntInsn(final int opcode, final int operand){239 if(mv != null)240 {241 mv.visitIntInsn(opcode, operand);242 }243 execute(opcode, operand, null);244 }246 public void visitVarInsn(final int opcode, final int var){247 if(mv != null)248 {249 mv.visitVarInsn(opcode, var);250 }251 execute(opcode, var, null);252 }254 public void visitTypeInsn(final int opcode, final String desc){255 if(opcode == Opcodes.NEW)256 {257 if(labels == null)258 {259 Label l = new Label();260 labels = new ArrayList(3);261 labels.add(l);262 if(mv != null)263 {264 mv.visitLabel(l);265 }266 }267 for(int i = 0; i < labels.size(); ++i)268 {269 uninitializedTypes.put(labels.get(i), desc);270 }271 }272 if(mv != null)273 {274 mv.visitTypeInsn(opcode, desc);275 }276 execute(opcode, 0, desc);277 }279 public void visitFieldInsn(280 final int opcode,281 final String owner,282 final String name,283 final String desc){284 if(mv != null)285 {286 mv.visitFieldInsn(opcode, owner, name, desc);287 }288 execute(opcode, 0, desc);289 }291 public void visitMethodInsn(292 final int opcode,293 final String owner,294 final String name,295 final String desc){296 if(mv != null)297 {298 mv.visitMethodInsn(opcode, owner, name, desc);299 }300 pop(desc);301 if(opcode != Opcodes.INVOKESTATIC)302 {303 Object t = pop();304 if(opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<')305 {306 Object u;307 if(t == Opcodes.UNINITIALIZED_THIS)308 {309 u = owner;310 }311 else312 {313 u = uninitializedTypes.get(t);314 }315 for(int i = 0; i < locals.size(); ++i)316 {317 if(locals.get(i) == t)318 {319 locals.set(i, u);320 }321 }322 for(int i = 0; i < stack.size(); ++i)323 {324 if(stack.get(i) == t)325 {326 stack.set(i, u);327 }328 }329 }330 }331 pushDesc(desc);332 labels = null;333 }335 public void visitJumpInsn(final int opcode, final Label label){336 if(mv != null)337 {338 mv.visitJumpInsn(opcode, label);339 }340 execute(opcode, 0, null);341 if(opcode == Opcodes.GOTO)342 {343 this.locals = null;344 this.stack = null;345 }346 }348 public void visitLabel(final Label label){349 if(mv != null)350 {351 mv.visitLabel(label);352 }353 if(labels == null)354 {355 labels = new ArrayList(3);356 }357 labels.add(label);358 }360 public void visitLdcInsn(final Object cst){361 if(mv != null)362 {363 mv.visitLdcInsn(cst);364 }365 if(cst instanceof Integer)366 {367 push(Opcodes.INTEGER);368 }369 else if(cst instanceof Long)370 {371 push(Opcodes.LONG);372 push(Opcodes.TOP);373 }374 else if(cst instanceof Float)375 {376 push(Opcodes.FLOAT);377 }378 else if(cst instanceof Double)379 {380 push(Opcodes.DOUBLE);381 push(Opcodes.TOP);382 }383 else if(cst instanceof String)384 {385 push("java/lang/String");386 }387 else if(cst instanceof Type)388 {389 push("java/lang/Class");390 }391 else392 {393 throw new IllegalArgumentException();394 }395 labels = null;396 }398 public void visitIincInsn(final int var, final int increment){399 if(mv != null)400 {401 mv.visitIincInsn(var, increment);402 }403 execute(Opcodes.IINC, var, null);404 }406 public void visitTableSwitchInsn(407 final int min,408 final int max,409 final Label dflt,410 final Label labels[]){411 if(mv != null)412 {413 mv.visitTableSwitchInsn(min, max, dflt, labels);414 }415 execute(Opcodes.TABLESWITCH, 0, null);416 this.locals = null;417 this.stack = null;418 }420 public void visitLookupSwitchInsn(421 final Label dflt,422 final int keys[],423 final Label labels[]){424 if(mv != null)425 {426 mv.visitLookupSwitchInsn(dflt, keys, labels);427 }428 execute(Opcodes.LOOKUPSWITCH, 0, null);429 this.locals = null;430 this.stack = null;431 }433 public void visitMultiANewArrayInsn(final String desc, final int dims){434 if(mv != null)435 {436 mv.visitMultiANewArrayInsn(desc, dims);437 }438 execute(Opcodes.MULTIANEWARRAY, dims, desc);439 }441 public void visitMaxs(final int maxStack, final int maxLocals){442 if(mv != null)443 {444 this.maxStack = Math.max(this.maxStack, maxStack);445 this.maxLocals = Math.max(this.maxLocals, maxLocals);446 mv.visitMaxs(this.maxStack, this.maxLocals);447 }448 }450 // ------------------------------------------------------------------------452 private Object get(final int local){453 maxLocals = Math.max(maxLocals, local);454 return local < locals.size() ? locals.get(local) : Opcodes.TOP;455 }457 private void set(final int local, final Object type){458 maxLocals = Math.max(maxLocals, local);459 while(local >= locals.size())460 {461 locals.add(Opcodes.TOP);462 }463 locals.set(local, type);464 }466 private void push(final Object type){467 stack.add(type);468 maxStack = Math.max(maxStack, stack.size());469 }471 private void pushDesc(final String desc){472 int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;473 switch(desc.charAt(index))474 {475 case'V':476 return;477 case'Z':478 case'C':479 case'B':480 case'S':481 case'I':482 push(Opcodes.INTEGER);483 return;484 case'F':485 push(Opcodes.FLOAT);486 return;487 case'J':488 push(Opcodes.LONG);489 push(Opcodes.TOP);490 return;491 case'D':492 push(Opcodes.DOUBLE);493 push(Opcodes.TOP);494 return;495 case'[':496 if(index == 0)497 {498 push(desc);499 }500 else501 {502 push(desc.substring(index, desc.length()));503 }504 break;505 // case 'L':506 default:507 if(index == 0)508 {509 push(desc.substring(1, desc.length() - 1));510 }511 else512 {513 push(desc.substring(index + 1, desc.length() - 1));514 }515 return;516 }517 }519 private Object pop(){520 return stack.remove(stack.size() - 1);521 }523 private void pop(final int n){524 int size = stack.size();525 int end = size - n;526 for(int i = size - 1; i >= end; --i)527 {528 stack.remove(i);529 }530 }532 private void pop(final String desc){533 char c = desc.charAt(0);534 if(c == '(')535 {536 int n = 0;537 Type[] types = Type.getArgumentTypes(desc);538 for(int i = 0; i < types.length; ++i)539 {540 n += types[i].getSize();541 }542 pop(n);543 }544 else if(c == 'J' || c == 'D')545 {546 pop(2);547 }548 else549 {550 pop(1);551 }552 }554 private void execute(final int opcode, final int iarg, final String sarg){555 if(this.locals == null)556 {557 return;558 }559 Object t1, t2, t3, t4;560 switch(opcode)561 {562 case Opcodes.NOP:563 case Opcodes.INEG:564 case Opcodes.LNEG:565 case Opcodes.FNEG:566 case Opcodes.DNEG:567 case Opcodes.I2B:568 case Opcodes.I2C:569 case Opcodes.I2S:570 case Opcodes.GOTO:571 case Opcodes.RETURN:572 break;573 case Opcodes.ACONST_NULL:574 push(Opcodes.NULL);575 break;576 case Opcodes.ICONST_M1:577 case Opcodes.ICONST_0:578 case Opcodes.ICONST_1:579 case Opcodes.ICONST_2:580 case Opcodes.ICONST_3:581 case Opcodes.ICONST_4:582 case Opcodes.ICONST_5:583 case Opcodes.BIPUSH:584 case Opcodes.SIPUSH:585 push(Opcodes.INTEGER);586 break;587 case Opcodes.LCONST_0:588 case Opcodes.LCONST_1:589 push(Opcodes.LONG);590 push(Opcodes.TOP);591 break;592 case Opcodes.FCONST_0:593 case Opcodes.FCONST_1:594 case Opcodes.FCONST_2:595 push(Opcodes.FLOAT);596 break;597 case Opcodes.DCONST_0:598 case Opcodes.DCONST_1:599 push(Opcodes.DOUBLE);600 push(Opcodes.TOP);601 break;602 case Opcodes.ILOAD:603 case Opcodes.FLOAD:604 case Opcodes.ALOAD:605 push(get(iarg));606 break;607 case Opcodes.LLOAD:608 case Opcodes.DLOAD:609 push(get(iarg));610 push(Opcodes.TOP);611 break;612 case Opcodes.IALOAD:613 case Opcodes.BALOAD:614 case Opcodes.CALOAD:615 case Opcodes.SALOAD:616 pop(2);617 push(Opcodes.INTEGER);618 break;619 case Opcodes.LALOAD:620 case Opcodes.D2L:621 pop(2);622 push(Opcodes.LONG);623 push(Opcodes.TOP);624 break;625 case Opcodes.FALOAD:626 pop(2);627 push(Opcodes.FLOAT);628 break;629 case Opcodes.DALOAD:630 case Opcodes.L2D:631 pop(2);632 push(Opcodes.DOUBLE);633 push(Opcodes.TOP);634 break;635 case Opcodes.AALOAD:636 pop(1);637 t1 = pop();638 pushDesc(((String) t1).substring(1));639 break;640 case Opcodes.ISTORE:641 case Opcodes.FSTORE:642 case Opcodes.ASTORE:643 t1 = pop();644 set(iarg, t1);645 if(iarg > 0)646 {647 t2 = get(iarg - 1);648 if(t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE)649 {650 set(iarg - 1, Opcodes.TOP);651 }652 }653 break;654 case Opcodes.LSTORE:655 case Opcodes.DSTORE:656 pop(1);657 t1 = pop();658 set(iarg, t1);659 set(iarg + 1, Opcodes.TOP);660 if(iarg > 0)661 {662 t2 = get(iarg - 1);663 if(t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE)664 {665 set(iarg - 1, Opcodes.TOP);666 }667 }668 break;669 case Opcodes.IASTORE:670 case Opcodes.BASTORE:671 case Opcodes.CASTORE:672 case Opcodes.SASTORE:673 case Opcodes.FASTORE:674 case Opcodes.AASTORE:675 pop(3);676 break;677 case Opcodes.LASTORE:678 case Opcodes.DASTORE:679 pop(4);680 break;681 case Opcodes.POP:682 case Opcodes.IFEQ:683 case Opcodes.IFNE:684 case Opcodes.IFLT:685 case Opcodes.IFGE:686 case Opcodes.IFGT:687 case Opcodes.IFLE:688 case Opcodes.IRETURN:689 case Opcodes.FRETURN:690 case Opcodes.ARETURN:691 case Opcodes.TABLESWITCH:692 case Opcodes.LOOKUPSWITCH:693 case Opcodes.ATHROW:694 case Opcodes.MONITORENTER:695 case Opcodes.MONITOREXIT:696 case Opcodes.IFNULL:697 case Opcodes.IFNONNULL:698 pop(1);699 break;700 case Opcodes.POP2:701 case Opcodes.IF_ICMPEQ:702 case Opcodes.IF_ICMPNE:703 case Opcodes.IF_ICMPLT:704 case Opcodes.IF_ICMPGE:705 case Opcodes.IF_ICMPGT:706 case Opcodes.IF_ICMPLE:707 case Opcodes.IF_ACMPEQ:708 case Opcodes.IF_ACMPNE:709 case Opcodes.LRETURN:710 case Opcodes.DRETURN:711 pop(2);712 break;713 case Opcodes.DUP:714 t1 = pop();715 push(t1);716 push(t1);717 break;718 case Opcodes.DUP_X1:719 t1 = pop();720 t2 = pop();721 push(t1);722 push(t2);723 push(t1);724 break;725 case Opcodes.DUP_X2:726 t1 = pop();727 t2 = pop();728 t3 = pop();729 push(t1);730 push(t3);731 push(t2);732 push(t1);733 break;734 case Opcodes.DUP2:735 t1 = pop();736 t2 = pop();737 push(t2);738 push(t1);739 push(t2);740 push(t1);741 break;742 case Opcodes.DUP2_X1:743 t1 = pop();744 t2 = pop();745 t3 = pop();746 push(t2);747 push(t1);748 push(t3);749 push(t2);750 push(t1);751 break;752 case Opcodes.DUP2_X2:753 t1 = pop();754 t2 = pop();755 t3 = pop();756 t4 = pop();757 push(t2);758 push(t1);759 push(t4);760 push(t3);761 push(t2);762 push(t1);763 break;764 case Opcodes.SWAP:765 t1 = pop();766 t2 = pop();767 push(t1);768 push(t2);769 break;770 case Opcodes.IADD:771 case Opcodes.ISUB:772 case Opcodes.IMUL:773 case Opcodes.IDIV:774 case Opcodes.IREM:775 case Opcodes.IAND:776 case Opcodes.IOR:777 case Opcodes.IXOR:778 case Opcodes.ISHL:779 case Opcodes.ISHR:780 case Opcodes.IUSHR:781 case Opcodes.L2I:782 case Opcodes.D2I:783 case Opcodes.FCMPL:784 case Opcodes.FCMPG:785 pop(2);786 push(Opcodes.INTEGER);787 break;788 case Opcodes.LADD:789 case Opcodes.LSUB:790 case Opcodes.LMUL:791 case Opcodes.LDIV:792 case Opcodes.LREM:793 case Opcodes.LAND:794 case Opcodes.LOR:795 case Opcodes.LXOR:796 pop(4);797 push(Opcodes.LONG);798 push(Opcodes.TOP);799 break;800 case Opcodes.FADD:801 case Opcodes.FSUB:802 case Opcodes.FMUL:803 case Opcodes.FDIV:804 case Opcodes.FREM:805 case Opcodes.L2F:806 case Opcodes.D2F:807 pop(2);808 push(Opcodes.FLOAT);809 break;810 case Opcodes.DADD:811 case Opcodes.DSUB:812 case Opcodes.DMUL:813 case Opcodes.DDIV:814 case Opcodes.DREM:815 pop(4);816 push(Opcodes.DOUBLE);817 push(Opcodes.TOP);818 break;819 case Opcodes.LSHL:820 case Opcodes.LSHR:821 case Opcodes.LUSHR:822 pop(3);823 push(Opcodes.LONG);824 push(Opcodes.TOP);825 break;826 case Opcodes.IINC:827 set(iarg, Opcodes.INTEGER);828 break;829 case Opcodes.I2L:830 case Opcodes.F2L:831 pop(1);832 push(Opcodes.LONG);833 push(Opcodes.TOP);834 break;835 case Opcodes.I2F:836 pop(1);837 push(Opcodes.FLOAT);838 break;839 case Opcodes.I2D:840 case Opcodes.F2D:841 pop(1);842 push(Opcodes.DOUBLE);843 push(Opcodes.TOP);844 break;845 case Opcodes.F2I:846 case Opcodes.ARRAYLENGTH:847 case Opcodes.INSTANCEOF:848 pop(1);849 push(Opcodes.INTEGER);850 break;851 case Opcodes.LCMP:852 case Opcodes.DCMPL:853 case Opcodes.DCMPG:854 pop(4);855 push(Opcodes.INTEGER);856 break;857 case Opcodes.JSR:858 case Opcodes.RET:859 throw new RuntimeException("JSR/RET are not supported");860 case Opcodes.GETSTATIC:861 pushDesc(sarg);862 break;863 case Opcodes.PUTSTATIC:864 pop(sarg);865 break;866 case Opcodes.GETFIELD:867 pop(1);868 pushDesc(sarg);869 break;870 case Opcodes.PUTFIELD:871 pop(sarg);872 pop();873 break;874 case Opcodes.NEW:875 push(labels.get(0));876 break;877 case Opcodes.NEWARRAY:878 pop();879 switch(iarg)880 {881 case Opcodes.T_BOOLEAN:882 pushDesc("[Z");883 break;884 case Opcodes.T_CHAR:885 pushDesc("[C");886 break;887 case Opcodes.T_BYTE:888 pushDesc("[B");889 break;890 case Opcodes.T_SHORT:891 pushDesc("[S");892 break;893 case Opcodes.T_INT:894 pushDesc("[I");895 break;896 case Opcodes.T_FLOAT:897 pushDesc("[F");898 break;899 case Opcodes.T_DOUBLE:900 pushDesc("[D");901 break;902 // case Opcodes.T_LONG:903 default:904 pushDesc("[J");905 break;906 }907 break;908 case Opcodes.ANEWARRAY:909 pop();910 if(sarg.charAt(0) == '[')911 {912 pushDesc("[" + sarg);913 }914 else915 {916 pushDesc("[L" + sarg + ";");917 }918 break;919 case Opcodes.CHECKCAST:920 pop();921 if(sarg.charAt(0) == '[')922 {923 pushDesc(sarg);924 }925 else926 {927 push(sarg);928 }929 break;930 // case Opcodes.MULTIANEWARRAY:931 default:932 pop(iarg);933 pushDesc(sarg);934 break;935 }936 labels = null;937 }938 }