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());
|
||||
}
|
||||
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()) {
|
||||
frameMap.enter(parameter, typeMapper.mapType(parameter));
|
||||
}
|
||||
@@ -311,7 +318,7 @@ public class FunctionCodegen extends ParentCodegenAware {
|
||||
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();
|
||||
@@ -777,45 +784,45 @@ public class FunctionCodegen extends ParentCodegenAware {
|
||||
final JvmMethodSignature jvmDelegateMethodSignature,
|
||||
final JvmMethodSignature jvmOverriddenMethodSignature
|
||||
) {
|
||||
generateMethod(OtherOrigin(functionDescriptor),
|
||||
jvmDelegateMethodSignature,
|
||||
functionDescriptor,
|
||||
new FunctionGenerationStrategy() {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
) {
|
||||
Method overriddenMethod = jvmOverriddenMethodSignature.getAsmMethod();
|
||||
Method delegateMethod = jvmDelegateMethodSignature.getAsmMethod();
|
||||
generateMethod(
|
||||
OtherOrigin(functionDescriptor), jvmDelegateMethodSignature, functionDescriptor,
|
||||
new FunctionGenerationStrategy() {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
) {
|
||||
Method overriddenMethod = jvmOverriddenMethodSignature.getAsmMethod();
|
||||
Method delegateMethod = jvmDelegateMethodSignature.getAsmMethod();
|
||||
|
||||
Type[] argTypes = delegateMethod.getArgumentTypes();
|
||||
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
|
||||
Type[] argTypes = delegateMethod.getArgumentTypes();
|
||||
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
|
||||
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
field.put(field.type, iv);
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
field.put(field.type, iv);
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
|
||||
String internalName = typeMapper.mapType(toClass).getInternalName();
|
||||
if (toClass.getKind() == ClassKind.TRAIT) {
|
||||
iv.invokeinterface(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
||||
}
|
||||
else {
|
||||
iv.invokevirtual(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
||||
}
|
||||
String internalName = typeMapper.mapType(toClass).getInternalName();
|
||||
if (toClass.getKind() == ClassKind.TRAIT) {
|
||||
iv.invokeinterface(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
|
||||
}
|
||||
else {
|
||||
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.jet.codegen.context.MethodContext;
|
||||
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.psi.JetDeclarationWithBody;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
|
||||
public abstract class FunctionGenerationStrategy {
|
||||
|
||||
private FrameMap frameMap;
|
||||
|
||||
public abstract void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@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> {
|
||||
private final JetDeclarationWithBody declaration;
|
||||
|
||||
@@ -79,12 +63,12 @@ public abstract class FunctionGenerationStrategy {
|
||||
@Override
|
||||
public final void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
) {
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context),
|
||||
signature.getReturnType(), context, state, parentCodegen);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), context, state, parentCodegen);
|
||||
doGenerateBody(codegen, signature);
|
||||
}
|
||||
|
||||
|
||||
@@ -813,6 +813,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
@@ -839,6 +840,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
@@ -1151,16 +1153,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
|
||||
}
|
||||
|
||||
final JvmMethodSignature signature = typeMapper.mapSignature(constructorDescriptor);
|
||||
JvmMethodSignature signature = typeMapper.mapSignature(constructorDescriptor);
|
||||
|
||||
functionCodegen.generateMethod(OtherOrigin(myClass, constructorDescriptor), signature, constructorDescriptor, constructorContext,
|
||||
new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) {
|
||||
return new ConstructorFrameMap(signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
generatePrimaryConstructorImpl(callableDescriptor, codegen, delegationFieldsInfo);
|
||||
|
||||
@@ -178,6 +178,7 @@ public class PackageCodegen {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
|
||||
@@ -37,10 +37,10 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import java.util.Collections;
|
||||
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.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.*;
|
||||
|
||||
// SCRIPT: script code generator
|
||||
@@ -146,7 +146,8 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
|
||||
|
||||
instructionAdapter.load(0, classType);
|
||||
|
||||
final FrameMap frameMap = methodContext.prepareFrame(typeMapper);
|
||||
final FrameMap frameMap = new FrameMap();
|
||||
frameMap.enterTemp(OBJECT_TYPE);
|
||||
|
||||
for (ScriptDescriptor importedScript : context.getEarlierScripts()) {
|
||||
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.getVisibilityAccessFlag;
|
||||
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_PROTECTED;
|
||||
|
||||
@@ -200,24 +199,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
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
|
||||
public CodegenContext getParentContext() {
|
||||
return parentContext;
|
||||
|
||||
Reference in New Issue
Block a user