optimized sure for non-nullable types

This commit is contained in:
Alex Tkachman
2011-12-03 18:56:54 +02:00
parent d33d1367de
commit d8e6c18cfe
5 changed files with 36 additions and 13 deletions
@@ -1196,7 +1196,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
receiver.put(receiver.type, v);
}
protected void generateFromResolvedCall(ReceiverDescriptor descriptor, Type type) {
public void generateFromResolvedCall(ReceiverDescriptor descriptor, Type type) {
if(descriptor instanceof ClassReceiver) {
Type exprType = asmType(descriptor.getType());
ClassReceiver classReceiver = (ClassReceiver) descriptor;
@@ -4,7 +4,12 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
@@ -16,9 +21,21 @@ import java.util.List;
public class Sure implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokestatic("jet/runtime/Intrinsics", "sure", "(Ljava/lang/Object;)Ljava/lang/Object;");
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
assert resolvedCall != null;
if(resolvedCall.getReceiverArgument().getType().isNullable()) {
receiver.put(receiver.type, v);
v.dup();
Label ok = new Label();
v.ifnonnull(ok);
v.invokestatic("jet/runtime/Intrinsics", "throwNpe", "()V");
v.mark(ok);
StackValue.onStack(receiver.type).put(expectedType, v);
}
else {
codegen.generateFromResolvedCall(resolvedCall.getReceiverArgument(), expectedType);
}
return StackValue.onStack(expectedType);
}
}
@@ -291,6 +291,18 @@ public class PrimitiveTypesTest extends CodegenTestCase {
blackBox();
}
public void testSureNonnull () throws Exception {
loadText("fun box() = 10.sure().toString()");
// System.out.println(generateToText());
assertFalse(generateToText().contains("IFNONNULL"));
}
public void testSureNullable () throws Exception {
loadText("val a : Int? = 10; fun box() = a.sure().toString()");
// System.out.println(generateToText());
assertTrue(generateToText().contains("IFNONNULL"));
}
public void testKt665() throws Exception {
loadText("fun f(x: Long, zzz: Long = 1): Long\n" +
"{\n" +
@@ -8,7 +8,7 @@ import java.lang.reflect.Method;
public class JetNpeTest extends CodegenTestCase {
public void testStackTrace () {
try {
Intrinsics.sure(null);
Intrinsics.throwNpe();
fail("No Sure thrown");
}
catch (NullPointerException e) {
+2 -8
View File
@@ -13,13 +13,7 @@ public class Intrinsics {
return ((self == null) ? "null" : self) + ((other == null) ? "null" : other.toString());
}
public static Object sure(Object self) {
if(self == null)
return throwNpe();
return self;
}
private static Object throwNpe() {
public static void throwNpe() {
throw new JetNullPointerException();
}
@@ -32,7 +26,7 @@ public class Intrinsics {
list.add(ste);
}
else {
if("jet.runtime.Intrinsics".equals(ste.getClassName()) && "sure".equals(ste.getMethodName())) {
if("jet.runtime.Intrinsics".equals(ste.getClassName()) && "throwNpe".equals(ste.getMethodName())) {
skip = false;
}
}