Move 'earlierScripts' from ScriptCodegen to ScriptContext
To get rid of a questionable usage of getParentCodegen() in ExpressionCodegen
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user