Get rid of ConstructorFrameMap, drop CodegenContext#prepareFrame()
Also refactor FunctionGenerationStrategy to take FrameMap as an instance instead of creating it in a subclass
This commit is contained in:
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
|
||||||
|
|
||||||
public class ConstructorFrameMap extends FrameMap {
|
|
||||||
private int myOuterThisIndex = -1;
|
|
||||||
|
|
||||||
public ConstructorFrameMap(@NotNull JvmMethodSignature signature) {
|
|
||||||
enterTemp(OBJECT_TYPE); // this
|
|
||||||
|
|
||||||
for (JvmMethodParameterSignature parameterType : signature.getValueParameters()) {
|
|
||||||
if (parameterType.getKind() == JvmMethodParameterKind.OUTER) {
|
|
||||||
myOuterThisIndex = enterTemp(OBJECT_TYPE); // this0
|
|
||||||
}
|
|
||||||
else if (parameterType.getKind() != JvmMethodParameterKind.VALUE) {
|
|
||||||
enterTemp(parameterType.getAsmType());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOuterThisIndex() {
|
|
||||||
return myOuterThisIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -297,8 +297,15 @@ public class FunctionCodegen extends ParentCodegenAware {
|
|||||||
generateStaticDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext());
|
generateStaticDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FrameMap frameMap = strategy.getFrameMap(typeMapper, context);
|
FrameMap frameMap = new FrameMap();
|
||||||
|
if (context.getContextKind() == OwnerKind.IMPLEMENTATION) {
|
||||||
|
frameMap.enterTemp(OBJECT_TYPE); // 0 slot for this
|
||||||
|
}
|
||||||
|
for (JvmMethodParameterSignature parameter : signature.getValueParameters()) {
|
||||||
|
if (parameter.getKind() != JvmMethodParameterKind.VALUE) {
|
||||||
|
frameMap.enterTemp(parameter.getAsmType());
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
|
||||||
frameMap.enter(parameter, typeMapper.mapType(parameter));
|
frameMap.enter(parameter, typeMapper.mapType(parameter));
|
||||||
}
|
}
|
||||||
@@ -311,7 +318,7 @@ public class FunctionCodegen extends ParentCodegenAware {
|
|||||||
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
|
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
strategy.generateBody(mv, signature, context, parentCodegen);
|
strategy.generateBody(mv, frameMap, signature, context, parentCodegen);
|
||||||
}
|
}
|
||||||
|
|
||||||
Label methodEnd = new Label();
|
Label methodEnd = new Label();
|
||||||
@@ -777,45 +784,45 @@ public class FunctionCodegen extends ParentCodegenAware {
|
|||||||
final JvmMethodSignature jvmDelegateMethodSignature,
|
final JvmMethodSignature jvmDelegateMethodSignature,
|
||||||
final JvmMethodSignature jvmOverriddenMethodSignature
|
final JvmMethodSignature jvmOverriddenMethodSignature
|
||||||
) {
|
) {
|
||||||
generateMethod(OtherOrigin(functionDescriptor),
|
generateMethod(
|
||||||
jvmDelegateMethodSignature,
|
OtherOrigin(functionDescriptor), jvmDelegateMethodSignature, functionDescriptor,
|
||||||
functionDescriptor,
|
new FunctionGenerationStrategy() {
|
||||||
new FunctionGenerationStrategy() {
|
@Override
|
||||||
@Override
|
public void generateBody(
|
||||||
public void generateBody(
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull FrameMap frameMap,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
Method overriddenMethod = jvmOverriddenMethodSignature.getAsmMethod();
|
Method overriddenMethod = jvmOverriddenMethodSignature.getAsmMethod();
|
||||||
Method delegateMethod = jvmDelegateMethodSignature.getAsmMethod();
|
Method delegateMethod = jvmDelegateMethodSignature.getAsmMethod();
|
||||||
|
|
||||||
Type[] argTypes = delegateMethod.getArgumentTypes();
|
Type[] argTypes = delegateMethod.getArgumentTypes();
|
||||||
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
|
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
|
||||||
|
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
iv.load(0, OBJECT_TYPE);
|
iv.load(0, OBJECT_TYPE);
|
||||||
field.put(field.type, iv);
|
field.put(field.type, iv);
|
||||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
|
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
|
||||||
//noinspection AssignmentToForLoopParameter
|
//noinspection AssignmentToForLoopParameter
|
||||||
reg += argTypes[i].getSize();
|
reg += argTypes[i].getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
String internalName = typeMapper.mapType(toClass).getInternalName();
|
String internalName = typeMapper.mapType(toClass).getInternalName();
|
||||||
if (toClass.getKind() == ClassKind.TRAIT) {
|
if (toClass.getKind() == ClassKind.TRAIT) {
|
||||||
iv.invokeinterface(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
iv.invokeinterface(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iv.invokevirtual(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
iv.invokevirtual(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue.onStack(overriddenMethod.getReturnType()).put(delegateMethod.getReturnType(), iv);
|
StackValue.onStack(overriddenMethod.getReturnType()).put(delegateMethod.getReturnType(), iv);
|
||||||
|
|
||||||
iv.areturn(delegateMethod.getReturnType());
|
iv.areturn(delegateMethod.getReturnType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,36 +19,20 @@ package org.jetbrains.jet.codegen;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||||
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.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public abstract class FunctionGenerationStrategy {
|
public abstract class FunctionGenerationStrategy {
|
||||||
|
|
||||||
private FrameMap frameMap;
|
|
||||||
|
|
||||||
public abstract void generateBody(
|
public abstract void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull FrameMap frameMap,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
);
|
);
|
||||||
|
|
||||||
@NotNull
|
|
||||||
protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) {
|
|
||||||
return context.prepareFrame(typeMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public FrameMap getFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) {
|
|
||||||
if (frameMap == null) {
|
|
||||||
frameMap = createFrameMap(typeMapper, context);
|
|
||||||
}
|
|
||||||
return frameMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FunctionDefault extends CodegenBased<CallableDescriptor> {
|
public static class FunctionDefault extends CodegenBased<CallableDescriptor> {
|
||||||
private final JetDeclarationWithBody declaration;
|
private final JetDeclarationWithBody declaration;
|
||||||
|
|
||||||
@@ -79,12 +63,12 @@ public abstract class FunctionGenerationStrategy {
|
|||||||
@Override
|
@Override
|
||||||
public final void generateBody(
|
public final void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull FrameMap frameMap,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
) {
|
) {
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context),
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), context, state, parentCodegen);
|
||||||
signature.getReturnType(), context, state, parentCodegen);
|
|
||||||
doGenerateBody(codegen, signature);
|
doGenerateBody(codegen, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -813,6 +813,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull FrameMap frameMap,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
@@ -839,6 +840,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull FrameMap frameMap,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
@@ -1151,16 +1153,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
|
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
final JvmMethodSignature signature = typeMapper.mapSignature(constructorDescriptor);
|
JvmMethodSignature signature = typeMapper.mapSignature(constructorDescriptor);
|
||||||
|
|
||||||
functionCodegen.generateMethod(OtherOrigin(myClass, constructorDescriptor), signature, constructorDescriptor, constructorContext,
|
functionCodegen.generateMethod(OtherOrigin(myClass, constructorDescriptor), signature, constructorDescriptor, constructorContext,
|
||||||
new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
|
new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) {
|
|
||||||
return new ConstructorFrameMap(signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
generatePrimaryConstructorImpl(callableDescriptor, codegen, delegationFieldsInfo);
|
generatePrimaryConstructorImpl(callableDescriptor, codegen, delegationFieldsInfo);
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ public class PackageCodegen {
|
|||||||
@Override
|
@Override
|
||||||
public void generateBody(
|
public void generateBody(
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull FrameMap frameMap,
|
||||||
@NotNull JvmMethodSignature signature,
|
@NotNull JvmMethodSignature signature,
|
||||||
@NotNull MethodContext context,
|
@NotNull MethodContext context,
|
||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
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.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
|
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.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
// SCRIPT: script code generator
|
// SCRIPT: script code generator
|
||||||
@@ -146,7 +146,8 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
|
|||||||
|
|
||||||
instructionAdapter.load(0, classType);
|
instructionAdapter.load(0, classType);
|
||||||
|
|
||||||
final FrameMap frameMap = methodContext.prepareFrame(typeMapper);
|
final FrameMap frameMap = new FrameMap();
|
||||||
|
frameMap.enterTemp(OBJECT_TYPE);
|
||||||
|
|
||||||
for (ScriptDescriptor importedScript : context.getEarlierScripts()) {
|
for (ScriptDescriptor importedScript : context.getEarlierScripts()) {
|
||||||
frameMap.enter(importedScript, OBJECT_TYPE);
|
frameMap.enter(importedScript, OBJECT_TYPE);
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ 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.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -200,24 +199,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
return new ClosureContext(typeMapper, funDescriptor, classDescriptor, this, localLookup);
|
return new ClosureContext(typeMapper, funDescriptor, classDescriptor, this, localLookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public FrameMap prepareFrame(@NotNull JetTypeMapper typeMapper) {
|
|
||||||
FrameMap frameMap = new FrameMap();
|
|
||||||
|
|
||||||
if (getContextKind() != OwnerKind.PACKAGE) {
|
|
||||||
frameMap.enterTemp(OBJECT_TYPE); // 0 slot for this
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableDescriptor receiverDescriptor = getCallableDescriptorWithReceiver();
|
|
||||||
if (receiverDescriptor != null) {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
Type type = typeMapper.mapType(receiverDescriptor.getReceiverParameter().getType());
|
|
||||||
frameMap.enterTemp(type); // Next slot for receiver
|
|
||||||
}
|
|
||||||
|
|
||||||
return frameMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CodegenContext getParentContext() {
|
public CodegenContext getParentContext() {
|
||||||
return parentContext;
|
return parentContext;
|
||||||
|
|||||||
Reference in New Issue
Block a user