1.1 --- a/javap/src/main/java/org/apidesign/javap/MethodData.java Fri Dec 07 19:16:21 2012 +0100
1.2 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java Wed Dec 12 11:04:02 2012 +0100
1.3 @@ -318,7 +318,7 @@
1.4 }
1.5
1.6 public StackMapIterator createStackMapIterator() {
1.7 - return new StackMapIterator(stackMapTable);
1.8 + return new StackMapIterator(this);
1.9 }
1.10
1.11 /**
2.1 --- a/javap/src/main/java/org/apidesign/javap/StackMapIterator.java Fri Dec 07 19:16:21 2012 +0100
2.2 +++ b/javap/src/main/java/org/apidesign/javap/StackMapIterator.java Wed Dec 12 11:04:02 2012 +0100
2.3 @@ -25,23 +25,15 @@
2.4
2.5 package org.apidesign.javap;
2.6
2.7 +import static org.apidesign.javap.RuntimeConstants.ITEM_Integer;
2.8 +import static org.apidesign.javap.RuntimeConstants.ITEM_Float;
2.9 +import static org.apidesign.javap.RuntimeConstants.ITEM_Double;
2.10 +import static org.apidesign.javap.RuntimeConstants.ITEM_Long;
2.11 +import static org.apidesign.javap.RuntimeConstants.ITEM_Object;
2.12 +
2.13 public final class StackMapIterator {
2.14 - private static final StackMapTableData INITIAL_FRAME =
2.15 - new StackMapTableData(-1) {
2.16 - @Override
2.17 - void applyTo(TypeArray localTypes, TypeArray stackTypes) {
2.18 - localTypes.clear();
2.19 - stackTypes.clear();
2.20 - }
2.21 -
2.22 - @Override
2.23 - public String toString() {
2.24 - return toString("INITIAL", 0, null, null);
2.25 - }
2.26 -
2.27 - };
2.28 -
2.29 private final StackMapTableData[] stackMapTable;
2.30 + private final TypeArray argTypes;
2.31 private final TypeArray localTypes;
2.32 private final TypeArray stackTypes;
2.33
2.34 @@ -50,19 +42,33 @@
2.35
2.36 private int byteCodeOffset;
2.37
2.38 - StackMapIterator(final StackMapTableData[] stackMapTable) {
2.39 + StackMapIterator(final MethodData methodData) {
2.40 + this(methodData.getStackMapTable(),
2.41 + methodData.getInternalSig(),
2.42 + methodData.isStatic());
2.43 + }
2.44 +
2.45 + StackMapIterator(final StackMapTableData[] stackMapTable,
2.46 + final String methodSignature,
2.47 + final boolean isStaticMethod) {
2.48 this.stackMapTable = (stackMapTable != null)
2.49 ? stackMapTable
2.50 : new StackMapTableData[0];
2.51
2.52 + argTypes = getArgTypes(methodSignature, isStaticMethod);
2.53 localTypes = new TypeArray();
2.54 stackTypes = new TypeArray();
2.55 +
2.56 + localTypes.addAll(argTypes);
2.57 +
2.58 lastFrameByteCodeOffset = -1;
2.59 advanceBy(0);
2.60 }
2.61
2.62 public String getFrameAsString() {
2.63 - return getCurrentFrame().toString();
2.64 + return (nextFrameIndex == 0)
2.65 + ? StackMapTableData.toString("INITIAL", 0, null, null)
2.66 + : stackMapTable[nextFrameIndex - 1].toString();
2.67 }
2.68
2.69 public int getFrameIndex() {
2.70 @@ -73,6 +79,14 @@
2.71 return stackTypes;
2.72 }
2.73
2.74 + public TypeArray getFrameLocals() {
2.75 + return localTypes;
2.76 + }
2.77 +
2.78 + public TypeArray getArguments() {
2.79 + return argTypes;
2.80 + }
2.81 +
2.82 public void advanceBy(final int numByteCodes) {
2.83 if (numByteCodes < 0) {
2.84 throw new IllegalStateException("Forward only iterator");
2.85 @@ -96,9 +110,70 @@
2.86 advanceBy(nextByteCodeOffset - byteCodeOffset);
2.87 }
2.88
2.89 - private StackMapTableData getCurrentFrame() {
2.90 - return (nextFrameIndex == 0)
2.91 - ? INITIAL_FRAME
2.92 - : stackMapTable[nextFrameIndex - 1];
2.93 + private static TypeArray getArgTypes(final String methodSignature,
2.94 + final boolean isStaticMethod) {
2.95 + final TypeArray argTypes = new TypeArray();
2.96 +
2.97 + if (!isStaticMethod) {
2.98 + argTypes.add(ITEM_Object);
2.99 + }
2.100 +
2.101 + if (methodSignature.charAt(0) != '(') {
2.102 + throw new IllegalArgumentException("Invalid method signature");
2.103 + }
2.104 +
2.105 + final int length = methodSignature.length();
2.106 + int skipType = 0;
2.107 + int argType;
2.108 + for (int i = 1; i < length; ++i) {
2.109 + switch (methodSignature.charAt(i)) {
2.110 + case 'B':
2.111 + case 'C':
2.112 + case 'S':
2.113 + case 'Z':
2.114 + case 'I':
2.115 + argType = ITEM_Integer;
2.116 + break;
2.117 + case 'J':
2.118 + argType = ITEM_Long;
2.119 + break;
2.120 + case 'F':
2.121 + argType = ITEM_Float;
2.122 + break;
2.123 + case 'D':
2.124 + argType = ITEM_Double;
2.125 + break;
2.126 + case 'L': {
2.127 + i = methodSignature.indexOf(';', i + 1);
2.128 + if (i == -1) {
2.129 + throw new IllegalArgumentException(
2.130 + "Invalid method signature");
2.131 + }
2.132 + argType = ITEM_Object;
2.133 + break;
2.134 + }
2.135 + case ')':
2.136 + // not interested in the return value type
2.137 + return argTypes;
2.138 + case '[':
2.139 + if (skipType == 0) {
2.140 + argTypes.add(ITEM_Object);
2.141 + }
2.142 + ++skipType;
2.143 + continue;
2.144 +
2.145 + default:
2.146 + throw new IllegalArgumentException(
2.147 + "Invalid method signature");
2.148 + }
2.149 +
2.150 + if (skipType == 0) {
2.151 + argTypes.add(argType);
2.152 + } else {
2.153 + --skipType;
2.154 + }
2.155 + }
2.156 +
2.157 + return argTypes;
2.158 }
2.159 }
3.1 --- a/javap/src/main/java/org/apidesign/javap/StackMapTableData.java Fri Dec 07 19:16:21 2012 +0100
3.2 +++ b/javap/src/main/java/org/apidesign/javap/StackMapTableData.java Wed Dec 12 11:04:02 2012 +0100
3.3 @@ -66,50 +66,15 @@
3.4 private static void appendTypes(final StringBuilder sb, final int[] types) {
3.5 sb.append('[');
3.6 if (types.length > 0) {
3.7 - appendType(sb, types[0]);
3.8 + sb.append(TypeArray.typeString(types[0]));
3.9 for (int i = 1; i < types.length; ++i) {
3.10 sb.append(", ");
3.11 - appendType(sb, types[i]);
3.12 + sb.append(TypeArray.typeString(types[i]));
3.13 }
3.14 }
3.15 sb.append(']');
3.16 }
3.17
3.18 - private static void appendType(final StringBuilder sb, final int type) {
3.19 - switch (type & 0xff) {
3.20 - case ITEM_Bogus:
3.21 - sb.append("_top_");
3.22 - break;
3.23 - case ITEM_Integer:
3.24 - sb.append("_int_");
3.25 - break;
3.26 - case ITEM_Float:
3.27 - sb.append("_float_");
3.28 - break;
3.29 - case ITEM_Double:
3.30 - sb.append("_double_");
3.31 - break;
3.32 - case ITEM_Long:
3.33 - sb.append("_long_");
3.34 - break;
3.35 - case ITEM_Null:
3.36 - sb.append("_null_");
3.37 - break;
3.38 - case ITEM_InitObject: // UninitializedThis
3.39 - sb.append("_init_");
3.40 - break;
3.41 - case ITEM_Object:
3.42 - sb.append("_object_");
3.43 - break;
3.44 - case ITEM_NewObject: // Uninitialized
3.45 - sb.append("_new_");
3.46 - break;
3.47 - default:
3.48 - sb.append("_unknown_");
3.49 - break;
3.50 - }
3.51 - }
3.52 -
3.53 static class SameFrame extends StackMapTableData {
3.54 SameFrame(int frameType, int offsetDelta) {
3.55 super(frameType);
4.1 --- a/javap/src/main/java/org/apidesign/javap/TypeArray.java Fri Dec 07 19:16:21 2012 +0100
4.2 +++ b/javap/src/main/java/org/apidesign/javap/TypeArray.java Wed Dec 12 11:04:02 2012 +0100
4.3 @@ -25,38 +25,85 @@
4.4
4.5 package org.apidesign.javap;
4.6
4.7 -public class TypeArray {
4.8 +import static org.apidesign.javap.RuntimeConstants.ITEM_Bogus;
4.9 +import static org.apidesign.javap.RuntimeConstants.ITEM_Integer;
4.10 +import static org.apidesign.javap.RuntimeConstants.ITEM_Float;
4.11 +import static org.apidesign.javap.RuntimeConstants.ITEM_Double;
4.12 +import static org.apidesign.javap.RuntimeConstants.ITEM_Long;
4.13 +import static org.apidesign.javap.RuntimeConstants.ITEM_Null;
4.14 +import static org.apidesign.javap.RuntimeConstants.ITEM_InitObject;
4.15 +import static org.apidesign.javap.RuntimeConstants.ITEM_Object;
4.16 +import static org.apidesign.javap.RuntimeConstants.ITEM_NewObject;
4.17 +
4.18 +public final class TypeArray {
4.19 private static final int CAPACITY_INCREMENT = 16;
4.20
4.21 private int[] types;
4.22 private int size;
4.23
4.24 + public TypeArray() {
4.25 + }
4.26 +
4.27 + public TypeArray(final TypeArray initialTypes) {
4.28 + setAll(initialTypes);
4.29 + }
4.30 +
4.31 public void add(final int newType) {
4.32 ensureCapacity(size + 1);
4.33 types[size++] = newType;
4.34 }
4.35
4.36 + public void addAll(final TypeArray newTypes) {
4.37 + addAll(newTypes.types, 0, newTypes.size);
4.38 + }
4.39 +
4.40 public void addAll(final int[] newTypes) {
4.41 - if (newTypes.length > 0) {
4.42 - ensureCapacity(size + newTypes.length);
4.43 - arraycopy(newTypes, 0, types, size, newTypes.length);
4.44 - size += newTypes.length;
4.45 + addAll(newTypes, 0, newTypes.length);
4.46 + }
4.47 +
4.48 + public void addAll(final int[] newTypes,
4.49 + final int offset,
4.50 + final int count) {
4.51 + if (count > 0) {
4.52 + ensureCapacity(size + count);
4.53 + arraycopy(newTypes, offset, types, size, count);
4.54 + size += count;
4.55 }
4.56 }
4.57
4.58 + public void set(final int index, final int newType) {
4.59 + types[index] = newType;
4.60 + }
4.61 +
4.62 + public void setAll(final TypeArray newTypes) {
4.63 + setAll(newTypes.types, 0, newTypes.size);
4.64 + }
4.65 +
4.66 public void setAll(final int[] newTypes) {
4.67 - if (newTypes.length > 0) {
4.68 - ensureCapacity(newTypes.length);
4.69 - arraycopy(newTypes, 0, types, 0, newTypes.length);
4.70 - size = newTypes.length;
4.71 + setAll(newTypes, 0, newTypes.length);
4.72 + }
4.73 +
4.74 + public void setAll(final int[] newTypes,
4.75 + final int offset,
4.76 + final int count) {
4.77 + if (count > 0) {
4.78 + ensureCapacity(count);
4.79 + arraycopy(newTypes, offset, types, 0, count);
4.80 + size = count;
4.81 } else {
4.82 clear();
4.83 }
4.84 }
4.85
4.86 public void setSize(final int newSize) {
4.87 - ensureCapacity(newSize);
4.88 - size = newSize;
4.89 + if (size != newSize) {
4.90 + ensureCapacity(newSize);
4.91 +
4.92 + for (int i = size; i < newSize; ++i) {
4.93 + types[i] = 0;
4.94 + }
4.95 + size = newSize;
4.96 + }
4.97 }
4.98
4.99 public void clear() {
4.100 @@ -71,6 +118,45 @@
4.101 return types[index];
4.102 }
4.103
4.104 + public static String typeString(final int type) {
4.105 + switch (type & 0xff) {
4.106 + case ITEM_Bogus:
4.107 + return "_top_";
4.108 + case ITEM_Integer:
4.109 + return "_int_";
4.110 + case ITEM_Float:
4.111 + return "_float_";
4.112 + case ITEM_Double:
4.113 + return "_double_";
4.114 + case ITEM_Long:
4.115 + return "_long_";
4.116 + case ITEM_Null:
4.117 + return "_null_";
4.118 + case ITEM_InitObject: // UninitializedThis
4.119 + return "_init_";
4.120 + case ITEM_Object:
4.121 + return "_object_";
4.122 + case ITEM_NewObject: // Uninitialized
4.123 + return "_new_";
4.124 + default:
4.125 + throw new IllegalArgumentException("Unknown type");
4.126 + }
4.127 + }
4.128 +
4.129 + @Override
4.130 + public String toString() {
4.131 + final StringBuilder sb = new StringBuilder("[");
4.132 + if (size > 0) {
4.133 + sb.append(typeString(types[0]));
4.134 + for (int i = 1; i < size; ++i) {
4.135 + sb.append(", ");
4.136 + sb.append(typeString(types[i]));
4.137 + }
4.138 + }
4.139 +
4.140 + return sb.append(']').toString();
4.141 + }
4.142 +
4.143 private void ensureCapacity(final int minCapacity) {
4.144 if ((minCapacity == 0)
4.145 || (types != null) && (minCapacity <= types.length)) {
5.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Dec 07 19:16:21 2012 +0100
5.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Dec 12 11:04:02 2012 +0100
5.3 @@ -188,85 +188,63 @@
5.4 if (jsb != null) {
5.5 return jsb;
5.6 }
5.7 - StringBuilder argsCnt = new StringBuilder();
5.8 - final String mn = findMethodName(m, argsCnt);
5.9 - out.append(prefix).append(mn).append(" = function");
5.10 + final String mn = findMethodName(m, new StringBuilder());
5.11 if (mn.equals("class__V")) {
5.12 toInitilize.add(className(jc) + "(false)." + mn);
5.13 }
5.14 - out.append('(');
5.15 - String space = "";
5.16 - for (int index = 0, i = 0; i < argsCnt.length(); i++) {
5.17 - out.append(space);
5.18 - out.append("arg").append(String.valueOf(index));
5.19 - space = ",";
5.20 - final String desc = null;// XXX findDescriptor(args.get(i).getDescriptor());
5.21 - if (argsCnt.charAt(i) == '1') {
5.22 - index += 2;
5.23 - } else {
5.24 - index++;
5.25 - }
5.26 - }
5.27 - out.append(") {").append("\n");
5.28 - if (m.getCode() != null) {
5.29 - int len = m.getMaxLocals();
5.30 - for (int i = argsCnt.length(); i < len; i++) {
5.31 - out.append(" var ");
5.32 - out.append("arg").append(String.valueOf(i)).append(";\n");
5.33 - }
5.34 - produceCode(m);
5.35 - } else {
5.36 - out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n");
5.37 - }
5.38 - out.append("};");
5.39 + generateMethod(prefix, mn, m);
5.40 return mn;
5.41 }
5.42 -
5.43 +
5.44 private String generateInstanceMethod(String prefix, MethodData m) throws IOException {
5.45 String jsb = javaScriptBody(prefix, m, false);
5.46 if (jsb != null) {
5.47 return jsb;
5.48 }
5.49 - StringBuilder argsCnt = new StringBuilder();
5.50 - final String mn = findMethodName(m, argsCnt);
5.51 - out.append(prefix).append(mn).append(" = function");
5.52 - out.append("(arg0");
5.53 - String space = ",";
5.54 - for (int index = 1, i = 0; i < argsCnt.length(); i++) {
5.55 - out.append(space);
5.56 - out.append("arg").append(String.valueOf(index));
5.57 - if (argsCnt.charAt(i) == '1') {
5.58 - index += 2;
5.59 - } else {
5.60 - index++;
5.61 - }
5.62 - }
5.63 - out.append(") {").append("\n");
5.64 - if (m.getCode() != null) {
5.65 - int len = m.getMaxLocals();
5.66 - for (int i = argsCnt.length(); i < len; i++) {
5.67 - out.append(" var ");
5.68 - out.append("arg").append(String.valueOf(i + 1)).append(";\n");
5.69 - }
5.70 - produceCode(m);
5.71 - } else {
5.72 - out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n");
5.73 - }
5.74 - out.append("};");
5.75 + final String mn = findMethodName(m, new StringBuilder());
5.76 + generateMethod(prefix, mn, m);
5.77 return mn;
5.78 }
5.79
5.80 - private void produceCode(MethodData m) throws IOException {
5.81 + private void generateMethod(String prefix, String name, MethodData m)
5.82 + throws IOException {
5.83 + final StackMapIterator stackMapIterator = m.createStackMapIterator();
5.84 + final LocalsMapper lmapper =
5.85 + new LocalsMapper(stackMapIterator.getArguments());
5.86 +
5.87 + out.append(prefix).append(name).append(" = function(");
5.88 + lmapper.outputArguments(out);
5.89 + out.append(") {").append("\n");
5.90 +
5.91 final byte[] byteCodes = m.getCode();
5.92 - final StackMapIterator stackMapIterator = m.createStackMapIterator();
5.93 - final StackToVariableMapper mapper = new StackToVariableMapper();
5.94 + if (byteCodes == null) {
5.95 + out.append(" throw 'no code found for ")
5.96 + .append(m.getInternalSig()).append("';\n");
5.97 + out.append("};");
5.98 + return;
5.99 + }
5.100 +
5.101 + final StackMapper smapper = new StackMapper();
5.102 +
5.103 + final int maxLocals = m.getMaxLocals();
5.104 + if (maxLocals > 0) {
5.105 + // TODO: generate only used local variables
5.106 + for (int j = 0; j <= VarType.LAST; ++j) {
5.107 + out.append("\n var ").append(Variable.getLocalVariable(j, 0));
5.108 + for (int i = 1; i < maxLocals; ++i) {
5.109 + out.append(", ");
5.110 + out.append(Variable.getLocalVariable(j, i));
5.111 + }
5.112 + out.append(';');
5.113 + }
5.114 + }
5.115
5.116 // maxStack includes two stack positions for every pushed long / double
5.117 // so this might generate more stack variables than we need
5.118 final int maxStack = m.getMaxStack();
5.119 if (maxStack > 0) {
5.120 // TODO: generate only used stack variables
5.121 - for (int j = 0; j <= Variable.LAST_TYPE; ++j) {
5.122 + for (int j = 0; j <= VarType.LAST; ++j) {
5.123 out.append("\n var ").append(Variable.getStackVariable(j, 0));
5.124 for (int i = 1; i < maxStack; ++i) {
5.125 out.append(", ");
5.126 @@ -284,7 +262,8 @@
5.127 stackMapIterator.advanceTo(i);
5.128 if (lastStackFrame != stackMapIterator.getFrameIndex()) {
5.129 lastStackFrame = stackMapIterator.getFrameIndex();
5.130 - mapper.syncWithFrameStack(stackMapIterator.getFrameStack());
5.131 + lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
5.132 + smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
5.133 out.append(" case " + i).append(": ");
5.134 } else {
5.135 out.append(" /* " + i).append(" */ ");
5.136 @@ -292,303 +271,293 @@
5.137 final int c = readByte(byteCodes, i);
5.138 switch (c) {
5.139 case opc_aload_0:
5.140 - emit(out, "@1 = arg0;", mapper.pushA());
5.141 + emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(0));
5.142 break;
5.143 case opc_iload_0:
5.144 - emit(out, "@1 = arg0;", mapper.pushI());
5.145 + emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(0));
5.146 break;
5.147 case opc_lload_0:
5.148 - emit(out, "@1 = arg0;", mapper.pushL());
5.149 + emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(0));
5.150 break;
5.151 case opc_fload_0:
5.152 - emit(out, "@1 = arg0;", mapper.pushF());
5.153 + emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(0));
5.154 break;
5.155 case opc_dload_0:
5.156 - emit(out, "@1 = arg0;", mapper.pushD());
5.157 + emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(0));
5.158 break;
5.159 case opc_aload_1:
5.160 - emit(out, "@1 = arg1;", mapper.pushA());
5.161 + emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(1));
5.162 break;
5.163 case opc_iload_1:
5.164 - emit(out, "@1 = arg1;", mapper.pushI());
5.165 + emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(1));
5.166 break;
5.167 case opc_lload_1:
5.168 - emit(out, "@1 = arg1;", mapper.pushL());
5.169 + emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(1));
5.170 break;
5.171 case opc_fload_1:
5.172 - emit(out, "@1 = arg1;", mapper.pushF());
5.173 + emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(1));
5.174 break;
5.175 case opc_dload_1:
5.176 - emit(out, "@1 = arg1;", mapper.pushD());
5.177 + emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(1));
5.178 break;
5.179 case opc_aload_2:
5.180 - emit(out, "@1 = arg2;", mapper.pushA());
5.181 + emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(2));
5.182 break;
5.183 case opc_iload_2:
5.184 - emit(out, "@1 = arg2;", mapper.pushI());
5.185 + emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(2));
5.186 break;
5.187 case opc_lload_2:
5.188 - emit(out, "@1 = arg2;", mapper.pushL());
5.189 + emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(2));
5.190 break;
5.191 case opc_fload_2:
5.192 - emit(out, "@1 = arg2;", mapper.pushF());
5.193 + emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(2));
5.194 break;
5.195 case opc_dload_2:
5.196 - emit(out, "@1 = arg2;", mapper.pushD());
5.197 + emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(2));
5.198 break;
5.199 case opc_aload_3:
5.200 - emit(out, "@1 = arg3;", mapper.pushA());
5.201 + emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(3));
5.202 break;
5.203 case opc_iload_3:
5.204 - emit(out, "@1 = arg3;", mapper.pushI());
5.205 + emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(3));
5.206 break;
5.207 case opc_lload_3:
5.208 - emit(out, "@1 = arg3;", mapper.pushL());
5.209 + emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(3));
5.210 break;
5.211 case opc_fload_3:
5.212 - emit(out, "@1 = arg3;", mapper.pushF());
5.213 + emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(3));
5.214 break;
5.215 case opc_dload_3:
5.216 - emit(out, "@1 = arg3;", mapper.pushD());
5.217 + emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(3));
5.218 break;
5.219 case opc_iload: {
5.220 final int indx = readByte(byteCodes, ++i);
5.221 - emit(out, "@1 = arg@2;",
5.222 - mapper.pushI(), Integer.toString(indx));
5.223 + emit(out, "@1 = @2;", smapper.pushI(), lmapper.getI(indx));
5.224 break;
5.225 }
5.226 case opc_lload: {
5.227 final int indx = readByte(byteCodes, ++i);
5.228 - emit(out, "@1 = arg@2;",
5.229 - mapper.pushL(), Integer.toString(indx));
5.230 + emit(out, "@1 = @2;", smapper.pushL(), lmapper.getL(indx));
5.231 break;
5.232 }
5.233 case opc_fload: {
5.234 final int indx = readByte(byteCodes, ++i);
5.235 - emit(out, "@1 = arg@2;",
5.236 - mapper.pushF(), Integer.toString(indx));
5.237 + emit(out, "@1 = @2;", smapper.pushF(), lmapper.getF(indx));
5.238 break;
5.239 }
5.240 case opc_dload: {
5.241 final int indx = readByte(byteCodes, ++i);
5.242 - emit(out, "@1 = arg@2;",
5.243 - mapper.pushD(), Integer.toString(indx));
5.244 + emit(out, "@1 = @2;", smapper.pushD(), lmapper.getD(indx));
5.245 break;
5.246 }
5.247 case opc_aload: {
5.248 final int indx = readByte(byteCodes, ++i);
5.249 - emit(out, "@1 = arg@2;",
5.250 - mapper.pushA(), Integer.toString(indx));
5.251 + emit(out, "@1 = @2;", smapper.pushA(), lmapper.getA(indx));
5.252 break;
5.253 }
5.254 case opc_istore: {
5.255 final int indx = readByte(byteCodes, ++i);
5.256 - emit(out, "arg@1 = @2;",
5.257 - Integer.toString(indx), mapper.popI());
5.258 + emit(out, "@1 = @2;", lmapper.setI(indx), smapper.popI());
5.259 break;
5.260 }
5.261 case opc_lstore: {
5.262 final int indx = readByte(byteCodes, ++i);
5.263 - emit(out, "arg@1 = @2;",
5.264 - Integer.toString(indx), mapper.popL());
5.265 + emit(out, "@1 = @2;", lmapper.setL(indx), smapper.popL());
5.266 break;
5.267 }
5.268 case opc_fstore: {
5.269 final int indx = readByte(byteCodes, ++i);
5.270 - emit(out, "arg@1 = @2;",
5.271 - Integer.toString(indx), mapper.popF());
5.272 + emit(out, "@1 = @2;", lmapper.setF(indx), smapper.popF());
5.273 break;
5.274 }
5.275 case opc_dstore: {
5.276 final int indx = readByte(byteCodes, ++i);
5.277 - emit(out, "arg@1 = @2;",
5.278 - Integer.toString(indx), mapper.popD());
5.279 + emit(out, "@1 = @2;", lmapper.setD(indx), smapper.popD());
5.280 break;
5.281 }
5.282 case opc_astore: {
5.283 final int indx = readByte(byteCodes, ++i);
5.284 - emit(out, "arg@1 = @2;",
5.285 - Integer.toString(indx), mapper.popA());
5.286 + emit(out, "@1 = @2;", lmapper.setA(indx), smapper.popA());
5.287 break;
5.288 }
5.289 case opc_astore_0:
5.290 - emit(out, "arg0 = @1;", mapper.popA());
5.291 + emit(out, "@1 = @2;", lmapper.setA(0), smapper.popA());
5.292 break;
5.293 case opc_istore_0:
5.294 - emit(out, "arg0 = @1;", mapper.popI());
5.295 + emit(out, "@1 = @2;", lmapper.setI(0), smapper.popI());
5.296 break;
5.297 case opc_lstore_0:
5.298 - emit(out, "arg0 = @1;", mapper.popL());
5.299 + emit(out, "@1 = @2;", lmapper.setL(0), smapper.popL());
5.300 break;
5.301 case opc_fstore_0:
5.302 - emit(out, "arg0 = @1;", mapper.popF());
5.303 + emit(out, "@1 = @2;", lmapper.setF(0), smapper.popF());
5.304 break;
5.305 case opc_dstore_0:
5.306 - emit(out, "arg0 = @1;", mapper.popD());
5.307 + emit(out, "@1 = @2;", lmapper.setD(0), smapper.popD());
5.308 break;
5.309 case opc_astore_1:
5.310 - emit(out, "arg1 = @1;", mapper.popA());
5.311 + emit(out, "@1 = @2;", lmapper.setA(1), smapper.popA());
5.312 break;
5.313 case opc_istore_1:
5.314 - emit(out, "arg1 = @1;", mapper.popI());
5.315 + emit(out, "@1 = @2;", lmapper.setI(1), smapper.popI());
5.316 break;
5.317 case opc_lstore_1:
5.318 - emit(out, "arg1 = @1;", mapper.popL());
5.319 + emit(out, "@1 = @2;", lmapper.setL(1), smapper.popL());
5.320 break;
5.321 case opc_fstore_1:
5.322 - emit(out, "arg1 = @1;", mapper.popF());
5.323 + emit(out, "@1 = @2;", lmapper.setF(1), smapper.popF());
5.324 break;
5.325 case opc_dstore_1:
5.326 - emit(out, "arg1 = @1;", mapper.popD());
5.327 + emit(out, "@1 = @2;", lmapper.setD(1), smapper.popD());
5.328 break;
5.329 case opc_astore_2:
5.330 - emit(out, "arg2 = @1;", mapper.popA());
5.331 + emit(out, "@1 = @2;", lmapper.setA(2), smapper.popA());
5.332 break;
5.333 case opc_istore_2:
5.334 - emit(out, "arg2 = @1;", mapper.popI());
5.335 + emit(out, "@1 = @2;", lmapper.setI(2), smapper.popI());
5.336 break;
5.337 case opc_lstore_2:
5.338 - emit(out, "arg2 = @1;", mapper.popL());
5.339 + emit(out, "@1 = @2;", lmapper.setL(2), smapper.popL());
5.340 break;
5.341 case opc_fstore_2:
5.342 - emit(out, "arg2 = @1;", mapper.popF());
5.343 + emit(out, "@1 = @2;", lmapper.setF(2), smapper.popF());
5.344 break;
5.345 case opc_dstore_2:
5.346 - emit(out, "arg2 = @1;", mapper.popD());
5.347 + emit(out, "@1 = @2;", lmapper.setD(2), smapper.popD());
5.348 break;
5.349 case opc_astore_3:
5.350 - emit(out, "arg3 = @1;", mapper.popA());
5.351 + emit(out, "@1 = @2;", lmapper.setA(3), smapper.popA());
5.352 break;
5.353 case opc_istore_3:
5.354 - emit(out, "arg3 = @1;", mapper.popI());
5.355 + emit(out, "@1 = @2;", lmapper.setI(3), smapper.popI());
5.356 break;
5.357 case opc_lstore_3:
5.358 - emit(out, "arg3 = @1;", mapper.popL());
5.359 + emit(out, "@1 = @2;", lmapper.setL(3), smapper.popL());
5.360 break;
5.361 case opc_fstore_3:
5.362 - emit(out, "arg3 = @1;", mapper.popF());
5.363 + emit(out, "@1 = @2;", lmapper.setF(3), smapper.popF());
5.364 break;
5.365 case opc_dstore_3:
5.366 - emit(out, "arg3 = @1;", mapper.popD());
5.367 + emit(out, "@1 = @2;", lmapper.setD(3), smapper.popD());
5.368 break;
5.369 case opc_iadd:
5.370 - emit(out, "@1 += @2;", mapper.getI(1), mapper.popI());
5.371 + emit(out, "@1 += @2;", smapper.getI(1), smapper.popI());
5.372 break;
5.373 case opc_ladd:
5.374 - emit(out, "@1 += @2;", mapper.getL(1), mapper.popL());
5.375 + emit(out, "@1 += @2;", smapper.getL(1), smapper.popL());
5.376 break;
5.377 case opc_fadd:
5.378 - emit(out, "@1 += @2;", mapper.getF(1), mapper.popF());
5.379 + emit(out, "@1 += @2;", smapper.getF(1), smapper.popF());
5.380 break;
5.381 case opc_dadd:
5.382 - emit(out, "@1 += @2;", mapper.getD(1), mapper.popD());
5.383 + emit(out, "@1 += @2;", smapper.getD(1), smapper.popD());
5.384 break;
5.385 case opc_isub:
5.386 - emit(out, "@1 -= @2;", mapper.getI(1), mapper.popI());
5.387 + emit(out, "@1 -= @2;", smapper.getI(1), smapper.popI());
5.388 break;
5.389 case opc_lsub:
5.390 - emit(out, "@1 -= @2;", mapper.getL(1), mapper.popL());
5.391 + emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL());
5.392 break;
5.393 case opc_fsub:
5.394 - emit(out, "@1 -= @2;", mapper.getF(1), mapper.popF());
5.395 + emit(out, "@1 -= @2;", smapper.getF(1), smapper.popF());
5.396 break;
5.397 case opc_dsub:
5.398 - emit(out, "@1 -= @2;", mapper.getD(1), mapper.popD());
5.399 + emit(out, "@1 -= @2;", smapper.getD(1), smapper.popD());
5.400 break;
5.401 case opc_imul:
5.402 - emit(out, "@1 *= @2;", mapper.getI(1), mapper.popI());
5.403 + emit(out, "@1 *= @2;", smapper.getI(1), smapper.popI());
5.404 break;
5.405 case opc_lmul:
5.406 - emit(out, "@1 *= @2;", mapper.getL(1), mapper.popL());
5.407 + emit(out, "@1 *= @2;", smapper.getL(1), smapper.popL());
5.408 break;
5.409 case opc_fmul:
5.410 - emit(out, "@1 *= @2;", mapper.getF(1), mapper.popF());
5.411 + emit(out, "@1 *= @2;", smapper.getF(1), smapper.popF());
5.412 break;
5.413 case opc_dmul:
5.414 - emit(out, "@1 *= @2;", mapper.getD(1), mapper.popD());
5.415 + emit(out, "@1 *= @2;", smapper.getD(1), smapper.popD());
5.416 break;
5.417 case opc_idiv:
5.418 emit(out, "@1 = Math.floor(@1 / @2);",
5.419 - mapper.getI(1), mapper.popI());
5.420 + smapper.getI(1), smapper.popI());
5.421 break;
5.422 case opc_ldiv:
5.423 emit(out, "@1 = Math.floor(@1 / @2);",
5.424 - mapper.getL(1), mapper.popL());
5.425 + smapper.getL(1), smapper.popL());
5.426 break;
5.427 case opc_fdiv:
5.428 - emit(out, "@1 /= @2;", mapper.getF(1), mapper.popF());
5.429 + emit(out, "@1 /= @2;", smapper.getF(1), smapper.popF());
5.430 break;
5.431 case opc_ddiv:
5.432 - emit(out, "@1 /= @2;", mapper.getD(1), mapper.popD());
5.433 + emit(out, "@1 /= @2;", smapper.getD(1), smapper.popD());
5.434 break;
5.435 case opc_irem:
5.436 - emit(out, "@1 %= @2;", mapper.getI(1), mapper.popI());
5.437 + emit(out, "@1 %= @2;", smapper.getI(1), smapper.popI());
5.438 break;
5.439 case opc_lrem:
5.440 - emit(out, "@1 %= @2;", mapper.getL(1), mapper.popL());
5.441 + emit(out, "@1 %= @2;", smapper.getL(1), smapper.popL());
5.442 break;
5.443 case opc_frem:
5.444 - emit(out, "@1 %= @2;", mapper.getF(1), mapper.popF());
5.445 + emit(out, "@1 %= @2;", smapper.getF(1), smapper.popF());
5.446 break;
5.447 case opc_drem:
5.448 - emit(out, "@1 %= @2;", mapper.getD(1), mapper.popD());
5.449 + emit(out, "@1 %= @2;", smapper.getD(1), smapper.popD());
5.450 break;
5.451 case opc_iand:
5.452 - emit(out, "@1 &= @2;", mapper.getI(1), mapper.popI());
5.453 + emit(out, "@1 &= @2;", smapper.getI(1), smapper.popI());
5.454 break;
5.455 case opc_land:
5.456 - emit(out, "@1 &= @2;", mapper.getL(1), mapper.popL());
5.457 + emit(out, "@1 &= @2;", smapper.getL(1), smapper.popL());
5.458 break;
5.459 case opc_ior:
5.460 - emit(out, "@1 |= @2;", mapper.getI(1), mapper.popI());
5.461 + emit(out, "@1 |= @2;", smapper.getI(1), smapper.popI());
5.462 break;
5.463 case opc_lor:
5.464 - emit(out, "@1 |= @2;", mapper.getL(1), mapper.popL());
5.465 + emit(out, "@1 |= @2;", smapper.getL(1), smapper.popL());
5.466 break;
5.467 case opc_ixor:
5.468 - emit(out, "@1 ^= @2;", mapper.getI(1), mapper.popI());
5.469 + emit(out, "@1 ^= @2;", smapper.getI(1), smapper.popI());
5.470 break;
5.471 case opc_lxor:
5.472 - emit(out, "@1 ^= @2;", mapper.getL(1), mapper.popL());
5.473 + emit(out, "@1 ^= @2;", smapper.getL(1), smapper.popL());
5.474 break;
5.475 case opc_ineg:
5.476 - emit(out, "@1 = -@1;", mapper.getI(0));
5.477 + emit(out, "@1 = -@1;", smapper.getI(0));
5.478 break;
5.479 case opc_lneg:
5.480 - emit(out, "@1 = -@1;", mapper.getL(0));
5.481 + emit(out, "@1 = -@1;", smapper.getL(0));
5.482 break;
5.483 case opc_fneg:
5.484 - emit(out, "@1 = -@1;", mapper.getF(0));
5.485 + emit(out, "@1 = -@1;", smapper.getF(0));
5.486 break;
5.487 case opc_dneg:
5.488 - emit(out, "@1 = -@1;", mapper.getD(0));
5.489 + emit(out, "@1 = -@1;", smapper.getD(0));
5.490 break;
5.491 case opc_ishl:
5.492 - emit(out, "@1 <<= @2;", mapper.getI(1), mapper.popI());
5.493 + emit(out, "@1 <<= @2;", smapper.getI(1), smapper.popI());
5.494 break;
5.495 case opc_lshl:
5.496 - emit(out, "@1 <<= @2;", mapper.getL(1), mapper.popI());
5.497 + emit(out, "@1 <<= @2;", smapper.getL(1), smapper.popI());
5.498 break;
5.499 case opc_ishr:
5.500 - emit(out, "@1 >>= @2;", mapper.getI(1), mapper.popI());
5.501 + emit(out, "@1 >>= @2;", smapper.getI(1), smapper.popI());
5.502 break;
5.503 case opc_lshr:
5.504 - emit(out, "@1 >>= @2;", mapper.getL(1), mapper.popI());
5.505 + emit(out, "@1 >>= @2;", smapper.getL(1), smapper.popI());
5.506 break;
5.507 case opc_iushr:
5.508 - emit(out, "@1 >>>= @2;", mapper.getI(1), mapper.popI());
5.509 + emit(out, "@1 >>>= @2;", smapper.getI(1), smapper.popI());
5.510 break;
5.511 case opc_lushr:
5.512 - emit(out, "@1 >>>= @2;", mapper.getL(1), mapper.popI());
5.513 + emit(out, "@1 >>>= @2;", smapper.getL(1), smapper.popI());
5.514 break;
5.515 case opc_iinc: {
5.516 final int varIndx = readByte(byteCodes, ++i);
5.517 final int incrBy = byteCodes[++i];
5.518 if (incrBy == 1) {
5.519 - emit(out, "arg@1++;", Integer.toString(varIndx));
5.520 + emit(out, "@1++;", lmapper.getI(varIndx));
5.521 } else {
5.522 - emit(out, "arg@1 += @2;",
5.523 - Integer.toString(varIndx),
5.524 + emit(out, "@1 += @2;",
5.525 + lmapper.getI(varIndx),
5.526 Integer.toString(incrBy));
5.527 }
5.528 break;
5.529 @@ -597,60 +566,60 @@
5.530 emit(out, "return;");
5.531 break;
5.532 case opc_ireturn:
5.533 - emit(out, "return @1;", mapper.popI());
5.534 + emit(out, "return @1;", smapper.popI());
5.535 break;
5.536 case opc_lreturn:
5.537 - emit(out, "return @1;", mapper.popL());
5.538 + emit(out, "return @1;", smapper.popL());
5.539 break;
5.540 case opc_freturn:
5.541 - emit(out, "return @1;", mapper.popF());
5.542 + emit(out, "return @1;", smapper.popF());
5.543 break;
5.544 case opc_dreturn:
5.545 - emit(out, "return @1;", mapper.popD());
5.546 + emit(out, "return @1;", smapper.popD());
5.547 break;
5.548 case opc_areturn:
5.549 - emit(out, "return @1;", mapper.popA());
5.550 + emit(out, "return @1;", smapper.popA());
5.551 break;
5.552 case opc_i2l:
5.553 - emit(out, "@2 = @1;", mapper.popI(), mapper.pushL());
5.554 + emit(out, "@2 = @1;", smapper.popI(), smapper.pushL());
5.555 break;
5.556 case opc_i2f:
5.557 - emit(out, "@2 = @1;", mapper.popI(), mapper.pushF());
5.558 + emit(out, "@2 = @1;", smapper.popI(), smapper.pushF());
5.559 break;
5.560 case opc_i2d:
5.561 - emit(out, "@2 = @1;", mapper.popI(), mapper.pushD());
5.562 + emit(out, "@2 = @1;", smapper.popI(), smapper.pushD());
5.563 break;
5.564 case opc_l2i:
5.565 - emit(out, "@2 = @1;", mapper.popL(), mapper.pushI());
5.566 + emit(out, "@2 = @1;", smapper.popL(), smapper.pushI());
5.567 break;
5.568 // max int check?
5.569 case opc_l2f:
5.570 - emit(out, "@2 = @1;", mapper.popL(), mapper.pushF());
5.571 + emit(out, "@2 = @1;", smapper.popL(), smapper.pushF());
5.572 break;
5.573 case opc_l2d:
5.574 - emit(out, "@2 = @1;", mapper.popL(), mapper.pushD());
5.575 + emit(out, "@2 = @1;", smapper.popL(), smapper.pushD());
5.576 break;
5.577 case opc_f2d:
5.578 - emit(out, "@2 = @1;", mapper.popF(), mapper.pushD());
5.579 + emit(out, "@2 = @1;", smapper.popF(), smapper.pushD());
5.580 break;
5.581 case opc_d2f:
5.582 - emit(out, "@2 = @1;", mapper.popD(), mapper.pushF());
5.583 + emit(out, "@2 = @1;", smapper.popD(), smapper.pushF());
5.584 break;
5.585 case opc_f2i:
5.586 emit(out, "@2 = Math.floor(@1);",
5.587 - mapper.popF(), mapper.pushI());
5.588 + smapper.popF(), smapper.pushI());
5.589 break;
5.590 case opc_f2l:
5.591 emit(out, "@2 = Math.floor(@1);",
5.592 - mapper.popF(), mapper.pushL());
5.593 + smapper.popF(), smapper.pushL());
5.594 break;
5.595 case opc_d2i:
5.596 emit(out, "@2 = Math.floor(@1);",
5.597 - mapper.popD(), mapper.pushI());
5.598 + smapper.popD(), smapper.pushI());
5.599 break;
5.600 case opc_d2l:
5.601 emit(out, "@2 = Math.floor(@1);",
5.602 - mapper.popD(), mapper.pushL());
5.603 + smapper.popD(), smapper.pushL());
5.604 break;
5.605 case opc_i2b:
5.606 case opc_i2c:
5.607 @@ -658,55 +627,55 @@
5.608 out.append("/* number conversion */");
5.609 break;
5.610 case opc_aconst_null:
5.611 - emit(out, "@1 = null;", mapper.pushA());
5.612 + emit(out, "@1 = null;", smapper.pushA());
5.613 break;
5.614 case opc_iconst_m1:
5.615 - emit(out, "@1 = -1;", mapper.pushI());
5.616 + emit(out, "@1 = -1;", smapper.pushI());
5.617 break;
5.618 case opc_iconst_0:
5.619 - emit(out, "@1 = 0;", mapper.pushI());
5.620 + emit(out, "@1 = 0;", smapper.pushI());
5.621 break;
5.622 case opc_dconst_0:
5.623 - emit(out, "@1 = 0;", mapper.pushD());
5.624 + emit(out, "@1 = 0;", smapper.pushD());
5.625 break;
5.626 case opc_lconst_0:
5.627 - emit(out, "@1 = 0;", mapper.pushL());
5.628 + emit(out, "@1 = 0;", smapper.pushL());
5.629 break;
5.630 case opc_fconst_0:
5.631 - emit(out, "@1 = 0;", mapper.pushF());
5.632 + emit(out, "@1 = 0;", smapper.pushF());
5.633 break;
5.634 case opc_iconst_1:
5.635 - emit(out, "@1 = 1;", mapper.pushI());
5.636 + emit(out, "@1 = 1;", smapper.pushI());
5.637 break;
5.638 case opc_lconst_1:
5.639 - emit(out, "@1 = 1;", mapper.pushL());
5.640 + emit(out, "@1 = 1;", smapper.pushL());
5.641 break;
5.642 case opc_fconst_1:
5.643 - emit(out, "@1 = 1;", mapper.pushF());
5.644 + emit(out, "@1 = 1;", smapper.pushF());
5.645 break;
5.646 case opc_dconst_1:
5.647 - emit(out, "@1 = 1;", mapper.pushD());
5.648 + emit(out, "@1 = 1;", smapper.pushD());
5.649 break;
5.650 case opc_iconst_2:
5.651 - emit(out, "@1 = 2;", mapper.pushI());
5.652 + emit(out, "@1 = 2;", smapper.pushI());
5.653 break;
5.654 case opc_fconst_2:
5.655 - emit(out, "@1 = 2;", mapper.pushF());
5.656 + emit(out, "@1 = 2;", smapper.pushF());
5.657 break;
5.658 case opc_iconst_3:
5.659 - emit(out, "@1 = 3;", mapper.pushI());
5.660 + emit(out, "@1 = 3;", smapper.pushI());
5.661 break;
5.662 case opc_iconst_4:
5.663 - emit(out, "@1 = 4;", mapper.pushI());
5.664 + emit(out, "@1 = 4;", smapper.pushI());
5.665 break;
5.666 case opc_iconst_5:
5.667 - emit(out, "@1 = 5;", mapper.pushI());
5.668 + emit(out, "@1 = 5;", smapper.pushI());
5.669 break;
5.670 case opc_ldc: {
5.671 int indx = readByte(byteCodes, ++i);
5.672 String v = encodeConstant(indx);
5.673 - int type = constantToVariableType(jc.getTag(indx));
5.674 - emit(out, "@1 = @2;", mapper.pushT(type), v);
5.675 + int type = VarType.fromConstantType(jc.getTag(indx));
5.676 + emit(out, "@1 = @2;", smapper.pushT(type), v);
5.677 break;
5.678 }
5.679 case opc_ldc_w:
5.680 @@ -714,110 +683,110 @@
5.681 int indx = readIntArg(byteCodes, i);
5.682 i += 2;
5.683 String v = encodeConstant(indx);
5.684 - int type = constantToVariableType(jc.getTag(indx));
5.685 - emit(out, "@1 = @2;", mapper.pushT(type), v);
5.686 + int type = VarType.fromConstantType(jc.getTag(indx));
5.687 + emit(out, "@1 = @2;", smapper.pushT(type), v);
5.688 break;
5.689 }
5.690 case opc_lcmp:
5.691 emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
5.692 - mapper.popL(), mapper.popL(), mapper.pushI());
5.693 + smapper.popL(), smapper.popL(), smapper.pushI());
5.694 break;
5.695 case opc_fcmpl:
5.696 case opc_fcmpg:
5.697 emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
5.698 - mapper.popF(), mapper.popF(), mapper.pushI());
5.699 + smapper.popF(), smapper.popF(), smapper.pushI());
5.700 break;
5.701 case opc_dcmpl:
5.702 case opc_dcmpg:
5.703 emit(out, "@3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
5.704 - mapper.popD(), mapper.popD(), mapper.pushI());
5.705 + smapper.popD(), smapper.popD(), smapper.pushI());
5.706 break;
5.707 case opc_if_acmpeq:
5.708 - i = generateIf(byteCodes, i, mapper.popA(), mapper.popA(),
5.709 + i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
5.710 "===");
5.711 break;
5.712 case opc_if_acmpne:
5.713 - i = generateIf(byteCodes, i, mapper.popA(), mapper.popA(),
5.714 + i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
5.715 "!=");
5.716 break;
5.717 case opc_if_icmpeq:
5.718 - i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
5.719 + i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
5.720 "==");
5.721 break;
5.722 case opc_ifeq: {
5.723 int indx = i + readIntArg(byteCodes, i);
5.724 emit(out, "if (@1 == 0) { gt = @2; continue; }",
5.725 - mapper.popI(), Integer.toString(indx));
5.726 + smapper.popI(), Integer.toString(indx));
5.727 i += 2;
5.728 break;
5.729 }
5.730 case opc_ifne: {
5.731 int indx = i + readIntArg(byteCodes, i);
5.732 emit(out, "if (@1 != 0) { gt = @2; continue; }",
5.733 - mapper.popI(), Integer.toString(indx));
5.734 + smapper.popI(), Integer.toString(indx));
5.735 i += 2;
5.736 break;
5.737 }
5.738 case opc_iflt: {
5.739 int indx = i + readIntArg(byteCodes, i);
5.740 emit(out, "if (@1 < 0) { gt = @2; continue; }",
5.741 - mapper.popI(), Integer.toString(indx));
5.742 + smapper.popI(), Integer.toString(indx));
5.743 i += 2;
5.744 break;
5.745 }
5.746 case opc_ifle: {
5.747 int indx = i + readIntArg(byteCodes, i);
5.748 emit(out, "if (@1 <= 0) { gt = @2; continue; }",
5.749 - mapper.popI(), Integer.toString(indx));
5.750 + smapper.popI(), Integer.toString(indx));
5.751 i += 2;
5.752 break;
5.753 }
5.754 case opc_ifgt: {
5.755 int indx = i + readIntArg(byteCodes, i);
5.756 emit(out, "if (@1 > 0) { gt = @2; continue; }",
5.757 - mapper.popI(), Integer.toString(indx));
5.758 + smapper.popI(), Integer.toString(indx));
5.759 i += 2;
5.760 break;
5.761 }
5.762 case opc_ifge: {
5.763 int indx = i + readIntArg(byteCodes, i);
5.764 emit(out, "if (@1 >= 0) { gt = @2; continue; }",
5.765 - mapper.popI(), Integer.toString(indx));
5.766 + smapper.popI(), Integer.toString(indx));
5.767 i += 2;
5.768 break;
5.769 }
5.770 case opc_ifnonnull: {
5.771 int indx = i + readIntArg(byteCodes, i);
5.772 emit(out, "if (@1 !== null) { gt = @2; continue; }",
5.773 - mapper.popA(), Integer.toString(indx));
5.774 + smapper.popA(), Integer.toString(indx));
5.775 i += 2;
5.776 break;
5.777 }
5.778 case opc_ifnull: {
5.779 int indx = i + readIntArg(byteCodes, i);
5.780 emit(out, "if (@1 === null) { gt = @2; continue; }",
5.781 - mapper.popA(), Integer.toString(indx));
5.782 + smapper.popA(), Integer.toString(indx));
5.783 i += 2;
5.784 break;
5.785 }
5.786 case opc_if_icmpne:
5.787 - i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
5.788 + i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
5.789 "!=");
5.790 break;
5.791 case opc_if_icmplt:
5.792 - i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
5.793 + i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
5.794 "<");
5.795 break;
5.796 case opc_if_icmple:
5.797 - i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
5.798 + i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
5.799 "<=");
5.800 break;
5.801 case opc_if_icmpgt:
5.802 - i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
5.803 + i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
5.804 ">");
5.805 break;
5.806 case opc_if_icmpge:
5.807 - i = generateIf(byteCodes, i, mapper.popI(), mapper.popI(),
5.808 + i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
5.809 ">=");
5.810 break;
5.811 case opc_goto: {
5.812 @@ -832,7 +801,7 @@
5.813 table += 4;
5.814 int n = readInt4(byteCodes, table);
5.815 table += 4;
5.816 - out.append("switch (").append(mapper.popI()).append(") {\n");
5.817 + out.append("switch (").append(smapper.popI()).append(") {\n");
5.818 while (n-- > 0) {
5.819 int cnstnt = readInt4(byteCodes, table);
5.820 table += 4;
5.821 @@ -852,7 +821,7 @@
5.822 table += 4;
5.823 int high = readInt4(byteCodes, table);
5.824 table += 4;
5.825 - out.append("switch (").append(mapper.popI()).append(") {\n");
5.826 + out.append("switch (").append(smapper.popI()).append(") {\n");
5.827 while (low <= high) {
5.828 int offset = i + readInt4(byteCodes, table);
5.829 table += 4;
5.830 @@ -864,23 +833,23 @@
5.831 break;
5.832 }
5.833 case opc_invokeinterface: {
5.834 - i = invokeVirtualMethod(byteCodes, i, mapper) + 2;
5.835 + i = invokeVirtualMethod(byteCodes, i, smapper) + 2;
5.836 break;
5.837 }
5.838 case opc_invokevirtual:
5.839 - i = invokeVirtualMethod(byteCodes, i, mapper);
5.840 + i = invokeVirtualMethod(byteCodes, i, smapper);
5.841 break;
5.842 case opc_invokespecial:
5.843 - i = invokeStaticMethod(byteCodes, i, mapper, false);
5.844 + i = invokeStaticMethod(byteCodes, i, smapper, false);
5.845 break;
5.846 case opc_invokestatic:
5.847 - i = invokeStaticMethod(byteCodes, i, mapper, true);
5.848 + i = invokeStaticMethod(byteCodes, i, smapper, true);
5.849 break;
5.850 case opc_new: {
5.851 int indx = readIntArg(byteCodes, i);
5.852 String ci = jc.getClassName(indx);
5.853 emit(out, "@1 = new @2;",
5.854 - mapper.pushA(), ci.replace('/', '_'));
5.855 + smapper.pushA(), ci.replace('/', '_'));
5.856 addReference(ci);
5.857 i += 2;
5.858 break;
5.859 @@ -888,21 +857,21 @@
5.860 case opc_newarray:
5.861 ++i; // skip type of array
5.862 emit(out, "@2 = new Array(@1).fillNulls();",
5.863 - mapper.popI(), mapper.pushA());
5.864 + smapper.popI(), smapper.pushA());
5.865 break;
5.866 case opc_anewarray:
5.867 i += 2; // skip type of array
5.868 emit(out, "@2 = new Array(@1).fillNulls();",
5.869 - mapper.popI(), mapper.pushA());
5.870 + smapper.popI(), smapper.pushA());
5.871 break;
5.872 case opc_multianewarray: {
5.873 i += 2;
5.874 int dim = readByte(byteCodes, ++i);
5.875 - out.append("{ var a0 = new Array(").append(mapper.popI())
5.876 + out.append("{ var a0 = new Array(").append(smapper.popI())
5.877 .append(").fillNulls();");
5.878 for (int d = 1; d < dim; d++) {
5.879 out.append("\n var l" + d).append(" = ")
5.880 - .append(mapper.popI()).append(';');
5.881 + .append(smapper.popI()).append(';');
5.882 out.append("\n for (var i" + d).append (" = 0; i" + d).
5.883 append(" < a" + (d - 1)).
5.884 append(".length; i" + d).append("++) {");
5.885 @@ -914,110 +883,110 @@
5.886 for (int d = 1; d < dim; d++) {
5.887 out.append("\n }");
5.888 }
5.889 - out.append("\n").append(mapper.pushA()).append(" = a0; }");
5.890 + out.append("\n").append(smapper.pushA()).append(" = a0; }");
5.891 break;
5.892 }
5.893 case opc_arraylength:
5.894 - emit(out, "@2 = @1.length;", mapper.popA(), mapper.pushI());
5.895 + emit(out, "@2 = @1.length;", smapper.popA(), smapper.pushI());
5.896 break;
5.897 case opc_lastore:
5.898 emit(out, "@3[@2] = @1;",
5.899 - mapper.popL(), mapper.popI(), mapper.popA());
5.900 + smapper.popL(), smapper.popI(), smapper.popA());
5.901 break;
5.902 case opc_fastore:
5.903 emit(out, "@3[@2] = @1;",
5.904 - mapper.popF(), mapper.popI(), mapper.popA());
5.905 + smapper.popF(), smapper.popI(), smapper.popA());
5.906 break;
5.907 case opc_dastore:
5.908 emit(out, "@3[@2] = @1;",
5.909 - mapper.popD(), mapper.popI(), mapper.popA());
5.910 + smapper.popD(), smapper.popI(), smapper.popA());
5.911 break;
5.912 case opc_aastore:
5.913 emit(out, "@3[@2] = @1;",
5.914 - mapper.popA(), mapper.popI(), mapper.popA());
5.915 + smapper.popA(), smapper.popI(), smapper.popA());
5.916 break;
5.917 case opc_iastore:
5.918 case opc_bastore:
5.919 case opc_castore:
5.920 case opc_sastore:
5.921 emit(out, "@3[@2] = @1;",
5.922 - mapper.popI(), mapper.popI(), mapper.popA());
5.923 + smapper.popI(), smapper.popI(), smapper.popA());
5.924 break;
5.925 case opc_laload:
5.926 emit(out, "@3 = @2[@1];",
5.927 - mapper.popI(), mapper.popA(), mapper.pushL());
5.928 + smapper.popI(), smapper.popA(), smapper.pushL());
5.929 break;
5.930 case opc_faload:
5.931 emit(out, "@3 = @2[@1];",
5.932 - mapper.popI(), mapper.popA(), mapper.pushF());
5.933 + smapper.popI(), smapper.popA(), smapper.pushF());
5.934 break;
5.935 case opc_daload:
5.936 emit(out, "@3 = @2[@1];",
5.937 - mapper.popI(), mapper.popA(), mapper.pushD());
5.938 + smapper.popI(), smapper.popA(), smapper.pushD());
5.939 break;
5.940 case opc_aaload:
5.941 emit(out, "@3 = @2[@1];",
5.942 - mapper.popI(), mapper.popA(), mapper.pushA());
5.943 + smapper.popI(), smapper.popA(), smapper.pushA());
5.944 break;
5.945 case opc_iaload:
5.946 case opc_baload:
5.947 case opc_caload:
5.948 case opc_saload:
5.949 emit(out, "@3 = @2[@1];",
5.950 - mapper.popI(), mapper.popA(), mapper.pushI());
5.951 + smapper.popI(), smapper.popA(), smapper.pushI());
5.952 break;
5.953 case opc_pop:
5.954 case opc_pop2:
5.955 - mapper.pop(1);
5.956 + smapper.pop(1);
5.957 out.append("/* pop */");
5.958 break;
5.959 case opc_dup: {
5.960 - final Variable v = mapper.get(0);
5.961 - emit(out, "@1 = @2;", mapper.pushT(v.getType()), v);
5.962 + final Variable v = smapper.get(0);
5.963 + emit(out, "@1 = @2;", smapper.pushT(v.getType()), v);
5.964 break;
5.965 }
5.966 case opc_dup2: {
5.967 - if (mapper.get(0).isCategory2()) {
5.968 - final Variable v = mapper.get(0);
5.969 - emit(out, "@1 = @2;", mapper.pushT(v.getType()), v);
5.970 + if (smapper.get(0).isCategory2()) {
5.971 + final Variable v = smapper.get(0);
5.972 + emit(out, "@1 = @2;", smapper.pushT(v.getType()), v);
5.973 } else {
5.974 - final Variable v1 = mapper.get(0);
5.975 - final Variable v2 = mapper.get(1);
5.976 + final Variable v1 = smapper.get(0);
5.977 + final Variable v2 = smapper.get(1);
5.978 emit(out, "{ @1 = @2; @3 = @4; }",
5.979 - mapper.pushT(v2.getType()), v2,
5.980 - mapper.pushT(v1.getType()), v1);
5.981 + smapper.pushT(v2.getType()), v2,
5.982 + smapper.pushT(v1.getType()), v1);
5.983 }
5.984 break;
5.985 }
5.986 case opc_dup_x1: {
5.987 - final Variable vi1 = mapper.pop();
5.988 - final Variable vi2 = mapper.pop();
5.989 - final Variable vo3 = mapper.pushT(vi1.getType());
5.990 - final Variable vo2 = mapper.pushT(vi2.getType());
5.991 - final Variable vo1 = mapper.pushT(vi1.getType());
5.992 + final Variable vi1 = smapper.pop();
5.993 + final Variable vi2 = smapper.pop();
5.994 + final Variable vo3 = smapper.pushT(vi1.getType());
5.995 + final Variable vo2 = smapper.pushT(vi2.getType());
5.996 + final Variable vo1 = smapper.pushT(vi1.getType());
5.997
5.998 emit(out, "{ @1 = @2; @3 = @4; @5 = @6; }",
5.999 vo1, vi1, vo2, vi2, vo3, vo1);
5.1000 break;
5.1001 }
5.1002 case opc_dup_x2: {
5.1003 - if (mapper.get(1).isCategory2()) {
5.1004 - final Variable vi1 = mapper.pop();
5.1005 - final Variable vi2 = mapper.pop();
5.1006 - final Variable vo3 = mapper.pushT(vi1.getType());
5.1007 - final Variable vo2 = mapper.pushT(vi2.getType());
5.1008 - final Variable vo1 = mapper.pushT(vi1.getType());
5.1009 + if (smapper.get(1).isCategory2()) {
5.1010 + final Variable vi1 = smapper.pop();
5.1011 + final Variable vi2 = smapper.pop();
5.1012 + final Variable vo3 = smapper.pushT(vi1.getType());
5.1013 + final Variable vo2 = smapper.pushT(vi2.getType());
5.1014 + final Variable vo1 = smapper.pushT(vi1.getType());
5.1015
5.1016 emit(out, "{ @1 = @2; @3 = @4; @5 = @6; }",
5.1017 vo1, vi1, vo2, vi2, vo3, vo1);
5.1018 } else {
5.1019 - final Variable vi1 = mapper.pop();
5.1020 - final Variable vi2 = mapper.pop();
5.1021 - final Variable vi3 = mapper.pop();
5.1022 - final Variable vo4 = mapper.pushT(vi1.getType());
5.1023 - final Variable vo3 = mapper.pushT(vi3.getType());
5.1024 - final Variable vo2 = mapper.pushT(vi2.getType());
5.1025 - final Variable vo1 = mapper.pushT(vi1.getType());
5.1026 + final Variable vi1 = smapper.pop();
5.1027 + final Variable vi2 = smapper.pop();
5.1028 + final Variable vi3 = smapper.pop();
5.1029 + final Variable vo4 = smapper.pushT(vi1.getType());
5.1030 + final Variable vo3 = smapper.pushT(vi3.getType());
5.1031 + final Variable vo2 = smapper.pushT(vi2.getType());
5.1032 + final Variable vo1 = smapper.pushT(vi1.getType());
5.1033
5.1034 emit(out, "{ @1 = @2; @3 = @4; @5 = @6; @7 = @8; }",
5.1035 vo1, vi1, vo2, vi2, vo3, vi3, vo4, vo1);
5.1036 @@ -1026,29 +995,29 @@
5.1037 }
5.1038 case opc_bipush:
5.1039 emit(out, "@1 = @2;",
5.1040 - mapper.pushI(), Integer.toString(byteCodes[++i]));
5.1041 + smapper.pushI(), Integer.toString(byteCodes[++i]));
5.1042 break;
5.1043 case opc_sipush:
5.1044 emit(out, "@1 = @2;",
5.1045 - mapper.pushI(),
5.1046 + smapper.pushI(),
5.1047 Integer.toString(readIntArg(byteCodes, i)));
5.1048 i += 2;
5.1049 break;
5.1050 case opc_getfield: {
5.1051 int indx = readIntArg(byteCodes, i);
5.1052 String[] fi = jc.getFieldInfoName(indx);
5.1053 - final int type = fieldToVariableType(fi[2].charAt(0));
5.1054 + final int type = VarType.fromFieldType(fi[2].charAt(0));
5.1055 emit(out, "@2 = @1.fld_@3;",
5.1056 - mapper.popA(), mapper.pushT(type), fi[1]);
5.1057 + smapper.popA(), smapper.pushT(type), fi[1]);
5.1058 i += 2;
5.1059 break;
5.1060 }
5.1061 case opc_getstatic: {
5.1062 int indx = readIntArg(byteCodes, i);
5.1063 String[] fi = jc.getFieldInfoName(indx);
5.1064 - final int type = fieldToVariableType(fi[2].charAt(0));
5.1065 + final int type = VarType.fromFieldType(fi[2].charAt(0));
5.1066 emit(out, "@1 = @2.@3;",
5.1067 - mapper.pushT(type), fi[0].replace('/', '_'), fi[1]);
5.1068 + smapper.pushT(type), fi[0].replace('/', '_'), fi[1]);
5.1069 i += 2;
5.1070 addReference(fi[0]);
5.1071 break;
5.1072 @@ -1056,18 +1025,18 @@
5.1073 case opc_putfield: {
5.1074 int indx = readIntArg(byteCodes, i);
5.1075 String[] fi = jc.getFieldInfoName(indx);
5.1076 - final int type = fieldToVariableType(fi[2].charAt(0));
5.1077 + final int type = VarType.fromFieldType(fi[2].charAt(0));
5.1078 emit(out, "@2.fld_@3 = @1;",
5.1079 - mapper.popT(type), mapper.popA(), fi[1]);
5.1080 + smapper.popT(type), smapper.popA(), fi[1]);
5.1081 i += 2;
5.1082 break;
5.1083 }
5.1084 case opc_putstatic: {
5.1085 int indx = readIntArg(byteCodes, i);
5.1086 String[] fi = jc.getFieldInfoName(indx);
5.1087 - final int type = fieldToVariableType(fi[2].charAt(0));
5.1088 + final int type = VarType.fromFieldType(fi[2].charAt(0));
5.1089 emit(out, "@1.@2 = @3;",
5.1090 - fi[0].replace('/', '_'), fi[1], mapper.popT(type));
5.1091 + fi[0].replace('/', '_'), fi[1], smapper.popT(type));
5.1092 i += 2;
5.1093 addReference(fi[0]);
5.1094 break;
5.1095 @@ -1079,7 +1048,7 @@
5.1096 // no way to check arrays right now
5.1097 // XXX proper exception
5.1098 emit(out, "if (@1.$instOf_@2 != 1) throw {};",
5.1099 - mapper.getA(0), type.replace('/', '_'));
5.1100 + smapper.getA(0), type.replace('/', '_'));
5.1101 }
5.1102 i += 2;
5.1103 break;
5.1104 @@ -1088,28 +1057,28 @@
5.1105 int indx = readIntArg(byteCodes, i);
5.1106 final String type = jc.getClassName(indx);
5.1107 emit(out, "@2 = @1.$instOf_@3 ? 1 : 0;",
5.1108 - mapper.popA(), mapper.pushI(), type.replace('/', '_'));
5.1109 + smapper.popA(), smapper.pushI(), type.replace('/', '_'));
5.1110 i += 2;
5.1111 break;
5.1112 }
5.1113 case opc_athrow: {
5.1114 - final Variable v = mapper.popA();
5.1115 - mapper.clear();
5.1116 + final Variable v = smapper.popA();
5.1117 + smapper.clear();
5.1118
5.1119 emit(out, "{ @1 = @2; throw @2; }",
5.1120 - mapper.pushA(), v);
5.1121 + smapper.pushA(), v);
5.1122 break;
5.1123 }
5.1124
5.1125 case opc_monitorenter: {
5.1126 out.append("/* monitor enter */");
5.1127 - mapper.popA();
5.1128 + smapper.popA();
5.1129 break;
5.1130 }
5.1131
5.1132 case opc_monitorexit: {
5.1133 out.append("/* monitor exit */");
5.1134 - mapper.popA();
5.1135 + smapper.popA();
5.1136 break;
5.1137 }
5.1138
5.1139 @@ -1127,6 +1096,7 @@
5.1140 out.append("\n");
5.1141 }
5.1142 out.append(" }\n");
5.1143 + out.append("};");
5.1144 }
5.1145
5.1146 private int generateIf(byte[] byteCodes, int i,
5.1147 @@ -1274,7 +1244,7 @@
5.1148 return name.toString();
5.1149 }
5.1150
5.1151 - private int invokeStaticMethod(byte[] byteCodes, int i, final StackToVariableMapper mapper, boolean isStatic)
5.1152 + private int invokeStaticMethod(byte[] byteCodes, int i, final StackMapper mapper, boolean isStatic)
5.1153 throws IOException {
5.1154 int methodIndex = readIntArg(byteCodes, i);
5.1155 String[] mi = jc.getFieldInfoName(methodIndex);
5.1156 @@ -1290,7 +1260,7 @@
5.1157 }
5.1158
5.1159 if (returnType[0] != 'V') {
5.1160 - out.append(mapper.pushT(fieldToVariableType(returnType[0])))
5.1161 + out.append(mapper.pushT(VarType.fromFieldType(returnType[0])))
5.1162 .append(" = ");
5.1163 }
5.1164
5.1165 @@ -1311,7 +1281,7 @@
5.1166 addReference(in);
5.1167 return i;
5.1168 }
5.1169 - private int invokeVirtualMethod(byte[] byteCodes, int i, final StackToVariableMapper mapper)
5.1170 + private int invokeVirtualMethod(byte[] byteCodes, int i, final StackMapper mapper)
5.1171 throws IOException {
5.1172 int methodIndex = readIntArg(byteCodes, i);
5.1173 String[] mi = jc.getFieldInfoName(methodIndex);
5.1174 @@ -1327,7 +1297,7 @@
5.1175 }
5.1176
5.1177 if (returnType[0] != 'V') {
5.1178 - out.append(mapper.pushT(fieldToVariableType(returnType[0])))
5.1179 + out.append(mapper.pushT(VarType.fromFieldType(returnType[0])))
5.1180 .append(" = ");
5.1181 }
5.1182
5.1183 @@ -1517,56 +1487,6 @@
5.1184 ap.parse(data, cd);
5.1185 }
5.1186
5.1187 - private static int constantToVariableType(final byte constantTag) {
5.1188 - switch (constantTag) {
5.1189 - case CONSTANT_INTEGER:
5.1190 - return Variable.TYPE_INT;
5.1191 - case CONSTANT_FLOAT:
5.1192 - return Variable.TYPE_FLOAT;
5.1193 - case CONSTANT_LONG:
5.1194 - return Variable.TYPE_LONG;
5.1195 - case CONSTANT_DOUBLE:
5.1196 - return Variable.TYPE_DOUBLE;
5.1197 -
5.1198 - case CONSTANT_CLASS:
5.1199 - case CONSTANT_UTF8:
5.1200 - case CONSTANT_UNICODE:
5.1201 - case CONSTANT_STRING:
5.1202 - return Variable.TYPE_REF;
5.1203 -
5.1204 - case CONSTANT_FIELD:
5.1205 - case CONSTANT_METHOD:
5.1206 - case CONSTANT_INTERFACEMETHOD:
5.1207 - case CONSTANT_NAMEANDTYPE:
5.1208 - /* unclear how to handle for now */
5.1209 - default:
5.1210 - throw new IllegalStateException("Unhandled constant tag");
5.1211 - }
5.1212 - }
5.1213 -
5.1214 - private static int fieldToVariableType(final char fieldType) {
5.1215 - switch (fieldType) {
5.1216 - case 'B':
5.1217 - case 'C':
5.1218 - case 'S':
5.1219 - case 'Z':
5.1220 - case 'I':
5.1221 - return Variable.TYPE_INT;
5.1222 - case 'J':
5.1223 - return Variable.TYPE_LONG;
5.1224 - case 'F':
5.1225 - return Variable.TYPE_FLOAT;
5.1226 - case 'D':
5.1227 - return Variable.TYPE_DOUBLE;
5.1228 - case 'L':
5.1229 - case '[':
5.1230 - return Variable.TYPE_REF;
5.1231 -
5.1232 - default:
5.1233 - throw new IllegalStateException("Unhandled field type");
5.1234 - }
5.1235 - }
5.1236 -
5.1237 private static void emit(final Appendable out,
5.1238 final String format,
5.1239 final CharSequence... params) throws IOException {
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java Wed Dec 12 11:04:02 2012 +0100
6.3 @@ -0,0 +1,141 @@
6.4 +/**
6.5 + * Back 2 Browser Bytecode Translator
6.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.7 + *
6.8 + * This program is free software: you can redistribute it and/or modify
6.9 + * it under the terms of the GNU General Public License as published by
6.10 + * the Free Software Foundation, version 2 of the License.
6.11 + *
6.12 + * This program is distributed in the hope that it will be useful,
6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 + * GNU General Public License for more details.
6.16 + *
6.17 + * You should have received a copy of the GNU General Public License
6.18 + * along with this program. Look for COPYING file in the top folder.
6.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
6.20 + */
6.21 +package org.apidesign.vm4brwsr;
6.22 +
6.23 +import java.io.IOException;
6.24 +import org.apidesign.javap.RuntimeConstants;
6.25 +import org.apidesign.javap.TypeArray;
6.26 +
6.27 +public final class LocalsMapper {
6.28 + private final TypeArray argTypeRecords;
6.29 + private final TypeArray localTypeRecords;
6.30 +
6.31 + public LocalsMapper(final TypeArray stackMapArgs) {
6.32 + final TypeArray initTypeRecords = new TypeArray();
6.33 + updateRecords(initTypeRecords, stackMapArgs);
6.34 +
6.35 + argTypeRecords = initTypeRecords;
6.36 + localTypeRecords = new TypeArray(initTypeRecords);
6.37 + }
6.38 +
6.39 + public void outputArguments(final Appendable out) throws IOException {
6.40 + final int argRecordCount = argTypeRecords.getSize();
6.41 + if (argRecordCount > 0) {
6.42 + Variable variable = getVariable(argTypeRecords, 0);
6.43 + out.append(variable);
6.44 +
6.45 + int i = variable.isCategory2() ? 2 : 1;
6.46 + while (i < argRecordCount) {
6.47 + variable = getVariable(argTypeRecords, i);
6.48 + out.append(", ");
6.49 + out.append(variable);
6.50 + i += variable.isCategory2() ? 2 : 1;
6.51 + }
6.52 + }
6.53 + }
6.54 +
6.55 + public void syncWithFrameLocals(final TypeArray frameLocals) {
6.56 + updateRecords(localTypeRecords, frameLocals);
6.57 + }
6.58 +
6.59 + public Variable setI(final int index) {
6.60 + return setT(index, VarType.INTEGER);
6.61 + }
6.62 +
6.63 + public Variable setL(final int index) {
6.64 + return setT(index, VarType.LONG);
6.65 + }
6.66 +
6.67 + public Variable setF(final int index) {
6.68 + return setT(index, VarType.FLOAT);
6.69 + }
6.70 +
6.71 + public Variable setD(final int index) {
6.72 + return setT(index, VarType.DOUBLE);
6.73 + }
6.74 +
6.75 + public Variable setA(final int index) {
6.76 + return setT(index, VarType.REFERENCE);
6.77 + }
6.78 +
6.79 + public Variable setT(final int index, final int type) {
6.80 + updateRecord(localTypeRecords, index, type);
6.81 + return Variable.getLocalVariable(type, index);
6.82 + }
6.83 +
6.84 + public Variable getI(final int index) {
6.85 + return getT(index, VarType.INTEGER);
6.86 + }
6.87 +
6.88 + public Variable getL(final int index) {
6.89 + return getT(index, VarType.LONG);
6.90 + }
6.91 +
6.92 + public Variable getF(final int index) {
6.93 + return getT(index, VarType.FLOAT);
6.94 + }
6.95 +
6.96 + public Variable getD(final int index) {
6.97 + return getT(index, VarType.DOUBLE);
6.98 + }
6.99 +
6.100 + public Variable getA(final int index) {
6.101 + return getT(index, VarType.REFERENCE);
6.102 + }
6.103 +
6.104 + public Variable getT(final int index, final int type) {
6.105 + final int oldRecordValue = localTypeRecords.get(index);
6.106 + if ((oldRecordValue & 0xff) != type) {
6.107 + throw new IllegalStateException("Type mismatch");
6.108 + }
6.109 +
6.110 + return Variable.getLocalVariable(type, index);
6.111 + }
6.112 +
6.113 + private static void updateRecords(final TypeArray typeRecords,
6.114 + final TypeArray stackMapTypes) {
6.115 + final int srcSize = stackMapTypes.getSize();
6.116 + for (int i = 0, dstIndex = 0; i < srcSize; ++i) {
6.117 + final int smType = stackMapTypes.get(i);
6.118 + if (smType == RuntimeConstants.ITEM_Bogus) {
6.119 + ++dstIndex;
6.120 + continue;
6.121 + }
6.122 + final int varType = VarType.fromStackMapType(smType);
6.123 + updateRecord(typeRecords, dstIndex, varType);
6.124 + dstIndex += VarType.isCategory2(varType) ? 2 : 1;
6.125 + }
6.126 + }
6.127 +
6.128 + private static void updateRecord(final TypeArray typeRecords,
6.129 + final int index, final int type) {
6.130 + if (typeRecords.getSize() < (index + 1)) {
6.131 + typeRecords.setSize(index + 1);
6.132 + }
6.133 +
6.134 + final int oldRecordValue = typeRecords.get(index);
6.135 + final int usedTypesMask =
6.136 + (oldRecordValue >> 8) | (1 << type);
6.137 + typeRecords.set(index, (usedTypesMask << 8) | type);
6.138 + }
6.139 +
6.140 + private static Variable getVariable(final TypeArray typeRecords,
6.141 + final int index) {
6.142 + return Variable.getLocalVariable(typeRecords.get(index) & 0xff, index);
6.143 + }
6.144 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java Wed Dec 12 11:04:02 2012 +0100
7.3 @@ -0,0 +1,194 @@
7.4 +/**
7.5 + * Back 2 Browser Bytecode Translator
7.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
7.7 + *
7.8 + * This program is free software: you can redistribute it and/or modify
7.9 + * it under the terms of the GNU General Public License as published by
7.10 + * the Free Software Foundation, version 2 of the License.
7.11 + *
7.12 + * This program is distributed in the hope that it will be useful,
7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.15 + * GNU General Public License for more details.
7.16 + *
7.17 + * You should have received a copy of the GNU General Public License
7.18 + * along with this program. Look for COPYING file in the top folder.
7.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
7.20 + */
7.21 +package org.apidesign.vm4brwsr;
7.22 +
7.23 +import org.apidesign.javap.TypeArray;
7.24 +
7.25 +public final class StackMapper {
7.26 + private final TypeArray stackTypeIndexPairs;
7.27 + private int[] typeCounters;
7.28 + private int[] typeMaxCounters;
7.29 +
7.30 + public StackMapper() {
7.31 + stackTypeIndexPairs = new TypeArray();
7.32 + typeCounters = new int[VarType.LAST + 1];
7.33 + typeMaxCounters = new int[VarType.LAST + 1];
7.34 + }
7.35 +
7.36 + public void clear() {
7.37 + for (int type = 0; type <= VarType.LAST; ++type) {
7.38 + typeCounters[type] = 0;
7.39 + }
7.40 + stackTypeIndexPairs.clear();
7.41 + }
7.42 +
7.43 + public void syncWithFrameStack(final TypeArray frameStack) {
7.44 + clear();
7.45 +
7.46 + final int size = frameStack.getSize();
7.47 + for (int i = 0; i < size; ++i) {
7.48 + pushTypeImpl(VarType.fromStackMapType(frameStack.get(i)));
7.49 + }
7.50 + }
7.51 +
7.52 + public Variable pushI() {
7.53 + return pushT(VarType.INTEGER);
7.54 + }
7.55 +
7.56 + public Variable pushL() {
7.57 + return pushT(VarType.LONG);
7.58 + }
7.59 +
7.60 + public Variable pushF() {
7.61 + return pushT(VarType.FLOAT);
7.62 + }
7.63 +
7.64 + public Variable pushD() {
7.65 + return pushT(VarType.DOUBLE);
7.66 + }
7.67 +
7.68 + public Variable pushA() {
7.69 + return pushT(VarType.REFERENCE);
7.70 + }
7.71 +
7.72 + public Variable pushT(final int type) {
7.73 + return getVariable(pushTypeImpl(type));
7.74 + }
7.75 +
7.76 + public Variable popI() {
7.77 + return popT(VarType.INTEGER);
7.78 + }
7.79 +
7.80 + public Variable popL() {
7.81 + return popT(VarType.LONG);
7.82 + }
7.83 +
7.84 + public Variable popF() {
7.85 + return popT(VarType.FLOAT);
7.86 + }
7.87 +
7.88 + public Variable popD() {
7.89 + return popT(VarType.DOUBLE);
7.90 + }
7.91 +
7.92 + public Variable popA() {
7.93 + return popT(VarType.REFERENCE);
7.94 + }
7.95 +
7.96 + public Variable popT(final int type) {
7.97 + final Variable variable = getT(0, type);
7.98 + popImpl(1);
7.99 + return variable;
7.100 + }
7.101 +
7.102 + public Variable pop() {
7.103 + final Variable variable = get(0);
7.104 + popImpl(1);
7.105 + return variable;
7.106 + }
7.107 +
7.108 + public void pop(final int count) {
7.109 + final int stackSize = stackTypeIndexPairs.getSize();
7.110 + if (count > stackSize) {
7.111 + throw new IllegalStateException("Stack underflow");
7.112 + }
7.113 + popImpl(count);
7.114 + }
7.115 +
7.116 + public Variable getI(final int indexFromTop) {
7.117 + return getT(indexFromTop, VarType.INTEGER);
7.118 + }
7.119 +
7.120 + public Variable getL(final int indexFromTop) {
7.121 + return getT(indexFromTop, VarType.LONG);
7.122 + }
7.123 +
7.124 + public Variable getF(final int indexFromTop) {
7.125 + return getT(indexFromTop, VarType.FLOAT);
7.126 + }
7.127 +
7.128 + public Variable getD(final int indexFromTop) {
7.129 + return getT(indexFromTop, VarType.DOUBLE);
7.130 + }
7.131 +
7.132 + public Variable getA(final int indexFromTop) {
7.133 + return getT(indexFromTop, VarType.REFERENCE);
7.134 + }
7.135 +
7.136 + public Variable getT(final int indexFromTop, final int type) {
7.137 + final int stackSize = stackTypeIndexPairs.getSize();
7.138 + if (indexFromTop >= stackSize) {
7.139 + throw new IllegalStateException("Stack underflow");
7.140 + }
7.141 + final int stackValue =
7.142 + stackTypeIndexPairs.get(stackSize - indexFromTop - 1);
7.143 + if ((stackValue & 0xff) != type) {
7.144 + throw new IllegalStateException("Type mismatch");
7.145 + }
7.146 +
7.147 + return getVariable(stackValue);
7.148 + }
7.149 +
7.150 + public Variable get(final int indexFromTop) {
7.151 + final int stackSize = stackTypeIndexPairs.getSize();
7.152 + if (indexFromTop >= stackSize) {
7.153 + throw new IllegalStateException("Stack underflow");
7.154 + }
7.155 + final int stackValue =
7.156 + stackTypeIndexPairs.get(stackSize - indexFromTop - 1);
7.157 +
7.158 + return getVariable(stackValue);
7.159 + }
7.160 +
7.161 + private int pushTypeImpl(final int type) {
7.162 + final int count = typeCounters[type];
7.163 + final int value = (count << 8) | (type & 0xff);
7.164 + incCounter(type);
7.165 + stackTypeIndexPairs.add(value);
7.166 +
7.167 + return value;
7.168 + }
7.169 +
7.170 + private void popImpl(final int count) {
7.171 + final int stackSize = stackTypeIndexPairs.getSize();
7.172 + for (int i = stackSize - count; i < stackSize; ++i) {
7.173 + final int value = stackTypeIndexPairs.get(i);
7.174 + decCounter(value & 0xff);
7.175 + }
7.176 +
7.177 + stackTypeIndexPairs.setSize(stackSize - count);
7.178 + }
7.179 +
7.180 + private void incCounter(final int type) {
7.181 + final int newValue = ++typeCounters[type];
7.182 + if (typeMaxCounters[type] < newValue) {
7.183 + typeMaxCounters[type] = newValue;
7.184 + }
7.185 + }
7.186 +
7.187 + private void decCounter(final int type) {
7.188 + --typeCounters[type];
7.189 + }
7.190 +
7.191 + public Variable getVariable(final int typeAndIndex) {
7.192 + final int type = typeAndIndex & 0xff;
7.193 + final int index = typeAndIndex >> 8;
7.194 +
7.195 + return Variable.getStackVariable(type, index);
7.196 + }
7.197 +}
8.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/StackToVariableMapper.java Fri Dec 07 19:16:21 2012 +0100
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,230 +0,0 @@
8.4 -/**
8.5 - * Back 2 Browser Bytecode Translator
8.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
8.7 - *
8.8 - * This program is free software: you can redistribute it and/or modify
8.9 - * it under the terms of the GNU General Public License as published by
8.10 - * the Free Software Foundation, version 2 of the License.
8.11 - *
8.12 - * This program is distributed in the hope that it will be useful,
8.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.15 - * GNU General Public License for more details.
8.16 - *
8.17 - * You should have received a copy of the GNU General Public License
8.18 - * along with this program. Look for COPYING file in the top folder.
8.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
8.20 - */
8.21 -package org.apidesign.vm4brwsr;
8.22 -
8.23 -import org.apidesign.javap.TypeArray;
8.24 -
8.25 -import static org.apidesign.javap.RuntimeConstants.ITEM_Bogus;
8.26 -import static org.apidesign.javap.RuntimeConstants.ITEM_Integer;
8.27 -import static org.apidesign.javap.RuntimeConstants.ITEM_Float;
8.28 -import static org.apidesign.javap.RuntimeConstants.ITEM_Double;
8.29 -import static org.apidesign.javap.RuntimeConstants.ITEM_Long;
8.30 -import static org.apidesign.javap.RuntimeConstants.ITEM_Null;
8.31 -import static org.apidesign.javap.RuntimeConstants.ITEM_InitObject;
8.32 -import static org.apidesign.javap.RuntimeConstants.ITEM_Object;
8.33 -import static org.apidesign.javap.RuntimeConstants.ITEM_NewObject;
8.34 -
8.35 -public final class StackToVariableMapper {
8.36 - private final TypeArray stackTypeIndexPairs;
8.37 - private int[] typeCounters;
8.38 - private int[] typeMaxCounters;
8.39 -
8.40 - public StackToVariableMapper() {
8.41 - stackTypeIndexPairs = new TypeArray();
8.42 - typeCounters = new int[Variable.LAST_TYPE + 1];
8.43 - typeMaxCounters = new int[Variable.LAST_TYPE + 1];
8.44 - }
8.45 -
8.46 - public void clear() {
8.47 - for (int type = 0; type <= Variable.LAST_TYPE; ++type) {
8.48 - typeCounters[type] = 0;
8.49 - }
8.50 - stackTypeIndexPairs.clear();
8.51 - }
8.52 -
8.53 - public void syncWithFrameStack(final TypeArray frameStack) {
8.54 - clear();
8.55 -
8.56 - final int size = frameStack.getSize();
8.57 - for (int i = 0; i < size; ++i) {
8.58 - final int frameStackValue = frameStack.get(i);
8.59 - switch (frameStackValue & 0xff) {
8.60 - case ITEM_Integer:
8.61 - pushTypeImpl(Variable.TYPE_INT);
8.62 - break;
8.63 - case ITEM_Float:
8.64 - pushTypeImpl(Variable.TYPE_FLOAT);
8.65 - break;
8.66 - case ITEM_Double:
8.67 - pushTypeImpl(Variable.TYPE_DOUBLE);
8.68 - break;
8.69 - case ITEM_Long:
8.70 - pushTypeImpl(Variable.TYPE_LONG);
8.71 - break;
8.72 - case ITEM_Object:
8.73 - pushTypeImpl(Variable.TYPE_REF);
8.74 - break;
8.75 -
8.76 - case ITEM_Bogus:
8.77 - case ITEM_Null:
8.78 - case ITEM_InitObject:
8.79 - case ITEM_NewObject:
8.80 - /* unclear how to handle for now */
8.81 - default:
8.82 - throw new IllegalStateException(
8.83 - "Unhandled frame stack type");
8.84 - }
8.85 - }
8.86 - }
8.87 -
8.88 - public Variable pushI() {
8.89 - return pushT(Variable.TYPE_INT);
8.90 - }
8.91 -
8.92 - public Variable pushL() {
8.93 - return pushT(Variable.TYPE_LONG);
8.94 - }
8.95 -
8.96 - public Variable pushF() {
8.97 - return pushT(Variable.TYPE_FLOAT);
8.98 - }
8.99 -
8.100 - public Variable pushD() {
8.101 - return pushT(Variable.TYPE_DOUBLE);
8.102 - }
8.103 -
8.104 - public Variable pushA() {
8.105 - return pushT(Variable.TYPE_REF);
8.106 - }
8.107 -
8.108 - public Variable pushT(final int type) {
8.109 - return getVariable(pushTypeImpl(type));
8.110 - }
8.111 -
8.112 - public Variable popI() {
8.113 - return popT(Variable.TYPE_INT);
8.114 - }
8.115 -
8.116 - public Variable popL() {
8.117 - return popT(Variable.TYPE_LONG);
8.118 - }
8.119 -
8.120 - public Variable popF() {
8.121 - return popT(Variable.TYPE_FLOAT);
8.122 - }
8.123 -
8.124 - public Variable popD() {
8.125 - return popT(Variable.TYPE_DOUBLE);
8.126 - }
8.127 -
8.128 - public Variable popA() {
8.129 - return popT(Variable.TYPE_REF);
8.130 - }
8.131 -
8.132 - public Variable popT(final int type) {
8.133 - final Variable variable = getT(0, type);
8.134 - popImpl(1);
8.135 - return variable;
8.136 - }
8.137 -
8.138 - public Variable pop() {
8.139 - final Variable variable = get(0);
8.140 - popImpl(1);
8.141 - return variable;
8.142 - }
8.143 -
8.144 - public void pop(final int count) {
8.145 - final int stackSize = stackTypeIndexPairs.getSize();
8.146 - if (count > stackSize) {
8.147 - throw new IllegalStateException("Stack underflow");
8.148 - }
8.149 - popImpl(count);
8.150 - }
8.151 -
8.152 - public Variable getI(final int indexFromTop) {
8.153 - return getT(indexFromTop, Variable.TYPE_INT);
8.154 - }
8.155 -
8.156 - public Variable getL(final int indexFromTop) {
8.157 - return getT(indexFromTop, Variable.TYPE_LONG);
8.158 - }
8.159 -
8.160 - public Variable getF(final int indexFromTop) {
8.161 - return getT(indexFromTop, Variable.TYPE_FLOAT);
8.162 - }
8.163 -
8.164 - public Variable getD(final int indexFromTop) {
8.165 - return getT(indexFromTop, Variable.TYPE_DOUBLE);
8.166 - }
8.167 -
8.168 - public Variable getA(final int indexFromTop) {
8.169 - return getT(indexFromTop, Variable.TYPE_REF);
8.170 - }
8.171 -
8.172 - public Variable getT(final int indexFromTop, final int type) {
8.173 - final int stackSize = stackTypeIndexPairs.getSize();
8.174 - if (indexFromTop >= stackSize) {
8.175 - throw new IllegalStateException("Stack underflow");
8.176 - }
8.177 - final int stackValue =
8.178 - stackTypeIndexPairs.get(stackSize - indexFromTop - 1);
8.179 - if ((stackValue & 0xff) != type) {
8.180 - throw new IllegalStateException("Type mismatch");
8.181 - }
8.182 -
8.183 - return getVariable(stackValue);
8.184 - }
8.185 -
8.186 - public Variable get(final int indexFromTop) {
8.187 - final int stackSize = stackTypeIndexPairs.getSize();
8.188 - if (indexFromTop >= stackSize) {
8.189 - throw new IllegalStateException("Stack underflow");
8.190 - }
8.191 - final int stackValue =
8.192 - stackTypeIndexPairs.get(stackSize - indexFromTop - 1);
8.193 -
8.194 - return getVariable(stackValue);
8.195 - }
8.196 -
8.197 - private int pushTypeImpl(final int type) {
8.198 - final int count = typeCounters[type];
8.199 - final int value = (count << 8) | (type & 0xff);
8.200 - incCounter(type);
8.201 - stackTypeIndexPairs.add(value);
8.202 -
8.203 - return value;
8.204 - }
8.205 -
8.206 - private void popImpl(final int count) {
8.207 - final int stackSize = stackTypeIndexPairs.getSize();
8.208 - for (int i = stackSize - count; i < stackSize; ++i) {
8.209 - final int value = stackTypeIndexPairs.get(i);
8.210 - decCounter(value & 0xff);
8.211 - }
8.212 -
8.213 - stackTypeIndexPairs.setSize(stackSize - count);
8.214 - }
8.215 -
8.216 - private void incCounter(final int type) {
8.217 - final int newValue = ++typeCounters[type];
8.218 - if (typeMaxCounters[type] < newValue) {
8.219 - typeMaxCounters[type] = newValue;
8.220 - }
8.221 - }
8.222 -
8.223 - private void decCounter(final int type) {
8.224 - --typeCounters[type];
8.225 - }
8.226 -
8.227 - public Variable getVariable(final int typeAndIndex) {
8.228 - final int type = typeAndIndex & 0xff;
8.229 - final int index = typeAndIndex >> 8;
8.230 -
8.231 - return Variable.getStackVariable(type, index);
8.232 - }
8.233 -}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VarType.java Wed Dec 12 11:04:02 2012 +0100
9.3 @@ -0,0 +1,110 @@
9.4 +/**
9.5 + * Back 2 Browser Bytecode Translator
9.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
9.7 + *
9.8 + * This program is free software: you can redistribute it and/or modify
9.9 + * it under the terms of the GNU General Public License as published by
9.10 + * the Free Software Foundation, version 2 of the License.
9.11 + *
9.12 + * This program is distributed in the hope that it will be useful,
9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.15 + * GNU General Public License for more details.
9.16 + *
9.17 + * You should have received a copy of the GNU General Public License
9.18 + * along with this program. Look for COPYING file in the top folder.
9.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
9.20 + */
9.21 +package org.apidesign.vm4brwsr;
9.22 +
9.23 +import org.apidesign.javap.RuntimeConstants;
9.24 +
9.25 +public final class VarType {
9.26 + public static final int INTEGER = 0;
9.27 + public static final int LONG = 1;
9.28 + public static final int FLOAT = 2;
9.29 + public static final int DOUBLE = 3;
9.30 + public static final int REFERENCE = 4;
9.31 +
9.32 + public static final int LAST = REFERENCE;
9.33 +
9.34 + private VarType() {
9.35 + }
9.36 +
9.37 + public static boolean isCategory2(final int varType) {
9.38 + return (varType == LONG) || (varType == DOUBLE);
9.39 + }
9.40 +
9.41 + public static int fromStackMapType(final int smType) {
9.42 + switch (smType & 0xff) {
9.43 + case RuntimeConstants.ITEM_Integer:
9.44 + return VarType.INTEGER;
9.45 + case RuntimeConstants.ITEM_Float:
9.46 + return VarType.FLOAT;
9.47 + case RuntimeConstants.ITEM_Double:
9.48 + return VarType.DOUBLE;
9.49 + case RuntimeConstants.ITEM_Long:
9.50 + return VarType.LONG;
9.51 + case RuntimeConstants.ITEM_Object:
9.52 + return VarType.REFERENCE;
9.53 +
9.54 + case RuntimeConstants.ITEM_Bogus:
9.55 + case RuntimeConstants.ITEM_Null:
9.56 + case RuntimeConstants.ITEM_InitObject:
9.57 + case RuntimeConstants.ITEM_NewObject:
9.58 + /* unclear how to handle for now */
9.59 + default:
9.60 + throw new IllegalStateException("Unhandled stack map type");
9.61 + }
9.62 + }
9.63 +
9.64 + public static int fromConstantType(final byte constantTag) {
9.65 + switch (constantTag) {
9.66 + case RuntimeConstants.CONSTANT_INTEGER:
9.67 + return VarType.INTEGER;
9.68 + case RuntimeConstants.CONSTANT_FLOAT:
9.69 + return VarType.FLOAT;
9.70 + case RuntimeConstants.CONSTANT_LONG:
9.71 + return VarType.LONG;
9.72 + case RuntimeConstants.CONSTANT_DOUBLE:
9.73 + return VarType.DOUBLE;
9.74 +
9.75 + case RuntimeConstants.CONSTANT_CLASS:
9.76 + case RuntimeConstants.CONSTANT_UTF8:
9.77 + case RuntimeConstants.CONSTANT_UNICODE:
9.78 + case RuntimeConstants.CONSTANT_STRING:
9.79 + return VarType.REFERENCE;
9.80 +
9.81 + case RuntimeConstants.CONSTANT_FIELD:
9.82 + case RuntimeConstants.CONSTANT_METHOD:
9.83 + case RuntimeConstants.CONSTANT_INTERFACEMETHOD:
9.84 + case RuntimeConstants.CONSTANT_NAMEANDTYPE:
9.85 + /* unclear how to handle for now */
9.86 + default:
9.87 + throw new IllegalStateException("Unhandled constant tag");
9.88 + }
9.89 + }
9.90 +
9.91 + public static int fromFieldType(final char fieldType) {
9.92 + switch (fieldType) {
9.93 + case 'B':
9.94 + case 'C':
9.95 + case 'S':
9.96 + case 'Z':
9.97 + case 'I':
9.98 + return VarType.INTEGER;
9.99 + case 'J':
9.100 + return VarType.LONG;
9.101 + case 'F':
9.102 + return VarType.FLOAT;
9.103 + case 'D':
9.104 + return VarType.DOUBLE;
9.105 + case 'L':
9.106 + case '[':
9.107 + return VarType.REFERENCE;
9.108 +
9.109 + default:
9.110 + throw new IllegalStateException("Unhandled field type");
9.111 + }
9.112 + }
9.113 +}
10.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Variable.java Fri Dec 07 19:16:21 2012 +0100
10.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Variable.java Wed Dec 12 11:04:02 2012 +0100
10.3 @@ -18,15 +18,8 @@
10.4 package org.apidesign.vm4brwsr;
10.5
10.6 public final class Variable implements CharSequence {
10.7 - public static final int TYPE_INT = 0;
10.8 - public static final int TYPE_LONG = 1;
10.9 - public static final int TYPE_FLOAT = 2;
10.10 - public static final int TYPE_DOUBLE = 3;
10.11 - public static final int TYPE_REF = 4;
10.12 -
10.13 - public static final int LAST_TYPE = TYPE_REF;
10.14 -
10.15 private static final String STACK_VAR_PREFIX = "st";
10.16 + private static final String LOCAL_VAR_PREFIX = "lc";
10.17
10.18 private final String name;
10.19 private final int type;
10.20 @@ -46,6 +39,12 @@
10.21 return new Variable(STACK_VAR_PREFIX, type, index);
10.22 }
10.23
10.24 + public static Variable getLocalVariable(
10.25 + final int type, final int index) {
10.26 + // TODO: precreate frequently used variables
10.27 + return new Variable(LOCAL_VAR_PREFIX, type, index);
10.28 + }
10.29 +
10.30 public String getName() {
10.31 return name;
10.32 }
10.33 @@ -59,7 +58,7 @@
10.34 }
10.35
10.36 public boolean isCategory2() {
10.37 - return (type == TYPE_LONG) || (type == TYPE_DOUBLE);
10.38 + return VarType.isCategory2(type);
10.39 }
10.40
10.41 @Override