Search in sources :

Example 1 with Handle

use of dyvilx.tools.asm.Handle in project Dyvil by Dyvil.

the class PropertyReference method writeReference.

@Override
public void writeReference(MethodWriter writer, int lineNumber) throws BytecodeException {
    StringBuilder desc = new StringBuilder().append('(');
    if (this.receiver != null) {
        this.receiver.writeExpression(writer, null);
        this.receiver.getType().appendExtendedName(desc);
    }
    final IType methodType = this.getterMethod.getType();
    final String getterName = this.getterMethod.getInternalName();
    desc.append(')').append('L').append(ReferenceType.LazyFields.getInternalRef(methodType, "")).append(';');
    final Handle getterHandle = this.getterMethod.toHandle();
    final Handle setterHandle = this.setterMethod.toHandle();
    writer.visitLineNumber(lineNumber);
    writer.visitInvokeDynamicInsn(getterName, desc.toString(), BOOTSTRAP, getterHandle, setterHandle);
}
Also used : IType(dyvilx.tools.compiler.ast.type.IType) Handle(dyvilx.tools.asm.Handle)

Example 2 with Handle

use of dyvilx.tools.asm.Handle in project Dyvil by Dyvil.

the class LambdaExpr method writeExpression.

@Override
public void writeExpression(MethodWriter writer, IType type) throws BytecodeException {
    int handleType = this.getHandleType();
    if (handleType == 0) {
        handleType = ClassFormat.H_INVOKESTATIC;
        if (this.captureHelper != null) {
            if (this.captureHelper.isThisCaptured()) {
                handleType = ClassFormat.H_INVOKESPECIAL;
            }
            this.captureHelper.writeCaptures(writer, this.lineNumber());
        }
    }
    final String desc = this.getTargetDescriptor();
    final String invokedName = this.method.getInternalName();
    final String invokedType = this.getInvokeDescriptor();
    final dyvilx.tools.asm.Type methodDescriptorType = dyvilx.tools.asm.Type.getMethodType(this.method.getDescriptor());
    final dyvilx.tools.asm.Type lambdaDescriptorType = dyvilx.tools.asm.Type.getMethodType(this.getLambdaDescriptor());
    final Handle handle = new Handle(handleType, this.owner, this.name, desc);
    writer.visitLineNumber(this.lineNumber());
    writer.visitInvokeDynamicInsn(invokedName, invokedType, BOOTSTRAP, methodDescriptorType, handle, lambdaDescriptorType);
    if (type != null) {
        this.type.writeCast(writer, type, this.lineNumber());
    }
}
Also used : Handle(dyvilx.tools.asm.Handle)

Example 3 with Handle

use of dyvilx.tools.asm.Handle in project Dyvil by Dyvil.

the class AbstractMethod method writeInvoke.

@Override
public void writeInvoke(MethodWriter writer, IValue receiver, ArgumentList arguments, ITypeContext typeContext, int lineNumber) throws BytecodeException {
    if (this.typeParameters != null) {
        this.typeParameters.writeArguments(writer, typeContext);
    }
    writer.visitLineNumber(lineNumber);
    final int opcode;
    final String mangledName = this.getInternalName();
    final String descriptor = this.getDescriptor();
    if (this.hasModifier(Modifiers.EXTENSION)) {
        // extension method invocation
        final Handle handle = new Handle(ClassFormat.H_INVOKESTATIC, this.enclosingClass.getInternalName(), mangledName, descriptor);
        writer.visitInvokeDynamicInsn(mangledName, descriptor, EXTENSION_BSM, handle);
        return;
    }
    final String owner;
    final boolean isInterface;
    if (receiver != null) {
        final IType receiverType = receiver.getType();
        if (receiver.isIgnoredClassAccess() && receiverType.hasTag(IType.TYPE_VAR)) {
            // Dynamic invocation of a static method based on a type variable
            writer.visitInvokeDynamicInsn(mangledName, descriptor.replace("(", "(Ljava/lang/Class;"), STATICVIRTUAL_BSM);
            return;
        }
        if (receiver.valueTag() == IValue.SUPER) {
            // Super-method invocation
            opcode = Opcodes.INVOKESPECIAL;
            owner = this.enclosingClass.getInternalName();
            isInterface = this.enclosingClass.isInterface();
        } else if (this.isStatic()) {
            opcode = Opcodes.INVOKESTATIC;
            owner = this.enclosingClass.getInternalName();
            isInterface = this.enclosingClass.isInterface();
        } else {
            // bugfix: for non-static calls, we use the type of the receiver to avoid
            // IllegalAccessExceptions on the owner class.
            // Example: Calling length() on a StringBuilder object resolves to AbstractStringBuilder.length(),
            // but AbstractStringBuilder is not accessible
            final IClass receiverClass = receiverType.getTheClass();
            opcode = this.getInvokeOpcode(receiverClass);
            owner = receiverType.getInternalName();
            isInterface = receiverClass.isInterface();
        }
    } else {
        opcode = this.getInvokeOpcode();
        owner = this.enclosingClass.getInternalName();
        isInterface = this.enclosingClass.isInterface();
    }
    writer.visitMethodInsn(opcode, owner, mangledName, descriptor, isInterface);
}
Also used : IClass(dyvilx.tools.compiler.ast.classes.IClass) Handle(dyvilx.tools.asm.Handle) IType(dyvilx.tools.compiler.ast.type.IType)

Aggregations

Handle (dyvilx.tools.asm.Handle)3 IType (dyvilx.tools.compiler.ast.type.IType)2 IClass (dyvilx.tools.compiler.ast.classes.IClass)1