Primary constructor generation via FunctionCodegen Strategy, local variable table generation via JvmMethodSignature and FunctionDescriptor
This commit is contained in:
@@ -147,7 +147,7 @@ public class AsmUtil {
|
|||||||
|
|
||||||
int flags = getCommonCallableFlags(functionDescriptor);
|
int flags = getCommonCallableFlags(functionDescriptor);
|
||||||
|
|
||||||
if (functionDescriptor.getModality() == Modality.FINAL) {
|
if (functionDescriptor.getModality() == Modality.FINAL && !(functionDescriptor instanceof ConstructorDescriptor)) {
|
||||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||||
if (!(containingDeclaration instanceof ClassDescriptor) ||
|
if (!(containingDeclaration instanceof ClassDescriptor) ||
|
||||||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) {
|
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) {
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class ClosureCodegen extends GenerationStateAware {
|
|||||||
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(interfaceFunction.getName(), funDescriptor);
|
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(interfaceFunction.getName(), funDescriptor);
|
||||||
|
|
||||||
FunctionCodegen fc = new FunctionCodegen(context, cv, state);
|
FunctionCodegen fc = new FunctionCodegen(context, cv, state);
|
||||||
fc.generateMethod(fun, jvmMethodSignature, false, null, funDescriptor, strategy);
|
fc.generateMethod(fun, jvmMethodSignature, false, funDescriptor, strategy);
|
||||||
|
|
||||||
this.constructor = generateConstructor(cv);
|
this.constructor = generateConstructor(cv);
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,10 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.asm4.Type;
|
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
|
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
@@ -48,15 +45,6 @@ public class ConstructorFrameMap extends FrameMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
|
|
||||||
List<ValueParameterDescriptor> paramDescrs = descriptor != null
|
|
||||||
? descriptor.getValueParameters()
|
|
||||||
: Collections.<ValueParameterDescriptor>emptyList();
|
|
||||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
|
||||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
|
||||||
enter(parameter, explicitArgTypes.get(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOuterThisIndex() {
|
public int getOuterThisIndex() {
|
||||||
|
|||||||
@@ -1249,7 +1249,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
JvmClassName closureSuperClass = samInterfaceClass == null ? getFunctionImplClassName(descriptor) : JvmClassName.byType(OBJECT_TYPE);
|
JvmClassName closureSuperClass = samInterfaceClass == null ? getFunctionImplClassName(descriptor) : JvmClassName.byType(OBJECT_TYPE);
|
||||||
|
|
||||||
ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context,
|
ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context,
|
||||||
this, new FunctionGenerationStrategy.Default(state, declaration));
|
this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration));
|
||||||
|
|
||||||
closureCodegen.gen();
|
closureCodegen.gen();
|
||||||
|
|
||||||
@@ -2335,14 +2335,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
JvmClassName closureSuperClass = JvmClassName.byType(typeMapper.mapType(kFunctionImpl));
|
JvmClassName closureSuperClass = JvmClassName.byType(typeMapper.mapType(kFunctionImpl));
|
||||||
|
|
||||||
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
|
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
|
||||||
new FunctionGenerationStrategy() {
|
new FunctionGenerationStrategy.CodegenBased(state, functionDescriptor) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public ExpressionCodegen initializeExpressionCodegen(
|
||||||
@NotNull MethodVisitor mv,
|
JvmMethodSignature signature, MethodContext context, MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
Type returnType
|
||||||
@NotNull MethodContext context,
|
|
||||||
@NotNull FrameMap frameMap
|
|
||||||
) {
|
) {
|
||||||
|
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||||
|
JetType returnJetType = referencedFunction.getReturnType();
|
||||||
|
assert returnJetType != null : "Return type can't be null: " + referencedFunction;
|
||||||
|
|
||||||
|
return super.initializeExpressionCodegen(signature, context,
|
||||||
|
mv, typeMapper.mapReturnType(returnJetType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
|
||||||
/*
|
/*
|
||||||
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invokation
|
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invokation
|
||||||
of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
|
of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
|
||||||
@@ -2352,17 +2361,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||||
JetType returnJetType = referencedFunction.getReturnType();
|
|
||||||
assert returnJetType != null : "Return type can't be null: " + referencedFunction;
|
|
||||||
Type returnType = typeMapper.mapReturnType(returnJetType);
|
|
||||||
|
|
||||||
JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction);
|
JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction);
|
||||||
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
|
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
|
||||||
|
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context, state);
|
|
||||||
|
|
||||||
final ReceiverValue receiverValue = computeAndSaveReceiver(signature, codegen);
|
final ReceiverValue receiverValue = computeAndSaveReceiver(signature, codegen);
|
||||||
computeAndSaveArguments(frameMap, fakeArguments, codegen);
|
computeAndSaveArguments(codegen.myFrameMap, fakeArguments, codegen);
|
||||||
|
|
||||||
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
|
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -2389,9 +2393,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
};
|
};
|
||||||
|
|
||||||
StackValue result;
|
StackValue result;
|
||||||
|
Type returnType = codegen.returnType;
|
||||||
if (referencedFunction instanceof ConstructorDescriptor) {
|
if (referencedFunction instanceof ConstructorDescriptor) {
|
||||||
if (returnType.getSort() == Type.ARRAY) {
|
if (returnType.getSort() == Type.ARRAY) {
|
||||||
codegen.generateNewArray(fakeExpression, returnJetType);
|
codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType());
|
||||||
result = StackValue.onStack(returnType);
|
result = StackValue.onStack(returnType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2403,7 +2408,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
result = codegen.invokeFunction(call, StackValue.none(), fakeResolvedCall);
|
result = codegen.invokeFunction(call, StackValue.none(), fakeResolvedCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionAdapter v = new InstructionAdapter(mv);
|
InstructionAdapter v = codegen.v;
|
||||||
result.put(returnType, v);
|
result.put(returnType, v);
|
||||||
v.areturn(returnType);
|
v.areturn(returnType);
|
||||||
}
|
}
|
||||||
@@ -2463,11 +2468,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
|
|
||||||
return new ExpressionReceiver(receiverExpression, receiver.getType());
|
return new ExpressionReceiver(receiverExpression, receiver.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean needsLocalVariableTable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.asm4.AnnotationVisitor;
|
||||||
import org.jetbrains.asm4.Label;
|
import org.jetbrains.asm4.Label;
|
||||||
import org.jetbrains.asm4.MethodVisitor;
|
import org.jetbrains.asm4.MethodVisitor;
|
||||||
import org.jetbrains.asm4.Type;
|
import org.jetbrains.asm4.Type;
|
||||||
@@ -28,8 +29,10 @@ import org.jetbrains.asm4.commons.Method;
|
|||||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||||
|
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
||||||
|
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
|
||||||
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
|
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
|
||||||
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
|
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
@@ -81,8 +84,8 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
|
|
||||||
if (kind != OwnerKind.TRAIT_IMPL || function.getBodyExpression() != null) {
|
if (kind != OwnerKind.TRAIT_IMPL || function.getBodyExpression() != null) {
|
||||||
boolean needJetAnnotations = kind != OwnerKind.TRAIT_IMPL;
|
boolean needJetAnnotations = kind != OwnerKind.TRAIT_IMPL;
|
||||||
generateMethod(function, method, needJetAnnotations, null, functionDescriptor,
|
generateMethod(function, method, needJetAnnotations, functionDescriptor,
|
||||||
new FunctionGenerationStrategy.Default(state, function));
|
new FunctionGenerationStrategy.FunctionDefault(state, functionDescriptor, function));
|
||||||
}
|
}
|
||||||
|
|
||||||
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), state, v, method.getAsmMethod(), functionDescriptor, kind,
|
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), state, v, method.getAsmMethod(), functionDescriptor, kind,
|
||||||
@@ -93,16 +96,25 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
@Nullable PsiElement origin,
|
@Nullable PsiElement origin,
|
||||||
@NotNull JvmMethodSignature jvmSignature,
|
@NotNull JvmMethodSignature jvmSignature,
|
||||||
boolean needJetAnnotations,
|
boolean needJetAnnotations,
|
||||||
@Nullable String propertyTypeSignature,
|
|
||||||
@NotNull FunctionDescriptor functionDescriptor,
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
@NotNull FunctionGenerationStrategy strategy
|
@NotNull FunctionGenerationStrategy strategy
|
||||||
) {
|
) {
|
||||||
MethodContext context = owner.intoFunction(functionDescriptor);
|
generateMethod(origin, jvmSignature, needJetAnnotations, functionDescriptor, owner.intoFunction(functionDescriptor), strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateMethod(
|
||||||
|
@Nullable PsiElement origin,
|
||||||
|
@NotNull JvmMethodSignature jvmSignature,
|
||||||
|
boolean needJetAnnotations,
|
||||||
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
|
@NotNull MethodContext methodContext,
|
||||||
|
@NotNull FunctionGenerationStrategy strategy
|
||||||
|
) {
|
||||||
|
|
||||||
Method asmMethod = jvmSignature.getAsmMethod();
|
Method asmMethod = jvmSignature.getAsmMethod();
|
||||||
|
|
||||||
MethodVisitor mv = v.newMethod(origin,
|
MethodVisitor mv = v.newMethod(origin,
|
||||||
getMethodAsmFlags(functionDescriptor, context.getContextKind()),
|
getMethodAsmFlags(functionDescriptor, methodContext.getContextKind()),
|
||||||
asmMethod.getName(),
|
asmMethod.getName(),
|
||||||
asmMethod.getDescriptor(),
|
asmMethod.getDescriptor(),
|
||||||
jvmSignature.getGenericsSignature(),
|
jvmSignature.getGenericsSignature(),
|
||||||
@@ -112,17 +124,17 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
|
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
|
||||||
|
|
||||||
if (needJetAnnotations) {
|
if (needJetAnnotations) {
|
||||||
genJetAnnotations(mv, functionDescriptor, propertyTypeSignature);
|
genJetAnnotations(mv, functionDescriptor, jvmSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAbstract(functionDescriptor, context.getContextKind())) return;
|
if (isAbstract(functionDescriptor, methodContext.getContextKind())) return;
|
||||||
|
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||||
genStubCode(mv);
|
genStubCode(mv);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
generateMethodBody(mv, functionDescriptor, context, jvmSignature, strategy);
|
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy);
|
||||||
|
|
||||||
endVisit(mv, null, origin);
|
endVisit(mv, null, origin);
|
||||||
|
|
||||||
@@ -132,7 +144,10 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context) {
|
private Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context) {
|
||||||
ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
|
ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
|
||||||
if (expectedThisObject != null) {
|
if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||||
|
return typeMapper.mapType(functionDescriptor.getReturnType());
|
||||||
|
}
|
||||||
|
else if (expectedThisObject != null) {
|
||||||
return typeMapper.mapType(expectedThisObject.getType());
|
return typeMapper.mapType(expectedThisObject.getType());
|
||||||
}
|
}
|
||||||
else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) {
|
else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) {
|
||||||
@@ -164,7 +179,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
generateStaticDelegateMethodBody(mv, signature.getAsmMethod(), (OwnerKind.StaticDelegateKind) kind);
|
generateStaticDelegateMethodBody(mv, signature.getAsmMethod(), (OwnerKind.StaticDelegateKind) kind);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FrameMap frameMap = context.prepareFrame(typeMapper);
|
FrameMap frameMap = strategy.getFrameMap(typeMapper, context);
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
|
||||||
frameMap.enter(parameter, typeMapper.mapType(parameter));
|
frameMap.enter(parameter, typeMapper.mapType(parameter));
|
||||||
@@ -174,7 +189,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
|
|
||||||
genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap);
|
genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap);
|
||||||
|
|
||||||
strategy.generateBody(mv, signature, context, frameMap);
|
strategy.generateBody(mv, signature, context);
|
||||||
|
|
||||||
localVariableNames.addAll(strategy.getLocalVariableNames());
|
localVariableNames.addAll(strategy.getLocalVariableNames());
|
||||||
}
|
}
|
||||||
@@ -182,10 +197,9 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
Label methodEnd = new Label();
|
Label methodEnd = new Label();
|
||||||
mv.visitLabel(methodEnd);
|
mv.visitLabel(methodEnd);
|
||||||
|
|
||||||
if (strategy.needsLocalVariableTable()) {
|
|
||||||
Type thisType = getThisTypeForFunction(functionDescriptor, context);
|
Type thisType = getThisTypeForFunction(functionDescriptor, context);
|
||||||
generateLocalVariableTable(mv, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars);
|
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars, kind);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -200,47 +214,59 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
|
|
||||||
private void generateLocalVariableTable(
|
private void generateLocalVariableTable(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull JvmMethodSignature jvmMethodSignature,
|
||||||
@NotNull FunctionDescriptor functionDescriptor,
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
@Nullable Type thisType,
|
@Nullable Type thisType,
|
||||||
@NotNull Label methodBegin,
|
@NotNull Label methodBegin,
|
||||||
@NotNull Label methodEnd,
|
@NotNull Label methodEnd,
|
||||||
@NotNull Collection<String> localVariableNames,
|
@NotNull Collection<String> localVariableNames,
|
||||||
@NotNull Map<Name, Label> labelsForSharedVars
|
@NotNull Map<Name, Label> labelsForSharedVars,
|
||||||
|
@NotNull OwnerKind ownerKind
|
||||||
) {
|
) {
|
||||||
// TODO: specify signatures
|
Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
|
||||||
|
List<JvmMethodParameterSignature> params = jvmMethodSignature.getKotlinParameterTypes();
|
||||||
|
int shift = 0;
|
||||||
|
|
||||||
int k = 0;
|
boolean isStatic = isStatic(ownerKind) || ownerKind == OwnerKind.TRAIT_IMPL;
|
||||||
|
if (!isStatic) {
|
||||||
if (thisType != null) {
|
//add this
|
||||||
mv.visitLocalVariable("this", thisType.getDescriptor(), null, methodBegin, methodEnd, k++);
|
if (thisType != null) {
|
||||||
|
mv.visitLocalVariable("this", thisType.getDescriptor(), null, methodBegin, methodEnd, shift);
|
||||||
|
} else {
|
||||||
|
//sometimes there is no thisType for callable reference
|
||||||
|
}
|
||||||
|
shift++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
|
for (int i = 0; i < params.size(); i++) {
|
||||||
if (receiverParameter != null) {
|
JvmMethodParameterSignature param = params.get(i);
|
||||||
Type type = typeMapper.mapType(receiverParameter.getType());
|
JvmMethodParameterKind kind = param.getKind();
|
||||||
mv.visitLocalVariable(JvmAbi.RECEIVER_PARAMETER, type.getDescriptor(), null, methodBegin, methodEnd, k);
|
String parameterName = "$" + param.getKind().name().toLowerCase();
|
||||||
k += type.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
|
if (needIndexForVar(kind)) {
|
||||||
Type type = typeMapper.mapType(parameter);
|
parameterName = parameterName + "$" + i;
|
||||||
|
|
||||||
Label divideLabel = labelsForSharedVars.get(parameter.getName());
|
|
||||||
String parameterName = parameter.getName().getName();
|
|
||||||
if (divideLabel != null) {
|
|
||||||
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, k);
|
|
||||||
|
|
||||||
String nameForSharedVar = createTmpVariableName(localVariableNames);
|
|
||||||
localVariableNames.add(nameForSharedVar);
|
|
||||||
|
|
||||||
Type sharedVarType = typeMapper.getSharedVarType(parameter);
|
|
||||||
mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k);
|
|
||||||
k += Math.max(type.getSize(), sharedVarType.getSize());
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, k);
|
Type type = param.getAsmType();
|
||||||
k += type.getSize();
|
if (kind == JvmMethodParameterKind.VALUE) {
|
||||||
|
ValueParameterDescriptor parameter = valueParameters.next();
|
||||||
|
Label divideLabel = labelsForSharedVars.get(parameter.getName());
|
||||||
|
parameterName = parameter.getName().getName();
|
||||||
|
if (divideLabel != null) {
|
||||||
|
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, shift);
|
||||||
|
|
||||||
|
String nameForSharedVar = createTmpVariableName(localVariableNames);
|
||||||
|
localVariableNames.add(nameForSharedVar);
|
||||||
|
|
||||||
|
Type sharedVarType = typeMapper.getSharedVarType(parameter);
|
||||||
|
mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, shift);
|
||||||
|
shift += Math.max(type.getSize(), sharedVarType.getSize());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift);
|
||||||
|
shift += type.getSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,18 +330,16 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
private void genJetAnnotations(
|
private void genJetAnnotations(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull FunctionDescriptor functionDescriptor,
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
@Nullable String propertyTypeSignature
|
@NotNull JvmMethodSignature jvmSignature
|
||||||
) {
|
) {
|
||||||
JvmMethodSignature jvmSignature =
|
|
||||||
typeMapper.mapToCallableMethod(functionDescriptor, false, false, false, OwnerKind.IMPLEMENTATION).getSignature();
|
|
||||||
|
|
||||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||||
assert propertyTypeSignature != null;
|
assert jvmSignature instanceof JvmPropertyAccessorSignature;
|
||||||
PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter(),
|
PropertyCodegen.generateJetPropertyAnnotation(mv, (JvmPropertyAccessorSignature) jvmSignature,
|
||||||
((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(), functionDescriptor.getVisibility());
|
((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty(), functionDescriptor.getVisibility());
|
||||||
}
|
}
|
||||||
else if (functionDescriptor instanceof SimpleFunctionDescriptor) {
|
else if (functionDescriptor instanceof SimpleFunctionDescriptor) {
|
||||||
if (propertyTypeSignature != null) {
|
if (jvmSignature instanceof JvmPropertyAccessorSignature) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
Modality modality = functionDescriptor.getModality();
|
Modality modality = functionDescriptor.getModality();
|
||||||
@@ -334,36 +358,57 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
||||||
aw.visitEnd();
|
aw.visitEnd();
|
||||||
}
|
}
|
||||||
|
else if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||||
|
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
|
||||||
|
|
||||||
|
int flagsValue = getFlagsForVisibility(functionDescriptor.getVisibility());
|
||||||
|
if (JvmStdlibNames.FLAGS_DEFAULT_VALUE != flagsValue) {
|
||||||
|
jetConstructorVisitor.visit(JvmStdlibNames.JET_FLAGS_FIELD, flagsValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
jetConstructorVisitor.visitEnd();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
|
||||||
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getKotlinParameterTypes();
|
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getKotlinParameterTypes();
|
||||||
|
|
||||||
assert kotlinParameterTypes != null;
|
assert kotlinParameterTypes != null;
|
||||||
|
|
||||||
int start = 0;
|
for (int i = 0; i < kotlinParameterTypes.size(); i++) {
|
||||||
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
|
JvmMethodParameterSignature param = kotlinParameterTypes.get(i);
|
||||||
if (receiverParameter != null) {
|
JvmMethodParameterKind kind = param.getKind();
|
||||||
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, start++);
|
String parameterName = "$" + param.getKind().name().toLowerCase();
|
||||||
av.writeName(JvmAbi.RECEIVER_PARAMETER);
|
|
||||||
av.writeReceiver();
|
ValueParameterDescriptor parameterDescriptor = null;
|
||||||
av.writeType(kotlinParameterTypes.get(0).getKotlinSignature());
|
if (kind == JvmMethodParameterKind.VALUE) {
|
||||||
av.visitEnd();
|
parameterDescriptor = valueParameters.next();
|
||||||
}
|
parameterName = parameterDescriptor.getName().getName();
|
||||||
|
} else if (needIndexForVar(kind)) {
|
||||||
|
parameterName = parameterName + "$" + i;
|
||||||
|
}
|
||||||
|
|
||||||
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
|
|
||||||
for (int i = 0; i != valueParameters.size(); ++i) {
|
|
||||||
ValueParameterDescriptor parameterDescriptor = valueParameters.get(i);
|
|
||||||
AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameterDescriptor);
|
AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameterDescriptor);
|
||||||
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start);
|
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
|
||||||
av.writeName(parameterDescriptor.getName().getName());
|
av.writeName(parameterName);
|
||||||
av.writeHasDefaultValue(parameterDescriptor.declaresDefaultValue());
|
if (kind == JvmMethodParameterKind.RECEIVER) {
|
||||||
av.writeVararg(parameterDescriptor.getVarargElementType() != null);
|
av.writeReceiver();
|
||||||
av.writeType(kotlinParameterTypes.get(i + start).getKotlinSignature());
|
}
|
||||||
|
if (parameterDescriptor != null) {
|
||||||
|
av.writeHasDefaultValue(parameterDescriptor.declaresDefaultValue());
|
||||||
|
av.writeVararg(parameterDescriptor.getVarargElementType() != null);
|
||||||
|
}
|
||||||
|
av.writeType(param.getKotlinSignature());
|
||||||
av.visitEnd();
|
av.visitEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean needIndexForVar(JvmMethodParameterKind kind) {
|
||||||
|
return kind == JvmMethodParameterKind.SHARED_VAR || kind == JvmMethodParameterKind.SUPER_CALL_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) {
|
public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) {
|
||||||
try {
|
try {
|
||||||
mv.visitMaxs(-1, -1);
|
mv.visitMaxs(-1, -1);
|
||||||
|
|||||||
@@ -18,22 +18,28 @@ package org.jetbrains.jet.codegen;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.asm4.MethodVisitor;
|
import org.jetbrains.asm4.MethodVisitor;
|
||||||
|
import org.jetbrains.asm4.Type;
|
||||||
|
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
|
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public abstract class FunctionGenerationStrategy {
|
public abstract class FunctionGenerationStrategy<T extends CallableDescriptor> {
|
||||||
|
|
||||||
private final Collection<String> localVariableNames = new ArrayList<String>();
|
private final Collection<String> localVariableNames = new ArrayList<String>();
|
||||||
|
|
||||||
|
private FrameMap frameMap;
|
||||||
|
|
||||||
public abstract void generateBody(
|
public abstract void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context
|
||||||
@NotNull FrameMap frameMap
|
|
||||||
);
|
);
|
||||||
|
|
||||||
protected void addLocalVariableName(@NotNull String name) {
|
protected void addLocalVariableName(@NotNull String name) {
|
||||||
@@ -45,31 +51,72 @@ public abstract class FunctionGenerationStrategy {
|
|||||||
return localVariableNames;
|
return localVariableNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean needsLocalVariableTable() {
|
@NotNull
|
||||||
return true;
|
protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context) {
|
||||||
|
return context.prepareFrame(typeMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public FrameMap getFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context) {
|
||||||
|
if (frameMap == null) {
|
||||||
|
frameMap = createFrameMap(typeMapper, context);
|
||||||
|
}
|
||||||
|
return frameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FunctionDefault extends CodegenBased<CallableDescriptor> {
|
||||||
|
|
||||||
public static class Default extends FunctionGenerationStrategy {
|
|
||||||
private final GenerationState state;
|
|
||||||
private final JetDeclarationWithBody declaration;
|
private final JetDeclarationWithBody declaration;
|
||||||
|
|
||||||
public Default(@NotNull GenerationState state, @NotNull JetDeclarationWithBody declaration) {
|
public FunctionDefault(
|
||||||
this.state = state;
|
@NotNull GenerationState state,
|
||||||
|
@NotNull CallableDescriptor descriptor,
|
||||||
|
@NotNull JetDeclarationWithBody declaration
|
||||||
|
) {
|
||||||
|
super(state, descriptor);
|
||||||
this.declaration = declaration;
|
this.declaration = declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
|
||||||
|
codegen.returnExpression(declaration.getBodyExpression());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy<T> {
|
||||||
|
|
||||||
|
private final GenerationState state;
|
||||||
|
protected final T callableDescriptor;
|
||||||
|
|
||||||
|
public CodegenBased(@NotNull GenerationState state, T callableDescriptor) {
|
||||||
|
this.state = state;
|
||||||
|
this.callableDescriptor = callableDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context
|
||||||
@NotNull FrameMap frameMap
|
|
||||||
) {
|
) {
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getAsmMethod().getReturnType(), context, state);
|
ExpressionCodegen codegen = initializeExpressionCodegen(signature, context, mv, signature.getAsmMethod().getReturnType());
|
||||||
|
doGenerateBody(codegen, signature);
|
||||||
|
generateLocalVarNames(codegen);
|
||||||
|
}
|
||||||
|
|
||||||
codegen.returnExpression(declaration.getBodyExpression());
|
abstract public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ExpressionCodegen initializeExpressionCodegen(
|
||||||
|
JvmMethodSignature signature,
|
||||||
|
MethodContext context,
|
||||||
|
MethodVisitor mv,
|
||||||
|
Type returnType
|
||||||
|
) {
|
||||||
|
return new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), returnType, context, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateLocalVarNames(@NotNull ExpressionCodegen codegen) {
|
||||||
for (String name : codegen.getLocalVariableNamesForExpression()) {
|
for (String name : codegen.getLocalVariableNamesForExpression()) {
|
||||||
addLocalVariableName(name);
|
addLocalVariableName(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -681,13 +681,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
JvmMethodSignature signature = typeMapper.mapSignature(function);
|
JvmMethodSignature signature = typeMapper.mapSignature(function);
|
||||||
|
|
||||||
FunctionCodegen fc = new FunctionCodegen(context, v, state);
|
FunctionCodegen fc = new FunctionCodegen(context, v, state);
|
||||||
fc.generateMethod(myClass, signature, true, null, function, new FunctionGenerationStrategy() {
|
fc.generateMethod(myClass, signature, true, function, new FunctionGenerationStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context
|
||||||
@NotNull FrameMap frameMap
|
|
||||||
) {
|
) {
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
if (!componentType.equals(Type.VOID_TYPE)) {
|
if (!componentType.equals(Type.VOID_TYPE)) {
|
||||||
@@ -706,13 +705,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final Type thisDescriptorType = typeMapper.mapType(descriptor.getDefaultType());
|
final Type thisDescriptorType = typeMapper.mapType(descriptor.getDefaultType());
|
||||||
|
|
||||||
FunctionCodegen fc = new FunctionCodegen(context, v, state);
|
FunctionCodegen fc = new FunctionCodegen(context, v, state);
|
||||||
fc.generateMethod(myClass, methodSignature, true, null, function, new FunctionGenerationStrategy() {
|
fc.generateMethod(myClass, methodSignature, true, function, new FunctionGenerationStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context
|
||||||
@NotNull FrameMap frameMap
|
|
||||||
) {
|
) {
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
|
|
||||||
@@ -860,10 +858,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
||||||
MethodVisitor mv =
|
MethodVisitor mv =
|
||||||
v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
|
v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
|
||||||
PropertyGetterDescriptor getter = ((PropertyDescriptor) entry.getValue()).getGetter();
|
PropertyGetterDescriptor getter = bridge.getGetter();
|
||||||
assert getter != null;
|
assert getter != null;
|
||||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(),
|
PropertyCodegen.generateJetPropertyAnnotation(mv,
|
||||||
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
|
originalSignature,
|
||||||
original,
|
original,
|
||||||
getter.getVisibility());
|
getter.getVisibility());
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||||
@@ -897,10 +895,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
||||||
MethodVisitor mv =
|
MethodVisitor mv =
|
||||||
v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||||
PropertySetterDescriptor setter = ((PropertyDescriptor) entry.getValue()).getSetter();
|
PropertySetterDescriptor setter = bridge.getSetter();
|
||||||
assert setter != null;
|
assert setter != null;
|
||||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(),
|
PropertyCodegen.generateJetPropertyAnnotation(mv,
|
||||||
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
|
originalSignature2,
|
||||||
original,
|
original,
|
||||||
setter.getVisibility());
|
setter.getVisibility());
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||||
@@ -967,6 +965,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
throw new IllegalStateException("incorrect kind for primary constructor: " + kind);
|
throw new IllegalStateException("incorrect kind for primary constructor: " + kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final MutableClosure closure = context.closure;
|
||||||
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
|
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
|
||||||
|
|
||||||
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
|
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
|
||||||
@@ -975,60 +974,49 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
|
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableClosure closure = context.closure;
|
final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, context.closure);
|
||||||
boolean hasCapturedThis = closure != null && closure.getCaptureThis() != null;
|
|
||||||
|
|
||||||
CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, context.closure);
|
|
||||||
JvmMethodSignature constructorMethod = callableMethod.getSignature();
|
JvmMethodSignature constructorMethod = callableMethod.getSignature();
|
||||||
|
|
||||||
assert constructorDescriptor != null;
|
assert constructorDescriptor != null;
|
||||||
int flags = getConstructorAsmFlags(constructorDescriptor);
|
|
||||||
MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(),
|
|
||||||
constructorMethod.getGenericsSignature(), null);
|
|
||||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
|
|
||||||
|
|
||||||
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
|
FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
|
||||||
|
|
||||||
int flagsValue = getFlagsForVisibility(constructorDescriptor.getVisibility());
|
functionCodegen.generateMethod(null, constructorMethod, true, constructorDescriptor, constructorContext,
|
||||||
if (JvmStdlibNames.FLAGS_DEFAULT_VALUE != flagsValue) {
|
new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
|
||||||
jetConstructorVisitor.visit(JvmStdlibNames.JET_FLAGS_FIELD, flagsValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
jetConstructorVisitor.visitEnd();
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected FrameMap createFrameMap(
|
||||||
|
@NotNull JetTypeMapper typeMapper, @NotNull CodegenContext context
|
||||||
|
) {
|
||||||
|
return new ConstructorFrameMap(callableMethod, callableDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(constructorDescriptor);
|
@Override
|
||||||
|
public void doGenerateBody(
|
||||||
|
ExpressionCodegen codegen, JvmMethodSignature signature
|
||||||
|
) {
|
||||||
|
generatePrimaryConstructorImpl(callableDescriptor, codegen, closure);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
writeParameterAnnotations(constructorDescriptor, constructorMethod, hasCapturedThis, mv);
|
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
|
||||||
|
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
|
||||||
|
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
|
||||||
genStubCode(mv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
generatePrimaryConstructorImpl(constructorDescriptor, constructorContext, constructorMethod, callableMethod, closure, mv);
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v);
|
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generatePrimaryConstructorImpl(
|
private void generatePrimaryConstructorImpl(
|
||||||
ConstructorDescriptor constructorDescriptor,
|
ConstructorDescriptor constructorDescriptor,
|
||||||
ConstructorContext constructorContext,
|
ExpressionCodegen codegen,
|
||||||
JvmMethodSignature constructorMethod,
|
MutableClosure closure
|
||||||
CallableMethod callableMethod,
|
|
||||||
MutableClosure closure,
|
|
||||||
MethodVisitor mv
|
|
||||||
) {
|
) {
|
||||||
mv.visitCode();
|
|
||||||
|
|
||||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
||||||
? constructorDescriptor.getValueParameters()
|
? constructorDescriptor.getValueParameters()
|
||||||
: Collections.<ValueParameterDescriptor>emptyList();
|
: Collections.<ValueParameterDescriptor>emptyList();
|
||||||
|
|
||||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor);
|
InstructionAdapter iv = codegen.v;
|
||||||
|
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state);
|
|
||||||
|
|
||||||
JvmClassName classname = JvmClassName.byType(classAsmType);
|
JvmClassName classname = JvmClassName.byType(classAsmType);
|
||||||
|
|
||||||
@@ -1039,7 +1027,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
genSuperCallToDelegatorToSuperClass(iv);
|
genSuperCallToDelegatorToSuperClass(iv);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor, frameMap);
|
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closure != null) {
|
if (closure != null) {
|
||||||
@@ -1068,7 +1056,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
VariableDescriptor descriptor = paramDescrs.get(curParam);
|
VariableDescriptor descriptor = paramDescrs.get(curParam);
|
||||||
Type type = typeMapper.mapType(descriptor);
|
Type type = typeMapper.mapType(descriptor);
|
||||||
iv.load(0, classAsmType);
|
iv.load(0, classAsmType);
|
||||||
iv.load(frameMap.getIndex(descriptor), type);
|
iv.load(codegen.myFrameMap.getIndex(descriptor), type);
|
||||||
iv.putfield(classAsmType.getInternalName(), descriptor.getName().getName(), type.getDescriptor());
|
iv.putfield(classAsmType.getInternalName(), descriptor.getName().getName(), type.getDescriptor());
|
||||||
}
|
}
|
||||||
curParam++;
|
curParam++;
|
||||||
@@ -1076,12 +1064,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
generateInitializers(codegen, iv, myClass.getDeclarations(), bindingContext, state);
|
generateInitializers(codegen, iv, myClass.getDeclarations(), bindingContext, state);
|
||||||
|
|
||||||
mv.visitInsn(RETURN);
|
iv.visitInsn(RETURN);
|
||||||
FunctionCodegen.endVisit(mv, "constructor", myClass);
|
|
||||||
|
|
||||||
assert constructorDescriptor != null;
|
|
||||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
|
|
||||||
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genSuperCallToDelegatorToSuperClass(InstructionAdapter iv) {
|
private void genSuperCallToDelegatorToSuperClass(InstructionAdapter iv) {
|
||||||
@@ -1113,37 +1096,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeParameterAnnotations(
|
|
||||||
ConstructorDescriptor constructorDescriptor,
|
|
||||||
JvmMethodSignature constructorMethod,
|
|
||||||
boolean hasThis0,
|
|
||||||
MethodVisitor mv
|
|
||||||
) {
|
|
||||||
if (constructorDescriptor != null) {
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (hasThis0) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
|
|
||||||
AnnotationCodegen.forParameter(i, mv, state.getTypeMapper()).genAnnotations(valueParameter);
|
|
||||||
JetValueParameterAnnotationWriter jetValueParameterAnnotation =
|
|
||||||
JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
|
|
||||||
jetValueParameterAnnotation.writeName(valueParameter.getName().getName());
|
|
||||||
jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
|
|
||||||
jetValueParameterAnnotation.writeVararg(valueParameter.getVarargElementType() != null);
|
|
||||||
jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i));
|
|
||||||
jetValueParameterAnnotation.visitEnd();
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void genCallToDelegatorByExpressionSpecifier(
|
private void genCallToDelegatorByExpressionSpecifier(
|
||||||
InstructionAdapter iv,
|
InstructionAdapter iv,
|
||||||
ExpressionCodegen codegen,
|
ExpressionCodegen codegen,
|
||||||
@@ -1450,8 +1402,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
private void generateDelegatorToConstructorCall(
|
private void generateDelegatorToConstructorCall(
|
||||||
InstructionAdapter iv, ExpressionCodegen codegen,
|
InstructionAdapter iv, ExpressionCodegen codegen,
|
||||||
ConstructorDescriptor constructorDescriptor,
|
ConstructorDescriptor constructorDescriptor
|
||||||
ConstructorFrameMap frameMap
|
|
||||||
) {
|
) {
|
||||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||||
|
|
||||||
@@ -1474,7 +1425,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, closureForSuper);
|
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, closureForSuper);
|
||||||
|
|
||||||
if (closureForSuper != null && closureForSuper.getCaptureThis() != null) {
|
if (closureForSuper != null && closureForSuper.getCaptureThis() != null) {
|
||||||
iv.load(frameMap.getOuterThisIndex(), OBJECT_TYPE);
|
iv.load(((ConstructorFrameMap)codegen.myFrameMap).getOuterThisIndex(), OBJECT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myClass instanceof JetObjectDeclaration &&
|
if (myClass instanceof JetObjectDeclaration &&
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.*;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.getDeprecatedAccessFlag;
|
import static org.jetbrains.jet.codegen.AsmUtil.getDeprecatedAccessFlag;
|
||||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||||
@@ -135,11 +133,10 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
FunctionGenerationStrategy strategy =
|
FunctionGenerationStrategy strategy =
|
||||||
defaultGetter
|
defaultGetter
|
||||||
? new DefaultPropertyAccessorStrategy(getterDescriptor)
|
? new DefaultPropertyAccessorStrategy(getterDescriptor)
|
||||||
: new FunctionGenerationStrategy.Default(state, getter);
|
: new FunctionGenerationStrategy.FunctionDefault(state, getterDescriptor, getter);
|
||||||
functionCodegen.generateMethod(getter != null ? getter : p,
|
functionCodegen.generateMethod(getter != null ? getter : p,
|
||||||
signature.getJvmMethodSignature(),
|
signature.getJvmMethodSignature(),
|
||||||
true,
|
true,
|
||||||
signature.getPropertyTypeKotlinSignature(),
|
|
||||||
getterDescriptor,
|
getterDescriptor,
|
||||||
strategy);
|
strategy);
|
||||||
}
|
}
|
||||||
@@ -159,11 +156,10 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
FunctionGenerationStrategy strategy =
|
FunctionGenerationStrategy strategy =
|
||||||
defaultSetter
|
defaultSetter
|
||||||
? new DefaultPropertyAccessorStrategy(setterDescriptor)
|
? new DefaultPropertyAccessorStrategy(setterDescriptor)
|
||||||
: new FunctionGenerationStrategy.Default(state, setter);
|
: new FunctionGenerationStrategy.FunctionDefault(state, setterDescriptor, setter);
|
||||||
functionCodegen.generateMethod(setter != null ? setter : p,
|
functionCodegen.generateMethod(setter != null ? setter : p,
|
||||||
signature.getJvmMethodSignature(),
|
signature.getJvmMethodSignature(),
|
||||||
true,
|
true,
|
||||||
signature.getPropertyTypeKotlinSignature(),
|
|
||||||
setterDescriptor,
|
setterDescriptor,
|
||||||
strategy);
|
strategy);
|
||||||
}
|
}
|
||||||
@@ -182,8 +178,7 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context
|
||||||
@NotNull FrameMap frameMap
|
|
||||||
) {
|
) {
|
||||||
generateDefaultAccessor(descriptor, new InstructionAdapter(mv), typeMapper, context);
|
generateDefaultAccessor(descriptor, new InstructionAdapter(mv), typeMapper, context);
|
||||||
}
|
}
|
||||||
@@ -233,7 +228,7 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void generateJetPropertyAnnotation(
|
public static void generateJetPropertyAnnotation(
|
||||||
MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters,
|
MethodVisitor mv, @NotNull JvmPropertyAccessorSignature propertyAccessorSignature,
|
||||||
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility
|
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility
|
||||||
) {
|
) {
|
||||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||||
@@ -245,8 +240,8 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
: JvmStdlibNames.FLAG_FORCE_OPEN_BIT;
|
: JvmStdlibNames.FLAG_FORCE_OPEN_BIT;
|
||||||
}
|
}
|
||||||
aw.writeFlags(flags | DescriptorKindUtils.kindToFlags(propertyDescriptor.getKind()));
|
aw.writeFlags(flags | DescriptorKindUtils.kindToFlags(propertyDescriptor.getKind()));
|
||||||
aw.writeTypeParameters(typeParameters);
|
aw.writeTypeParameters(propertyAccessorSignature.getKotlinTypeParameter());
|
||||||
aw.writePropertyType(kotlinType);
|
aw.writePropertyType(propertyAccessorSignature.getPropertyTypeKotlinSignature());
|
||||||
aw.visitEnd();
|
aw.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user