use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class ImplementationBodyCodegen method generatePrimaryConstructorImpl.
private void generatePrimaryConstructorImpl(@NotNull ClassConstructorDescriptor constructorDescriptor, @NotNull ExpressionCodegen codegen, @NotNull DelegationFieldsInfo fieldsInfo, @Nullable KtPrimaryConstructor primaryConstructor) {
InstructionAdapter iv = codegen.v;
markLineNumberForConstructor(constructorDescriptor, primaryConstructor, codegen);
generateClosureInitialization(iv);
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor, getDelegationConstructorCall(bindingContext, constructorDescriptor));
if (isNonCompanionObject(descriptor)) {
StackValue.singletonViaInstance(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
}
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatedSuperTypeEntry) specifier, fieldsInfo);
}
}
int curParam = 0;
List<ValueParameterDescriptor> parameters = constructorDescriptor.getValueParameters();
for (KtParameter parameter : getPrimaryConstructorParameters()) {
if (parameter.hasValOrVar()) {
VariableDescriptor descriptor = parameters.get(curParam);
Type type = typeMapper.mapType(descriptor);
iv.load(0, classAsmType);
iv.load(codegen.myFrameMap.getIndex(descriptor), type);
PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
assert propertyDescriptor != null : "Property descriptor is not found for primary constructor parameter: " + parameter;
iv.putfield(classAsmType.getInternalName(), context.getFieldName(propertyDescriptor, false), type.getDescriptor());
}
curParam++;
}
if (isCompanionObject(descriptor)) {
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
parentCodegen.generateCompanionObjectInitializer(descriptor);
}
if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
generateInitializers(new Function0<ExpressionCodegen>() {
@Override
public ExpressionCodegen invoke() {
return parentCodegen.createOrGetClInitCodegen();
}
});
} else {
generateInitializers(codegen);
}
iv.visitInsn(RETURN);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class ImplementationBodyCodegen method initializeEnumConstants.
private void initializeEnumConstants(@NotNull List<KtEnumEntry> enumEntries) {
if (!state.getClassBuilderMode().generateBodies)
return;
ExpressionCodegen codegen = createOrGetClInitCodegen();
InstructionAdapter iv = codegen.v;
Type arrayAsmType = typeMapper.mapType(DescriptorUtilsKt.getBuiltIns(descriptor).getArrayType(INVARIANT, descriptor.getDefaultType()));
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass), ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, ENUM_VALUES_FIELD_NAME, arrayAsmType.getDescriptor(), null, null);
iv.iconst(enumEntries.size());
iv.newarray(classAsmType);
if (!enumEntries.isEmpty()) {
iv.dup();
for (int ordinal = 0, size = enumEntries.size(); ordinal < size; ordinal++) {
initializeEnumConstant(enumEntries, ordinal);
}
}
iv.putstatic(classAsmType.getInternalName(), ENUM_VALUES_FIELD_NAME, arrayAsmType.getDescriptor());
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class FunctionCodegen method generateBridge.
private void generateBridge(@Nullable PsiElement origin, @NotNull FunctionDescriptor descriptor, @NotNull Method bridge, @NotNull Method delegateTo, boolean isSpecialBridge, boolean isStubDeclarationWithDelegationToSuper) {
boolean isSpecialOrDelegationToSuper = isSpecialBridge || isStubDeclarationWithDelegationToSuper;
// TODO.
int flags = ACC_PUBLIC | ACC_BRIDGE | (!isSpecialOrDelegationToSuper ? ACC_SYNTHETIC : 0) | (isSpecialBridge ? ACC_FINAL : 0);
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.Bridge(descriptor, origin), flags, bridge.getName(), bridge.getDescriptor(), null, null);
if (!state.getClassBuilderMode().generateBodies)
return;
mv.visitCode();
Type[] argTypes = bridge.getArgumentTypes();
Type[] originalArgTypes = delegateTo.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv);
MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv);
if (delegateTo.getArgumentTypes().length > 0 && isSpecialBridge) {
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes());
}
iv.load(0, OBJECT_TYPE);
for (int i = 0, reg = 1; i < argTypes.length; i++) {
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
//noinspection AssignmentToForLoopParameter
reg += argTypes[i].getSize();
}
if (isStubDeclarationWithDelegationToSuper) {
ClassDescriptor parentClass = getSuperClassDescriptor((ClassDescriptor) descriptor.getContainingDeclaration());
assert parentClass != null;
String parentInternalName = typeMapper.mapClass(parentClass).getInternalName();
iv.invokespecial(parentInternalName, delegateTo.getName(), delegateTo.getDescriptor(), false);
} else {
if (isJvm8InterfaceWithDefaultsMember(descriptor, state)) {
iv.invokeinterface(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor());
} else {
iv.invokevirtual(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor(), false);
}
}
StackValue.coerce(delegateTo.getReturnType(), bridge.getReturnType(), iv);
iv.areturn(bridge.getReturnType());
endVisit(mv, "bridge method", origin);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class FunctionReferenceGenerationStrategy method doGenerateBody.
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
/*
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invocation
of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
ExpressionCodegen and, in order for it to generate code correctly, we save to its 'tempVariables' field every
argument of our fake expression, pointing it to the corresponding index in our locals. This way generation of
every argument boils down to calling LOAD with the corresponding index
*/
KtCallExpression fakeExpression = CodegenUtil.constructFakeFunctionCall(state.getProject(), referencedFunction);
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
final ReceiverValue dispatchReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getDispatchReceiverParameter());
final ReceiverValue extensionReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getExtensionReceiverParameter());
computeAndSaveArguments(fakeArguments, codegen);
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
private final Map<ValueParameterDescriptor, ResolvedValueArgument> argumentMap;
{
argumentMap = new LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>(fakeArguments.size());
int index = 0;
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
for (ValueArgument argument : fakeArguments) {
argumentMap.put(parameters.get(index), new ExpressionValueArgument(argument));
index++;
}
}
@Nullable
@Override
public ReceiverValue getExtensionReceiver() {
return extensionReceiver;
}
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return dispatchReceiver;
}
@NotNull
@Override
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
return new ArrayList<ResolvedValueArgument>(argumentMap.values());
}
@NotNull
@Override
public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
return argumentMap;
}
};
StackValue result;
Type returnType = codegen.getReturnType();
if (referencedFunction instanceof ConstructorDescriptor) {
if (returnType.getSort() == Type.ARRAY) {
//noinspection ConstantConditions
result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType(), fakeResolvedCall);
} else {
result = codegen.generateConstructorCall(fakeResolvedCall, returnType);
}
} else {
Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
}
InstructionAdapter v = codegen.v;
result.put(returnType, v);
v.areturn(returnType);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class ExpressionCodegen method visitObjectLiteralExpression.
@Override
public StackValue visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, StackValue receiver) {
final ObjectLiteralResult objectLiteralResult = generateObjectLiteral(expression);
final ClassDescriptor classDescriptor = objectLiteralResult.classDescriptor;
final Type type = typeMapper.mapType(classDescriptor);
return StackValue.operation(type, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
if (objectLiteralResult.wereReifiedMarkers) {
ReifiedTypeInliner.putNeedClassReificationMarker(v);
}
v.anew(type);
v.dup();
pushClosureOnStack(classDescriptor, true, defaultCallGenerator, /* functionReferenceReceiver = */
null);
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null : "There should be primary constructor for object literal";
ResolvedCall<ConstructorDescriptor> superCall = getDelegationConstructorCall(bindingContext, primaryConstructor);
if (superCall != null) {
// For an anonymous object, we should also generate all non-default arguments that it captures for its super call
ConstructorDescriptor superConstructor = superCall.getResultingDescriptor();
ConstructorDescriptor constructorToCall = SamCodegenUtil.resolveSamAdapter(superConstructor);
List<ValueParameterDescriptor> superValueParameters = superConstructor.getValueParameters();
int params = superValueParameters.size();
List<Type> superMappedTypes = typeMapper.mapToCallableMethod(constructorToCall, false).getValueParameterTypes();
assert superMappedTypes.size() >= params : String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", superMappedTypes.size(), params, classDescriptor);
List<ResolvedValueArgument> valueArguments = new ArrayList<ResolvedValueArgument>(params);
List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(params);
List<Type> mappedTypes = new ArrayList<Type>(params);
for (ValueParameterDescriptor parameter : superValueParameters) {
ResolvedValueArgument argument = superCall.getValueArguments().get(parameter);
if (!(argument instanceof DefaultValueArgument)) {
valueArguments.add(argument);
valueParameters.add(parameter);
mappedTypes.add(superMappedTypes.get(parameter.getIndex()));
}
}
ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(ExpressionCodegen.this, defaultCallGenerator, valueParameters, mappedTypes);
argumentGenerator.generate(valueArguments, valueArguments, null);
}
Collection<ClassConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Unexpected number of constructors for class: " + classDescriptor + " " + constructors;
ConstructorDescriptor constructorDescriptor = CollectionsKt.single(constructors);
Method constructor = typeMapper.mapAsmMethod(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
v.invokespecial(type.getInternalName(), "<init>", constructor.getDescriptor(), false);
return Unit.INSTANCE;
}
});
}
Aggregations