references to a local properties
This commit is contained in:
@@ -1,10 +1,8 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import gnu.trove.TObjectIntHashMap;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.ValueParameterDescriptor;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -22,11 +20,11 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
private final Stack<Label> myLoopEnds = new Stack<Label>();
|
private final Stack<Label> myLoopEnds = new Stack<Label>();
|
||||||
|
|
||||||
private final InstructionAdapter v;
|
private final InstructionAdapter v;
|
||||||
private final TObjectIntHashMap<JetProperty> myVarIndex = new TObjectIntHashMap<JetProperty>();
|
private final FrameMap myMap;
|
||||||
private int myMaxVarIndex = 0;
|
|
||||||
private final BindingContext bindingContext;
|
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.v = new InstructionAdapter(v);
|
||||||
this.bindingContext = bindingContext;
|
this.bindingContext = bindingContext;
|
||||||
}
|
}
|
||||||
@@ -214,7 +212,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
List<JetElement> statements = expression.getStatements();
|
List<JetElement> statements = expression.getStatements();
|
||||||
for (JetElement statement : statements) {
|
for (JetElement statement : statements) {
|
||||||
if (statement instanceof JetProperty) {
|
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) {
|
for (JetElement statement : statements) {
|
||||||
if (statement instanceof JetProperty) {
|
if (statement instanceof JetProperty) {
|
||||||
JetProperty var = (JetProperty) statement;
|
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);
|
v.visitLocalVariable(var.getName(), getType(var).getDescriptor(), null, blockStart, blockEnd, index);
|
||||||
myMaxVarIndex--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,15 +248,43 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitReferenceExpression(JetReferenceExpression expression) {
|
public void visitReferenceExpression(JetReferenceExpression expression) {
|
||||||
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression(expression);
|
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression(expression);
|
||||||
if (descriptor instanceof ValueParameterDescriptor) {
|
int index = myMap.getIndex(descriptor);
|
||||||
final int index = ((ValueParameterDescriptor) descriptor).getIndex();
|
if (index >= 0) {
|
||||||
v.visitVarInsn(Opcodes.ALOAD, index); // TODO +1 for non-static methods
|
v.visitVarInsn(Opcodes.ALOAD, index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
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) {
|
private Type getType(JetProperty var) {
|
||||||
return InstructionAdapter.OBJECT_TYPE; // TODO:
|
return InstructionAdapter.OBJECT_TYPE; // TODO:
|
||||||
}
|
}
|
||||||
@@ -270,7 +295,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitProperty(JetProperty property) {
|
public void visitProperty(JetProperty property) {
|
||||||
int index = myVarIndex.get(property);
|
int index = myMap.getIndex(bindingContext.getPropertyDescriptor(property));
|
||||||
|
|
||||||
assert index >= 0;
|
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.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
|
import org.jetbrains.jet.lang.types.ValueParameterDescriptor;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -56,7 +57,15 @@ public class FunctionCodegen {
|
|||||||
method.getName(), method.getDescriptor(), null, null);
|
method.getName(), method.getDescriptor(), null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
final JetExpression bodyExpression = f.getBodyExpression();
|
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);
|
generateReturn(mv, bodyExpression);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
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);
|
JetProperty p = PsiTreeUtil.getParentOfType(getFile().findElementAt(0), JetProperty.class);
|
||||||
|
|
||||||
TraceMethodVisitor trace = new TraceMethodVisitor();
|
TraceMethodVisitor trace = new TraceMethodVisitor();
|
||||||
p.getInitializer().accept(new ExpressionCodegen(trace, null));
|
p.getInitializer().accept(new ExpressionCodegen(trace, null, new FrameMap()));
|
||||||
|
|
||||||
StringWriter out = new StringWriter();
|
StringWriter out = new StringWriter();
|
||||||
trace.print(new PrintWriter(out));
|
trace.print(new PrintWriter(out));
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
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.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||||
@@ -54,8 +52,19 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
|||||||
|
|
||||||
final Class aClass = generateToClass();
|
final Class aClass = generateToClass();
|
||||||
final Method main = firstMethod(aClass);
|
final Method main = firstMethod(aClass);
|
||||||
final Object returnValue = main.invoke(null, 42);
|
final Object returnValue = main.invoke(null, 50);
|
||||||
assertEquals(new Integer(42), returnValue);
|
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() {
|
private String generateToText() {
|
||||||
|
|||||||
Reference in New Issue
Block a user