Example #1
0
 public static void endVisit(
     MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) {
   try {
     mv.visitMaxs(-1, -1);
     mv.visitEnd();
   } catch (ProcessCanceledException e) {
     throw e;
   } catch (Throwable t) {
     String bytecode = renderByteCodeIfAvailable(mv);
     throw new CompilationException(
         "wrong code generated"
             + (description != null ? " for " + description : "")
             + t.getClass().getName()
             + " "
             + t.getMessage()
             + (bytecode != null ? "\nbytecode:\n" + bytecode : ""),
         t,
         method);
   }
 }
Example #2
0
  public void generateMethod(
      @NotNull JvmDeclarationOrigin origin,
      @NotNull FunctionDescriptor functionDescriptor,
      @NotNull MethodContext methodContext,
      @NotNull FunctionGenerationStrategy strategy) {
    OwnerKind contextKind = methodContext.getContextKind();
    if (isInterface(functionDescriptor.getContainingDeclaration())
        && functionDescriptor.getVisibility() == Visibilities.PRIVATE
        && contextKind != OwnerKind.DEFAULT_IMPLS) {
      return;
    }

    JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, contextKind);
    Method asmMethod = jvmSignature.getAsmMethod();

    int flags = getMethodAsmFlags(functionDescriptor, contextKind);
    boolean isNative = NativeKt.hasNativeAnnotation(functionDescriptor);

    if (isNative && owner instanceof MultifileClassFacadeContext) {
      // Native methods are only defined in facades and do not need package part implementations
      return;
    }
    MethodVisitor mv =
        v.newMethod(
            origin,
            flags,
            asmMethod.getName(),
            asmMethod.getDescriptor(),
            jvmSignature.getGenericsSignature(),
            getThrownExceptions(functionDescriptor, typeMapper));

    if (CodegenContextUtil.isImplClassOwner(owner)) {
      v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
    }

    generateMethodAnnotations(functionDescriptor, asmMethod, mv);

    generateParameterAnnotations(
        functionDescriptor, mv, typeMapper.mapSignature(functionDescriptor));

    generateBridges(functionDescriptor);

    boolean staticInCompanionObject =
        AnnotationUtilKt.isPlatformStaticInCompanionObject(functionDescriptor);
    if (staticInCompanionObject) {
      ImplementationBodyCodegen parentBodyCodegen =
          (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
      parentBodyCodegen.addAdditionalTask(
          new JvmStaticGenerator(functionDescriptor, origin, state));
    }

    if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES
        || isAbstractMethod(functionDescriptor, contextKind)) {
      generateLocalVariableTable(
          mv,
          jvmSignature,
          functionDescriptor,
          getThisTypeForFunction(functionDescriptor, methodContext, typeMapper),
          new Label(),
          new Label(),
          contextKind);

      mv.visitEnd();
      return;
    }

    if (!isNative) {
      generateMethodBody(
          mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen);
    } else if (staticInCompanionObject) {
      // native @JvmStatic foo() in companion object should delegate to the static native function
      // moved to the outer class
      mv.visitCode();
      FunctionDescriptor staticFunctionDescriptor =
          JvmStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
      JvmMethodSignature jvmMethodSignature =
          typeMapper.mapSignature(
              memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor, null));
      Type owningType =
          typeMapper.mapClass(
              (ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
      generateDelegateToMethodBody(
          false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
    }

    endVisit(mv, null, origin.getElement());
  }