use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class RedundantBoxingMethodTransformer method adaptCastInstruction.
private static void adaptCastInstruction(@NotNull MethodNode node, @NotNull BoxedValueDescriptor value, @NotNull Pair<AbstractInsnNode, Type> castWithType) {
AbstractInsnNode castInsn = castWithType.getFirst();
MethodNode castInsnsListener = new MethodNode(Opcodes.ASM5);
new InstructionAdapter(castInsnsListener).cast(value.getUnboxedType(), castWithType.getSecond());
for (AbstractInsnNode insn : castInsnsListener.instructions.toArray()) {
node.instructions.insertBefore(castInsn, insn);
}
node.instructions.remove(castInsn);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class AnonymousObjectTransformer method generateConstructorAndFields.
private void generateConstructorAndFields(@NotNull ClassBuilder classBuilder, @NotNull ParametersBuilder allCapturedBuilder, @NotNull ParametersBuilder constructorInlineBuilder, @NotNull FieldRemapper parentRemapper, @NotNull List<CapturedParamInfo> constructorAdditionalFakeParams) {
List<Type> descTypes = new ArrayList<Type>();
Parameters constructorParams = constructorInlineBuilder.buildParameters();
int[] capturedIndexes = new int[constructorParams.getParameters().size()];
int index = 0;
int size = 0;
//complex processing cause it could have super constructor call params
for (ParameterInfo info : constructorParams) {
if (!info.isSkipped) {
//not inlined
if (info.isCaptured() || info instanceof CapturedParamInfo) {
capturedIndexes[index] = size;
index++;
}
if (size != 0) {
//skip this
descTypes.add(info.getType());
}
size += info.getType().getSize();
}
}
String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
//TODO for inline method make public class
transformationInfo.setNewConstructorDescriptor(constructorDescriptor);
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN, constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
final Label newBodyStartLabel = new Label();
constructorVisitor.visitLabel(newBodyStartLabel);
//initialize captured fields
List<NewJavaField> newFieldsWithSkipped = TransformationUtilsKt.getNewFieldsToGenerate(allCapturedBuilder.listCaptured());
List<FieldInfo> fieldInfoWithSkipped = TransformationUtilsKt.transformToFieldInfo(Type.getObjectType(transformationInfo.getNewClassName()), newFieldsWithSkipped);
int paramIndex = 0;
InstructionAdapter capturedFieldInitializer = new InstructionAdapter(constructorVisitor);
for (int i = 0; i < fieldInfoWithSkipped.size(); i++) {
FieldInfo fieldInfo = fieldInfoWithSkipped.get(i);
if (!newFieldsWithSkipped.get(i).getSkip()) {
AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer);
}
paramIndex++;
}
//so we need to add them to captured params
for (CapturedParamInfo info : constructorAdditionalFakeParams) {
CapturedParamInfo fake = constructorInlineBuilder.addCapturedParamCopy(info);
if (fake.getLambda() != null) {
//set remap value to skip this fake (captured with lambda already skipped)
StackValue composed = StackValue.field(fake.getType(), oldObjectType, fake.getNewFieldName(), false, StackValue.LOCAL_0);
fake.setRemapValue(composed);
}
}
MethodNode intermediateMethodNode = new MethodNode(constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode);
AbstractInsnNode first = intermediateMethodNode.instructions.getFirst();
final Label oldStartLabel = first instanceof LabelNode ? ((LabelNode) first).getLabel() : null;
intermediateMethodNode.accept(new MethodBodyVisitor(capturedFieldInitializer) {
@Override
public void visitLocalVariable(@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index) {
if (oldStartLabel == start) {
//patch for jack&jill
start = newBodyStartLabel;
}
super.visitLocalVariable(name, desc, signature, start, end, index);
}
});
constructorVisitor.visitEnd();
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class InlineCodegenUtil method createSpecialEnumMethodBody.
public static MethodNode createSpecialEnumMethodBody(@NotNull ExpressionCodegen codegen, @NotNull String name, @NotNull KotlinType type, @NotNull KotlinTypeMapper typeMapper) {
boolean isValueOf = "enumValueOf".equals(name);
Type invokeType = typeMapper.mapType(type);
String desc = getSpecialEnumFunDescriptor(invokeType, isValueOf);
MethodNode node = new MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null);
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, new InstructionAdapter(node));
if (isValueOf) {
node.visitInsn(Opcodes.ACONST_NULL);
node.visitVarInsn(Opcodes.ALOAD, 0);
node.visitMethodInsn(Opcodes.INVOKESTATIC, ENUM_TYPE.getInternalName(), "valueOf", Type.getMethodDescriptor(ENUM_TYPE, JAVA_CLASS_TYPE, AsmTypes.JAVA_STRING_TYPE), false);
} else {
node.visitInsn(Opcodes.ICONST_0);
node.visitTypeInsn(Opcodes.ANEWARRAY, ENUM_TYPE.getInternalName());
}
node.visitInsn(Opcodes.ARETURN);
node.visitMaxs(isValueOf ? 3 : 2, isValueOf ? 1 : 0);
return node;
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class ImplementationBodyCodegen method generateSecondaryConstructorImpl.
private void generateSecondaryConstructorImpl(@NotNull ClassConstructorDescriptor constructorDescriptor, @NotNull ExpressionCodegen codegen) {
InstructionAdapter iv = codegen.v;
KtSecondaryConstructor constructor = (KtSecondaryConstructor) DescriptorToSourceUtils.descriptorToDeclaration(constructorDescriptor);
markLineNumberForConstructor(constructorDescriptor, constructor, codegen);
ResolvedCall<ConstructorDescriptor> constructorDelegationCall = getDelegationConstructorCall(bindingContext, constructorDescriptor);
ConstructorDescriptor delegateConstructor = constructorDelegationCall == null ? null : constructorDelegationCall.getResultingDescriptor();
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor, constructorDelegationCall);
if (!isSameClassConstructor(delegateConstructor)) {
// Initialization happens only for constructors delegating to super
generateClosureInitialization(iv);
generateInitializers(codegen);
}
assert constructor != null;
if (constructor.hasBody()) {
codegen.gen(constructor.getBodyExpression(), Type.VOID_TYPE);
}
iv.visitInsn(RETURN);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class MemberCodegen method generateConstInstance.
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
v.newField(JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor(), null, null);
if (state.getClassBuilderMode().generateBodies) {
InstructionAdapter iv = createOrGetClInitCodegen().v;
iv.anew(thisAsmType);
iv.dup();
iv.invokespecial(thisAsmType.getInternalName(), "<init>", "()V", false);
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
}
}
Aggregations