Search in sources :

Example 11 with InstructionAdapter

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);
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) Type.getObjectType(org.jetbrains.org.objectweb.asm.Type.getObjectType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 12 with InstructionAdapter

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());
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) Type.getObjectType(org.jetbrains.org.objectweb.asm.Type.getObjectType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 13 with InstructionAdapter

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);
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) TraceMethodVisitor(org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor)

Example 14 with InstructionAdapter

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);
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedCall(org.jetbrains.kotlin.resolve.calls.model.ResolvedCall) DelegatingResolvedCall(org.jetbrains.kotlin.resolve.calls.model.DelegatingResolvedCall) Type(org.jetbrains.org.objectweb.asm.Type) DelegatingResolvedCall(org.jetbrains.kotlin.resolve.calls.model.DelegatingResolvedCall) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ReceiverValue(org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue)

Example 15 with InstructionAdapter

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;
        }
    });
}
Also used : SamConstructorDescriptor(org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor) TypeAliasConstructorDescriptor(org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor) Method(org.jetbrains.org.objectweb.asm.commons.Method) Unit(kotlin.Unit) IElementType(com.intellij.psi.tree.IElementType) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Aggregations

InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)35 KotlinType (org.jetbrains.kotlin.types.KotlinType)23 Type (org.jetbrains.org.objectweb.asm.Type)16 IElementType (com.intellij.psi.tree.IElementType)10 Unit (kotlin.Unit)10 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)7 Label (org.jetbrains.org.objectweb.asm.Label)5 Method (org.jetbrains.org.objectweb.asm.commons.Method)5 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)4 NotNull (org.jetbrains.annotations.NotNull)3 Type.getObjectType (org.jetbrains.org.objectweb.asm.Type.getObjectType)3 Nullable (org.jetbrains.annotations.Nullable)2 PrimitiveType (org.jetbrains.kotlin.builtins.PrimitiveType)2 JvmPrimitiveType (org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType)2 JvmMethodSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature)2 TypeUtils.isNullableType (org.jetbrains.kotlin.types.TypeUtils.isNullableType)2 TraceMethodVisitor (org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor)2 Method (java.lang.reflect.Method)1 KotlinBuiltIns (org.jetbrains.kotlin.builtins.KotlinBuiltIns)1 AsmUtil.getVisibilityForBackingField (org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField)1