private int getReturn(Type type) { if (type.isPrimitive()) { // TODO: other primitive types switch (type.getClassIdentifier().charAt(0)) { case 'I': // int case 'Z': // boolean return IRETURN; case 'J': // long return LRETURN; case 'F': // float return FRETURN; case 'D': // float return DRETURN; default: throw new RuntimeException("Unsupported " + type + " " + type.getClassIdentifier().charAt(0)); } } else { return ARETURN; } }
private int getALoad(Type type) { if (type.isPrimitive()) { // TODO: other primitive types switch (type.getClassIdentifier().charAt(0)) { case 'I': // int case 'Z': // boolean return IALOAD; case 'J': // long return LALOAD; case 'F': // float return FALOAD; case 'D': // double return DALOAD; case 'C': // char case 'V': // void case 'B': // byte case 'S': // short default: throw new RuntimeException("Unsupported "+type); } } else { return AALOAD; } }
private void incLocalVarIndex(Type type) { if (!type.isPrimitive()) { ++ currentLocalVariableByteCodeIndex; } else { switch (type.getClassIdentifier().charAt(0)) { case 'I': // int case 'Z': // boolean case 'F': // float case 'C': // char case 'V': // void case 'B': // byte case 'S': // short ++ currentLocalVariableByteCodeIndex; break; case 'J': // long case 'D': // double currentLocalVariableByteCodeIndex += 2; break; default: throw new RuntimeException("Unsupported "+type); } } }
private int getLoad(Type type) { if (type.isPrimitive()) { // TODO: other primitive types switch (type.getClassIdentifier().charAt(0)) { case 'I': // int case 'Z': // boolean return ILOAD; case 'J': // long return LLOAD; case 'F': // float return FLOAD; case 'D': // double return DLOAD; case 'C': // char case 'V': // void case 'B': // byte case 'S': // short default: throw new RuntimeException("Unsupported "+type); } } else { return ALOAD; } }
private int getStore(Type type) { if (type.isPrimitive()) { // TODO: other primitive types switch (type.getClassIdentifier().charAt(0)) { case 'I': // int case 'Z': // boolean return ISTORE; case 'J': // long return LSTORE; case 'F': // float return FSTORE; case 'D': // double return DSTORE; case 'C': // char case 'V': // void case 'B': // byte case 'S': // short default: throw new RuntimeException("Unsupported "+type); } } else { return ASTORE; } }
public void cast(Type type, Object... comments) { addInstruction(new TypeInsnNode(CHECKCAST, type.getClassIdentifier()), comments); }
public void box(PrimitiveType primitiveType, Object... comment) { addInstruction( new MethodInsnNode( INVOKESTATIC, primitiveType.getBoxedType().getClassIdentifier(), "valueOf", "("+primitiveType.getSignature()+")"+primitiveType.getBoxedType().getSignature()), addComment(comment, "unboxing", primitiveType)); }
@Override public void visit(InstanceOfExpression instanceOfExpression) { methodByteCodeContext.incIndent("instanceOF"); instanceOfExpression.getExpression().accept(this); methodByteCodeContext.addInstruction(new TypeInsnNode(INSTANCEOF, instanceOfExpression.getType().getClassIdentifier())); lastExpressionType = BOOLEAN; methodByteCodeContext.decIndent(); }
@Override public void visit(InstanceOfExpression instanceOfExpression) { methodByteCodeContext.incIndent("if instanceof", instanceOfExpression.getType()); ASMMethodGenerator.this.visit(instanceOfExpression.getExpression()); methodByteCodeContext.addInstruction(new TypeInsnNode(INSTANCEOF, instanceOfExpression.getType().getClassIdentifier()), "if"); generateThenElse(IFEQ, ifStatement.getElseStatements(), ifStatement.getThenStatements()); methodByteCodeContext.decIndent(); }
public void unbox(PrimitiveType primitiveType, Object... comment) { String boxedClassIdentifier = primitiveType.getBoxedType().getClassIdentifier(); addInstruction(new TypeInsnNode(CHECKCAST, boxedClassIdentifier), addComment(comment, "unboxing", primitiveType)); addInstruction(new MethodInsnNode( INVOKEVIRTUAL, boxedClassIdentifier, primitiveType.getName()+"Value", "()"+primitiveType.getClassIdentifier()), addComment(comment, "unboxing", primitiveType)); }
@Override public void visit(InstantiationExpression instantiationExpression) { // new instance involves creating a new object and then calling the constructor Type type = instantiationExpression.getType(); methodByteCodeContext.incIndent("new ", type.getName(), "()"); methodByteCodeContext.addInstruction(new TypeInsnNode(NEW, type.getClassIdentifier()), "new ", type.getName(), "()"); methodByteCodeContext.dup("for constructor call"); // so that we still have a reference to the object after we call the constructor. Method constructor = type.getConstructor(instantiationExpression.getParameters().size()); if (constructor == null) { throw new RuntimeException( "can't find constructor with " + instantiationExpression.getParameters().size() + " parameters in " + type); } loadParameters("<init>", constructor, instantiationExpression.getParameters()); methodByteCodeContext.addInstruction(new MethodInsnNode(INVOKESPECIAL, type.getClassIdentifier(), "<init>", constructor.getSignature()), "new ", type.getName(), "(...)"); lastExpressionType = type; methodByteCodeContext.decIndent(); }
classNode.superName = futureType.getExtending().getClassIdentifier(); if (classNode.name.indexOf('$') != -1) { String declaringClass = classNode.name.substring(0, classNode.name.lastIndexOf("$"));
public void newArray(Type type, Object... comments) { if (type.isPrimitive()) { switch (type.getClassIdentifier().charAt(0)) { case 'I': // int addInstruction(new IntInsnNode(NEWARRAY, T_INT), comments); addInstruction(new TypeInsnNode(ANEWARRAY, type.getClassIdentifier()), comments);
@Override public void visit(CallConstructorExpression callConstructorExpression) { methodByteCodeContext.incIndent("call super constructor"); methodByteCodeContext.loadThis(); Method constructor = methodContext.getType().getSuperConstructor(callConstructorExpression.getParameters().size()); if (constructor == null) { throw new RuntimeException( "can't find constructor with " + callConstructorExpression.getParameters().size() + " parameters in " + methodContext.getType().getExtending() + " parent of " + methodContext.getType()); } loadParameters("<init>", constructor, callConstructorExpression.getParameters()); methodByteCodeContext.addInstruction(new MethodInsnNode(INVOKESPECIAL, methodContext.getType().getExtending().getClassIdentifier(), "<init>", constructor.getSignature()), "super(...)"); methodByteCodeContext.decIndent(); }