references to a local properties

This commit is contained in:
Maxim Shafirov
2011-03-13 21:05:30 +03:00
parent e9192a61ee
commit 5e054c2f0a
6 changed files with 93 additions and 18 deletions
@@ -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();
+6
View File
@@ -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() {