use of dyvilx.tools.compiler.backend.MethodWriterImpl 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);
}
use of dyvilx.tools.compiler.backend.MethodWriterImpl 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();
}
use of dyvilx.tools.compiler.backend.MethodWriterImpl in project Dyvil by Dyvil.
the class ObjectClassMetadata method write.
@Override
public void write(ClassWriter writer) throws BytecodeException {
super.write(writer);
String internalName = this.theClass.getInternalName();
if ((this.members & TOSTRING) == 0) {
// Generate a toString() method that simply returns the name of this
// object type.
MethodWriterImpl mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC, "toString", "()Ljava/lang/String;", null, null));
mw.visitCode();
mw.setThisType(internalName);
mw.visitLdcInsn(this.theClass.getName().unqualified);
mw.visitInsn(Opcodes.ARETURN);
mw.visitEnd(Types.STRING);
}
if ((this.members & EQUALS) == 0) {
// Generate an equals(Object) method that compares the objects for
// identity
MethodWriterImpl mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null));
mw.visitCode();
mw.setThisType(internalName);
mw.visitParameter(1, "obj", Types.ANY, 0);
mw.visitVarInsn(Opcodes.ALOAD, 0);
mw.visitVarInsn(Opcodes.ALOAD, 1);
Label label = new Label();
mw.visitJumpInsn(Opcodes.IF_ACMPNE, label);
mw.visitLdcInsn(1);
mw.visitInsn(Opcodes.IRETURN);
mw.visitLabel(label);
mw.visitLdcInsn(0);
mw.visitInsn(Opcodes.IRETURN);
mw.visitEnd();
}
if ((this.members & HASHCODE) == 0) {
MethodWriterImpl mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PUBLIC, "hashCode", "()I", null, null));
mw.visitCode();
mw.setThisType(internalName);
mw.visitLdcInsn(internalName.hashCode());
mw.visitInsn(Opcodes.IRETURN);
mw.visitEnd();
}
if ((this.members & READ_RESOLVE) == 0) {
MethodWriterImpl mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PRIVATE | Modifiers.SYNTHETIC, "readResolve", "()Ljava/lang/Object;", null, null));
writeResolveBody(mw, internalName);
}
if ((this.members & WRITE_REPLACE) == 0) {
MethodWriterImpl mw = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.PRIVATE | Modifiers.SYNTHETIC, "writeReplace", "()Ljava/lang/Object;", null, null));
writeResolveBody(mw, internalName);
}
}
use of dyvilx.tools.compiler.backend.MethodWriterImpl 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();
}
use of dyvilx.tools.compiler.backend.MethodWriterImpl 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);
}
Aggregations