Mercurial > lasercutter
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/asm/commons/AnalyzerAdapter.java Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,938 @@ 1.4 +/*** 1.5 + * ASM: a very small and fast Java bytecode manipulation framework 1.6 + * Copyright (c) 2000-2005 INRIA, France Telecom 1.7 + * All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions 1.11 + * are met: 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 2. Redistributions in binary form must reproduce the above copyright 1.15 + * notice, this list of conditions and the following disclaimer in the 1.16 + * documentation and/or other materials provided with the distribution. 1.17 + * 3. Neither the name of the copyright holders nor the names of its 1.18 + * contributors may be used to endorse or promote products derived from 1.19 + * this software without specific prior written permission. 1.20 + * 1.21 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.22 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.23 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.24 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.25 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.26 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.27 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.28 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.29 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.30 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1.31 + * THE POSSIBILITY OF SUCH DAMAGE. 1.32 + */ 1.33 +package clojure.asm.commons; 1.34 + 1.35 +import java.util.ArrayList; 1.36 +import java.util.HashMap; 1.37 +import java.util.List; 1.38 +import java.util.Map; 1.39 + 1.40 +import clojure.asm.Label; 1.41 +import clojure.asm.MethodAdapter; 1.42 +import clojure.asm.MethodVisitor; 1.43 +import clojure.asm.Opcodes; 1.44 +import clojure.asm.Type; 1.45 + 1.46 +/** 1.47 + * A {@link MethodAdapter} that keeps track of stack map frame changes between 1.48 + * {@link #visitFrame(int,int,Object[],int,Object[]) visitFrame} calls. This 1.49 + * adapter must be used with the 1.50 + * {@link clojure.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>XXX</i> 1.51 + * instruction delegates to the next visitor in the chain, if any, and then 1.52 + * simulates the effect of this instruction on the stack map frame, represented 1.53 + * by {@link #locals} and {@link #stack}. The next visitor in the chain can get 1.54 + * the state of the stack map frame <i>before</i> each instruction by reading 1.55 + * the value of these fields in its visit<i>XXX</i> methods (this requires a 1.56 + * reference to the AnalyzerAdapter that is before it in the chain). 1.57 + * 1.58 + * @author Eric Bruneton 1.59 + */ 1.60 +public class AnalyzerAdapter extends MethodAdapter{ 1.61 + 1.62 +/** 1.63 + * <code>List</code> of the local variable slots for current execution 1.64 + * frame. Primitive types are represented by {@link Opcodes#TOP}, 1.65 + * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, 1.66 + * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or 1.67 + * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a 1.68 + * two elements, the second one being TOP). Reference types are represented 1.69 + * by String objects (representing internal names, or type descriptors for 1.70 + * array types), and uninitialized types by Label objects (this label 1.71 + * designates the NEW instruction that created this uninitialized value). 1.72 + * This field is <tt>null</tt> for unreacheable instructions. 1.73 + */ 1.74 +public List locals; 1.75 + 1.76 +/** 1.77 + * <code>List</code> of the operand stack slots for current execution 1.78 + * frame. Primitive types are represented by {@link Opcodes#TOP}, 1.79 + * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, 1.80 + * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or 1.81 + * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a 1.82 + * two elements, the second one being TOP). Reference types are represented 1.83 + * by String objects (representing internal names, or type descriptors for 1.84 + * array types), and uninitialized types by Label objects (this label 1.85 + * designates the NEW instruction that created this uninitialized value). 1.86 + * This field is <tt>null</tt> for unreacheable instructions. 1.87 + */ 1.88 +public List stack; 1.89 + 1.90 +/** 1.91 + * The labels that designate the next instruction to be visited. May be 1.92 + * <tt>null</tt>. 1.93 + */ 1.94 +private List labels; 1.95 + 1.96 +/** 1.97 + * Information about uninitialized types in the current execution frame. 1.98 + * This map associates internal names to Label objects. Each label 1.99 + * designates a NEW instruction that created the currently uninitialized 1.100 + * types, and the associated internal name represents the NEW operand, i.e. 1.101 + * the final, initialized type value. 1.102 + */ 1.103 +private Map uninitializedTypes; 1.104 + 1.105 +/** 1.106 + * The maximum stack size of this method. 1.107 + */ 1.108 +private int maxStack; 1.109 + 1.110 +/** 1.111 + * The maximum number of local variables of this method. 1.112 + */ 1.113 +private int maxLocals; 1.114 + 1.115 +/** 1.116 + * Creates a new {@link AnalyzerAdapter}. 1.117 + * 1.118 + * @param owner the owner's class name. 1.119 + * @param access the method's access flags (see {@link Opcodes}). 1.120 + * @param name the method's name. 1.121 + * @param desc the method's descriptor (see {@link Type Type}). 1.122 + * @param mv the method visitor to which this adapter delegates calls. May 1.123 + * be <tt>null</tt>. 1.124 + */ 1.125 +public AnalyzerAdapter( 1.126 + final String owner, 1.127 + final int access, 1.128 + final String name, 1.129 + final String desc, 1.130 + final MethodVisitor mv){ 1.131 + super(mv); 1.132 + locals = new ArrayList(); 1.133 + stack = new ArrayList(); 1.134 + uninitializedTypes = new HashMap(); 1.135 + 1.136 + if((access & Opcodes.ACC_STATIC) == 0) 1.137 + { 1.138 + if(name.equals("<init>")) 1.139 + { 1.140 + locals.add(Opcodes.UNINITIALIZED_THIS); 1.141 + } 1.142 + else 1.143 + { 1.144 + locals.add(owner); 1.145 + } 1.146 + } 1.147 + Type[] types = Type.getArgumentTypes(desc); 1.148 + for(int i = 0; i < types.length; ++i) 1.149 + { 1.150 + Type type = types[i]; 1.151 + switch(type.getSort()) 1.152 + { 1.153 + case Type.BOOLEAN: 1.154 + case Type.CHAR: 1.155 + case Type.BYTE: 1.156 + case Type.SHORT: 1.157 + case Type.INT: 1.158 + locals.add(Opcodes.INTEGER); 1.159 + break; 1.160 + case Type.FLOAT: 1.161 + locals.add(Opcodes.FLOAT); 1.162 + break; 1.163 + case Type.LONG: 1.164 + locals.add(Opcodes.LONG); 1.165 + locals.add(Opcodes.TOP); 1.166 + break; 1.167 + case Type.DOUBLE: 1.168 + locals.add(Opcodes.DOUBLE); 1.169 + locals.add(Opcodes.TOP); 1.170 + break; 1.171 + case Type.ARRAY: 1.172 + locals.add(types[i].getDescriptor()); 1.173 + break; 1.174 + // case Type.OBJECT: 1.175 + default: 1.176 + locals.add(types[i].getInternalName()); 1.177 + } 1.178 + } 1.179 +} 1.180 + 1.181 +public void visitFrame( 1.182 + final int type, 1.183 + final int nLocal, 1.184 + final Object[] local, 1.185 + final int nStack, 1.186 + final Object[] stack){ 1.187 + if(type != Opcodes.F_NEW) 1.188 + { // uncompressed frame 1.189 + throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag"); 1.190 + } 1.191 + 1.192 + if(mv != null) 1.193 + { 1.194 + mv.visitFrame(type, nLocal, local, nStack, stack); 1.195 + } 1.196 + 1.197 + if(this.locals != null) 1.198 + { 1.199 + this.locals.clear(); 1.200 + this.stack.clear(); 1.201 + } 1.202 + else 1.203 + { 1.204 + this.locals = new ArrayList(); 1.205 + this.stack = new ArrayList(); 1.206 + } 1.207 + visitFrameTypes(nLocal, local, this.locals); 1.208 + visitFrameTypes(nStack, stack, this.stack); 1.209 + maxStack = Math.max(maxStack, this.stack.size()); 1.210 +} 1.211 + 1.212 +private void visitFrameTypes( 1.213 + final int n, 1.214 + final Object[] types, 1.215 + final List result){ 1.216 + for(int i = 0; i < n; ++i) 1.217 + { 1.218 + Object type = types[i]; 1.219 + result.add(type); 1.220 + if(type == Opcodes.LONG || type == Opcodes.DOUBLE) 1.221 + { 1.222 + result.add(Opcodes.TOP); 1.223 + } 1.224 + } 1.225 +} 1.226 + 1.227 +public void visitInsn(final int opcode){ 1.228 + if(mv != null) 1.229 + { 1.230 + mv.visitInsn(opcode); 1.231 + } 1.232 + execute(opcode, 0, null); 1.233 + if((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) 1.234 + || opcode == Opcodes.ATHROW) 1.235 + { 1.236 + this.locals = null; 1.237 + this.stack = null; 1.238 + } 1.239 +} 1.240 + 1.241 +public void visitIntInsn(final int opcode, final int operand){ 1.242 + if(mv != null) 1.243 + { 1.244 + mv.visitIntInsn(opcode, operand); 1.245 + } 1.246 + execute(opcode, operand, null); 1.247 +} 1.248 + 1.249 +public void visitVarInsn(final int opcode, final int var){ 1.250 + if(mv != null) 1.251 + { 1.252 + mv.visitVarInsn(opcode, var); 1.253 + } 1.254 + execute(opcode, var, null); 1.255 +} 1.256 + 1.257 +public void visitTypeInsn(final int opcode, final String desc){ 1.258 + if(opcode == Opcodes.NEW) 1.259 + { 1.260 + if(labels == null) 1.261 + { 1.262 + Label l = new Label(); 1.263 + labels = new ArrayList(3); 1.264 + labels.add(l); 1.265 + if(mv != null) 1.266 + { 1.267 + mv.visitLabel(l); 1.268 + } 1.269 + } 1.270 + for(int i = 0; i < labels.size(); ++i) 1.271 + { 1.272 + uninitializedTypes.put(labels.get(i), desc); 1.273 + } 1.274 + } 1.275 + if(mv != null) 1.276 + { 1.277 + mv.visitTypeInsn(opcode, desc); 1.278 + } 1.279 + execute(opcode, 0, desc); 1.280 +} 1.281 + 1.282 +public void visitFieldInsn( 1.283 + final int opcode, 1.284 + final String owner, 1.285 + final String name, 1.286 + final String desc){ 1.287 + if(mv != null) 1.288 + { 1.289 + mv.visitFieldInsn(opcode, owner, name, desc); 1.290 + } 1.291 + execute(opcode, 0, desc); 1.292 +} 1.293 + 1.294 +public void visitMethodInsn( 1.295 + final int opcode, 1.296 + final String owner, 1.297 + final String name, 1.298 + final String desc){ 1.299 + if(mv != null) 1.300 + { 1.301 + mv.visitMethodInsn(opcode, owner, name, desc); 1.302 + } 1.303 + pop(desc); 1.304 + if(opcode != Opcodes.INVOKESTATIC) 1.305 + { 1.306 + Object t = pop(); 1.307 + if(opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') 1.308 + { 1.309 + Object u; 1.310 + if(t == Opcodes.UNINITIALIZED_THIS) 1.311 + { 1.312 + u = owner; 1.313 + } 1.314 + else 1.315 + { 1.316 + u = uninitializedTypes.get(t); 1.317 + } 1.318 + for(int i = 0; i < locals.size(); ++i) 1.319 + { 1.320 + if(locals.get(i) == t) 1.321 + { 1.322 + locals.set(i, u); 1.323 + } 1.324 + } 1.325 + for(int i = 0; i < stack.size(); ++i) 1.326 + { 1.327 + if(stack.get(i) == t) 1.328 + { 1.329 + stack.set(i, u); 1.330 + } 1.331 + } 1.332 + } 1.333 + } 1.334 + pushDesc(desc); 1.335 + labels = null; 1.336 +} 1.337 + 1.338 +public void visitJumpInsn(final int opcode, final Label label){ 1.339 + if(mv != null) 1.340 + { 1.341 + mv.visitJumpInsn(opcode, label); 1.342 + } 1.343 + execute(opcode, 0, null); 1.344 + if(opcode == Opcodes.GOTO) 1.345 + { 1.346 + this.locals = null; 1.347 + this.stack = null; 1.348 + } 1.349 +} 1.350 + 1.351 +public void visitLabel(final Label label){ 1.352 + if(mv != null) 1.353 + { 1.354 + mv.visitLabel(label); 1.355 + } 1.356 + if(labels == null) 1.357 + { 1.358 + labels = new ArrayList(3); 1.359 + } 1.360 + labels.add(label); 1.361 +} 1.362 + 1.363 +public void visitLdcInsn(final Object cst){ 1.364 + if(mv != null) 1.365 + { 1.366 + mv.visitLdcInsn(cst); 1.367 + } 1.368 + if(cst instanceof Integer) 1.369 + { 1.370 + push(Opcodes.INTEGER); 1.371 + } 1.372 + else if(cst instanceof Long) 1.373 + { 1.374 + push(Opcodes.LONG); 1.375 + push(Opcodes.TOP); 1.376 + } 1.377 + else if(cst instanceof Float) 1.378 + { 1.379 + push(Opcodes.FLOAT); 1.380 + } 1.381 + else if(cst instanceof Double) 1.382 + { 1.383 + push(Opcodes.DOUBLE); 1.384 + push(Opcodes.TOP); 1.385 + } 1.386 + else if(cst instanceof String) 1.387 + { 1.388 + push("java/lang/String"); 1.389 + } 1.390 + else if(cst instanceof Type) 1.391 + { 1.392 + push("java/lang/Class"); 1.393 + } 1.394 + else 1.395 + { 1.396 + throw new IllegalArgumentException(); 1.397 + } 1.398 + labels = null; 1.399 +} 1.400 + 1.401 +public void visitIincInsn(final int var, final int increment){ 1.402 + if(mv != null) 1.403 + { 1.404 + mv.visitIincInsn(var, increment); 1.405 + } 1.406 + execute(Opcodes.IINC, var, null); 1.407 +} 1.408 + 1.409 +public void visitTableSwitchInsn( 1.410 + final int min, 1.411 + final int max, 1.412 + final Label dflt, 1.413 + final Label labels[]){ 1.414 + if(mv != null) 1.415 + { 1.416 + mv.visitTableSwitchInsn(min, max, dflt, labels); 1.417 + } 1.418 + execute(Opcodes.TABLESWITCH, 0, null); 1.419 + this.locals = null; 1.420 + this.stack = null; 1.421 +} 1.422 + 1.423 +public void visitLookupSwitchInsn( 1.424 + final Label dflt, 1.425 + final int keys[], 1.426 + final Label labels[]){ 1.427 + if(mv != null) 1.428 + { 1.429 + mv.visitLookupSwitchInsn(dflt, keys, labels); 1.430 + } 1.431 + execute(Opcodes.LOOKUPSWITCH, 0, null); 1.432 + this.locals = null; 1.433 + this.stack = null; 1.434 +} 1.435 + 1.436 +public void visitMultiANewArrayInsn(final String desc, final int dims){ 1.437 + if(mv != null) 1.438 + { 1.439 + mv.visitMultiANewArrayInsn(desc, dims); 1.440 + } 1.441 + execute(Opcodes.MULTIANEWARRAY, dims, desc); 1.442 +} 1.443 + 1.444 +public void visitMaxs(final int maxStack, final int maxLocals){ 1.445 + if(mv != null) 1.446 + { 1.447 + this.maxStack = Math.max(this.maxStack, maxStack); 1.448 + this.maxLocals = Math.max(this.maxLocals, maxLocals); 1.449 + mv.visitMaxs(this.maxStack, this.maxLocals); 1.450 + } 1.451 +} 1.452 + 1.453 +// ------------------------------------------------------------------------ 1.454 + 1.455 +private Object get(final int local){ 1.456 + maxLocals = Math.max(maxLocals, local); 1.457 + return local < locals.size() ? locals.get(local) : Opcodes.TOP; 1.458 +} 1.459 + 1.460 +private void set(final int local, final Object type){ 1.461 + maxLocals = Math.max(maxLocals, local); 1.462 + while(local >= locals.size()) 1.463 + { 1.464 + locals.add(Opcodes.TOP); 1.465 + } 1.466 + locals.set(local, type); 1.467 +} 1.468 + 1.469 +private void push(final Object type){ 1.470 + stack.add(type); 1.471 + maxStack = Math.max(maxStack, stack.size()); 1.472 +} 1.473 + 1.474 +private void pushDesc(final String desc){ 1.475 + int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; 1.476 + switch(desc.charAt(index)) 1.477 + { 1.478 + case'V': 1.479 + return; 1.480 + case'Z': 1.481 + case'C': 1.482 + case'B': 1.483 + case'S': 1.484 + case'I': 1.485 + push(Opcodes.INTEGER); 1.486 + return; 1.487 + case'F': 1.488 + push(Opcodes.FLOAT); 1.489 + return; 1.490 + case'J': 1.491 + push(Opcodes.LONG); 1.492 + push(Opcodes.TOP); 1.493 + return; 1.494 + case'D': 1.495 + push(Opcodes.DOUBLE); 1.496 + push(Opcodes.TOP); 1.497 + return; 1.498 + case'[': 1.499 + if(index == 0) 1.500 + { 1.501 + push(desc); 1.502 + } 1.503 + else 1.504 + { 1.505 + push(desc.substring(index, desc.length())); 1.506 + } 1.507 + break; 1.508 + // case 'L': 1.509 + default: 1.510 + if(index == 0) 1.511 + { 1.512 + push(desc.substring(1, desc.length() - 1)); 1.513 + } 1.514 + else 1.515 + { 1.516 + push(desc.substring(index + 1, desc.length() - 1)); 1.517 + } 1.518 + return; 1.519 + } 1.520 +} 1.521 + 1.522 +private Object pop(){ 1.523 + return stack.remove(stack.size() - 1); 1.524 +} 1.525 + 1.526 +private void pop(final int n){ 1.527 + int size = stack.size(); 1.528 + int end = size - n; 1.529 + for(int i = size - 1; i >= end; --i) 1.530 + { 1.531 + stack.remove(i); 1.532 + } 1.533 +} 1.534 + 1.535 +private void pop(final String desc){ 1.536 + char c = desc.charAt(0); 1.537 + if(c == '(') 1.538 + { 1.539 + int n = 0; 1.540 + Type[] types = Type.getArgumentTypes(desc); 1.541 + for(int i = 0; i < types.length; ++i) 1.542 + { 1.543 + n += types[i].getSize(); 1.544 + } 1.545 + pop(n); 1.546 + } 1.547 + else if(c == 'J' || c == 'D') 1.548 + { 1.549 + pop(2); 1.550 + } 1.551 + else 1.552 + { 1.553 + pop(1); 1.554 + } 1.555 +} 1.556 + 1.557 +private void execute(final int opcode, final int iarg, final String sarg){ 1.558 + if(this.locals == null) 1.559 + { 1.560 + return; 1.561 + } 1.562 + Object t1, t2, t3, t4; 1.563 + switch(opcode) 1.564 + { 1.565 + case Opcodes.NOP: 1.566 + case Opcodes.INEG: 1.567 + case Opcodes.LNEG: 1.568 + case Opcodes.FNEG: 1.569 + case Opcodes.DNEG: 1.570 + case Opcodes.I2B: 1.571 + case Opcodes.I2C: 1.572 + case Opcodes.I2S: 1.573 + case Opcodes.GOTO: 1.574 + case Opcodes.RETURN: 1.575 + break; 1.576 + case Opcodes.ACONST_NULL: 1.577 + push(Opcodes.NULL); 1.578 + break; 1.579 + case Opcodes.ICONST_M1: 1.580 + case Opcodes.ICONST_0: 1.581 + case Opcodes.ICONST_1: 1.582 + case Opcodes.ICONST_2: 1.583 + case Opcodes.ICONST_3: 1.584 + case Opcodes.ICONST_4: 1.585 + case Opcodes.ICONST_5: 1.586 + case Opcodes.BIPUSH: 1.587 + case Opcodes.SIPUSH: 1.588 + push(Opcodes.INTEGER); 1.589 + break; 1.590 + case Opcodes.LCONST_0: 1.591 + case Opcodes.LCONST_1: 1.592 + push(Opcodes.LONG); 1.593 + push(Opcodes.TOP); 1.594 + break; 1.595 + case Opcodes.FCONST_0: 1.596 + case Opcodes.FCONST_1: 1.597 + case Opcodes.FCONST_2: 1.598 + push(Opcodes.FLOAT); 1.599 + break; 1.600 + case Opcodes.DCONST_0: 1.601 + case Opcodes.DCONST_1: 1.602 + push(Opcodes.DOUBLE); 1.603 + push(Opcodes.TOP); 1.604 + break; 1.605 + case Opcodes.ILOAD: 1.606 + case Opcodes.FLOAD: 1.607 + case Opcodes.ALOAD: 1.608 + push(get(iarg)); 1.609 + break; 1.610 + case Opcodes.LLOAD: 1.611 + case Opcodes.DLOAD: 1.612 + push(get(iarg)); 1.613 + push(Opcodes.TOP); 1.614 + break; 1.615 + case Opcodes.IALOAD: 1.616 + case Opcodes.BALOAD: 1.617 + case Opcodes.CALOAD: 1.618 + case Opcodes.SALOAD: 1.619 + pop(2); 1.620 + push(Opcodes.INTEGER); 1.621 + break; 1.622 + case Opcodes.LALOAD: 1.623 + case Opcodes.D2L: 1.624 + pop(2); 1.625 + push(Opcodes.LONG); 1.626 + push(Opcodes.TOP); 1.627 + break; 1.628 + case Opcodes.FALOAD: 1.629 + pop(2); 1.630 + push(Opcodes.FLOAT); 1.631 + break; 1.632 + case Opcodes.DALOAD: 1.633 + case Opcodes.L2D: 1.634 + pop(2); 1.635 + push(Opcodes.DOUBLE); 1.636 + push(Opcodes.TOP); 1.637 + break; 1.638 + case Opcodes.AALOAD: 1.639 + pop(1); 1.640 + t1 = pop(); 1.641 + pushDesc(((String) t1).substring(1)); 1.642 + break; 1.643 + case Opcodes.ISTORE: 1.644 + case Opcodes.FSTORE: 1.645 + case Opcodes.ASTORE: 1.646 + t1 = pop(); 1.647 + set(iarg, t1); 1.648 + if(iarg > 0) 1.649 + { 1.650 + t2 = get(iarg - 1); 1.651 + if(t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) 1.652 + { 1.653 + set(iarg - 1, Opcodes.TOP); 1.654 + } 1.655 + } 1.656 + break; 1.657 + case Opcodes.LSTORE: 1.658 + case Opcodes.DSTORE: 1.659 + pop(1); 1.660 + t1 = pop(); 1.661 + set(iarg, t1); 1.662 + set(iarg + 1, Opcodes.TOP); 1.663 + if(iarg > 0) 1.664 + { 1.665 + t2 = get(iarg - 1); 1.666 + if(t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) 1.667 + { 1.668 + set(iarg - 1, Opcodes.TOP); 1.669 + } 1.670 + } 1.671 + break; 1.672 + case Opcodes.IASTORE: 1.673 + case Opcodes.BASTORE: 1.674 + case Opcodes.CASTORE: 1.675 + case Opcodes.SASTORE: 1.676 + case Opcodes.FASTORE: 1.677 + case Opcodes.AASTORE: 1.678 + pop(3); 1.679 + break; 1.680 + case Opcodes.LASTORE: 1.681 + case Opcodes.DASTORE: 1.682 + pop(4); 1.683 + break; 1.684 + case Opcodes.POP: 1.685 + case Opcodes.IFEQ: 1.686 + case Opcodes.IFNE: 1.687 + case Opcodes.IFLT: 1.688 + case Opcodes.IFGE: 1.689 + case Opcodes.IFGT: 1.690 + case Opcodes.IFLE: 1.691 + case Opcodes.IRETURN: 1.692 + case Opcodes.FRETURN: 1.693 + case Opcodes.ARETURN: 1.694 + case Opcodes.TABLESWITCH: 1.695 + case Opcodes.LOOKUPSWITCH: 1.696 + case Opcodes.ATHROW: 1.697 + case Opcodes.MONITORENTER: 1.698 + case Opcodes.MONITOREXIT: 1.699 + case Opcodes.IFNULL: 1.700 + case Opcodes.IFNONNULL: 1.701 + pop(1); 1.702 + break; 1.703 + case Opcodes.POP2: 1.704 + case Opcodes.IF_ICMPEQ: 1.705 + case Opcodes.IF_ICMPNE: 1.706 + case Opcodes.IF_ICMPLT: 1.707 + case Opcodes.IF_ICMPGE: 1.708 + case Opcodes.IF_ICMPGT: 1.709 + case Opcodes.IF_ICMPLE: 1.710 + case Opcodes.IF_ACMPEQ: 1.711 + case Opcodes.IF_ACMPNE: 1.712 + case Opcodes.LRETURN: 1.713 + case Opcodes.DRETURN: 1.714 + pop(2); 1.715 + break; 1.716 + case Opcodes.DUP: 1.717 + t1 = pop(); 1.718 + push(t1); 1.719 + push(t1); 1.720 + break; 1.721 + case Opcodes.DUP_X1: 1.722 + t1 = pop(); 1.723 + t2 = pop(); 1.724 + push(t1); 1.725 + push(t2); 1.726 + push(t1); 1.727 + break; 1.728 + case Opcodes.DUP_X2: 1.729 + t1 = pop(); 1.730 + t2 = pop(); 1.731 + t3 = pop(); 1.732 + push(t1); 1.733 + push(t3); 1.734 + push(t2); 1.735 + push(t1); 1.736 + break; 1.737 + case Opcodes.DUP2: 1.738 + t1 = pop(); 1.739 + t2 = pop(); 1.740 + push(t2); 1.741 + push(t1); 1.742 + push(t2); 1.743 + push(t1); 1.744 + break; 1.745 + case Opcodes.DUP2_X1: 1.746 + t1 = pop(); 1.747 + t2 = pop(); 1.748 + t3 = pop(); 1.749 + push(t2); 1.750 + push(t1); 1.751 + push(t3); 1.752 + push(t2); 1.753 + push(t1); 1.754 + break; 1.755 + case Opcodes.DUP2_X2: 1.756 + t1 = pop(); 1.757 + t2 = pop(); 1.758 + t3 = pop(); 1.759 + t4 = pop(); 1.760 + push(t2); 1.761 + push(t1); 1.762 + push(t4); 1.763 + push(t3); 1.764 + push(t2); 1.765 + push(t1); 1.766 + break; 1.767 + case Opcodes.SWAP: 1.768 + t1 = pop(); 1.769 + t2 = pop(); 1.770 + push(t1); 1.771 + push(t2); 1.772 + break; 1.773 + case Opcodes.IADD: 1.774 + case Opcodes.ISUB: 1.775 + case Opcodes.IMUL: 1.776 + case Opcodes.IDIV: 1.777 + case Opcodes.IREM: 1.778 + case Opcodes.IAND: 1.779 + case Opcodes.IOR: 1.780 + case Opcodes.IXOR: 1.781 + case Opcodes.ISHL: 1.782 + case Opcodes.ISHR: 1.783 + case Opcodes.IUSHR: 1.784 + case Opcodes.L2I: 1.785 + case Opcodes.D2I: 1.786 + case Opcodes.FCMPL: 1.787 + case Opcodes.FCMPG: 1.788 + pop(2); 1.789 + push(Opcodes.INTEGER); 1.790 + break; 1.791 + case Opcodes.LADD: 1.792 + case Opcodes.LSUB: 1.793 + case Opcodes.LMUL: 1.794 + case Opcodes.LDIV: 1.795 + case Opcodes.LREM: 1.796 + case Opcodes.LAND: 1.797 + case Opcodes.LOR: 1.798 + case Opcodes.LXOR: 1.799 + pop(4); 1.800 + push(Opcodes.LONG); 1.801 + push(Opcodes.TOP); 1.802 + break; 1.803 + case Opcodes.FADD: 1.804 + case Opcodes.FSUB: 1.805 + case Opcodes.FMUL: 1.806 + case Opcodes.FDIV: 1.807 + case Opcodes.FREM: 1.808 + case Opcodes.L2F: 1.809 + case Opcodes.D2F: 1.810 + pop(2); 1.811 + push(Opcodes.FLOAT); 1.812 + break; 1.813 + case Opcodes.DADD: 1.814 + case Opcodes.DSUB: 1.815 + case Opcodes.DMUL: 1.816 + case Opcodes.DDIV: 1.817 + case Opcodes.DREM: 1.818 + pop(4); 1.819 + push(Opcodes.DOUBLE); 1.820 + push(Opcodes.TOP); 1.821 + break; 1.822 + case Opcodes.LSHL: 1.823 + case Opcodes.LSHR: 1.824 + case Opcodes.LUSHR: 1.825 + pop(3); 1.826 + push(Opcodes.LONG); 1.827 + push(Opcodes.TOP); 1.828 + break; 1.829 + case Opcodes.IINC: 1.830 + set(iarg, Opcodes.INTEGER); 1.831 + break; 1.832 + case Opcodes.I2L: 1.833 + case Opcodes.F2L: 1.834 + pop(1); 1.835 + push(Opcodes.LONG); 1.836 + push(Opcodes.TOP); 1.837 + break; 1.838 + case Opcodes.I2F: 1.839 + pop(1); 1.840 + push(Opcodes.FLOAT); 1.841 + break; 1.842 + case Opcodes.I2D: 1.843 + case Opcodes.F2D: 1.844 + pop(1); 1.845 + push(Opcodes.DOUBLE); 1.846 + push(Opcodes.TOP); 1.847 + break; 1.848 + case Opcodes.F2I: 1.849 + case Opcodes.ARRAYLENGTH: 1.850 + case Opcodes.INSTANCEOF: 1.851 + pop(1); 1.852 + push(Opcodes.INTEGER); 1.853 + break; 1.854 + case Opcodes.LCMP: 1.855 + case Opcodes.DCMPL: 1.856 + case Opcodes.DCMPG: 1.857 + pop(4); 1.858 + push(Opcodes.INTEGER); 1.859 + break; 1.860 + case Opcodes.JSR: 1.861 + case Opcodes.RET: 1.862 + throw new RuntimeException("JSR/RET are not supported"); 1.863 + case Opcodes.GETSTATIC: 1.864 + pushDesc(sarg); 1.865 + break; 1.866 + case Opcodes.PUTSTATIC: 1.867 + pop(sarg); 1.868 + break; 1.869 + case Opcodes.GETFIELD: 1.870 + pop(1); 1.871 + pushDesc(sarg); 1.872 + break; 1.873 + case Opcodes.PUTFIELD: 1.874 + pop(sarg); 1.875 + pop(); 1.876 + break; 1.877 + case Opcodes.NEW: 1.878 + push(labels.get(0)); 1.879 + break; 1.880 + case Opcodes.NEWARRAY: 1.881 + pop(); 1.882 + switch(iarg) 1.883 + { 1.884 + case Opcodes.T_BOOLEAN: 1.885 + pushDesc("[Z"); 1.886 + break; 1.887 + case Opcodes.T_CHAR: 1.888 + pushDesc("[C"); 1.889 + break; 1.890 + case Opcodes.T_BYTE: 1.891 + pushDesc("[B"); 1.892 + break; 1.893 + case Opcodes.T_SHORT: 1.894 + pushDesc("[S"); 1.895 + break; 1.896 + case Opcodes.T_INT: 1.897 + pushDesc("[I"); 1.898 + break; 1.899 + case Opcodes.T_FLOAT: 1.900 + pushDesc("[F"); 1.901 + break; 1.902 + case Opcodes.T_DOUBLE: 1.903 + pushDesc("[D"); 1.904 + break; 1.905 + // case Opcodes.T_LONG: 1.906 + default: 1.907 + pushDesc("[J"); 1.908 + break; 1.909 + } 1.910 + break; 1.911 + case Opcodes.ANEWARRAY: 1.912 + pop(); 1.913 + if(sarg.charAt(0) == '[') 1.914 + { 1.915 + pushDesc("[" + sarg); 1.916 + } 1.917 + else 1.918 + { 1.919 + pushDesc("[L" + sarg + ";"); 1.920 + } 1.921 + break; 1.922 + case Opcodes.CHECKCAST: 1.923 + pop(); 1.924 + if(sarg.charAt(0) == '[') 1.925 + { 1.926 + pushDesc(sarg); 1.927 + } 1.928 + else 1.929 + { 1.930 + push(sarg); 1.931 + } 1.932 + break; 1.933 + // case Opcodes.MULTIANEWARRAY: 1.934 + default: 1.935 + pop(iarg); 1.936 + pushDesc(sarg); 1.937 + break; 1.938 + } 1.939 + labels = null; 1.940 +} 1.941 +}