int currentStack = compileContext.getStackCount();
int size = ((type.getNBytes() > 4) ? 2 : 1);
if (index == HELPER_IDX) {
// not allowed to reassign the helper binding
throw new CompileException("DollarExpression.compileAssign : invalid assignment to helper binding $$");
} else {
// value to be assigned is TOS and will already be coerced to the correct value type
// copy it so we leave it as a a return value on the stack
if (size == 2) {
mv.visitInsn(Opcodes.DUP2);
} else {
mv.visitInsn(Opcodes.DUP);
}
// stack the current helper then insert it below the value
mv.visitVarInsn(Opcodes.ALOAD, 0);
if (size == 2) {
// use a DUP_X2 to push a copy below the value then pop the redundant value
mv.visitInsn(Opcodes.DUP_X2);
mv.visitInsn(Opcodes.POP);
} else {
// we can just swap the two values
mv.visitInsn(Opcodes.SWAP);
}
// stack the name for the variable and swap below the value
mv.visitLdcInsn(targetName);
if (size == 2) {
// use a DUP_X2 to push a copy below the value then pop the redundant value
mv.visitInsn(Opcodes.DUP_X2);
// this is the high water mark
// at this point the stack has gone from [ .. val1 val2] to [.. val1 val2 helper name val1 val2 name]
compileContext.addStackCount(5);
mv.visitInsn(Opcodes.POP);
compileContext.addStackCount(-1);
} else {
// this is the high water mark
// at this point the stack has gone from [ .. val] to [.. val helper val name]
compileContext.addStackCount(3);
// we can just swap the two values
mv.visitInsn(Opcodes.SWAP);
}
// ensure we have an object
compileObjectConversion(type, Type.OBJECT, mv, compileContext);
// call the setBinding method
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V");
// the call will remove 3 from the stack height
compileContext.addStackCount(-3);
// ok, the stack height should be as it was
if (compileContext.getStackCount() != currentStack) {
throw new CompileException("variable.compileAssignment : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack);
}
}
}