Lazy calculation of outer expression
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user