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