private void generateConstInstance() { MethodVisitor mv = v.newMethod( OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_SYNTHETIC, "<clinit>", "()V", null, ArrayUtil.EMPTY_STRING_ARRAY); InstructionAdapter iv = new InstructionAdapter(mv); v.newField( OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, asmType.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); iv.anew(asmType); iv.dup(); iv.invokespecial(asmType.getInternalName(), "<init>", "()V", false); iv.putstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor()); mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "<clinit>", element); } }
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); }
@NotNull private Method generateConstructor(@NotNull Type superClassAsmType) { List<FieldInfo> args = calculateConstructorParameters(typeMapper, closure, asmType); Type[] argTypes = fieldListToTypeArray(args); Method constructor = new Method("<init>", Type.VOID_TYPE, argTypes); MethodVisitor mv = v.newMethod( OtherOrigin(element, funDescriptor), visibilityFlag, "<init>", constructor.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); int k = 1; for (FieldInfo fieldInfo : args) { k = genAssignInstanceFieldFromParam(fieldInfo, k, iv); } iv.load(0, superClassAsmType); if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE)) { int arity = funDescriptor.getValueParameters().size(); if (funDescriptor.getExtensionReceiverParameter() != null) arity++; if (funDescriptor.getDispatchReceiverParameter() != null) arity++; iv.iconst(arity); iv.invokespecial(superClassAsmType.getInternalName(), "<init>", "(I)V", false); } else { iv.invokespecial(superClassAsmType.getInternalName(), "<init>", "()V", false); } iv.visitInsn(RETURN); FunctionCodegen.endVisit(iv, "constructor", element); } return constructor; }
private SMAP generateMethodBody( @NotNull MethodVisitor adapter, @NotNull FunctionDescriptor descriptor, @NotNull MethodContext context, @NotNull JetExpression expression, @NotNull JvmMethodSignature jvmMethodSignature, boolean isLambda) { FakeMemberCodegen parentCodegen = new FakeMemberCodegen( codegen.getParentCodegen(), expression, (FieldOwnerContext) context.getParentContext(), isLambda ? codegen.getParentCodegen().getClassName() : typeMapper.mapOwner(descriptor).getInternalName()); FunctionGenerationStrategy strategy = expression instanceof JetCallableReferenceExpression ? new FunctionReferenceGenerationStrategy( state, descriptor, CallUtilKt.getResolvedCallWithAssert( ((JetCallableReferenceExpression) expression).getCallableReference(), codegen.getBindingContext())) : new FunctionGenerationStrategy.FunctionDefault( state, descriptor, (JetDeclarationWithBody) expression); FunctionCodegen.generateMethodBody( adapter, descriptor, context, jvmMethodSignature, strategy, // Wrapping for preventing marking actual parent codegen as containing reifier markers parentCodegen); return createSMAPWithDefaultMapping( expression, parentCodegen.getOrCreateSourceMapper().getResultMappings()); }
@NotNull private SMAPAndMethodNode createMethodNode(boolean callDefault) throws ClassNotFoundException, IOException { JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind()); Method asmMethod; if (callDefault) { asmMethod = typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind()); } else { asmMethod = jvmSignature.getAsmMethod(); } SMAPAndMethodNode nodeAndSMAP; if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) { JetTypeMapper.ContainingClassesInfo containingClasses = typeMapper.getContainingClassesForDeserializedCallable( (DeserializedSimpleFunctionDescriptor) functionDescriptor); VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable(containingClasses.getImplClassId(), state); nodeAndSMAP = InlineCodegenUtil.getMethodNode( file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containingClasses.getFacadeClassId()); if (nodeAndSMAP == null) { throw new RuntimeException( "Couldn't obtain compiled function body for " + descriptorName(functionDescriptor)); } } else { PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor); if (element == null || !(element instanceof JetNamedFunction)) { throw new RuntimeException( "Couldn't find declaration for function " + descriptorName(functionDescriptor)); } JetNamedFunction inliningFunction = (JetNamedFunction) element; MethodNode node = new MethodNode( InlineCodegenUtil.API, getMethodAsmFlags(functionDescriptor, context.getContextKind()) | (callDefault ? Opcodes.ACC_STATIC : 0), asmMethod.getName(), asmMethod.getDescriptor(), jvmSignature.getGenericsSignature(), null); // for maxLocals calculation MethodVisitor maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node); MethodContext methodContext = context.getParentContext().intoFunction(functionDescriptor); SMAP smap; if (callDefault) { Type implementationOwner = typeMapper.mapOwner(functionDescriptor); FakeMemberCodegen parentCodegen = new FakeMemberCodegen( codegen.getParentCodegen(), inliningFunction, (FieldOwnerContext) methodContext.getParentContext(), implementationOwner.getInternalName()); FunctionCodegen.generateDefaultImplBody( methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT, inliningFunction, parentCodegen); smap = createSMAPWithDefaultMapping( inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings()); } else { smap = generateMethodBody( maxCalcAdapter, functionDescriptor, methodContext, inliningFunction, jvmSignature, false); } nodeAndSMAP = new SMAPAndMethodNode(node, smap); maxCalcAdapter.visitMaxs(-1, -1); maxCalcAdapter.visitEnd(); } return nodeAndSMAP; }