@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$; } }); }
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); }
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); }