Search in sources :

Example 1 with MethodWriter

use of dyvilx.tools.compiler.backend.MethodWriter in project Dyvil by Dyvil.

the class LambdaExpr method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    if (this.getHandleType() != 0) {
        return;
    }
    final boolean thisCaptured = this.captureHelper != null && this.captureHelper.isThisCaptured();
    final int modifiers = thisCaptured ? Modifiers.PRIVATE : Modifiers.PRIVATE | Modifiers.STATIC;
    final MethodWriter methodWriter = new MethodWriterImpl(writer, writer.visitMethod(modifiers, this.name, this.getTargetDescriptor(), null, null));
    int index = 0;
    if (this.captureHelper != null) {
        if (thisCaptured) {
            methodWriter.setThisType(this.owner);
            index = 1;
        }
        this.captureHelper.writeCaptureParameters(methodWriter, index);
    }
    this.parameters.write(methodWriter);
    // Write the Value
    methodWriter.visitCode();
    this.value.writeExpression(methodWriter, this.returnType);
    methodWriter.visitEnd(this.returnType);
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter)

Example 2 with MethodWriter

use of dyvilx.tools.compiler.backend.MethodWriter in project Dyvil by Dyvil.

the class Field method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    final long flags = ModifierUtil.getFlags(this);
    final int modifiers = ModifierUtil.getJavaModifiers(flags);
    final String name = this.getInternalName();
    final String descriptor = this.getDescriptor();
    final String signature = this.getType().needsSignature() ? this.getSignature() : null;
    final Object value = this.getObjectValue();
    final FieldVisitor fieldVisitor = writer.visitField(modifiers, name, descriptor, signature, value);
    this.writeAnnotations(fieldVisitor, flags);
    fieldVisitor.visitEnd();
    if (this.property != null) {
        this.property.write(writer);
    }
    if (!this.hasModifier(Modifiers.LAZY)) {
        return;
    }
    final String lazyName = name + "$lazy";
    final String ownerClass = this.enclosingClass.getInternalName();
    final boolean isStatic = (flags & Modifiers.STATIC) != 0;
    writer.visitField(isStatic ? Modifiers.PRIVATE | Modifiers.STATIC : Modifiers.PRIVATE, lazyName, "Z", null, null);
    final MethodWriter access = new MethodWriterImpl(writer, writer.visitMethod(modifiers, lazyName, "()" + descriptor, null, null));
    access.visitCode();
    // Get the $lazy flag
    int getOpcode;
    if (!isStatic) {
        access.setLocalType(0, ownerClass);
        access.visitVarInsn(Opcodes.ALOAD, 0);
        access.visitFieldInsn(getOpcode = Opcodes.GETFIELD, ownerClass, lazyName, "Z");
    } else {
        access.visitFieldInsn(getOpcode = Opcodes.GETSTATIC, ownerClass, lazyName, "Z");
    }
    Label label = new Label();
    final int returnOpcode = this.type.getReturnOpcode();
    // if (this.fieldName$lazy) {
    access.visitJumpInsn(Opcodes.IFEQ, label);
    if (!isStatic) {
        access.visitVarInsn(Opcodes.ALOAD, 0);
    }
    // this.fieldName ->
    access.visitFieldInsn(getOpcode, ownerClass, name, descriptor);
    // return
    access.visitInsn(returnOpcode);
    // }
    access.visitTargetLabel(label);
    if (!isStatic) {
        access.visitVarInsn(Opcodes.ALOAD, 0);
        access.visitInsn(Opcodes.DUP);
        access.visitLdcInsn(1);
        access.visitFieldInsn(Opcodes.PUTFIELD, ownerClass, lazyName, "Z");
        this.value.writeExpression(access, this.type);
        access.visitInsn(Opcodes.AUTO_DUP_X1);
        access.visitFieldInsn(Opcodes.PUTFIELD, ownerClass, name, descriptor);
    } else {
        access.visitLdcInsn(1);
        access.visitFieldInsn(Opcodes.PUTSTATIC, ownerClass, lazyName, "Z");
        this.value.writeExpression(access, this.type);
        access.visitInsn(Opcodes.AUTO_DUP);
        access.visitFieldInsn(Opcodes.PUTSTATIC, ownerClass, name, descriptor);
    }
    access.visitInsn(returnOpcode);
    access.visitEnd();
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) Label(dyvilx.tools.asm.Label) FieldVisitor(dyvilx.tools.asm.FieldVisitor)

Example 3 with MethodWriter

use of dyvilx.tools.compiler.backend.MethodWriter in project Dyvil by Dyvil.

the class CaptureParameter method getDefaultValue.

@Override
public IValue getDefaultValue(IContext context) {
    final IValue access = new FieldAccess(this.variable) {

        @Override
        public void writeExpression(MethodWriter writer, IType type) throws BytecodeException {
            this.field.writeGetRaw(writer, this.receiver, this.lineNumber());
        }
    }.resolve(MarkerList.BLACKHOLE, context);
    // ensures proper capture
    access.checkTypes(MarkerList.BLACKHOLE, context);
    return access;
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) BytecodeException(dyvilx.tools.compiler.backend.exception.BytecodeException) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) IType(dyvilx.tools.compiler.ast.type.IType)

Example 4 with MethodWriter

use of dyvilx.tools.compiler.backend.MethodWriter in project Dyvil by Dyvil.

the class TraitMetadata method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    final String internalName = this.theClass.getInternalName();
    final MethodWriter initWriter = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC | Modifiers.STATIC, INIT_NAME, "(L" + internalName + ";)V", null, null));
    initWriter.visitCode();
    initWriter.setLocalType(0, internalName);
    this.theClass.writeClassInit(initWriter);
    initWriter.visitInsn(Opcodes.RETURN);
    initWriter.visitEnd();
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter)

Example 5 with MethodWriter

use of dyvilx.tools.compiler.backend.MethodWriter in project Dyvil by Dyvil.

the class AnonymousClassMetadata method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    final CaptureHelper<CaptureField> captureHelper = this.theClass.captureHelper;
    final FieldThis thisField = this.theClass.thisField;
    final IConstructor constructor = this.theClass.constructor;
    captureHelper.writeCaptureFields(writer);
    final MethodWriter initWriter = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.MANDATED, "<init>", this.theClass.getConstructorDesc(), null, null));
    final ParameterList parameterList = constructor.getParameters();
    final int parameterCount = parameterList.size();
    // Signature & Parameter Data
    initWriter.setThisType(this.theClass.getInternalName());
    parameterList.write(initWriter);
    int index = initWriter.localCount();
    int thisIndex = index;
    if (thisField != null) {
        thisField.writeField(writer);
        index = initWriter.visitParameter(index, thisField.getName(), thisField.getTargetClass().getThisType(), Modifiers.MANDATED);
    }
    captureHelper.writeCaptureParameters(initWriter, index);
    // Constructor Body
    initWriter.visitCode();
    initWriter.visitVarInsn(Opcodes.ALOAD, 0);
    for (int i = 0; i < parameterCount; i++) {
        parameterList.get(i).writeGet(initWriter);
    }
    constructor.writeInvoke(initWriter, 0);
    if (thisField != null) {
        initWriter.visitVarInsn(Opcodes.ALOAD, 0);
        initWriter.visitVarInsn(Opcodes.ALOAD, thisIndex);
        initWriter.visitFieldInsn(Opcodes.PUTFIELD, this.theClass.getInternalName(), thisField.getName(), thisField.getDescriptor());
    }
    captureHelper.writeFieldAssignments(initWriter);
    this.theClass.writeClassInit(initWriter);
    initWriter.visitEnd(Types.VOID);
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) IConstructor(dyvilx.tools.compiler.ast.constructor.IConstructor) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) CaptureField(dyvilx.tools.compiler.ast.field.capture.CaptureField)

Aggregations

MethodWriter (dyvilx.tools.compiler.backend.MethodWriter)11 MethodWriterImpl (dyvilx.tools.compiler.backend.MethodWriterImpl)10 IType (dyvilx.tools.compiler.ast.type.IType)5 Label (dyvilx.tools.asm.Label)3 IValue (dyvilx.tools.compiler.ast.expression.IValue)3 ICallableMember (dyvilx.tools.compiler.ast.method.ICallableMember)2 BytecodeException (dyvilx.tools.compiler.backend.exception.BytecodeException)2 HashSet (dyvil.collection.mutable.HashSet)1 Name (dyvil.lang.Name)1 Modifiers (dyvil.reflect.Modifiers)1 Opcodes (dyvil.reflect.Opcodes)1 AnnotatableVisitor (dyvilx.tools.asm.AnnotatableVisitor)1 AnnotationVisitor (dyvilx.tools.asm.AnnotationVisitor)1 FieldVisitor (dyvilx.tools.asm.FieldVisitor)1 TypeReference (dyvilx.tools.asm.TypeReference)1 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)1 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)1 ExternalAnnotation (dyvilx.tools.compiler.ast.attribute.annotation.ExternalAnnotation)1 ModifierUtil (dyvilx.tools.compiler.ast.attribute.modifiers.ModifierUtil)1 IClass (dyvilx.tools.compiler.ast.classes.IClass)1