Search in sources :

Example 6 with Label

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

the class CastOperator method writeExpression.

@Override
public void writeExpression(MethodWriter writer, IType type) throws BytecodeException {
    if (type == null) {
        type = this.type;
    }
    if (Types.isVoid(type)) {
        this.value.writeExpression(writer, null);
        writer.visitInsn(Opcodes.AUTO_POP);
        return;
    }
    if (!this.optional) {
        this.value.writeExpression(writer, null);
        this.value.getType().writeCast(writer, type, this.lineNumber());
        return;
    }
    final Label elseLabel = new Label();
    final Label endLabel = new Label();
    // Generate the following code:
    // { let a = <expr>; if a is <Type> { a as Type } else null }
    final int localCount = writer.localCount();
    final int varIndex = this.value.writeStoreLoad(writer, null);
    // if (a is <Type>)
    writer.visitTypeInsn(Opcodes.INSTANCEOF, this.type.getInternalName());
    writer.visitJumpInsn(Opcodes.IFEQ, elseLabel);
    // { a as Type
    writer.visitVarInsn(Opcodes.ALOAD, varIndex);
    this.value.getType().writeCast(writer, type, this.lineNumber());
    writer.visitJumpInsn(Opcodes.GOTO, endLabel);
    // } else { null
    writer.visitTargetLabel(elseLabel);
    writer.visitInsn(Opcodes.ACONST_NULL);
    // }
    writer.visitTargetLabel(endLabel);
    writer.resetLocals(localCount);
}
Also used : Label(dyvilx.tools.asm.Label)

Example 7 with Label

use of dyvilx.tools.asm.Label 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 Label

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

the class SpecialIntrinsicData method writeIntrinsic.

@Override
public void writeIntrinsic(MethodWriter writer, IValue receiver, ArgumentList arguments, int lineNumber) throws BytecodeException {
    final int varIndex = writer.localCount();
    final int[] ints = this.instructions;
    int insnIndex = 0;
    final Label[] labels = this.getLabels();
    Label label;
    for (int i = 0, length = ints.length; i < length; i++) {
        if (labels != null && (label = labels[insnIndex++]) != null) {
            writer.visitTargetLabel(label);
        }
        final int opcode = ints[i];
        if (Opcodes.isFieldOpcode(opcode)) {
            final String owner = this.strings[ints[i + 1]];
            final String name = this.strings[ints[i + 2]];
            final String desc = this.strings[ints[i + 3]];
            writer.visitFieldInsn(opcode, owner, name, desc);
            i += 3;
            continue;
        }
        if (Opcodes.isMethodOpcode(opcode)) {
            final String owner = this.strings[ints[i + 1]];
            final String name = this.strings[ints[i + 2]];
            final String desc = this.strings[ints[i + 3]];
            writer.visitLineNumber(lineNumber);
            visitMethodInsn(writer, opcode, owner, name, desc);
            i += 3;
            continue;
        }
        if (Opcodes.isJumpOpcode(opcode)) {
            // noinspection ConstantConditions
            writer.visitJumpInsn(opcode, labels[ints[i + 1]]);
            i += 1;
            continue;
        }
        if (Opcodes.isLoadOpcode(opcode) || Opcodes.isStoreOpcode(opcode)) {
            writer.visitVarInsn(opcode, varIndex + ints[i + 1]);
            i += 1;
            continue;
        }
        switch(opcode) {
            case Opcodes.BIPUSH:
            case Opcodes.SIPUSH:
                writer.visitLdcInsn(ints[i + 1]);
                i++;
                continue;
            case Opcodes.LDC:
                final String constant = this.strings[ints[i + 1]];
                writeLDC(writer, constant);
                i++;
                continue;
        }
        IntrinsicData.writeInsn(writer, this.method, opcode, receiver, arguments, lineNumber);
    }
    if (labels != null && (label = labels[insnIndex]) != null) {
        writer.visitTargetLabel(label);
    }
    writer.resetLocals(varIndex);
}
Also used : Label(dyvilx.tools.asm.Label)

Example 9 with Label

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

the class Pattern method writeJumpOnMatch.

default void writeJumpOnMatch(MethodWriter writer, int varIndex, Label target) throws BytecodeException {
    final Label rightLabel = new Label();
    this.writeJumpOnMismatch(writer, varIndex, rightLabel);
    writer.visitJumpInsn(Opcodes.GOTO, target);
    writer.visitLabel(rightLabel);
}
Also used : Label(dyvilx.tools.asm.Label)

Example 10 with Label

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

the class CaseClasses method writeEquals.

public static void writeEquals(MethodWriter writer, IClass theClass) throws BytecodeException {
    Label label;
    // Write check 'if (this == obj) return true'
    writer.visitVarInsn(ALOAD, 0);
    writer.visitVarInsn(ALOAD, 1);
    writer.visitJumpInsn(IF_ACMPNE, label = new Label());
    writer.visitLdcInsn(1);
    writer.visitInsn(IRETURN);
    writer.visitLabel(label);
    // if (obj == null) return false
    writer.visitVarInsn(ALOAD, 1);
    writer.visitJumpInsn(IFNONNULL, label = new Label());
    writer.visitLdcInsn(0);
    writer.visitInsn(IRETURN);
    writer.visitLabel(label);
    // if (this.getClass() != obj.getClass()) return false
    writer.visitVarInsn(ALOAD, 0);
    writer.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
    writer.visitVarInsn(ALOAD, 1);
    writer.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
    writer.visitJumpInsn(IF_ACMPEQ, label = new Label());
    writer.visitLdcInsn(0);
    writer.visitInsn(IRETURN);
    writer.visitLabel(label);
    // var = (ClassName) obj
    writer.visitVarInsn(ALOAD, 1);
    writer.visitTypeInsn(CHECKCAST, theClass.getInternalName());
    // 'var' variable that stores the casted 'obj' parameter
    writer.visitVarInsn(ASTORE, 2);
    label = new Label();
    final ParameterList parameters = theClass.getParameters();
    for (int i = 0, count = parameters.size(); i < count; i++) {
        writeEquals(writer, parameters.get(i), label);
    }
    writer.visitLdcInsn(1);
    writer.visitInsn(IRETURN);
    writer.visitLabel(label);
    writer.visitLdcInsn(0);
    writer.visitInsn(IRETURN);
}
Also used : Label(dyvilx.tools.asm.Label) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList)

Aggregations

Label (dyvilx.tools.asm.Label)16 MethodWriterImpl (dyvilx.tools.compiler.backend.MethodWriterImpl)4 IType (dyvilx.tools.compiler.ast.type.IType)3 MethodWriter (dyvilx.tools.compiler.backend.MethodWriter)3 Nullable (dyvil.annotation.internal.Nullable)1 HashSet (dyvil.collection.mutable.HashSet)1 FieldVisitor (dyvilx.tools.asm.FieldVisitor)1 ParameterList (dyvilx.tools.compiler.ast.parameter.ParameterList)1 Pattern (dyvilx.tools.compiler.ast.pattern.Pattern)1 ArrayType (dyvilx.tools.compiler.ast.type.compound.ArrayType)1