Example #1
0
  public void generateBridges(@NotNull FunctionDescriptor descriptor) {
    if (descriptor instanceof ConstructorDescriptor) return;
    if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
    if (isInterface(descriptor.getContainingDeclaration())) return;

    // equals(Any?), hashCode(), toString() never need bridges
    if (isMethodOfAny(descriptor)) return;

    // If the function doesn't have a physical declaration among super-functions, it's a SAM adapter
    // or alike and doesn't need bridges
    if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return;

    boolean isSpecial =
        SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;

    Set<Bridge<Method>> bridgesToGenerate;
    if (!isSpecial) {
      bridgesToGenerate =
          ImplKt.generateBridgesForFunctionDescriptor(descriptor, getSignatureMapper(typeMapper));
      if (!bridgesToGenerate.isEmpty()) {
        PsiElement origin =
            descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
        boolean isSpecialBridge =
            BuiltinMethodsWithSpecialGenericSignature
                    .getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor)
                != null;

        for (Bridge<Method> bridge : bridgesToGenerate) {
          generateBridge(
              origin, descriptor, bridge.getFrom(), bridge.getTo(), isSpecialBridge, false);
        }
      }
    } else {
      Set<BridgeForBuiltinSpecial<Method>> specials =
          BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
              descriptor, getSignatureMapper(typeMapper));

      if (!specials.isEmpty()) {
        PsiElement origin =
            descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
        for (BridgeForBuiltinSpecial<Method> bridge : specials) {
          generateBridge(
              origin,
              descriptor,
              bridge.getFrom(),
              bridge.getTo(),
              bridge.isSpecial(),
              bridge.isDelegateToSuper());
        }
      }

      if (!descriptor.getKind().isReal()
          && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
        CallableDescriptor overridden =
            SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
        assert overridden != null;

        Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
        int flags = ACC_ABSTRACT | getVisibilityAccessFlag(descriptor);
        v.newMethod(
            JvmDeclarationOriginKt.OtherOrigin(overridden),
            flags,
            method.getName(),
            method.getDescriptor(),
            null,
            null);
      }
    }
  }
Example #2
0
  public static void generateMethodBody(
      @NotNull MethodVisitor mv,
      @NotNull FunctionDescriptor functionDescriptor,
      @NotNull MethodContext context,
      @NotNull JvmMethodSignature signature,
      @NotNull FunctionGenerationStrategy strategy,
      @NotNull MemberCodegen<?> parentCodegen) {
    mv.visitCode();

    Label methodBegin = new Label();
    mv.visitLabel(methodBegin);

    JetTypeMapper typeMapper = parentCodegen.typeMapper;
    if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(
        functionDescriptor, getSignatureMapper(typeMapper))) {
      generateTypeCheckBarrierIfNeeded(
          new InstructionAdapter(mv),
          functionDescriptor,
          signature.getReturnType(),
          /* delegateParameterType = */ null);
    }

    Label methodEnd;

    int functionFakeIndex = -1;
    int lambdaFakeIndex = -1;

    if (context.getParentContext() instanceof MultifileClassFacadeContext) {
      generateFacadeDelegateMethodBody(
          mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
      methodEnd = new Label();
    } else {
      FrameMap frameMap =
          createFrameMap(
              parentCodegen.state,
              functionDescriptor,
              signature,
              isStaticMethod(context.getContextKind(), functionDescriptor));
      if (context.isInlineMethodContext()) {
        functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
      }

      if (context instanceof InlineLambdaContext) {
        lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
      }

      Label methodEntry = new Label();
      mv.visitLabel(methodEntry);
      context.setMethodStartLabel(methodEntry);

      if (!JetTypeMapper.isAccessor(functionDescriptor)) {
        genNotNullAssertionsForParameters(
            new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
      }
      methodEnd = new Label();
      context.setMethodEndLabel(methodEnd);
      strategy.generateBody(mv, frameMap, signature, context, parentCodegen);
    }

    mv.visitLabel(methodEnd);

    Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
    generateLocalVariableTable(
        mv,
        signature,
        functionDescriptor,
        thisType,
        methodBegin,
        methodEnd,
        context.getContextKind());

    if (context.isInlineMethodContext() && functionFakeIndex != -1) {
      mv.visitLocalVariable(
          JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION
              + functionDescriptor.getName().asString(),
          Type.INT_TYPE.getDescriptor(),
          null,
          methodBegin,
          methodEnd,
          functionFakeIndex);
    }

    if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
      String name = thisType.getClassName();
      int indexOfLambdaOrdinal = name.lastIndexOf("$");
      if (indexOfLambdaOrdinal > 0) {
        int lambdaOrdinal = Integer.parseInt(name.substring(indexOfLambdaOrdinal + 1));
        mv.visitLocalVariable(
            JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + lambdaOrdinal,
            Type.INT_TYPE.getDescriptor(),
            null,
            methodBegin,
            methodEnd,
            lambdaFakeIndex);
      }
    }
  }