optimized sure for non-nullable types
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user