Refactor CodegenBinding#getAsmType()

- make it return the ASM_TYPE slice value and assert it is there
- move all the computation to the separate method "computeAsmType"
- only call getAsmType() in those places where the type must be recorded at
  slice ASM_TYPE, otherwise call JetTypeMapper#mapType(), which will check the
  slice and call computeAsmType
This commit is contained in:
Alexander Udalov
2014-09-02 18:58:07 +04:00
parent c1125402bd
commit d4a845da01
5 changed files with 37 additions and 29 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.intellij.util.ArrayUtil;
import kotlin.Function0; import kotlin.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.CodegenContext;
@@ -38,7 +39,8 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.method; import static org.jetbrains.jet.codegen.AsmUtil.method;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForScriptDescriptor;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin; import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN; import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
@@ -52,17 +54,17 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@NotNull GenerationState state, @NotNull GenerationState state,
@NotNull CodegenContext parentContext @NotNull CodegenContext parentContext
) { ) {
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, declaration); BindingContext bindingContext = state.getBindingContext();
ScriptDescriptor scriptDescriptor = bindingContext.get(BindingContext.SCRIPT, declaration);
assert scriptDescriptor != null; assert scriptDescriptor != null;
ClassDescriptor classDescriptorForScript = state.getBindingContext().get(CLASS_FOR_SCRIPT, scriptDescriptor); ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
assert classDescriptorForScript != null; assert classDescriptorForScript != null;
Type className = state.getBindingContext().get(ASM_TYPE, classDescriptorForScript); Type classType = asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
assert className != null;
ClassBuilder builder = state.getFactory().newVisitor(OtherOrigin(declaration, classDescriptorForScript), ClassBuilder builder = state.getFactory().newVisitor(OtherOrigin(declaration, classDescriptorForScript),
className, declaration.getContainingFile()); classType, declaration.getContainingFile());
List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter(); List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
ScriptContext scriptContext = parentContext.intoScript( ScriptContext scriptContext = parentContext.intoScript(
scriptDescriptor, scriptDescriptor,
@@ -90,8 +92,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@Override @Override
protected void generateDeclaration() { protected void generateDeclaration() {
Type classType = bindingContext.get(ASM_TYPE, context.getContextDescriptor()); Type classType = typeMapper.mapClass(context.getContextDescriptor());
assert classType != null;
v.defineClass(scriptDeclaration, v.defineClass(scriptDeclaration,
V1_6, V1_6,
@@ -99,7 +100,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
classType.getInternalName(), classType.getInternalName(),
null, null,
"java/lang/Object", "java/lang/Object",
new String[0]); ArrayUtil.EMPTY_STRING_ARRAY);
generateReflectionObjectField(state, classType, v, method("kClassFromKotlin", K_CLASS_IMPL_TYPE, getType(Class.class)), generateReflectionObjectField(state, classType, v, method("kClassFromKotlin", K_CLASS_IMPL_TYPE, getType(Class.class)),
JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v); JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v);
@@ -124,6 +125,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@NotNull ClassBuilder classBuilder, @NotNull ClassBuilder classBuilder,
@NotNull final MethodContext methodContext @NotNull final MethodContext methodContext
) { ) {
//noinspection ConstantConditions
Type blockType = typeMapper.mapType(scriptDescriptor.getScriptCodeDescriptor().getReturnType()); Type blockType = typeMapper.mapType(scriptDescriptor.getScriptCodeDescriptor().getReturnType());
PropertyDescriptor scriptResultProperty = scriptDescriptor.getScriptResultProperty(); PropertyDescriptor scriptResultProperty = scriptDescriptor.getScriptResultProperty();
@@ -142,8 +144,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
final InstructionAdapter iv = new InstructionAdapter(mv); final InstructionAdapter iv = new InstructionAdapter(mv);
Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript); Type classType = typeMapper.mapType(classDescriptorForScript);
assert classType != null;
iv.load(0, classType); iv.load(0, classType);
iv.invokespecial("java/lang/Object", "<init>", "()V", false); iv.invokespecial("java/lang/Object", "<init>", "()V", false);
@@ -23,7 +23,10 @@ import com.intellij.util.containers.Stack;
import kotlin.Function1; import kotlin.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.JvmRuntimeTypes;
import org.jetbrains.jet.codegen.SamCodegenUtil;
import org.jetbrains.jet.codegen.SamType;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.when.SwitchCodegenUtil; import org.jetbrains.jet.codegen.when.SwitchCodegenUtil;
import org.jetbrains.jet.codegen.when.WhenByEnumsMapping; import org.jetbrains.jet.codegen.when.WhenByEnumsMapping;
@@ -261,8 +264,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
recordClosure(expression.getObjectDeclaration(), classDescriptor, name); recordClosure(expression.getObjectDeclaration(), classDescriptor, name);
pushClassDescriptor(classDescriptor); pushClassDescriptor(classDescriptor);
//noinspection ConstantConditions nameStack.push(CodegenBinding.getAsmType(bindingContext, classDescriptor).getInternalName());
nameStack.push(bindingContext.get(ASM_TYPE, classDescriptor).getInternalName());
super.visitObjectLiteralExpression(expression); super.visitObjectLiteralExpression(expression);
nameStack.pop(); nameStack.pop();
popClassDescriptor(); popClassDescriptor();
@@ -287,19 +287,25 @@ public class CodegenBinding {
@NotNull @NotNull
public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) { public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
klass = (ClassDescriptor) klass.getOriginal(); Type type = bindingContext.get(ASM_TYPE, klass);
assert type != null : "Type is not yet recorded for " + klass;
return type;
}
@NotNull
public static Type computeAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass); Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
if (alreadyComputedType != null) { if (alreadyComputedType != null) {
return alreadyComputedType; return alreadyComputedType;
} }
Type asmType = Type.getObjectType(getAsmTypeImpl(bindingContext, klass)); Type asmType = Type.getObjectType(computeAsmTypeImpl(bindingContext, klass));
assert PsiCodegenPredictor.checkPredictedNameFromPsi(klass, asmType); assert PsiCodegenPredictor.checkPredictedNameFromPsi(klass, asmType);
return asmType; return asmType;
} }
@NotNull @NotNull
private static String getAsmTypeImpl(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) { private static String computeAsmTypeImpl(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
DeclarationDescriptor container = klass.getContainingDeclaration(); DeclarationDescriptor container = klass.getContainingDeclaration();
Name name = SpecialNames.safeIdentifier(klass.getName()); Name name = SpecialNames.safeIdentifier(klass.getName());
@@ -316,7 +322,7 @@ public class CodegenBinding {
assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass; assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
String containerInternalName = getAsmType(bindingContext, (ClassDescriptor) container).getInternalName(); String containerInternalName = computeAsmTypeImpl(bindingContext, (ClassDescriptor) container);
switch (klass.getKind()) { switch (klass.getKind()) {
case ENUM_ENTRY: case ENUM_ENTRY:
return containerInternalName; return containerInternalName;
@@ -20,7 +20,6 @@ import kotlin.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.binding.MutableClosure;
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.codegen.state.JetTypeMapper;
@@ -39,7 +38,8 @@ import java.util.Map;
import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD; import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD;
import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag; import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.anonymousClassForFunction;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.canHaveOuter;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE; import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED; import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
@@ -266,13 +266,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue>() { lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue>() {
@Override @Override
public StackValue invoke() { public StackValue invoke() {
BindingContext bindingContext = typeMapper.getBindingContext();
ClassDescriptor enclosingClass = getEnclosingClass(); ClassDescriptor enclosingClass = getEnclosingClass();
return enclosingClass != null && canHaveOuter(bindingContext, classDescriptor) if (enclosingClass == null) return null;
? StackValue.field(typeMapper.mapType(enclosingClass),
CodegenBinding.getAsmType(bindingContext, classDescriptor), return canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
CAPTURED_THIS_FIELD, ? StackValue.field(typeMapper.mapType(enclosingClass), typeMapper.mapType(classDescriptor),
false) CAPTURED_THIS_FIELD, false)
: null; : null;
} }
}); });
@@ -289,7 +288,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
for (LocalLookup.LocalLookupCase aCase : LocalLookup.LocalLookupCase.values()) { for (LocalLookup.LocalLookupCase aCase : LocalLookup.LocalLookupCase.values()) {
if (aCase.isCase(d)) { if (aCase.isCase(d)) {
Type classType = state.getBindingContext().get(ASM_TYPE, getThisDescriptor()); Type classType = state.getTypeMapper().mapType(getThisDescriptor());
StackValue innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType); StackValue innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType);
if (innerValue == null) { if (innerValue == null) {
break; break;
@@ -277,7 +277,7 @@ public class JetTypeMapper {
} }
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
Type asmType = getAsmType(bindingContext, (ClassDescriptor) descriptor); Type asmType = computeAsmType(bindingContext, (ClassDescriptor) descriptor.getOriginal());
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed); writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed);
return asmType; return asmType;
} }
@@ -296,7 +296,7 @@ public class JetTypeMapper {
@NotNull @NotNull
public Type mapTraitImpl(@NotNull ClassDescriptor descriptor) { public Type mapTraitImpl(@NotNull ClassDescriptor descriptor) {
return Type.getObjectType(getAsmType(bindingContext, descriptor).getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX); return Type.getObjectType(mapType(descriptor).getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
} }
@NotNull @NotNull