Lazy calculation of outer expression

This commit is contained in:
Mikhael Bogdanov
2013-10-30 14:19:37 +04:00
parent 47cd9a71a2
commit 936c0a0ae9
5 changed files with 41 additions and 23 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
<orderEntry type="library" name="protobuf-java" level="project" />
<orderEntry type="module" module-name="serialization.java" />
<orderEntry type="module" module-name="descriptor.loader.java" />
<orderEntry type="library" name="kotlin-runtime" level="project" />
<orderEntry type="module" module-name="util" />
</component>
</module>
@@ -1129,7 +1129,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
final MutableClosure closure = context.closure;
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, closure);
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen.context;
import jet.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
@@ -30,6 +31,8 @@ import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.storage.LockBasedStorageManager;
import org.jetbrains.jet.storage.NullableLazyValue;
import java.util.Collections;
import java.util.HashMap;
@@ -62,7 +65,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
private Map<DeclarationDescriptor, CodegenContext> childContexts;
protected StackValue outerExpression;
private NullableLazyValue<StackValue> lazyOuterExpression;
private final LocalLookup enclosingLocalLookup;
@@ -129,7 +132,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
private StackValue getOuterExpression(@Nullable StackValue prefix, boolean ignoreNoOuter, boolean captureThis) {
if (outerExpression == null) {
if (lazyOuterExpression == null || lazyOuterExpression.invoke() == null) {
if (ignoreNoOuter) {
return null;
}
@@ -140,7 +143,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (captureThis) {
closure.setCaptureThis();
}
return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression;
return prefix != null ? StackValue.composed(prefix, lazyOuterExpression.invoke()) : lazyOuterExpression.invoke();
}
@NotNull
@@ -184,13 +187,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
public ConstructorContext intoConstructor(ConstructorDescriptor descriptor) {
public ConstructorContext intoConstructor(@Nullable ConstructorDescriptor descriptor, @Nullable MutableClosure closure) {
if (descriptor == null) {
descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true)
.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
Visibilities.PUBLIC);
}
return new ConstructorContext(descriptor, getContextKind(), this);
return new ConstructorContext(descriptor, getContextKind(), this, closure);
}
@NotNull
@@ -294,14 +297,19 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
public abstract boolean isStatic();
protected void initOuterExpression(JetTypeMapper typeMapper, ClassDescriptor classDescriptor) {
ClassDescriptor enclosingClass = getEnclosingClass();
outerExpression = enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
? StackValue.field(typeMapper.mapType(enclosingClass),
CodegenBinding.getAsmType(typeMapper.getBindingTrace(), classDescriptor),
CAPTURED_THIS_FIELD,
false)
: null;
protected void initOuterExpression(@NotNull final JetTypeMapper typeMapper, @NotNull final ClassDescriptor classDescriptor) {
lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue>() {
@Override
public StackValue invoke() {
ClassDescriptor enclosingClass = getEnclosingClass();
return enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
? StackValue.field(typeMapper.mapType(enclosingClass),
CodegenBinding.getAsmType(typeMapper.getBindingTrace(), classDescriptor),
CAPTURED_THIS_FIELD,
false)
: null;
}
});
}
public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) {
@@ -17,9 +17,10 @@
package org.jetbrains.jet.codegen.context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.OwnerKind;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
@@ -30,17 +31,15 @@ public class ConstructorContext extends MethodContext {
public ConstructorContext(
@NotNull ConstructorDescriptor contextDescriptor,
@NotNull OwnerKind kind,
@NotNull CodegenContext parent
@NotNull CodegenContext parent,
@Nullable MutableClosure closure
) {
super(contextDescriptor, kind, parent);
ClassDescriptor type = getEnclosingClass();
outerExpression = type != null ? local1 : null;
super(contextDescriptor, kind, parent, closure);
}
@Override
public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) {
return outerExpression;
return closure != null && closure.getCaptureThis() != null ? local1 : null;
}
@Override
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen.context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.codegen.OwnerKind;
import org.jetbrains.jet.codegen.StackValue;
@@ -27,14 +28,24 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
public class MethodContext extends CodegenContext {
public MethodContext(
@NotNull FunctionDescriptor contextType,
@NotNull OwnerKind contextKind,
@NotNull CodegenContext parentContext
) {
this(contextType, contextKind, parentContext, null);
}
protected MethodContext(
@NotNull FunctionDescriptor contextType,
@NotNull OwnerKind contextKind,
@NotNull CodegenContext parentContext,
@Nullable MutableClosure closure
) {
super(contextType instanceof PropertyAccessorDescriptor
? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty()
: contextType, contextKind, parentContext, null,
: contextType, contextKind, parentContext, closure,
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null);
}