Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-05-13 13:49:14 +04:00
3 changed files with 54 additions and 7 deletions
@@ -53,7 +53,7 @@ public class ExpressionCodegen extends JetVisitor {
private final FrameMap myMap; private final FrameMap myMap;
private final JetTypeMapper typeMapper; private final JetTypeMapper typeMapper;
private final Type returnType; private final Type returnType;
private final ClassDescriptor contextType; private final DeclarationDescriptor contextType;
private final OwnerKind contextKind; private final OwnerKind contextKind;
private final BindingContext bindingContext; private final BindingContext bindingContext;
@@ -62,7 +62,7 @@ public class ExpressionCodegen extends JetVisitor {
FrameMap myMap, FrameMap myMap,
JetTypeMapper typeMapper, JetTypeMapper typeMapper,
Type returnType, Type returnType,
ClassDescriptor contextType, DeclarationDescriptor contextType,
OwnerKind contextKind) { OwnerKind contextKind) {
this.myMap = myMap; this.myMap = myMap;
this.typeMapper = typeMapper; this.typeMapper = typeMapper;
@@ -1194,17 +1194,60 @@ public class ExpressionCodegen extends JetVisitor {
throw new UnsupportedOperationException("Cannot generate this expression in top level context"); throw new UnsupportedOperationException("Cannot generate this expression in top level context");
} }
ClassDescriptor contextClass = (ClassDescriptor) contextType;
if (contextKind == OwnerKind.IMPLEMENTATION) { if (contextKind == OwnerKind.IMPLEMENTATION) {
v.load(0, JetTypeMapper.jetImplementationType(contextType)); v.load(0, JetTypeMapper.jetImplementationType(contextClass));
} }
else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) { else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) {
v.getfield(JetTypeMapper.jvmName(contextType, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextType).getDescriptor()); v.getfield(JetTypeMapper.jvmName(contextClass, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextClass).getDescriptor());
} }
else { else {
throw new UnsupportedOperationException("Unknown kind: " + contextKind); throw new UnsupportedOperationException("Unknown kind: " + contextKind);
} }
} }
@Override
public void visitTryExpression(JetTryExpression expression) {
if (expression.getFinallyBlock() != null) {
throw new UnsupportedOperationException("finally block in try/catch not yet supported");
}
Label tryStart = new Label();
v.mark(tryStart);
gen(expression.getTryBlock(), Type.VOID_TYPE);
Label tryEnd = new Label();
v.mark(tryEnd);
Label end = new Label();
v.goTo(end); // TODO don't generate goto if there's no code following try/catch
for (JetCatchClause clause : expression.getCatchClauses()) {
Label clauseStart = new Label();
v.mark(clauseStart);
VariableDescriptor descriptor = bindingContext.getVariableDescriptor(clause.getCatchParameter());
Type descriptorType = typeMapper.mapType(descriptor.getOutType());
myMap.enter(descriptor, 1);
int index = myMap.getIndex(descriptor);
v.store(index, descriptorType);
gen(clause.getCatchBody(), Type.VOID_TYPE);
v.goTo(end); // TODO don't generate goto if there's no code following try/catch
myMap.leave(descriptor);
v.visitTryCatchBlock(tryStart, tryEnd, clauseStart, descriptorType.getInternalName());
}
v.mark(end);
}
@Override
public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) {
JetSimpleNameExpression operationSign = expression.getOperationSign();
if (operationSign.getReferencedNameElementType() == JetTokens.COLON) {
gen(expression.getLeft());
}
else {
throw new UnsupportedOperationException("should generate a cast, but don't know how");
}
}
private static class CompilationException extends RuntimeException { private static class CompilationException extends RuntimeException {
} }
} }
@@ -1,6 +1,7 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
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;
@@ -46,7 +47,9 @@ public class FunctionCodegen {
boolean isAbstract = kind == OwnerKind.INTERFACE || bodyExpression == null; boolean isAbstract = kind == OwnerKind.INTERFACE || bodyExpression == null;
if (isAbstract) flags |= Opcodes.ACC_ABSTRACT; if (isAbstract) flags |= Opcodes.ACC_ABSTRACT;
ClassDescriptor ownerClass = owner instanceof JetClass ? bindingContext.getClassDescriptor((JetClass) owner) : null; DeclarationDescriptor contextDescriptor = owner instanceof JetClass
? bindingContext.getClassDescriptor((JetClass) owner)
: bindingContext.getNamespaceDescriptor((JetNamespace) owner);
final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
if (kind != OwnerKind.INTERFACE) { if (kind != OwnerKind.INTERFACE) {
@@ -63,7 +66,7 @@ public class FunctionCodegen {
frameMap.enter(parameter, argTypes[i].getSize()); frameMap.enter(parameter, argTypes[i].getSize());
} }
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), ownerClass, kind); ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), contextDescriptor, kind);
if (kind instanceof OwnerKind.DelegateKind) { if (kind instanceof OwnerKind.DelegateKind) {
OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind; OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
@@ -103,8 +103,9 @@ public class ControlStructuresTest extends CodegenTestCase {
public void testTryCatch() throws Exception { public void testTryCatch() throws Exception {
loadFile("tryCatch.jet"); loadFile("tryCatch.jet");
System.out.println(generateToText());
final Method main = generateFunction(); final Method main = generateFunction();
assertEquals("no message", main.invoke(null, "0")); assertEquals("no message", main.invoke(null, "0"));
assertEquals("xxx", main.invoke(null, "a")); assertEquals("For input string: \"a\"", main.invoke(null, "a"));
} }
} }