Search in sources :

Example 6 with MethodWriter

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

the class CodeClass method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    // Header
    String signature = this.getSignature();
    String superClass = null;
    String[] interfaces = this.getInterfaceArray();
    if (this.superType != null) {
        superClass = this.superType.getInternalName();
    }
    final long flags = ModifierUtil.getFlags(this);
    int modifiers = ModifierUtil.getJavaModifiers(flags);
    if ((modifiers & Modifiers.INTERFACE) == 0) {
        modifiers |= ASMConstants.ACC_SUPER;
    }
    writer.visit(ClassFormat.CLASS_VERSION, modifiers, this.getInternalName(), signature, superClass, interfaces);
    // Source
    writer.visitSource(this.getHeader().getName() + DyvilFileType.DYVIL_EXTENSION, null);
    if (this.enclosingClass != null) {
        this.writeInnerClassInfo(writer);
    }
    // Annotations
    this.writeAnnotations(writer, flags);
    if (this.superType != null) {
        IClass iclass = this.superType.getTheClass();
        if (iclass != null) {
            iclass.writeInnerClassInfo(writer);
        }
    }
    if (this.interfaces != null) {
        for (IType type : this.interfaces) {
            final IClass iclass = type.getTheClass();
            if (iclass != null) {
                iclass.writeInnerClassInfo(writer);
            }
        }
    }
    // Compute Trait Classes
    final Set<IClass> traitClasses;
    if ((modifiers & Modifiers.INTERFACE) == 0) {
        traitClasses = new ArraySet<>();
        this.traitInit = !fillTraitClasses(this, traitClasses, true) && !traitClasses.isEmpty();
    } else {
        traitClasses = null;
    }
    for (int i = 0; i < this.compilableCount; i++) {
        this.compilables[i].write(writer);
    }
    this.metadata.write(writer);
    this.writeClassParameters(writer);
    if (this.body != null) {
        this.body.write(writer);
    }
    this.metadata.writePost(writer);
    // Create the static <clinit> method
    MethodWriter initWriter = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.STATIC, "<clinit>", "()V", null, null));
    initWriter.visitCode();
    this.writeStaticInit(initWriter);
    initWriter.visitEnd(Types.VOID);
    if (traitClasses == null || traitClasses.isEmpty()) {
        return;
    }
    // Create the virtual <traitinit> method
    initWriter = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PROTECTED, TraitMetadata.INIT_NAME, "()V", null, null));
    initWriter.visitCode();
    initWriter.setLocalType(0, this.getInternalName());
    for (IClass traitClass : traitClasses) {
        final String internal = traitClass.getInternalName();
        // Load 'this'
        initWriter.visitVarInsn(Opcodes.ALOAD, 0);
        // Invoke the static <traitinit> method of the trait class
        initWriter.visitMethodInsn(Opcodes.INVOKESTATIC, internal, TraitMetadata.INIT_NAME, "(L" + internal + ";)V", true);
    }
    initWriter.visitInsn(Opcodes.RETURN);
    initWriter.visitEnd();
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) IType(dyvilx.tools.compiler.ast.type.IType)

Example 7 with MethodWriter

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

the class CodeConstructor method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    final long flags = ModifierUtil.getFlags(this);
    final MethodWriter methodWriter = new MethodWriterImpl(writer, writer.visitMethod(ModifierUtil.getJavaModifiers(flags), "<init>", this.getDescriptor(), this.getSignature(), this.getInternalExceptions()));
    // Write Modifiers and Annotations
    ModifierUtil.writeModifiers(methodWriter, flags);
    this.attributes.write(methodWriter);
    if (this.hasModifier(Modifiers.DEPRECATED) && this.getAnnotation(Deprecation.DEPRECATED_CLASS) == null) {
        methodWriter.visitAnnotation(Deprecation.DYVIL_EXTENDED, true).visitEnd();
    }
    // Write Parameters
    methodWriter.setThisType(this.enclosingClass.getInternalName());
    this.parameters.write(methodWriter);
    // Write Code
    final Label start = new Label();
    final Label end = new Label();
    methodWriter.visitCode();
    methodWriter.visitLabel(start);
    if (this.initializerCall != null) {
        this.initializerCall.writeExpression(methodWriter, Types.VOID);
    }
    if (this.initializerCall == null || this.initializerCall.isSuper()) {
        this.enclosingClass.writeClassInit(methodWriter);
    }
    if (this.value != null) {
        this.value.writeExpression(methodWriter, Types.VOID);
    }
    methodWriter.visitLabel(end);
    methodWriter.visitEnd(Types.VOID);
    // Write Local Variable Data
    methodWriter.visitLocalVariable("this", 'L' + this.enclosingClass.getInternalName() + ';', null, start, end, 0);
    this.parameters.writeLocals(methodWriter, start, end);
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) Label(dyvilx.tools.asm.Label)

Example 8 with MethodWriter

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

the class IParameter method writeParameter.

default void writeParameter(MethodWriter writer) {
    final AttributeList annotations = this.getAttributes();
    final IType type = this.getInternalType();
    final long flags = ModifierUtil.getFlags(this);
    final int index = this.getIndex();
    final int localIndex = writer.localCount();
    this.setLocalIndex(localIndex);
    // Add the ACC_VARARGS modifier if necessary
    final int javaModifiers = ModifierUtil.getJavaModifiers(flags) | (this.isVarargs() ? Modifiers.ACC_VARARGS : 0);
    writer.visitParameter(localIndex, this.getQualifiedLabel(), type, javaModifiers);
    // Annotations
    final AnnotatableVisitor visitor = (desc, visible) -> writer.visitParameterAnnotation(index, desc, visible);
    if (annotations != null) {
        annotations.write(visitor);
    }
    ModifierUtil.writeModifiers(visitor, flags);
    IType.writeAnnotations(type, writer, TypeReference.newFormalParameterReference(index), "");
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) Name(dyvil.lang.Name) IContext(dyvilx.tools.compiler.ast.context.IContext) IClassMember(dyvilx.tools.compiler.ast.member.IClassMember) AnnotationReader(dyvilx.tools.compiler.backend.visitor.AnnotationReader) IType(dyvilx.tools.compiler.ast.type.IType) Annotation(dyvilx.tools.compiler.ast.attribute.annotation.Annotation) Opcodes(dyvil.reflect.Opcodes) IVariable(dyvilx.tools.compiler.ast.field.IVariable) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) AnnotatableVisitor(dyvilx.tools.asm.AnnotatableVisitor) ModifierUtil(dyvilx.tools.compiler.ast.attribute.modifiers.ModifierUtil) ClassWriter(dyvilx.tools.compiler.backend.ClassWriter) ICallableMember(dyvilx.tools.compiler.ast.method.ICallableMember) BytecodeException(dyvilx.tools.compiler.backend.exception.BytecodeException) DummyValue(dyvilx.tools.compiler.ast.expression.DummyValue) Modifiers(dyvil.reflect.Modifiers) AnnotationVisitor(dyvilx.tools.asm.AnnotationVisitor) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) TypeReference(dyvilx.tools.asm.TypeReference) IClass(dyvilx.tools.compiler.ast.classes.IClass) InternalType(dyvilx.tools.compiler.ast.type.raw.InternalType) ExternalAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.ExternalAnnotation) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) AnnotatableVisitor(dyvilx.tools.asm.AnnotatableVisitor) IType(dyvilx.tools.compiler.ast.type.IType)

Example 9 with MethodWriter

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

the class IParameter method writeDefaultValue.

default void writeDefaultValue(ClassWriter writer) {
    final IValue value = this.getValue();
    assert value != null;
    final ICallableMember method = this.getMethod();
    final IType type = this.getType();
    final String name;
    final int access;
    if (method == null) {
        name = "init$paramDefault$" + this.getInternalName();
        access = Modifiers.STATIC;
    } else {
        name = method.getInternalName() + "$paramDefault$" + this.getInternalName();
        access = (method.getAttributes().flags() & Modifiers.MEMBER_MODIFIERS) | Modifiers.STATIC;
    }
    final String desc = "()" + this.getDescriptor();
    final String signature = "()" + this.getSignature();
    final MethodWriter mw = new MethodWriterImpl(writer, writer.visitMethod(access, name, desc, signature, null));
    mw.visitCode();
    value.writeExpression(mw, type);
    mw.visitEnd(type);
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) ICallableMember(dyvilx.tools.compiler.ast.method.ICallableMember) IType(dyvilx.tools.compiler.ast.type.IType)

Example 10 with MethodWriter

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

the class CaseClassMetadata method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    super.write(writer);
    MethodWriter mw;
    final String internal = this.theClass.getInternalName();
    if ((this.members & EQUALS) == 0) {
        mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null));
        mw.setThisType(internal);
        mw.visitParameter(1, "obj", Types.OBJECT, 0);
        mw.visitCode();
        CaseClasses.writeEquals(mw, this.theClass);
        mw.visitEnd();
    }
    if ((this.members & HASHCODE) == 0) {
        mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC, "hashCode", "()I", null, null));
        mw.setThisType(internal);
        mw.visitCode();
        CaseClasses.writeHashCode(mw, this.theClass);
        mw.visitEnd();
    }
    if ((this.members & TOSTRING) == 0) {
        mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC, "toString", "()Ljava/lang/String;", null, null));
        mw.setThisType(internal);
        mw.visitCode();
        CaseClasses.writeToString(mw, this.theClass);
        mw.visitEnd();
    }
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter)

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