Construct delegates in expression codegen, not in LocalLookup

This commit is contained in:
Mikhael Bogdanov
2016-06-03 16:57:55 +03:00
parent 2578fc3344
commit 6f761d4e7d
4 changed files with 45 additions and 45 deletions
@@ -2330,7 +2330,28 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return lookupCapturedValueInConstructorParameters(descriptor);
}
return context.lookupInContext(descriptor, StackValue.LOCAL_0, state, false);
return lookupInContext(descriptor, StackValue.LOCAL_0, state, false, context);
}
@Nullable
StackValue lookupInContext(
@NotNull DeclarationDescriptor descriptor,
@NotNull StackValue prefix,
@NotNull GenerationState state,
boolean ignoreNoOuter,
@NotNull CodegenContext context
) {
StackValue value = context.lookupInContext(descriptor, prefix, state, ignoreNoOuter);
if(!isDelegatedLocalVariable(descriptor) || value == null) {
return value;
}
VariableDescriptor metadata = getDelegatedLocalVariableMetadata((VariableDescriptor) descriptor, state.getBindingContext());
StackValue metadataValue = context.lookupInContext(metadata, prefix, state, ignoreNoOuter);
assert metadataValue != null : "Metadata stack value should be non-null for local delegated property";
return delegatedVariableValue(value, metadataValue, (VariableDescriptorWithAccessors) descriptor, state.getBindingContext(),
state.getTypeMapper());
}
@Nullable
@@ -3752,7 +3773,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
VariableDescriptorWithAccessors variableDescriptor = (VariableDescriptorWithAccessors) descriptor;
StackValue metadataValue = getVariableMetadataValue(variableDescriptor);
return JvmCodegenUtil.delegatedVariableValue(varValue, metadataValue, variableDescriptor, bindingContext, typeMapper);
return delegatedVariableValue(varValue, metadataValue, variableDescriptor, bindingContext, typeMapper);
}
private void initializeLocalVariable(
@@ -4454,4 +4475,24 @@ The "returned" value of try expression with no finally is either the last expres
labelName = name;
}
}
@NotNull
private static StackValue.Delegate delegatedVariableValue(
@NotNull StackValue delegateValue,
@NotNull StackValue metadataValue,
@NotNull VariableDescriptorWithAccessors variableDescriptor,
@NotNull BindingContext bindingContext,
@NotNull KotlinTypeMapper typeMapper
) {
VariableDescriptor delegateVariableDescriptor = bindingContext.get(LOCAL_VARIABLE_DELEGATE, variableDescriptor);
assert delegateVariableDescriptor != null : variableDescriptor;
VariableAccessorDescriptor getterDescriptor = variableDescriptor.getGetter();
VariableAccessorDescriptor setterDescriptor = variableDescriptor.getSetter();
//noinspection ConstantConditions
CallableMethod getterMethod = typeMapper.mapToCallableMethod(getterDescriptor, false);
CallableMethod setterMethod = setterDescriptor != null ? typeMapper.mapToCallableMethod(setterDescriptor, false) : null;
return StackValue.delegate(typeMapper.mapType(variableDescriptor.getType()), delegateValue, metadataValue, getterMethod, setterMethod);
}
}
@@ -1256,7 +1256,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void lookupInContext(@NotNull DeclarationDescriptor toLookup) {
context.lookupInContext(toLookup, StackValue.LOCAL_0, state, true);
ExpressionCodegen.lookupInContext(toLookup, StackValue.LOCAL_0, state, true, context);
}
@Override
@@ -49,7 +49,6 @@ import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.File;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.LOCAL_VARIABLE_DELEGATE;
import static org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS;
import static org.jetbrains.kotlin.descriptors.ClassKind.INTERFACE;
import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT;
@@ -293,24 +292,4 @@ public class JvmCodegenUtil {
}
return null;
}
@NotNull
public static StackValue.Delegate delegatedVariableValue(
@NotNull StackValue delegateValue,
@NotNull StackValue metadataValue,
VariableDescriptorWithAccessors variableDescriptor,
@NotNull BindingContext bindingContext,
@NotNull KotlinTypeMapper typeMapper
) {
VariableDescriptor delegateVariableDescriptor = bindingContext.get(LOCAL_VARIABLE_DELEGATE, variableDescriptor);
assert delegateVariableDescriptor != null : variableDescriptor;
VariableAccessorDescriptor getterDescriptor = variableDescriptor.getGetter();
VariableAccessorDescriptor setterDescriptor = variableDescriptor.getSetter();
//noinspection ConstantConditions
CallableMethod getterMethod = typeMapper.mapToCallableMethod(getterDescriptor, false);
CallableMethod setterMethod = setterDescriptor != null ? typeMapper.mapToCallableMethod(setterDescriptor, false) : null;
return StackValue.delegate(typeMapper.mapType(variableDescriptor.getType()), delegateValue, metadataValue, getterMethod, setterMethod);
}
}
@@ -51,20 +51,13 @@ public interface LocalLookup {
Type classType
) {
VariableDescriptor vd = (VariableDescriptor) d;
VariableDescriptor originalVariableDescriptor = vd;
boolean idx = localLookup != null && localLookup.lookupLocal(vd);
if (!idx) return null;
boolean delegatedVar = false;
VariableDescriptor delegateVariableDescriptor = state.getBindingContext().get(LOCAL_VARIABLE_DELEGATE, vd);
if (delegateVariableDescriptor != null) {
vd = delegateVariableDescriptor;
delegatedVar = true;
}
Type sharedVarType = state.getTypeMapper().getSharedVarType(vd);
Type localType = state.getTypeMapper().mapType(vd);
Type localType = state.getTypeMapper().mapType(delegateVariableDescriptor != null ? delegateVariableDescriptor : vd);
Type type = sharedVarType != null ? sharedVarType : localType;
String fieldName = "$" + vd.getName();
@@ -79,19 +72,6 @@ public interface LocalLookup {
}
else {
innerValue = StackValue.field(type, classType, fieldName, false, thiz, vd);
if (delegatedVar) {
VariableDescriptor metadataVariableDescriptor = getDelegatedLocalVariableMetadata(originalVariableDescriptor, state.getBindingContext());
StackValue metadataValue = innerValue(metadataVariableDescriptor, localLookup, state, closure, classType);
assert metadataValue != null : originalVariableDescriptor;
innerValue = JvmCodegenUtil.delegatedVariableValue(
innerValue,
metadataValue,
(VariableDescriptorWithAccessors) originalVariableDescriptor,
state.getBindingContext(),
state.getTypeMapper()
);
}
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, type);
}