use of org.objectweb.asm.Opcodes.INVOKESPECIAL in project groovy by apache.
the class StaticTypesCallSiteWriter method writeListDotProperty.
private void writeListDotProperty(final Expression receiver, final String propertyName, final boolean safe) {
// for lists, replace list.foo with:
// def result = new ArrayList(list.size())
// for (item in list) result.add(item.foo)
// result
ClassNode componentType = receiver.getNodeMetaData(StaticCompilationMetadataKeys.COMPONENT_TYPE);
if (componentType == null) {
componentType = OBJECT_TYPE;
}
CompileStack compileStack = controller.getCompileStack();
MethodVisitor mv = controller.getMethodVisitor();
Label exit = new Label();
if (safe) {
receiver.visit(controller.getAcg());
Label doGet = new Label();
mv.visitJumpInsn(IFNONNULL, doGet);
controller.getOperandStack().remove(1);
mv.visitInsn(ACONST_NULL);
mv.visitJumpInsn(GOTO, exit);
mv.visitLabel(doGet);
}
Variable tmpList = varX("tmpList", ClassHelper.make(ArrayList.class));
int var = compileStack.defineTemporaryVariable(tmpList, false);
Variable iterator = varX("iterator", Iterator_TYPE);
int it = compileStack.defineTemporaryVariable(iterator, false);
Variable nextVar = varX("next", componentType);
final int next = compileStack.defineTemporaryVariable(nextVar, false);
mv.visitTypeInsn(NEW, "java/util/ArrayList");
mv.visitInsn(DUP);
receiver.visit(controller.getAcg());
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
controller.getOperandStack().remove(1);
mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "(I)V", false);
mv.visitVarInsn(ASTORE, var);
Label l1 = new Label();
mv.visitLabel(l1);
receiver.visit(controller.getAcg());
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
controller.getOperandStack().remove(1);
mv.visitVarInsn(ASTORE, it);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitVarInsn(ALOAD, it);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
Label l3 = new Label();
mv.visitJumpInsn(IFEQ, l3);
mv.visitVarInsn(ALOAD, it);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(componentType));
mv.visitVarInsn(ASTORE, next);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitVarInsn(ALOAD, var);
PropertyExpression pexp = propX(bytecodeX(componentType, v -> v.visitVarInsn(ALOAD, next)), propertyName);
pexp.visit(controller.getAcg());
controller.getOperandStack().box();
controller.getOperandStack().remove(1);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
mv.visitInsn(POP);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitJumpInsn(GOTO, l2);
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, var);
if (safe) {
mv.visitLabel(exit);
}
controller.getOperandStack().push(ClassHelper.make(ArrayList.class));
controller.getCompileStack().removeVar(next);
controller.getCompileStack().removeVar(it);
controller.getCompileStack().removeVar(var);
}
use of org.objectweb.asm.Opcodes.INVOKESPECIAL in project groovy by apache.
the class StaticTypesLambdaWriter method newGroovyLambdaWrapperAndLoad.
private void newGroovyLambdaWrapperAndLoad(final ClassNode lambdaClass, final LambdaExpression expression, final boolean accessingInstanceMembers) {
CompileStack compileStack = controller.getCompileStack();
OperandStack operandStack = controller.getOperandStack();
MethodVisitor mv = controller.getMethodVisitor();
String lambdaClassInternalName = BytecodeHelper.getClassInternalName(lambdaClass);
mv.visitTypeInsn(NEW, lambdaClassInternalName);
mv.visitInsn(DUP);
if (controller.isStaticMethod() || compileStack.isInSpecialConstructorCall() || !accessingInstanceMembers) {
classX(controller.getThisType()).visit(controller.getAcg());
} else {
loadThis();
}
operandStack.dup();
loadSharedVariables(expression);
Optional<ConstructorNode> generatedConstructor = lambdaClass.getDeclaredConstructors().stream().filter(ctor -> Boolean.TRUE.equals(ctor.getNodeMetaData(IS_GENERATED_CONSTRUCTOR))).findFirst();
if (!generatedConstructor.isPresent()) {
throw new GroovyBugError("Failed to find the generated constructor");
}
Parameter[] lambdaClassConstructorParameters = generatedConstructor.get().getParameters();
mv.visitMethodInsn(INVOKESPECIAL, lambdaClassInternalName, "<init>", BytecodeHelper.getMethodDescriptor(VOID_TYPE, lambdaClassConstructorParameters), lambdaClass.isInterface());
operandStack.replace(CLOSURE_TYPE, lambdaClassConstructorParameters.length);
}
use of org.objectweb.asm.Opcodes.INVOKESPECIAL in project groovy by apache.
the class AsmClassGenerator method visitStdMethod.
private void visitStdMethod(final MethodNode node, final boolean isConstructor, final Parameter[] parameters, final Statement code) {
controller.getCompileStack().init(node.getVariableScope(), parameters);
controller.getCallSiteWriter().makeSiteEntry();
MethodVisitor mv = controller.getMethodVisitor();
if (isConstructor && (code == null || !((ConstructorNode) node).firstStatementIsSpecialConstructorCall())) {
boolean hasCallToSuper = false;
if (code != null && controller.getClassNode().getOuterClass() != null) {
// the call to super is already added so we must ensure not to add it twice
if (code instanceof BlockStatement) {
hasCallToSuper = ((BlockStatement) code).getStatements().stream().map(statement -> statement instanceof ExpressionStatement ? ((ExpressionStatement) statement).getExpression() : null).anyMatch(expression -> expression instanceof ConstructorCallExpression && ((ConstructorCallExpression) expression).isSuperCall());
}
}
if (!hasCallToSuper) {
if (code != null) {
// GROOVY-9373
controller.visitLineNumber(code.getLineNumber());
}
// add call to "super()"
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, controller.getInternalBaseClassName(), "<init>", "()V", false);
}
}
if (code != null) {
code.visit(this);
}
if (code == null || maybeFallsThrough(code)) {
if (code != null) {
// GROOVY-7647, GROOVY-9373
controller.visitLineNumber(code.getLastLineNumber());
}
if (node.isVoidMethod()) {
mv.visitInsn(RETURN);
} else {
ClassNode type = node.getReturnType();
if (isPrimitiveType(type)) {
mv.visitLdcInsn(Integer.valueOf(0));
OperandStack operandStack = controller.getOperandStack();
operandStack.push(ClassHelper.int_TYPE);
operandStack.doGroovyCast(type);
BytecodeHelper.doReturn(mv, type);
operandStack.remove(1);
} else {
mv.visitInsn(ACONST_NULL);
BytecodeHelper.doReturn(mv, type);
}
}
}
controller.getCompileStack().clear();
}
Aggregations