Merge remote branch 'origin/master'
This commit is contained in:
Generated
+11
@@ -127,6 +127,17 @@
|
|||||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||||
<option name="USE_RELATIVE_INDENTS" value="false" />
|
<option name="USE_RELATIVE_INDENTS" value="false" />
|
||||||
</ADDITIONAL_INDENT_OPTIONS>
|
</ADDITIONAL_INDENT_OPTIONS>
|
||||||
|
<codeStyleSettings language="JavaScript">
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="PHP">
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||||
|
</codeStyleSettings>
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
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.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
@@ -72,7 +73,9 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
public void visitIfExpression(JetIfExpression expression) {
|
public void visitIfExpression(JetIfExpression expression) {
|
||||||
JetType expressionType = bindingContext.getExpressionType(expression);
|
JetType expressionType = bindingContext.getExpressionType(expression);
|
||||||
Type asmType = typeMapper.mapType(expressionType);
|
Type asmType = typeMapper.mapType(expressionType);
|
||||||
gen(expression.getCondition(), Type.BOOLEAN_TYPE);
|
int oldStackDepth = myStack.size();
|
||||||
|
gen(expression.getCondition());
|
||||||
|
assert myStack.size() == oldStackDepth+1;
|
||||||
|
|
||||||
JetExpression thenExpression = expression.getThen();
|
JetExpression thenExpression = expression.getThen();
|
||||||
JetExpression elseExpression = expression.getElse();
|
JetExpression elseExpression = expression.getElse();
|
||||||
@@ -93,7 +96,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
|
|
||||||
|
|
||||||
Label elseLabel = new Label();
|
Label elseLabel = new Label();
|
||||||
v.ifeq(elseLabel); // == 0, i.e. false
|
myStack.pop().condJump(elseLabel, true, v); // == 0, i.e. false
|
||||||
|
|
||||||
gen(thenExpression, asmType);
|
gen(thenExpression, asmType);
|
||||||
|
|
||||||
@@ -173,12 +176,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
private void generateSingleBranchIf(JetExpression expression, boolean inverse) {
|
private void generateSingleBranchIf(JetExpression expression, boolean inverse) {
|
||||||
Label endLabel = new Label();
|
Label endLabel = new Label();
|
||||||
|
|
||||||
if (inverse) {
|
myStack.pop().condJump(endLabel, inverse, v);
|
||||||
v.ifeq(endLabel);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.ifne(endLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
genToUnit(expression);
|
genToUnit(expression);
|
||||||
|
|
||||||
@@ -449,7 +447,8 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBinaryExpression(JetBinaryExpression expression) {
|
public void visitBinaryExpression(JetBinaryExpression expression) {
|
||||||
if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.EQ) {
|
final IElementType opToken = expression.getOperationReference().getReferencedNameElementType();
|
||||||
|
if (opToken == JetTokens.EQ) {
|
||||||
generateAssignmentExpression(expression);
|
generateAssignmentExpression(expression);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -457,21 +456,44 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
if (op instanceof FunctionDescriptor) {
|
if (op instanceof FunctionDescriptor) {
|
||||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||||
if (cls instanceof ClassDescriptor && cls.getName().equals("Int")) {
|
if (cls instanceof ClassDescriptor && cls.getName().equals("Int")) {
|
||||||
if (op.getName().equals("plus")) {
|
if (op.getName().equals("compareTo")) {
|
||||||
JetType returnType = ((FunctionDescriptor) op).getUnsubstitutedReturnType();
|
generateCompareOp(expression, opToken);
|
||||||
if (returnType.equals(stdlib.getIntType())) {
|
|
||||||
gen(expression.getLeft(), Type.INT_TYPE);
|
|
||||||
gen(expression.getRight(), Type.INT_TYPE);
|
|
||||||
v.add(Type.INT_TYPE);
|
|
||||||
myStack.push(StackValue.onStack(Type.INT_TYPE));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
int opcode;
|
||||||
|
if (op.getName().equals("plus")) {
|
||||||
|
opcode = Opcodes.IADD;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("Don't know how to generate binary op method " + op.getName());
|
||||||
|
}
|
||||||
|
generateBinaryOp(expression, (FunctionDescriptor) op, opcode);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
|
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateBinaryOp(JetBinaryExpression expression, FunctionDescriptor op, int opcode) {
|
||||||
|
JetType returnType = op.getUnsubstitutedReturnType();
|
||||||
|
if (returnType.equals(stdlib.getIntType())) {
|
||||||
|
gen(expression.getLeft(), Type.INT_TYPE);
|
||||||
|
gen(expression.getRight(), Type.INT_TYPE);
|
||||||
|
v.visitInsn(Type.INT_TYPE.getOpcode(opcode));
|
||||||
|
myStack.push(StackValue.onStack(Type.INT_TYPE));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("Don't know how to generate binary op with return type " + returnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateCompareOp(JetBinaryExpression expression, IElementType opToken) {
|
||||||
|
gen(expression.getLeft(), Type.INT_TYPE);
|
||||||
|
gen(expression.getRight(), Type.INT_TYPE);
|
||||||
|
myStack.push(StackValue.icmp(opToken));
|
||||||
|
}
|
||||||
|
|
||||||
private void generateAssignmentExpression(JetBinaryExpression expression) {
|
private void generateAssignmentExpression(JetBinaryExpression expression) {
|
||||||
if (expression.getLeft() instanceof JetReferenceExpression) {
|
if (expression.getLeft() instanceof JetReferenceExpression) {
|
||||||
final JetReferenceExpression lhs = (JetReferenceExpression) expression.getLeft();
|
final JetReferenceExpression lhs = (JetReferenceExpression) expression.getLeft();
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
import org.objectweb.asm.Label;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
@@ -22,6 +26,12 @@ public abstract class StackValue {
|
|||||||
return new Constant(value);
|
return new Constant(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StackValue icmp(IElementType opToken) {
|
||||||
|
return new IntCompare(opToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void condJump(Label label, boolean inverse, InstructionAdapter v);
|
||||||
|
|
||||||
public static class Local extends StackValue {
|
public static class Local extends StackValue {
|
||||||
private final int index;
|
private final int index;
|
||||||
private final JetType type;
|
private final JetType type;
|
||||||
@@ -36,6 +46,17 @@ public abstract class StackValue {
|
|||||||
v.load(index, type);
|
v.load(index, type);
|
||||||
// TODO box/unbox
|
// TODO box/unbox
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void condJump(Label label, boolean inverse, InstructionAdapter v) {
|
||||||
|
put(Type.INT_TYPE, v);
|
||||||
|
if (inverse) {
|
||||||
|
v.ifeq(label);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v.ifne(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OnStack extends StackValue {
|
public static class OnStack extends StackValue {
|
||||||
@@ -48,6 +69,11 @@ public abstract class StackValue {
|
|||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void condJump(Label label, boolean inverse, InstructionAdapter v) {
|
||||||
|
throw new UnsupportedOperationException("don't know how to generate this condjump");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Constant extends StackValue {
|
public static class Constant extends StackValue {
|
||||||
@@ -72,5 +98,35 @@ public abstract class StackValue {
|
|||||||
v.aconst(value);
|
v.aconst(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void condJump(Label label, boolean inverse, InstructionAdapter v) {
|
||||||
|
throw new UnsupportedOperationException("don't know how to generate this condjump");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IntCompare extends StackValue {
|
||||||
|
private final IElementType opToken;
|
||||||
|
|
||||||
|
public IntCompare(IElementType opToken) {
|
||||||
|
this.opToken = opToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(Type type, InstructionAdapter v) {
|
||||||
|
throw new UnsupportedOperationException("don't know how to put an IntCompare on stack");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void condJump(Label label, boolean inverse, InstructionAdapter v) {
|
||||||
|
int opcode;
|
||||||
|
if (opToken == JetTokens.GT) {
|
||||||
|
opcode = inverse ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("don't know how to generate this condjump");
|
||||||
|
}
|
||||||
|
v.visitJumpInsn(opcode, label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo(f: Int): Boolean {
|
||||||
|
if (f > 0) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -132,6 +132,15 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
|||||||
assertEquals(2, main.invoke(null));
|
assertEquals(2, main.invoke(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGt() throws Exception {
|
||||||
|
loadFile("gt.jet");
|
||||||
|
|
||||||
|
System.out.println(generateToText());
|
||||||
|
final Method main = generateFunction();
|
||||||
|
assertEquals(true, main.invoke(null, 1));
|
||||||
|
assertEquals(false, main.invoke(null, 0));
|
||||||
|
}
|
||||||
|
|
||||||
private void loadFile(final String name) {
|
private void loadFile(final String name) {
|
||||||
myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name);
|
myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user