references to a local properties
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.types.ValueParameterDescriptor;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -22,11 +20,11 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
private final Stack<Label> myLoopEnds = new Stack<Label>();
|
||||
|
||||
private final InstructionAdapter v;
|
||||
private final TObjectIntHashMap<JetProperty> myVarIndex = new TObjectIntHashMap<JetProperty>();
|
||||
private int myMaxVarIndex = 0;
|
||||
private final FrameMap myMap;
|
||||
private final BindingContext bindingContext;
|
||||
|
||||
public ExpressionCodegen(MethodVisitor v, BindingContext bindingContext) {
|
||||
public ExpressionCodegen(MethodVisitor v, BindingContext bindingContext, FrameMap myMap) {
|
||||
this.myMap = myMap;
|
||||
this.v = new InstructionAdapter(v);
|
||||
this.bindingContext = bindingContext;
|
||||
}
|
||||
@@ -214,7 +212,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
List<JetElement> statements = expression.getStatements();
|
||||
for (JetElement statement : statements) {
|
||||
if (statement instanceof JetProperty) {
|
||||
myVarIndex.put((JetProperty) statement, myMaxVarIndex++);
|
||||
myMap.enter(bindingContext.getPropertyDescriptor((JetProperty) statement));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,9 +226,8 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
for (JetElement statement : statements) {
|
||||
if (statement instanceof JetProperty) {
|
||||
JetProperty var = (JetProperty) statement;
|
||||
int index = myVarIndex.remove(var);
|
||||
int index = myMap.leave(bindingContext.getPropertyDescriptor(var));
|
||||
v.visitLocalVariable(var.getName(), getType(var).getDescriptor(), null, blockStart, blockEnd, index);
|
||||
myMaxVarIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,15 +248,43 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
@Override
|
||||
public void visitReferenceExpression(JetReferenceExpression expression) {
|
||||
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression(expression);
|
||||
if (descriptor instanceof ValueParameterDescriptor) {
|
||||
final int index = ((ValueParameterDescriptor) descriptor).getIndex();
|
||||
v.visitVarInsn(Opcodes.ALOAD, index); // TODO +1 for non-static methods
|
||||
int index = myMap.getIndex(descriptor);
|
||||
if (index >= 0) {
|
||||
v.visitVarInsn(Opcodes.ALOAD, index);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void visitCallExpression(JetCallExpression expression) {
|
||||
List<JetArgument> args = expression.getValueArguments();
|
||||
for (JetArgument arg : args) {
|
||||
gen(arg.getArgumentExpression());
|
||||
}
|
||||
|
||||
JetExpression callee = expression.getCalleeExpression();
|
||||
|
||||
if (callee instanceof JetReferenceExpression) {
|
||||
DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetReferenceExpression) callee);
|
||||
if (funDescriptor instanceof FunctionDescriptor) {
|
||||
}
|
||||
else {
|
||||
throw new CompilationException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Don't know how to generate a call");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBinaryExpression(JetBinaryExpression expression) {
|
||||
}
|
||||
*/
|
||||
|
||||
private Type getType(JetProperty var) {
|
||||
return InstructionAdapter.OBJECT_TYPE; // TODO:
|
||||
}
|
||||
@@ -270,7 +295,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
|
||||
@Override
|
||||
public void visitProperty(JetProperty property) {
|
||||
int index = myVarIndex.get(property);
|
||||
int index = myMap.getIndex(bindingContext.getPropertyDescriptor(property));
|
||||
|
||||
assert index >= 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class FrameMap {
|
||||
private final TObjectIntHashMap<DeclarationDescriptor> myVarIndex = new TObjectIntHashMap<DeclarationDescriptor>();
|
||||
private int myMaxIndex = 0;
|
||||
|
||||
public void enter(DeclarationDescriptor descriptor) {
|
||||
myVarIndex.put(descriptor, myMaxIndex++);
|
||||
}
|
||||
|
||||
public int leave(DeclarationDescriptor descriptor) {
|
||||
myMaxIndex--;
|
||||
return myVarIndex.remove(descriptor);
|
||||
}
|
||||
|
||||
public int getIndex(DeclarationDescriptor descriptor) {
|
||||
return myVarIndex.get(descriptor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.ValueParameterDescriptor;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -56,7 +57,15 @@ public class FunctionCodegen {
|
||||
method.getName(), method.getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
final JetExpression bodyExpression = f.getBodyExpression();
|
||||
bodyExpression.accept(new ExpressionCodegen(mv, bindingContext));
|
||||
FrameMap frameMap = new FrameMap();
|
||||
|
||||
List<ValueParameterDescriptor> parameDescrs = bindingContext.getFunctionDescriptor(f).getUnsubstitutedValueParameters();
|
||||
|
||||
for (ValueParameterDescriptor parameter : parameDescrs) {
|
||||
frameMap.enter(parameter);
|
||||
}
|
||||
|
||||
bodyExpression.accept(new ExpressionCodegen(mv, bindingContext, frameMap));
|
||||
generateReturn(mv, bodyExpression);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
fun f(a:Int) : Int {
|
||||
val x = 42
|
||||
val y = 50
|
||||
|
||||
y
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class ExpressionGenTest extends LightDaemonAnalyzerTestCase {
|
||||
JetProperty p = PsiTreeUtil.getParentOfType(getFile().findElementAt(0), JetProperty.class);
|
||||
|
||||
TraceMethodVisitor trace = new TraceMethodVisitor();
|
||||
p.getInitializer().accept(new ExpressionCodegen(trace, null));
|
||||
p.getInitializer().accept(new ExpressionCodegen(trace, null, new FrameMap()));
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
trace.print(new PrintWriter(out));
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
@@ -54,8 +52,19 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
final Class aClass = generateToClass();
|
||||
final Method main = firstMethod(aClass);
|
||||
final Object returnValue = main.invoke(null, 42);
|
||||
assertEquals(new Integer(42), returnValue);
|
||||
final Object returnValue = main.invoke(null, 50);
|
||||
assertEquals(new Integer(50), returnValue);
|
||||
}
|
||||
|
||||
public void testLocalPropery() throws Exception {
|
||||
myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/localProperty.jet");
|
||||
final String text = generateToText();
|
||||
System.out.println(text);
|
||||
|
||||
final Class aClass = generateToClass();
|
||||
final Method main = firstMethod(aClass);
|
||||
final Object returnValue = main.invoke(null, 76);
|
||||
assertEquals(new Integer(50), returnValue);
|
||||
}
|
||||
|
||||
private String generateToText() {
|
||||
|
||||
Reference in New Issue
Block a user