コード例 #1
0
  @NotNull
  public StackValue putInstanceOnStack(
      @NotNull final ExpressionCodegen codegen,
      @Nullable final FunctionDescriptor functionReferenceTarget) {
    return StackValue.operation(
        asmType,
        new Function1<InstructionAdapter, Unit>() {
          @Override
          public Unit invoke(InstructionAdapter v) {
            if (isConst(closure)) {
              v.getstatic(
                  asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
            } else {
              v.anew(asmType);
              v.dup();

              codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
              v.invokespecial(
                  asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
            }

            if (functionReferenceTarget != null) {
              equipFunctionReferenceWithReflection(v, functionReferenceTarget);
            }

            return Unit.INSTANCE$;
          }
        });
  }
コード例 #2
0
  private void generateBridge(@NotNull Method bridge, @NotNull Method delegate) {
    if (bridge.equals(delegate)) return;

    MethodVisitor mv =
        v.newMethod(
            OtherOrigin(element, funDescriptor),
            ACC_PUBLIC | ACC_BRIDGE,
            bridge.getName(),
            bridge.getDescriptor(),
            null,
            ArrayUtil.EMPTY_STRING_ARRAY);

    if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;

    mv.visitCode();

    InstructionAdapter iv = new InstructionAdapter(mv);
    ImplementationBodyCodegen.markLineNumberForSyntheticFunction(
        DescriptorUtils.getParentOfType(funDescriptor, ClassDescriptor.class), iv);

    iv.load(0, asmType);

    ReceiverParameterDescriptor receiver = funDescriptor.getExtensionReceiverParameter();
    int count = 1;
    if (receiver != null) {
      StackValue.local(count, bridge.getArgumentTypes()[count - 1])
          .put(typeMapper.mapType(receiver.getType()), iv);
      count++;
    }

    List<ValueParameterDescriptor> params = funDescriptor.getValueParameters();
    for (ValueParameterDescriptor param : params) {
      StackValue.local(count, bridge.getArgumentTypes()[count - 1])
          .put(typeMapper.mapType(param.getType()), iv);
      count++;
    }

    iv.invokevirtual(
        asmType.getInternalName(), delegate.getName(), delegate.getDescriptor(), false);
    StackValue.onStack(delegate.getReturnType()).put(bridge.getReturnType(), iv);

    iv.areturn(bridge.getReturnType());

    FunctionCodegen.endVisit(mv, "bridge", element);
  }
コード例 #3
0
  private static void equipFunctionReferenceWithReflection(
      @NotNull InstructionAdapter v, @NotNull FunctionDescriptor target) {
    DeclarationDescriptor container = target.getContainingDeclaration();

    Type type;
    if (container instanceof PackageFragmentDescriptor) {
      type =
          target.getExtensionReceiverParameter() != null
              ? K_TOP_LEVEL_EXTENSION_FUNCTION
              : K_TOP_LEVEL_FUNCTION;
    } else if (container instanceof ClassDescriptor) {
      type = K_MEMBER_FUNCTION;
    } else {
      type = K_LOCAL_FUNCTION;
    }

    Method method = method("function", K_FUNCTION, FUNCTION_REFERENCE);
    v.invokestatic(REFLECTION, method.getName(), method.getDescriptor(), false);
    StackValue.coerce(K_FUNCTION, type, v);
  }