Move 'earlierScripts' from ScriptCodegen to ScriptContext

To get rid of a questionable usage of getParentCodegen() in ExpressionCodegen
This commit is contained in:
Alexander Udalov
2014-04-24 19:14:12 +04:00
parent 6bd46d38f5
commit 5fe7bfdd83
5 changed files with 54 additions and 59 deletions
@@ -2175,7 +2175,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
else { else {
Type classType = asmTypeForScriptDescriptor(bindingContext, receiver.getDeclarationDescriptor()); Type classType = asmTypeForScriptDescriptor(bindingContext, receiver.getDeclarationDescriptor());
String fieldName = getParentScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor()); String fieldName = scriptContext.getScriptFieldName(receiver.getDeclarationDescriptor());
result.put(currentScriptType, v); result.put(currentScriptType, v);
StackValue.field(classType, currentScriptType, fieldName, false).put(classType, v); StackValue.field(classType, currentScriptType, fieldName, false).put(classType, v);
} }
@@ -3896,18 +3896,6 @@ The "returned" value of try expression with no finally is either the last expres
return context.getContextDescriptor().toString(); return context.getContextDescriptor().toString();
} }
@NotNull
private ScriptCodegen getParentScriptCodegen() {
MemberCodegen<?> codegen = parentCodegen;
while (codegen != null) {
if (codegen instanceof ScriptCodegen) {
return (ScriptCodegen) codegen;
}
codegen = codegen.getParentCodegen();
}
throw new IllegalStateException("Script codegen should be present in codegen tree");
}
@NotNull @NotNull
public FrameMap getFrameMap() { public FrameMap getFrameMap() {
return myFrameMap; return myFrameMap;
@@ -18,9 +18,7 @@ package org.jetbrains.jet.codegen;
import kotlin.Function0; import kotlin.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.FieldOwnerContext;
import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.context.MethodContext;
import org.jetbrains.jet.codegen.context.ScriptContext; import org.jetbrains.jet.codegen.context.ScriptContext;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
@@ -61,26 +59,28 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
assert className != null; assert className != null;
ClassBuilder builder = state.getFactory().newVisitor(className, declaration.getContainingFile()); ClassBuilder builder = state.getFactory().newVisitor(className, declaration.getContainingFile());
ScriptContext scriptContext = parentContext.intoScript(scriptDescriptor, classDescriptorForScript); List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
return new ScriptCodegen(declaration, state, scriptContext, state.getEarlierScriptsForReplInterpreter(), builder); ScriptContext scriptContext = parentContext.intoScript(
scriptDescriptor,
earlierScripts == null ? Collections.<ScriptDescriptor>emptyList() : earlierScripts,
classDescriptorForScript
);
return new ScriptCodegen(declaration, state, scriptContext, builder);
} }
private final JetScript scriptDeclaration; private final JetScript scriptDeclaration;
private final ScriptContext context; private final ScriptContext context;
private final List<ScriptDescriptor> earlierScripts;
private final ScriptDescriptor scriptDescriptor; private final ScriptDescriptor scriptDescriptor;
private ScriptCodegen( private ScriptCodegen(
@NotNull JetScript scriptDeclaration, @NotNull JetScript scriptDeclaration,
@NotNull GenerationState state, @NotNull GenerationState state,
@NotNull ScriptContext context, @NotNull ScriptContext context,
@Nullable List<ScriptDescriptor> earlierScripts,
@NotNull ClassBuilder builder @NotNull ClassBuilder builder
) { ) {
super(state, null, context, scriptDeclaration, builder); super(state, null, context, scriptDeclaration, builder);
this.scriptDeclaration = scriptDeclaration; this.scriptDeclaration = scriptDeclaration;
this.context = context; this.context = context;
this.earlierScripts = earlierScripts == null ? Collections.<ScriptDescriptor>emptyList() : earlierScripts;
this.scriptDescriptor = context.getScriptDescriptor(); this.scriptDescriptor = context.getScriptDescriptor();
} }
@@ -100,7 +100,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@Override @Override
protected void generateBody() { protected void generateBody() {
genMembers(context, v); genMembers(v);
genFieldsForParameters(scriptDescriptor, v); genFieldsForParameters(scriptDescriptor, v);
genConstructor(scriptDescriptor, context.getContextDescriptor(), v, genConstructor(scriptDescriptor, context.getContextDescriptor(), v,
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor())); context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()));
@@ -115,15 +115,14 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@NotNull ScriptDescriptor scriptDescriptor, @NotNull ScriptDescriptor scriptDescriptor,
@NotNull ClassDescriptor classDescriptorForScript, @NotNull ClassDescriptor classDescriptorForScript,
@NotNull ClassBuilder classBuilder, @NotNull ClassBuilder classBuilder,
@NotNull final MethodContext context @NotNull final MethodContext methodContext
) { ) {
Type blockType = typeMapper.mapType(scriptDescriptor.getScriptCodeDescriptor().getReturnType()); Type blockType = typeMapper.mapType(scriptDescriptor.getScriptCodeDescriptor().getReturnType());
classBuilder.newField(null, ACC_PUBLIC | ACC_FINAL, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, classBuilder.newField(null, ACC_PUBLIC | ACC_FINAL, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME,
blockType.getDescriptor(), null, null); blockType.getDescriptor(), null, null);
JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, earlierScripts); JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, context.getEarlierScripts());
MethodVisitor mv = classBuilder.newMethod( MethodVisitor mv = classBuilder.newMethod(
scriptDeclaration, ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), scriptDeclaration, ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(),
@@ -141,9 +140,9 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
instructionAdapter.load(0, classType); instructionAdapter.load(0, classType);
final FrameMap frameMap = context.prepareFrame(typeMapper); final FrameMap frameMap = methodContext.prepareFrame(typeMapper);
for (ScriptDescriptor importedScript : earlierScripts) { for (ScriptDescriptor importedScript : context.getEarlierScripts()) {
frameMap.enter(importedScript, OBJECT_TYPE); frameMap.enter(importedScript, OBJECT_TYPE);
} }
@@ -158,18 +157,18 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
generateInitializers(new Function0<ExpressionCodegen>() { generateInitializers(new Function0<ExpressionCodegen>() {
@Override @Override
public ExpressionCodegen invoke() { public ExpressionCodegen invoke() {
return new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, context, state, ScriptCodegen.this); return new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, methodContext, state, ScriptCodegen.this);
} }
}); });
int offset = 1; int offset = 1;
for (ScriptDescriptor earlierScript : earlierScripts) { for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript); Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript);
instructionAdapter.load(0, classType); instructionAdapter.load(0, classType);
instructionAdapter.load(offset, earlierClassType); instructionAdapter.load(offset, earlierClassType);
offset += earlierClassType.getSize(); offset += earlierClassType.getSize();
instructionAdapter.putfield(classType.getInternalName(), getScriptFieldName(earlierScript), earlierClassType.getDescriptor()); instructionAdapter.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
} }
for (ValueParameterDescriptor parameter : scriptDescriptor.getScriptCodeDescriptor().getValueParameters()) { for (ValueParameterDescriptor parameter : scriptDescriptor.getScriptCodeDescriptor().getValueParameters()) {
@@ -181,7 +180,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
} }
StackValue stackValue = StackValue stackValue =
new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state, this).gen(scriptDeclaration.getBlockExpression()); new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this).gen(scriptDeclaration.getBlockExpression());
if (stackValue.type != Type.VOID_TYPE) { if (stackValue.type != Type.VOID_TYPE) {
stackValue.put(stackValue.type, instructionAdapter); stackValue.put(stackValue.type, instructionAdapter);
instructionAdapter.putfield(classType.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, instructionAdapter.putfield(classType.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME,
@@ -194,10 +193,10 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
} }
private void genFieldsForParameters(@NotNull ScriptDescriptor script, @NotNull ClassBuilder classBuilder) { private void genFieldsForParameters(@NotNull ScriptDescriptor script, @NotNull ClassBuilder classBuilder) {
for (ScriptDescriptor earlierScript : earlierScripts) { for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
Type earlierClassName = asmTypeForScriptDescriptor(bindingContext, earlierScript); Type earlierClassName = asmTypeForScriptDescriptor(bindingContext, earlierScript);
int access = ACC_PRIVATE | ACC_FINAL; int access = ACC_PRIVATE | ACC_FINAL;
classBuilder.newField(null, access, getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null); classBuilder.newField(null, access, context.getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null);
} }
for (ValueParameterDescriptor parameter : script.getScriptCodeDescriptor().getValueParameters()) { for (ValueParameterDescriptor parameter : script.getScriptCodeDescriptor().getValueParameters()) {
@@ -207,21 +206,9 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
} }
} }
private void genMembers(@NotNull FieldOwnerContext context, @NotNull ClassBuilder classBuilder) { private void genMembers(@NotNull ClassBuilder classBuilder) {
for (JetDeclaration decl : scriptDeclaration.getDeclarations()) { for (JetDeclaration declaration : scriptDeclaration.getDeclarations()) {
genFunctionOrProperty((JetTypeParameterListOwner) decl, classBuilder); genFunctionOrProperty((JetTypeParameterListOwner) declaration, classBuilder);
} }
} }
private int getScriptIndex(@NotNull ScriptDescriptor scriptDescriptor) {
int index = earlierScripts.indexOf(scriptDescriptor);
if (index < 0) {
throw new IllegalStateException("Unregistered script: " + scriptDescriptor);
}
return index + 1;
}
public String getScriptFieldName(@NotNull ScriptDescriptor scriptDescriptor) {
return "script$" + getScriptIndex(scriptDescriptor);
}
} }
@@ -36,6 +36,7 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD; import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD;
@@ -198,8 +199,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
// SCRIPT: generate into script, move to ScriptingUtil // SCRIPT: generate into script, move to ScriptingUtil
@NotNull @NotNull
public ScriptContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) { public ScriptContext intoScript(
return new ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure); @NotNull ScriptDescriptor script,
@NotNull List<ScriptDescriptor> earlierScripts,
@NotNull ClassDescriptor classDescriptor
) {
return new ScriptContext(script, earlierScripts, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
} }
@NotNull @NotNull
@@ -23,21 +23,24 @@ import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import java.util.List;
// SCRIPT: script as field owner context // SCRIPT: script as field owner context
public class ScriptContext extends FieldOwnerContext<ClassDescriptor> { public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
@NotNull
private final ScriptDescriptor scriptDescriptor; private final ScriptDescriptor scriptDescriptor;
private final List<ScriptDescriptor> earlierScripts;
public ScriptContext( public ScriptContext(
@NotNull ScriptDescriptor scriptDescriptor, @NotNull ScriptDescriptor scriptDescriptor,
@NotNull List<ScriptDescriptor> earlierScripts,
@NotNull ClassDescriptor contextDescriptor, @NotNull ClassDescriptor contextDescriptor,
@NotNull OwnerKind contextKind, @NotNull OwnerKind contextKind,
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable MutableClosure closure @Nullable MutableClosure closure
) { ) {
super(contextDescriptor, contextKind, parentContext, closure, contextDescriptor, null); super(contextDescriptor, contextKind, parentContext, closure, contextDescriptor, null);
this.scriptDescriptor = scriptDescriptor; this.scriptDescriptor = scriptDescriptor;
this.earlierScripts = earlierScripts;
} }
@NotNull @NotNull
@@ -45,6 +48,20 @@ public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
return scriptDescriptor; return scriptDescriptor;
} }
@NotNull
public List<ScriptDescriptor> getEarlierScripts() {
return earlierScripts;
}
@NotNull
public String getScriptFieldName(@NotNull ScriptDescriptor scriptDescriptor) {
int index = earlierScripts.indexOf(scriptDescriptor);
if (index < 0) {
throw new IllegalStateException("Unregistered script: " + scriptDescriptor);
}
return "script$" + (index + 1);
}
@Override @Override
public boolean isStatic() { public boolean isStatic() {
return true; return true;
@@ -70,6 +70,7 @@ import java.lang.reflect.Field;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -340,15 +341,12 @@ public class ReplInterpreter {
@NotNull GenerationState state, @NotNull GenerationState state,
@NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts @NotNull List<Pair<ScriptDescriptor, Type>> earlierScripts
) { ) {
for (Pair<ScriptDescriptor, Type> t : earlierScripts) { List<ScriptDescriptor> earlierScriptDescriptors = new ArrayList<ScriptDescriptor>(earlierScripts.size());
ScriptDescriptor earlierDescriptor = t.first; for (Pair<ScriptDescriptor, Type> pair : earlierScripts) {
Type earlierClassType = t.second; ScriptDescriptor earlierDescriptor = pair.first;
registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassType); Type earlierClassType = pair.second;
}
List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList(); registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassType);
for (Pair<ScriptDescriptor, Type> t : earlierScripts) {
ScriptDescriptor earlierDescriptor = t.first;
earlierScriptDescriptors.add(earlierDescriptor); earlierScriptDescriptors.add(earlierDescriptor);
} }
state.setEarlierScriptsForReplInterpreter(earlierScriptDescriptors); state.setEarlierScriptsForReplInterpreter(earlierScriptDescriptors);