Example #1
0
  void generateDefaultIfNeeded(
      @NotNull MethodContext owner,
      @NotNull FunctionDescriptor functionDescriptor,
      @NotNull OwnerKind kind,
      @NotNull DefaultParameterValueLoader loadStrategy,
      @Nullable KtNamedFunction function) {
    DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();

    if (kind != OwnerKind.DEFAULT_IMPLS && isInterface(contextClass)) {
      return;
    }

    if (!isDefaultNeeded(functionDescriptor)) {
      return;
    }

    int flags =
        getVisibilityAccessFlag(functionDescriptor)
            | getDeprecatedAccessFlag(functionDescriptor)
            | ACC_SYNTHETIC;
    if (!(functionDescriptor instanceof ConstructorDescriptor)) {
      flags |= ACC_STATIC | ACC_BRIDGE;
    }
    // $default methods are never private to be accessible from other class files (e.g. inner)
    // without the need of synthetic accessors
    flags &= ~ACC_PRIVATE;

    Method defaultMethod = typeMapper.mapDefaultMethod(functionDescriptor, kind);

    MethodVisitor mv =
        v.newMethod(
            JvmDeclarationOriginKt.Synthetic(function, functionDescriptor),
            flags,
            defaultMethod.getName(),
            defaultMethod.getDescriptor(),
            null,
            getThrownExceptions(functionDescriptor, typeMapper));

    // Only method annotations are copied to the $default method. Parameter annotations are not
    // copied until there are valid use cases;
    // enum constructors have two additional synthetic parameters which somewhat complicate this
    // task
    AnnotationCodegen.forMethod(mv, typeMapper)
        .genAnnotations(functionDescriptor, defaultMethod.getReturnType());

    if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
      if (this.owner instanceof MultifileClassFacadeContext) {
        mv.visitCode();
        generateFacadeDelegateMethodBody(
            mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
        endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
      } else {
        mv.visitCode();
        generateDefaultImplBody(
            owner, functionDescriptor, mv, loadStrategy, function, memberCodegen, defaultMethod);
        endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
      }
    }
  }
Example #2
0
  private void generateBridge(
      @Nullable PsiElement origin,
      @NotNull FunctionDescriptor descriptor,
      @NotNull Method bridge,
      @NotNull Method delegateTo,
      boolean isSpecialBridge,
      boolean isStubDeclarationWithDelegationToSuper) {
    boolean isSpecialOrDelegationToSuper =
        isSpecialBridge || isStubDeclarationWithDelegationToSuper;
    int flags =
        ACC_PUBLIC
            | ACC_BRIDGE
            | (!isSpecialOrDelegationToSuper ? ACC_SYNTHETIC : 0)
            | (isSpecialBridge ? ACC_FINAL : 0); // TODO.

    MethodVisitor mv =
        v.newMethod(
            JvmDeclarationOriginKt.Bridge(descriptor, origin),
            flags,
            bridge.getName(),
            bridge.getDescriptor(),
            null,
            null);
    if (state.getClassBuilderMode() != ClassBuilderMode.FULL) 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 == 1 && isSpecialBridge) {
      generateTypeCheckBarrierIfNeeded(
          iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes()[0]);
    }

    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());
    } else {
      iv.invokevirtual(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor());
    }

    StackValue.coerce(delegateTo.getReturnType(), bridge.getReturnType(), iv);
    iv.areturn(bridge.getReturnType());

    endVisit(mv, "bridge method", origin);
  }
  private void createStaticInitializer() {
    final MethodVisitor mv = cv.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
    mv.visitCode();

    patchStaticInitializer(mv);

    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  public byte[] buildClass(ClassDefinition core)
      throws IOException, IntrospectionException, SecurityException, IllegalArgumentException,
          ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
          InvocationTargetException, InstantiationException, NoSuchFieldException {

    Class coreKlazz = core.getDefinedClass();
    String coreName = coreKlazz.getName();
    String wrapperName = coreName + "Wrapper";

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    FieldVisitor fv;
    MethodVisitor mv;

    cw.visit(
        V1_5,
        ACC_PUBLIC + ACC_SUPER,
        BuildUtils.getInternalType(wrapperName),
        BuildUtils.getTypeDescriptor(coreName)
            + "Lorg/drools/factmodel/traits/CoreWrapper<"
            + BuildUtils.getTypeDescriptor(coreName)
            + ">;",
        BuildUtils.getInternalType(coreName),
        new String[] {
          Type.getInternalName(CoreWrapper.class), Type.getInternalName(Externalizable.class)
        });

    {
      fv = cw.visitField(ACC_PRIVATE, "core", BuildUtils.getTypeDescriptor(coreName), null, null);
      fv.visitEnd();
    }
    {
      fv =
          cw.visitField(
              ACC_PRIVATE,
              TraitableBean.MAP_FIELD_NAME,
              Type.getDescriptor(Map.class),
              "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;",
              null);
      fv.visitEnd();
    }
    {
      fv =
          cw.visitField(
              ACC_PRIVATE,
              TraitableBean.TRAITSET_FIELD_NAME,
              Type.getDescriptor(Map.class),
              "Ljava/util/Map<Ljava/lang/String;Lorg/drools/factmodel/traits/Thing;>;",
              null);
      fv.visitEnd();
    }

    {
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
      mv.visitCode();

      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, BuildUtils.getInternalType(coreName), "<init>", "()V");

      //            mv.visitVarInsn( ALOAD, 0 );
      //            mv.visitTypeInsn( NEW, Type.getInternalName( HashMap.class ) );
      //            mv.visitInsn( DUP );
      //            mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( HashMap.class ),
      // "<init>", "()V" );
      //            mv.visitFieldInsn( PUTFIELD,
      //                    BuildUtils.getInternalType( wrapperName ),
      //                    TraitableBean.MAP_FIELD_NAME,
      //                    Type.getDescriptor( Map.class ) );

      //            mv.visitVarInsn( ALOAD, 0 );
      //            mv.visitTypeInsn( NEW, Type.getInternalName( VetoableTypedMap.class ) );
      //            mv.visitInsn( DUP );
      //            mv.visitTypeInsn( NEW, Type.getInternalName( HashMap.class ) );
      //            mv.visitInsn( DUP );
      //            mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( HashMap.class ),
      // "<init>", "()V" );
      //            mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( VetoableTypedMap.class
      // ), "<init>", "(" + Type.getDescriptor( Map.class ) + ")V" );
      //            mv.visitFieldInsn( PUTFIELD,
      //                    BuildUtils.getInternalType( wrapperName ),
      //                    TraitableBean.TRAITSET_FIELD_NAME,
      //                    Type.getDescriptor( Map.class ) );

      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "getCore")) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "getCore",
                "()" + Type.getDescriptor(Object.class),
                "()" + BuildUtils.getTypeDescriptor(coreName),
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            BuildUtils.getInternalType(wrapperName),
            "core",
            BuildUtils.getTypeDescriptor(coreName));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "getDynamicProperties")) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "getDynamicProperties",
                "()" + Type.getDescriptor(Map.class),
                "()Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;",
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            BuildUtils.getInternalType(wrapperName),
            TraitableBean.MAP_FIELD_NAME,
            Type.getDescriptor(Map.class));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();

        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "setDynamicProperties",
                "(" + Type.getDescriptor(Map.class) + ")V",
                "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;)V",
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(
            PUTFIELD,
            BuildUtils.getInternalType(wrapperName),
            TraitableBean.MAP_FIELD_NAME,
            Type.getDescriptor(Map.class));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "getTraitMap")) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "getTraitMap",
                "()" + Type.getDescriptor(Map.class),
                "()Ljava/util/Map<Ljava/lang/String;Lorg/drools/factmodel/traits/Thing;>;",
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            BuildUtils.getInternalType(wrapperName),
            TraitableBean.TRAITSET_FIELD_NAME,
            Type.getDescriptor(Map.class));
        Label l0 = new Label();
        mv.visitJumpInsn(IFNONNULL, l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitTypeInsn(NEW, Type.getInternalName(VetoableTypedMap.class));
        mv.visitInsn(DUP);
        mv.visitTypeInsn(NEW, Type.getInternalName(HashMap.class));
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(HashMap.class), "<init>", "()V");
        mv.visitMethodInsn(
            INVOKESPECIAL,
            Type.getInternalName(VetoableTypedMap.class),
            "<init>",
            "(" + Type.getDescriptor(Map.class) + ")V");
        mv.visitFieldInsn(
            PUTFIELD,
            BuildUtils.getInternalType(wrapperName),
            TraitableBean.TRAITSET_FIELD_NAME,
            Type.getDescriptor(Map.class));
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            BuildUtils.getInternalType(wrapperName),
            TraitableBean.TRAITSET_FIELD_NAME,
            Type.getDescriptor(Map.class));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "setTraitMap", Map.class)) {
      {
        mv = cw.visitMethod(ACC_PUBLIC, "setTraitMap", "(Ljava/util/Map;)V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitTypeInsn(NEW, Type.getInternalName(VetoableTypedMap.class));
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(
            INVOKESPECIAL,
            Type.getInternalName(VetoableTypedMap.class),
            "<init>",
            "(" + Type.getDescriptor(Map.class) + ")V");
        mv.visitFieldInsn(
            PUTFIELD,
            BuildUtils.getInternalType(wrapperName),
            TraitableBean.TRAITSET_FIELD_NAME,
            Type.getDescriptor(Map.class));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "addTrait", String.class, Thing.class)) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "addTrait",
                "(" + Type.getDescriptor(String.class) + Type.getDescriptor(Thing.class) + ")V",
                "(" + Type.getDescriptor(String.class) + Type.getDescriptor(Thing.class) + ")V",
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            BuildUtils.getInternalType(wrapperName),
            "getTraitMap",
            "()" + Type.getDescriptor(Map.class));
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(VetoableTypedMap.class));
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            Type.getInternalName(VetoableTypedMap.class),
            "putSafe",
            "("
                + Type.getDescriptor(String.class)
                + Type.getDescriptor(Thing.class)
                + ")"
                + Type.getDescriptor(Thing.class));
        mv.visitInsn(POP);
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "getTrait", String.class)) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "getTrait",
                "(" + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(Thing.class),
                "(" + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(Thing.class),
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            BuildUtils.getInternalType(wrapperName),
            "getTraitMap",
            "()" + Type.getDescriptor(Map.class));
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "get",
            "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(Object.class));
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Thing.class));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "hasTrait", String.class)) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC, "hasTrait", "(" + Type.getDescriptor(String.class) + ")Z", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            BuildUtils.getInternalType(wrapperName),
            "getTraitMap",
            "()" + Type.getDescriptor(Map.class));
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "containsKey",
            "(" + Type.getDescriptor(Object.class) + ")Z");
        mv.visitInsn(IRETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "removeTrait", String.class)) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "removeTrait",
                "(" + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(Thing.class),
                "(" + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(Thing.class),
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            BuildUtils.getInternalType(wrapperName),
            "getTraitMap",
            "()" + Type.getDescriptor(Map.class));
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "remove",
            "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(Object.class));
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Thing.class));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }
    if (coreKlazz == null || needsMethod(coreKlazz, "getTraits")) {
      {
        mv =
            cw.visitMethod(
                ACC_PUBLIC,
                "getTraits",
                "()" + Type.getDescriptor(Collection.class),
                "()Ljava/util/Collection<Ljava/lang/String;>;",
                null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            BuildUtils.getInternalType(wrapperName),
            "getTraitMap",
            "()" + Type.getDescriptor(Map.class));
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "keySet",
            "()" + Type.getDescriptor(Set.class));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }

    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "writeExternal",
              "(" + Type.getDescriptor(ObjectOutput.class) + ")V",
              null,
              new String[] {Type.getInternalName(IOException.class)});
      mv.visitCode();

      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          BuildUtils.getInternalType(wrapperName),
          "getCore",
          "()" + Type.getDescriptor(Object.class));
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(ObjectOutput.class),
          "writeObject",
          "(" + Type.getDescriptor(Object.class) + ")V");

      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD,
          BuildUtils.getInternalType(wrapperName),
          TraitableBean.MAP_FIELD_NAME,
          Type.getDescriptor(Map.class));
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(ObjectOutput.class),
          "writeObject",
          "(" + Type.getDescriptor(Object.class) + ")V");

      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD,
          BuildUtils.getInternalType(wrapperName),
          TraitableBean.TRAITSET_FIELD_NAME,
          Type.getDescriptor(Map.class));
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(ObjectOutput.class),
          "writeObject",
          "(" + Type.getDescriptor(Object.class) + ")V");

      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "readExternal",
              "(" + Type.getDescriptor(ObjectInput.class) + ")V",
              null,
              new String[] {
                Type.getInternalName(IOException.class),
                Type.getInternalName(ClassNotFoundException.class)
              });
      mv.visitCode();

      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(ObjectInput.class),
          "readObject",
          "()" + Type.getDescriptor(Object.class));
      mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(coreName));
      mv.visitFieldInsn(
          PUTFIELD,
          BuildUtils.getInternalType(wrapperName),
          "core",
          BuildUtils.getTypeDescriptor(coreName));

      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(ObjectInput.class),
          "readObject",
          "()" + Type.getDescriptor(Object.class));
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Map.class));
      mv.visitFieldInsn(
          PUTFIELD,
          BuildUtils.getInternalType(wrapperName),
          TraitableBean.MAP_FIELD_NAME,
          Type.getDescriptor(Map.class));

      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(ObjectInput.class),
          "readObject",
          "()" + Type.getDescriptor(Object.class));
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Map.class));
      mv.visitFieldInsn(
          PUTFIELD,
          BuildUtils.getInternalType(wrapperName),
          TraitableBean.TRAITSET_FIELD_NAME,
          Type.getDescriptor(Map.class));

      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC, "init", "(" + BuildUtils.getTypeDescriptor(coreName) + ")V", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(
          PUTFIELD,
          BuildUtils.getInternalType(wrapperName),
          "core",
          BuildUtils.getTypeDescriptor(coreName));
      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    Method[] ms = coreKlazz.getMethods();
    for (Method method : ms) {
      if (Modifier.isFinal(method.getModifiers())) {
        continue;
      }

      String signature = TraitFactory.buildSignature(method);
      {
        mv = cw.visitMethod(ACC_PUBLIC, method.getName(), signature, null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            BuildUtils.getInternalType(wrapperName),
            "core",
            BuildUtils.getTypeDescriptor(coreName));
        int j = 1;
        for (Class arg : method.getParameterTypes()) {
          mv.visitVarInsn(BuildUtils.varType(arg.getName()), j++);
        }
        mv.visitMethodInsn(
            INVOKEVIRTUAL, BuildUtils.getInternalType(coreName), method.getName(), signature);

        mv.visitInsn(BuildUtils.returnType(method.getReturnType().getName()));
        int stack = TraitFactory.getStackSize(method);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
      }
    }

    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC,
              "init",
              "(" + Type.getDescriptor(Object.class) + ")V",
              null,
              null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(coreName));
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          BuildUtils.getInternalType(wrapperName),
          "init",
          "(" + BuildUtils.getTypeDescriptor(coreName) + ")V");
      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "denyTrait",
              "(" + Type.getDescriptor(Class.class) + ")V",
              null,
              new String[] {Type.getInternalName(LogicalTypeInconsistencyException.class)});
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD,
          BuildUtils.getInternalType(wrapperName),
          TraitableBean.TRAITSET_FIELD_NAME,
          Type.getDescriptor(Map.class));
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(VetoableTypedMap.class));
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(VetoableTypedMap.class),
          "addToVetoable",
          "(" + Type.getDescriptor(Class.class) + ")V");
      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC, "allowTrait", "(" + Type.getDescriptor(Class.class) + ")V", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD,
          BuildUtils.getInternalType(wrapperName),
          TraitableBean.TRAITSET_FIELD_NAME,
          Type.getDescriptor(Map.class));
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(VetoableTypedMap.class));
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(VetoableTypedMap.class),
          "removeFromVetoable",
          "(" + Type.getDescriptor(Class.class) + ")V");
      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
  }
  private static void generateFirstActivity(ApplicationWriter aw) {
    ClassVisitor cv;
    MethodVisitor mv;

    cv = aw.visitClass(ACC_PUBLIC, "Lft/nevo/FirstActivity;", null, "Landroid/app/Activity;", null);
    cv.visit(0, ACC_PUBLIC, "Lft/nevo/FirstActivity;", null, "Landroid/app/Activity;", null);

    cv.visitSource("FirstActivity.java", null);
    {
      mv = cv.visitMethod(ACC_PUBLIC + ACC_CONSTRUCTOR, "<init>", "V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitLineNumber(6, l0);
      mv.visitMethodInsn(
          INSN_INVOKE_DIRECT, "Landroid/app/Activity;", "<init>", "V", new int[] {0});
      mv.visitInsn(INSN_RETURN_VOID);
      mv.visitMaxs(1, 0);
      mv.visitEnd();
    }
    {
      mv = cv.visitMethod(ACC_PUBLIC, "onCreate", "VLandroid/os/Bundle;", null, null);
      mv.visitCode();
      mv.visitParameters(new String[] {"savedInstanceState"});
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitLineNumber(10, l0);
      mv.visitMethodInsn(
          INSN_INVOKE_SUPER,
          "Landroid/app/Activity;",
          "onCreate",
          "VLandroid/os/Bundle;",
          new int[] {1, 2});
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitLineNumber(11, l1);
      mv.visitVarInsn(INSN_CONST_HIGH16, 0, 2130903040);
      mv.visitMethodInsn(
          INSN_INVOKE_VIRTUAL, "Lft/nevo/FirstActivity;", "setContentView", "VI", new int[] {1, 0});
      Label l2 = new Label();
      mv.visitLabel(l2);
      mv.visitLineNumber(14, l2);
      mv.visitInsn(INSN_RETURN_VOID);
      mv.visitMaxs(3, 0);
      mv.visitEnd();
    }

    {
      mv = cv.visitMethod(ACC_PUBLIC, "myMethod", "V", null, null);
      mv.visitCode();

      // Added code.
      Label label1 = new Label();
      Label label2 = new Label();

      mv.visitLabel(label1);
      mv.visitJumpInsn(INSN_GOTO_16, label2, 0, 0);
      mv.visitJumpInsn(INSN_GOTO_16, label2, 0, 0);

      // NOPs are inserted here.
      for (int i = 0; i < MethodAdapterResizeGoto8BitsDoubleRefs.NB_NOPS; i++) {
        mv.visitInsn(INSN_NOP);
      }

      mv.visitLabel(label2);
      mv.visitJumpInsn(INSN_GOTO_16, label1, 0, 0);
      mv.visitJumpInsn(INSN_GOTO_16, label1, 0, 0);

      mv.visitInsn(INSN_RETURN_VOID);
      mv.visitMaxs(1, 0);
      mv.visitEnd();
    }
    cv.visitEnd();
  }
Example #6
0
 /**
  * Makes the given method visitor visit this method.
  *
  * @param mv a method visitor.
  */
 public void accept(final MethodVisitor mv) {
   // visits the method parameters
   int i, j, n;
   n = parameters == null ? 0 : parameters.size();
   for (i = 0; i < n; i++) {
     ParameterNode parameter = parameters.get(i);
     mv.visitParameter(parameter.name, parameter.access);
   }
   // visits the method attributes
   if (annotationDefault != null) {
     AnnotationVisitor av = mv.visitAnnotationDefault();
     AnnotationNode.accept(av, null, annotationDefault);
     if (av != null) {
       av.visitEnd();
     }
   }
   n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
   for (i = 0; i < n; ++i) {
     AnnotationNode an = visibleAnnotations.get(i);
     an.accept(mv.visitAnnotation(an.desc, true));
   }
   n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
   for (i = 0; i < n; ++i) {
     AnnotationNode an = invisibleAnnotations.get(i);
     an.accept(mv.visitAnnotation(an.desc, false));
   }
   n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
   for (i = 0; i < n; ++i) {
     TypeAnnotationNode an = visibleTypeAnnotations.get(i);
     an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, true));
   }
   n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations.size();
   for (i = 0; i < n; ++i) {
     TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
     an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, false));
   }
   n = visibleParameterAnnotations == null ? 0 : visibleParameterAnnotations.length;
   for (i = 0; i < n; ++i) {
     List<?> l = visibleParameterAnnotations[i];
     if (l == null) {
       continue;
     }
     for (j = 0; j < l.size(); ++j) {
       AnnotationNode an = (AnnotationNode) l.get(j);
       an.accept(mv.visitParameterAnnotation(i, an.desc, true));
     }
   }
   n = invisibleParameterAnnotations == null ? 0 : invisibleParameterAnnotations.length;
   for (i = 0; i < n; ++i) {
     List<?> l = invisibleParameterAnnotations[i];
     if (l == null) {
       continue;
     }
     for (j = 0; j < l.size(); ++j) {
       AnnotationNode an = (AnnotationNode) l.get(j);
       an.accept(mv.visitParameterAnnotation(i, an.desc, false));
     }
   }
   if (visited) {
     instructions.resetLabels();
   }
   n = attrs == null ? 0 : attrs.size();
   for (i = 0; i < n; ++i) {
     mv.visitAttribute(attrs.get(i));
   }
   // visits the method's code
   if (instructions.size() > 0) {
     mv.visitCode();
     // visits try catch blocks
     n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
     for (i = 0; i < n; ++i) {
       tryCatchBlocks.get(i).updateIndex(i);
       tryCatchBlocks.get(i).accept(mv);
     }
     // visits instructions
     instructions.accept(mv);
     // visits local variables
     n = localVariables == null ? 0 : localVariables.size();
     for (i = 0; i < n; ++i) {
       localVariables.get(i).accept(mv);
     }
     // visits local variable annotations
     n = visibleLocalVariableAnnotations == null ? 0 : visibleLocalVariableAnnotations.size();
     for (i = 0; i < n; ++i) {
       visibleLocalVariableAnnotations.get(i).accept(mv, true);
     }
     n = invisibleLocalVariableAnnotations == null ? 0 : invisibleLocalVariableAnnotations.size();
     for (i = 0; i < n; ++i) {
       invisibleLocalVariableAnnotations.get(i).accept(mv, false);
     }
     // visits maxs
     mv.visitMaxs(maxStack, maxLocals);
     visited = true;
   }
   mv.visitEnd();
 }
Example #7
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);
      }
    }
  }
Example #8
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());
  }
Example #9
0
 /** Starts the visit of the method's code, if any (i.e. non abstract method). */
 public void visitCode() {
   if (mv != null) {
     mv.visitCode();
   }
 }