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);
}
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);
}
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);
}
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);
}
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);
}
Aggregations