private static void loadExplicitArgumentsOnStack( @NotNull Type ownerType, boolean isStatic, @NotNull JvmMethodSignature signature, @NotNull CallGenerator callGenerator) { int var = 0; if (!isStatic) { callGenerator.putValueIfNeeded(ownerType, StackValue.local(var, ownerType)); var += ownerType.getSize(); } for (JvmMethodParameterSignature parameterSignature : signature.getValueParameters()) { if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) { Type type = parameterSignature.getAsmType(); callGenerator.putValueIfNeeded(type, StackValue.local(var, type)); var += type.getSize(); } } }
private static void generateLocalVariableTable( @NotNull MethodVisitor mv, @NotNull JvmMethodSignature jvmMethodSignature, @NotNull FunctionDescriptor functionDescriptor, @Nullable Type thisType, @NotNull Label methodBegin, @NotNull Label methodEnd, @NotNull OwnerKind ownerKind) { Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator(); List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters(); int shift = 0; boolean isStatic = AsmUtil.isStaticMethod(ownerKind, functionDescriptor); if (!isStatic) { // add this if (thisType != null) { mv.visitLocalVariable( "this", thisType.getDescriptor(), null, methodBegin, methodEnd, shift); } else { // TODO: provide thisType for callable reference } shift++; } for (int i = 0; i < params.size(); i++) { JvmMethodParameterSignature param = params.get(i); JvmMethodParameterKind kind = param.getKind(); String parameterName; if (kind == JvmMethodParameterKind.VALUE) { ValueParameterDescriptor parameter = valueParameters.next(); parameterName = parameter.getName().asString(); } else { String lowercaseKind = kind.name().toLowerCase(); parameterName = needIndexForVar(kind) ? "$" + lowercaseKind + "$" + i : "$" + lowercaseKind; } Type type = param.getAsmType(); mv.visitLocalVariable( parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift); shift += type.getSize(); } }
private static void generateDelegateToMethodBody( boolean isStatic, @NotNull MethodVisitor mv, @NotNull Method asmMethod, @NotNull String classToDelegateTo) { InstructionAdapter iv = new InstructionAdapter(mv); Type[] argTypes = asmMethod.getArgumentTypes(); // The first line of some package file is written to the line number attribute of a static // delegate to allow to 'step into' it // This is similar to what javac does with bridge methods Label label = new Label(); iv.visitLabel(label); iv.visitLineNumber(1, label); int k = isStatic ? 0 : 1; for (Type argType : argTypes) { iv.load(k, argType); k += argType.getSize(); } iv.invokestatic(classToDelegateTo, asmMethod.getName(), asmMethod.getDescriptor(), false); iv.areturn(asmMethod.getReturnType()); }