/** * Gets the type of the value at a given index on the operand stack. * * @param index the operand stack index * @return the type of the value at index <code>index</code> on the operand stack */ public Klass getStackTypeAt(int index) { Assert.that(index < sp, "index out of bounds"); if (stack[index] == null) { return Klass.getSecondWordType(stack[index - 1].getType()); } else { return stack[index].getType(); } }
/** * Emulates the storing of a value to a local variable. * * @param index the index of the local variable being stored to * @param type the type of the value * @param local the variable to which the value is stored */ public void store(int index, Klass type, Local local) { Klass localType = local.getType(); Assert.that(localType.isAssignableFrom(type) || localType == getLocalTypeFor(type)); verifyLocalVariableIndex(localType, index); localTypes[index] = type; if (localType.isDoubleWord()) { localTypes[index + 1] = Klass.getSecondWordType(localType); } else { verifyUseOfSquawkPrimitive(localType, type); } }
/** * Emulates loading a value of a given type from a local variable. * * @param index the index of the local variable being loaded from * @param localType the expected type of the variable from which the value is loaded * @return the variable from which the value is loaded */ public Local load(int index, Klass localType) { verifyLocalVariableIndex(localType, index); Klass derivedType = localTypes[index]; if (!localType.isAssignableFrom(derivedType)) { throw codeParser.verifyError("incompatible type in local variable"); } if (localType.isDoubleWord()) { Klass secondWordType = Klass.getSecondWordType(localType); if (!secondWordType.isAssignableFrom(localTypes[index + 1])) { throw codeParser.verifyError("incompatible type in local variable"); } } if (derivedType.isSquawkPrimitive()) { localType = derivedType; } return allocateLocal(localType, index); }