From d8e6c18cfec867b0ca0b1645f7d121b5f1e08d6c Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 3 Dec 2011 18:56:54 +0200 Subject: [PATCH] optimized sure for non-nullable types --- .../jet/codegen/ExpressionCodegen.java | 2 +- .../jet/codegen/intrinsics/Sure.java | 23 ++++++++++++++++--- .../jet/codegen/PrimitiveTypesTest.java | 12 ++++++++++ .../org/jetbrains/jet/runtime/JetNpeTest.java | 2 +- stdlib/src/jet/runtime/Intrinsics.java | 10 ++------ 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 0542a3bdbcf..50fc7ea2a96 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1196,7 +1196,7 @@ public class ExpressionCodegen extends JetVisitor { 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; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java index 0019fed155f..c31e2983c25 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java @@ -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 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 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); } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index b9fc3be67c6..42be29b03b2 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -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" + diff --git a/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java b/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java index 51dd11b201b..2f3c350b6a0 100644 --- a/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java +++ b/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java @@ -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) { diff --git a/stdlib/src/jet/runtime/Intrinsics.java b/stdlib/src/jet/runtime/Intrinsics.java index 1011e0ea2a7..d162e3634d6 100644 --- a/stdlib/src/jet/runtime/Intrinsics.java +++ b/stdlib/src/jet/runtime/Intrinsics.java @@ -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; } }