From 4cb3d30e5b52d09ce058fcb5fbdec76a8e818c2a Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Mon, 10 Nov 2014 19:26:07 +0300 Subject: [PATCH] Added thiz constant in StackValue, some refactorings --- .../jetbrains/jet/codegen/ClosureCodegen.java | 6 +- .../jet/codegen/ExpressionCodegen.java | 87 ++++++++----------- .../{StackValueI.java => IStackValue.java} | 4 +- .../codegen/ImplementationBodyCodegen.java | 17 ++-- .../jetbrains/jet/codegen/MemberCodegen.java | 2 +- .../jet/codegen/PropertyCodegen.java | 4 +- .../jetbrains/jet/codegen/ScriptCodegen.java | 2 +- .../org/jetbrains/jet/codegen/StackValue.java | 70 +++++++-------- .../org/jetbrains/jet/codegen/StackValue.kt | 40 ++++----- .../jet/codegen/context/CodegenContext.java | 11 +-- .../jet/codegen/context/LocalLookup.java | 8 +- .../jet/codegen/context/MethodContext.java | 4 +- .../inline/AnonymousObjectTransformer.java | 4 +- .../jet/codegen/inline/InlineCodegen.java | 3 +- .../jet/codegen/inline/LambdaInfo.java | 4 +- .../RegeneratedLambdaFieldRemapper.java | 2 +- .../jet/codegen/intrinsics/Equals.java | 2 +- .../codegen/intrinsics/IdentityEquals.java | 2 +- .../codegen/intrinsics/IntrinsicMethod.java | 3 +- .../jetbrains/jet/codegen/intrinsics/Not.java | 2 +- 20 files changed, 122 insertions(+), 155 deletions(-) rename compiler/backend/src/org/jetbrains/jet/codegen/{StackValueI.java => IStackValue.java} (93%) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 4689825bd29..1bd7c0f0250 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -204,7 +204,7 @@ public class ClosureCodegen extends ParentCodegenAware { } @NotNull - public StackValue putInstanceOnStack(@NotNull InstructionAdapter v, @NotNull final ExpressionCodegen codegen) { + public StackValue putInstanceOnStack(@NotNull final ExpressionCodegen codegen) { return StackValue.operation(asmType, new Function1() { @Override public Unit invoke(InstructionAdapter v) { @@ -215,8 +215,8 @@ public class ClosureCodegen extends ParentCodegenAware { v.anew(asmType); v.dup(); - codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator); - v.invokespecial(asmType.getInternalName(), "", constructor.getDescriptor(), false); + codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator); + v.invokespecial(asmType.getInternalName(), "", constructor.getDescriptor(), false); } return Unit.INSTANCE$; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index dc41bce3083..2007b8d3dad 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -24,7 +24,6 @@ import com.intellij.psi.tree.IElementType; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.Stack; -import jet.runtime.typeinfo.JetValueParameter; import kotlin.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -246,9 +245,7 @@ public class ExpressionCodegen extends JetVisitor implem @NotNull ClassDescriptor required ) { if (!isInterface(provided) && isInterface(required)) { - //TODO: is needed double wrapping? - Type type = asmType(required.getDefaultType()); - return StackValue.lazyCast(StackValue.lazyCast(inner, OBJECT_TYPE), type); + return StackValue.coercion(inner, asmType(required.getDefaultType())); } return inner; @@ -307,7 +304,7 @@ public class ExpressionCodegen extends JetVisitor implem public StackValue genLazy(JetElement expr, Type type) { StackValue value = gen(expr); - return StackValue.lazyCast(value, type); + return StackValue.coercion(value, type); } private StackValue genStatement(JetElement statement) { @@ -421,7 +418,7 @@ public class ExpressionCodegen extends JetVisitor implem if (isEmptyExpression(thenExpression)) { if (isEmptyExpression(elseExpression)) { - return StackValue.lazyCast(condition, asmType); + return StackValue.coercion(condition, asmType); } return generateSingleBranchIf(condition, expression, elseExpression, false, isStatement); } @@ -433,7 +430,7 @@ public class ExpressionCodegen extends JetVisitor implem return StackValue.operation(asmType, new Function1() { @Override - public Unit invoke(@JetValueParameter(name = "p1") InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { Label elseLabel = new Label(); condition.condJump(elseLabel, true, v); // == 0, i.e. false @@ -783,7 +780,8 @@ public class ExpressionCodegen extends JetVisitor implem LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, loopRange, "No hasNext() function " + DiagnosticUtils.atLocation(loopRange)); @SuppressWarnings("ConstantConditions") Call fakeCall = makeFakeCall(new TransientReceiver(iteratorCall.getResultingDescriptor().getReturnType())); - invokeFunctionNotLazy(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator)); + StackValue result = invokeFunction(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator)); + result.put(result.type, v); JetType type = hasNextCall.getResultingDescriptor().getReturnType(); assert type != null && JetTypeChecker.DEFAULT.isSubtypeOf(type, KotlinBuiltIns.getInstance().getBooleanType()); @@ -1246,7 +1244,7 @@ public class ExpressionCodegen extends JetVisitor implem Type targetType = isStatement ? Type.VOID_TYPE : expressionType(ifExpression); return StackValue.operation(targetType, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { Label elseLabel = new Label(); condition.condJump(elseLabel, inverse, v); @@ -1318,7 +1316,7 @@ public class ExpressionCodegen extends JetVisitor implem else { return StackValue.operation(AsmTypeConstants.JAVA_STRING_TYPE, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { genStringBuilderConstructor(v); for (JetStringTemplateEntry entry : entries) { if (entry instanceof JetStringTemplateEntryWithExpression) { @@ -1408,7 +1406,7 @@ public class ExpressionCodegen extends JetVisitor implem parentCodegen.setWereReifierMarkers(true); } - return closureCodegen.putInstanceOnStack(v, this); + return closureCodegen.putInstanceOnStack(this); } @Override @@ -1830,7 +1828,7 @@ public class ExpressionCodegen extends JetVisitor implem IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor); if (intrinsic != null) { Type returnType = typeMapper.mapType(memberDescriptor); - return intrinsic.generate(this, v, returnType, expression, Collections.emptyList(), receiver); + return intrinsic.generate(this, returnType, expression, Collections.emptyList(), receiver); } } @@ -1882,7 +1880,6 @@ public class ExpressionCodegen extends JetVisitor implem ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor; ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor); StackValue script = StackValue.thisOrOuter(this, scriptClass, false, false); - //script.put(script.type, v); Type fieldType = typeMapper.mapType(valueParameterDescriptor); return StackValue.field(fieldType, scriptClassType, valueParameterDescriptor.getName().getIdentifier(), false, script); } @@ -1897,7 +1894,7 @@ public class ExpressionCodegen extends JetVisitor implem return stackValueForLocal(descriptor, index); } - return context.lookupInContext(descriptor, StackValue.local(0, OBJECT_TYPE), state, false); + return context.lookupInContext(descriptor, StackValue.thiz(), state, false); } @@ -2146,17 +2143,6 @@ public class ExpressionCodegen extends JetVisitor implem return invokeFunction(resolvedCall.getCall(), resolvedCall, receiver); } - @NotNull - public void invokeFunctionNotLazy(@NotNull ResolvedCall resolvedCall, @NotNull StackValue receiver) { - StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, receiver); - result.put(result.type, v); - } - - public void invokeFunctionNotLazy(@NotNull Call call, @NotNull ResolvedCall resolvedCall, @NotNull StackValue receiver) { - StackValue result = invokeFunction(call, resolvedCall, receiver); - result.put(result.type, v); - } - @NotNull public StackValue invokeFunction(@NotNull Call call, @NotNull final ResolvedCall resolvedCall, @NotNull final StackValue receiver) { if (resolvedCall instanceof VariableAsFunctionResolvedCall) { @@ -2182,7 +2168,7 @@ public class ExpressionCodegen extends JetVisitor implem if (callable instanceof CallableMethod) { return StackValue.functionCall(returnType, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { CallableMethod callableMethod = (CallableMethod) callable; invokeMethodWithArguments(callableMethod, resolvedCall, receiver); @@ -2199,7 +2185,7 @@ public class ExpressionCodegen extends JetVisitor implem args.add(argument.getArgumentExpression()); } - return ((IntrinsicMethod) callable).generate(this, v, returnType, call.getCallElement(), args, newReceiver); + return ((IntrinsicMethod) callable).generate(this, returnType, call.getCallElement(), args, newReceiver); } } @@ -2357,7 +2343,7 @@ public class ExpressionCodegen extends JetVisitor implem if (DescriptorUtils.isClassObject(receiverDescriptor)) { CallableMemberDescriptor contextDescriptor = context.getContextDescriptor(); if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) { - return StackValue.local(0, OBJECT_TYPE); + return StackValue.thiz(); } else { return StackValue.singleton(receiverDescriptor, typeMapper); @@ -2399,7 +2385,7 @@ public class ExpressionCodegen extends JetVisitor implem // SCRIPT: generate script, move to ScriptingUtil private StackValue generateScript(@NotNull ScriptReceiver receiver) { CodegenContext cur = context; - StackValue result = StackValue.local(0, OBJECT_TYPE); + StackValue result = StackValue.thiz(); boolean inStartConstructorContext = cur instanceof ConstructorContext; while (cur != null) { if (!inStartConstructorContext) { @@ -2568,7 +2554,6 @@ public class ExpressionCodegen extends JetVisitor implem FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); if (functionDescriptor != null) { CallableReferenceGenerationStrategy strategy = new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall); - return genClosure(expression, functionDescriptor, strategy, null, KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER); } @@ -2616,7 +2601,7 @@ public class ExpressionCodegen extends JetVisitor implem return StackValue.operation(factoryMethod.getReturnType(), new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { v.visitLdcInsn(descriptor.getName().asString()); v.getstatic(packageClassInternalName, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, K_PACKAGE_IMPL_TYPE.getDescriptor()); @@ -2789,7 +2774,7 @@ public class ExpressionCodegen extends JetVisitor implem Type type = expressionType(expression); if (expression instanceof JetSafeQualifiedExpression && !isPrimitive(type)) { - return StackValue.lazyCast(generateSafeQualifiedExpression((JetSafeQualifiedExpression) expression, ifnull), type); + return StackValue.coercion(generateSafeQualifiedExpression((JetSafeQualifiedExpression) expression, ifnull), type); } else { return genLazy(expression, type); @@ -2803,6 +2788,7 @@ public class ExpressionCodegen extends JetVisitor implem Type receiverType = expressionType(receiver); StackValue receiverValue = generateExpressionWithNullFallback(receiver, ifNull); + //Do not optimize for primitives cause in case of safe call extension receiver should be generated before dispatch one StackValue newReceiver = new StackValue.Safe(receiverType, receiverValue, isPrimitive(receiverType) ? null : ifNull); return genQualified(newReceiver, selector); } @@ -2813,13 +2799,12 @@ public class ExpressionCodegen extends JetVisitor implem Type type = boxType(expressionType(expression)); StackValue value = generateSafeQualifiedExpression(expression, ifnull); - StackValue newReceiver = StackValue.lazyCast(value, type); + StackValue newReceiver = StackValue.coercion(value, type); StackValue result; if (!isPrimitive(expressionType(expression.getReceiverExpression()))) { result = new StackValue.SafeFallback(type, ifnull, newReceiver); } else { - //TODO safefallbacl result = newReceiver; } @@ -2863,7 +2848,7 @@ public class ExpressionCodegen extends JetVisitor implem Callable callable = resolveToCallable(descriptor, false); if (callable instanceof IntrinsicMethod) { Type returnType = typeMapper.mapType(descriptor); - return ((IntrinsicMethod) callable).generate(this, v, returnType, expression, + return ((IntrinsicMethod) callable).generate(this, returnType, expression, Arrays.asList(expression.getLeft(), expression.getRight()), receiver); } @@ -2875,13 +2860,14 @@ public class ExpressionCodegen extends JetVisitor implem final JetExpression deparenthesized = JetPsiUtil.deparenthesize(rangeExpression); return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { if (isIntRangeExpr(deparenthesized)) { genInIntRange(leftValue, (JetBinaryExpression) deparenthesized); } else { ResolvedCall resolvedCall = getResolvedCallWithAssert(operationReference, bindingContext); - invokeFunctionNotLazy(resolvedCall, StackValue.none()); + StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none()); + result.put(result.type, v); } if (operationReference.getReferencedNameElementType() == JetTokens.NOT_IN) { genInvertBoolean(v); @@ -2930,7 +2916,7 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue generateBooleanAnd(final JetBinaryExpression expression) { return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { gen(expression.getLeft(), Type.BOOLEAN_TYPE); Label ifFalse = new Label(); v.ifeq(ifFalse); @@ -2948,7 +2934,7 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue generateBooleanOr(final JetBinaryExpression expression) { return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { gen(expression.getLeft(), Type.BOOLEAN_TYPE); Label ifTrue = new Label(); v.ifne(ifTrue); @@ -2999,7 +2985,7 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue genCmpWithZero(final JetExpression exp, final Type expType, final IElementType opToken) { return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { gen(exp, expType); Label trueLabel = new Label(); Label afterLabel = new Label(); @@ -3105,7 +3091,7 @@ public class ExpressionCodegen extends JetVisitor implem } else { type = Type.INT_TYPE; - leftValue = StackValue.lazyCast(invokeFunction(resolvedCall, receiver), type); + leftValue = StackValue.coercion(invokeFunction(resolvedCall, receiver), type); rightValue = StackValue.constant(0, type); } return StackValue.cmp(expression.getOperationToken(), type, leftValue, rightValue); @@ -3135,7 +3121,7 @@ public class ExpressionCodegen extends JetVisitor implem value.put(lhsType, v); // receiver lhs Type returnType = typeMapper.mapType(descriptor); - StackValue rightSide = ((IntrinsicMethod) callable).generate(this, v, returnType, expression, + StackValue rightSide = ((IntrinsicMethod) callable).generate(this, returnType, expression, Collections.singletonList(expression.getRight()), StackValue.onStack(lhsType)); value.store(rightSide, v, true); return StackValue.none(); @@ -3220,7 +3206,7 @@ public class ExpressionCodegen extends JetVisitor implem Callable callable = resolveToCallable((FunctionDescriptor) op, false); if (callable instanceof IntrinsicMethod) { Type returnType = typeMapper.mapType(op); - return ((IntrinsicMethod) callable).generate(this, v, returnType, expression, + return ((IntrinsicMethod) callable).generate(this, returnType, expression, Collections.singletonList(expression.getBaseExpression()), receiver); } @@ -3296,7 +3282,7 @@ public class ExpressionCodegen extends JetVisitor implem return StackValue.operation(asmResultType, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { StackValue value = gen(expression.getBaseExpression()); value = StackValue.complexWriteReadReceiver(value); @@ -3364,7 +3350,8 @@ public class ExpressionCodegen extends JetVisitor implem ResolvedCall resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration); assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText(); Call call = makeFakeCall(initializerAsReceiver); - invokeFunctionNotLazy(call, resolvedCall, local); + StackValue result = invokeFunction(call, resolvedCall, local); + result.put(result.type, v); return null; } }); @@ -3480,7 +3467,7 @@ public class ExpressionCodegen extends JetVisitor implem return StackValue.operation(type, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { gen(args.get(0), Type.INT_TYPE); newArrayInstruction(arrayType); @@ -3664,7 +3651,7 @@ The "returned" value of try expression with no finally is either the last expres return StackValue.operation(expectedAsmType, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { JetFinallySection finallyBlock = expression.getFinallyBlock(); FinallyBlockStackElement finallyBlockStackElement = null; @@ -3815,7 +3802,7 @@ The "returned" value of try expression with no finally is either the last expres return StackValue.operation(rightTypeAsm, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { value.put(boxType(value.type), v); if (opToken != JetTokens.AS_SAFE) { @@ -3875,7 +3862,7 @@ The "returned" value of try expression with no finally is either the last expres condType = OBJECT_TYPE; } StackValue condition = genLazy(patternExpression, condType); - return genEqualsForExpressionsOnStack(JetTokens.EQEQ, StackValue.lazyCast(expressionToMatch, subjectType), condition); + return genEqualsForExpressionsOnStack(JetTokens.EQEQ, StackValue.coercion(expressionToMatch, subjectType), condition); } else { return gen(patternExpression); @@ -3957,7 +3944,7 @@ The "returned" value of try expression with no finally is either the last expres return StackValue.operation(resultType, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, ExpressionCodegen.this); if (switchCodegen != null) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValueI.java b/compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java similarity index 93% rename from compiler/backend/src/org/jetbrains/jet/codegen/StackValueI.java rename to compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java index 520481ec7e2..c4300420adb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValueI.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java @@ -21,12 +21,14 @@ import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; -public interface StackValueI { +public interface IStackValue { void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth); void put(@NotNull Type type, @NotNull InstructionAdapter v); + void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver); + void store(@NotNull Type topOfStackType, @NotNull InstructionAdapter v); void store(@NotNull StackValue value, @NotNull InstructionAdapter v); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 0395fb728eb..156bb681d80 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -800,10 +800,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { : "Function container should be annotated with [data]: " + function; PropertyDescriptor property = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter); assert property != null : "Copy function doesn't correspond to any property: " + function; - codegen.v.load(0, thisDescriptorType); Type propertyType = typeMapper.mapType(property); - codegen.intermediateValueForProperty(property, false, null, StackValue.none()) - .putNoReceiver(propertyType, codegen.v); + codegen.intermediateValueForProperty(property, false, null, StackValue.thiz()) + .put(propertyType, codegen.v); } }, null @@ -899,7 +898,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); - StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR, StackValue.none()); + StackValue property = + codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR, + StackValue.none()); InstructionAdapter iv = codegen.v; @@ -1135,7 +1136,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if (isObject(descriptor)) { - StackValue.singleton(descriptor, typeMapper).store(StackValue.local(0, classAsmType), iv); + StackValue.singleton(descriptor, typeMapper).store(StackValue.thiz(), iv); } for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) { @@ -1301,7 +1302,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } else return; - constructorContext.lookupInContext(toLookup, StackValue.local(0, OBJECT_TYPE), state, true); + constructorContext.lookupInContext(toLookup, StackValue.thiz(), state, true); } @Override @@ -1310,7 +1311,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert descriptor instanceof CallableDescriptor || descriptor instanceof ClassDescriptor : "'This' reference target should be class or callable descriptor but was " + descriptor; if (descriptor instanceof ClassDescriptor) { - context.lookupInContext(descriptor, StackValue.local(0, OBJECT_TYPE), state, true); + context.lookupInContext(descriptor, StackValue.thiz(), state, true); } if (descriptor instanceof CallableDescriptor) { @@ -1345,7 +1346,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ResolvedCall resolvedCall = CallUtilPackage.getResolvedCallWithAssert(superCall, bindingContext); ClassDescriptor superClass = ((ConstructorDescriptor) resolvedCall.getResultingDescriptor()).getContainingDeclaration(); if (superClass.isInner()) { - constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.local(0, OBJECT_TYPE), state, true); + constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.thiz(), state, true); } if (!isAnonymousObject(descriptor)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 14cf7eccf36..7965202f230 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -238,7 +238,7 @@ public abstract class MemberCodegen { new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this).gen(scriptDeclaration.getBlockExpression()); if (stackValue.type != Type.VOID_TYPE) { StackValue.Field resultValue = StackValue - .field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.local(0, classType)); + .field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.thiz()); resultValue.store(stackValue, iv); } else { stackValue.put(blockType, iv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index b58732e35af..daa8255c22e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -47,7 +47,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*; -public abstract class StackValue implements StackValueI { +public abstract class StackValue implements IStackValue { private static final String NULLABLE_BYTE_TYPE_NAME = "java/lang/Byte"; private static final String NULLABLE_SHORT_TYPE_NAME = "java/lang/Short"; @@ -77,7 +77,9 @@ public abstract class StackValue implements StackValueI { } @Override - public abstract void put(@NotNull Type type, @NotNull InstructionAdapter v); + public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + put(type, v, false); + } @Override public void dup(@NotNull InstructionAdapter v, boolean withReceiver) { @@ -126,6 +128,10 @@ public abstract class StackValue implements StackValueI { return new Local(index, type); } + public static Local thiz() { + return local(0, OBJECT_TYPE); + } + @NotNull public static StackValue shared(int index, @NotNull Type type) { return new Shared(index, type); @@ -373,8 +379,8 @@ public abstract class StackValue implements StackValueI { return new FieldForSharedVar(field.type, field.owner, field.name, newSharedVarReceiver); } - public static StackValue lazyCast(@NotNull StackValue receiver, @NotNull Type type) { - return CodegenPackage.castValue(receiver, type); + public static StackValue coercion(@NotNull StackValue receiver, @NotNull Type type) { + return CodegenPackage.coercion(receiver, type); } public static StackValue thisOrOuter(@NotNull ExpressionCodegen codegen, @NotNull ClassDescriptor descriptor, boolean isSuper, boolean isExplicit) { @@ -929,7 +935,7 @@ public abstract class StackValue implements StackValueI { ((CallableMethod) getter).invokeWithNotNullAssertion(v, state, resolvedGetCall); } else { - StackValue result = ((IntrinsicMethod) getter).generate(codegen, v, this.type, null, null, null); + StackValue result = ((IntrinsicMethod) getter).generate(codegen, this.type, null, null, null); result.put(result.type, v); } coerceTo(type, v); @@ -994,7 +1000,7 @@ public abstract class StackValue implements StackValueI { } else { //noinspection ConstantConditions - StackValue result = ((IntrinsicMethod) setter).generate(codegen, v, null, null, null, null); + StackValue result = ((IntrinsicMethod) setter).generate(codegen, null, null, null, null); result.put(result.type, v); } } @@ -1311,7 +1317,7 @@ public abstract class StackValue implements StackValueI { value.store(StackValue.onStack(this.type), v, true); } - putNoReceiver(value, this.type, v); + value.put(this.type, v, true); coerceTo(type, v); } } @@ -1440,16 +1446,6 @@ public abstract class StackValue implements StackValueI { this.isStaticStore = isStaticStore; } - @Override - public void put( - @NotNull Type type, @NotNull InstructionAdapter v - ) { - putReceiver(v, true); - putNoReceiver(type, v); - } - - @Override - public abstract void putNoReceiver(@NotNull Type type, @NotNull InstructionAdapter v); @Override public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) { @@ -1473,6 +1469,14 @@ public abstract class StackValue implements StackValueI { this.receiver = receiver; } + @Override + public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { + if (!skipReceiver) { + putReceiver(v, true); + } + putNoReceiver(type, v); + } + public abstract void putReceiver(@NotNull InstructionAdapter v, boolean isRead); public abstract void putNoReceiver(@NotNull Type type, @NotNull InstructionAdapter v); @@ -1530,25 +1534,19 @@ public abstract class StackValue implements StackValueI { } } - public abstract static class ReadOnlyValue extends StackValueWithoutReceiver { - - public ReadOnlyValue(@NotNull Type type) { - super(type); - } - - @Override - public void store( - @NotNull Type topOfStackType, @NotNull InstructionAdapter v - ) { - throw new UnsupportedOperationException("Read only value could be stored"); - } - } - public abstract static class StackValueWithoutReceiver extends StackValue { public StackValueWithoutReceiver(@NotNull Type type) { super(type); } + + @Override + public abstract void put(@NotNull Type type, @NotNull InstructionAdapter v); + + @Override + public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { + put(type, v); + } } @@ -1582,7 +1580,7 @@ public abstract class StackValue implements StackValueI { } } - public static class Receiver extends StackValue { + public static class Receiver extends StackValueWithoutReceiver { private final StackValue[] instructions; @@ -1651,14 +1649,6 @@ public abstract class StackValue implements StackValueI { } } - private static void putNoReceiver(StackValue value, Type type, InstructionAdapter iv) { - if (value instanceof StackValueWithSimpleReceiver) { - ((StackValueWithSimpleReceiver) value).putNoReceiver(type, iv); - } else { - value.put(type, iv); - } - } - static class Safe extends StackValueWithoutReceiver { @NotNull private final Type type; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt index ea45bb44b4b..c2764255589 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt @@ -23,14 +23,16 @@ import org.jetbrains.jet.codegen.StackValue.StackValueWithReceiver import org.jetbrains.jet.codegen.StackValue.StackValueWithoutReceiver import org.jetbrains.jet.codegen.StackValue.StackValueWithSimpleReceiver -public fun castValue(value: StackValue, castType: Type): StackValue { - return if (value is StackValueWithReceiver) CastValueWithReceiver(value, castType) else CastValue(value, castType) +public fun coercion(value: StackValue, castType: Type): StackValue { + return if (value is StackValueWithReceiver) CoercionValueWithReceiver(value, castType) else CoercionValue(value, castType) } -class CastValueWithReceiver(val value: StackValueWithReceiver, val castType: Type) : StackValueWithSimpleReceiver(castType, !value.hasReceiver(true), !value.hasReceiver(false), value.receiver), StackValueI by value { +class CoercionValue(val value: StackValue, val castType: Type) : StackValueWithoutReceiver(castType), IStackValue by value + +class CoercionValueWithReceiver(val value: StackValueWithReceiver, val castType: Type) : StackValueWithSimpleReceiver(castType, !value.hasReceiver(true), !value.hasReceiver(false), value.receiver), IStackValue by value { override fun putReceiver(v: InstructionAdapter, isRead: Boolean) { - value.putReceiver(v, isRead ) + value.putReceiver(v, isRead) } override fun putNoReceiver(type: Type, v: InstructionAdapter) { @@ -42,23 +44,8 @@ class CastValueWithReceiver(val value: StackValueWithReceiver, val castType: Typ } } -class CastValue(val value: StackValue, val castType: Type) : StackValueWithoutReceiver(castType), StackValueI by value { -} - -class FunctionCallStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValueWithoutReceiver(resultType) { - - override fun put(type: Type, v: InstructionAdapter) { - lambda(v) - coerceTo(type, v) - } - - override fun store(topOfStackType: Type, v: InstructionAdapter) { - throw UnsupportedOperationException(); - } -} - -public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks: StackValueWithLeaveTask.()-> Unit) : StackValueWithReceiver(stackValue.type, if (stackValue is StackValueWithReceiver) stackValue.receiver else StackValue.none()), StackValueI by stackValue { +public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks: StackValueWithLeaveTask.()-> Unit) : StackValueWithReceiver(stackValue.type, if (stackValue is StackValueWithReceiver) stackValue.receiver else StackValue.none()), IStackValue by stackValue { override fun put(type: Type, v: InstructionAdapter) { stackValue.put(type, v) @@ -89,7 +76,14 @@ public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks: } } -class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValueWithoutReceiver(resultType) { +public abstract class ReadOnlyValue(type: Type) : StackValueWithoutReceiver(type) { + + override fun store(topOfStackType: Type, v: InstructionAdapter) { + throw UnsupportedOperationException("Read only value could not be stored") + } +} + +open class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : ReadOnlyValue(resultType) { override fun put(type: Type, v: InstructionAdapter) { lambda(v) @@ -99,4 +93,6 @@ class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapt override fun store(topOfStackType: Type, v: InstructionAdapter) { throw UnsupportedOperationException(); } -} \ No newline at end of file +} + +class FunctionCallStackValue(resultType: Type, lambda: (v: InstructionAdapter)-> Unit) : OperationStackValue(resultType, lambda) \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index b74002f032a..c02715e1f58 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -269,7 +269,7 @@ public abstract class CodegenContext { return canHaveOuter(typeMapper.getBindingContext(), classDescriptor) ? StackValue.field(typeMapper.mapType(enclosingClass), typeMapper.mapType(classDescriptor), - CAPTURED_THIS_FIELD, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)) + CAPTURED_THIS_FIELD, false, StackValue.thiz()) : null; } }); @@ -291,7 +291,6 @@ public abstract class CodegenContext { break; } else { - //return result == null ? innerValue : composedOrStatic(result, innerValue); return StackValue.changeReceiverForFieldAndSharedVar(innerValue, result); } } @@ -442,14 +441,6 @@ public abstract class CodegenContext { return childContexts == null ? null : childContexts.get(child); } - //@NotNull - //private static StackValue composedOrStatic(@NotNull StackValue prefix, @NotNull StackValue suffix) { - // if (isStaticField(suffix)) { - // return suffix; - // } - // return StackValue.composed(prefix, suffix); - //} - private static boolean isStaticField(@NotNull StackValue value) { return value instanceof StackValue.Field && ((StackValue.Field) value).isStaticPut; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java index 02ceb3ec74a..0cf1c02c969 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java @@ -60,7 +60,7 @@ public interface LocalLookup { Type type = sharedVarType != null ? sharedVarType : localType; String fieldName = "$" + vd.getName(); - StackValue.Local thiz = StackValue.local(0, AsmTypeConstants.OBJECT_TYPE); + StackValue.Local thiz = StackValue.thiz(); StackValue.StackValueWithSimpleReceiver innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, classType, fieldName, thiz) : StackValue.field(type, classType, fieldName, false, thiz); @@ -98,11 +98,11 @@ public interface LocalLookup { if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) { // This is an optimization: we can obtain an instance of a const closure simply by GETSTATIC ...$instance // (instead of passing this instance to the constructor and storing as a field) - return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)); + return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.thiz()); } String fieldName = "$" + vd.getName(); - StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)); + StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.thiz()); closure.recordField(fieldName, localType); closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType)); @@ -131,7 +131,7 @@ public interface LocalLookup { JetType receiverType = closure.getEnclosingReceiverDescriptor().getType(); Type type = state.getTypeMapper().mapType(receiverType); - StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)); + StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.thiz()); closure.setCaptureReceiver(); return innerValue; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java index 1a3f9f8c7a3..9897437adbc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java @@ -65,7 +65,7 @@ public class MethodContext extends CodegenContext { @Override public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) { if (getContextDescriptor() == d) { - return result != null ? result : StackValue.local(0, AsmTypeConstants.OBJECT_TYPE); + return result != null ? result : StackValue.thiz(); } return getParentContext().lookupInContext(d, result, state, ignoreNoOuter); @@ -77,7 +77,7 @@ public class MethodContext extends CodegenContext { return getReceiverExpression(state.getTypeMapper()); } ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter(); - return lookupInContext(parameter, StackValue.local(0, OBJECT_TYPE), state, ignoreNoOuter); + return lookupInContext(parameter, StackValue.thiz(), state, ignoreNoOuter); } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java index 3d8f239dbd6..2ecc1a9f822 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java @@ -254,7 +254,7 @@ public class AnonymousObjectTransformer { oldObjectType, fake.getNewFieldName(), false, - StackValue.local(0, oldObjectType)); + StackValue.thiz()); fake.setRemapValue(composed); } } @@ -397,7 +397,7 @@ public class AnonymousObjectTransformer { oldObjectType, /*TODO owner type*/ recapturedParamInfo.getNewFieldName(), false, - StackValue.local(0, oldObjectType)); + StackValue.thiz()); recapturedParamInfo.setRemapValue(composed); allRecapturedParameters.add(desc); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java index e1da804ed53..0d715f965ff 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java @@ -339,7 +339,8 @@ public class InlineCodegen implements CallGenerator { StackValue receiver = null; if (stackValue instanceof StackValue.Field) { receiver = ((StackValue.Field) stackValue).receiver; - } else if(stackValue instanceof StackValue.FieldForSharedVar) { + } + else if (stackValue instanceof StackValue.FieldForSharedVar) { receiver = ((StackValue.Field) ((StackValue.FieldForSharedVar) stackValue).receiver).receiver; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java index 6734b9abafc..d8e7d06a668 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java @@ -112,7 +112,7 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner { new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD, null, StackValue.field(type, closureClassType, AsmUtil.CAPTURED_THIS_FIELD, false, - StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)), + StackValue.thiz()), type); capturedVars.add(getCapturedParamInfo(descriptor)); } @@ -124,7 +124,7 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner { AsmUtil.CAPTURED_RECEIVER_FIELD, null, StackValue.field(type, closureClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, - StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)), + StackValue.thiz()), type); capturedVars.add(getCapturedParamInfo(descriptor)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java index ab1073890b7..39583c271c4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java @@ -94,7 +94,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper { StackValue result = StackValue.field(field.getType(), Type.getObjectType(newOwnerType), /*TODO owner type*/ field.getNewFieldName(), false, - prefix == null ? StackValue.local(0, Type.getObjectType(getLambdaInternalName())) : prefix); + prefix == null ? StackValue.thiz() : prefix); return searchInParent ? parent.getFieldForInline(node, result) : result; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java index 548df0d06a0..90c8cf57abc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java @@ -45,7 +45,7 @@ public class Equals extends IntrinsicMethod { StackValue leftExpr; JetExpression rightExpr; if (element instanceof JetCallExpression) { - leftExpr = StackValue.lazyCast(receiver, OBJECT_TYPE); + leftExpr = StackValue.coercion(receiver, OBJECT_TYPE); rightExpr = arguments.get(0); } else { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java index 8b14c5800dc..a2834dabb1f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java @@ -45,7 +45,7 @@ public class IdentityEquals extends IntrinsicMethod { StackValue left; StackValue right; if (element instanceof JetCallExpression) { - left = StackValue.lazyCast(receiver, OBJECT_TYPE); + left = StackValue.coercion(receiver, OBJECT_TYPE); right = codegen.genLazy(arguments.get(0), OBJECT_TYPE); } else { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java index 1d5a56adaf3..7ca04b98331 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java @@ -33,7 +33,6 @@ import java.util.List; public abstract class IntrinsicMethod implements Callable { public final StackValue generate( @NotNull final ExpressionCodegen codegen, - @NotNull final InstructionAdapter v, @NotNull final Type returnType, @Nullable final PsiElement element, @Nullable final List arguments, @@ -42,7 +41,7 @@ public abstract class IntrinsicMethod implements Callable { return StackValue.operation(returnType, new Function1() { @Override - public Unit invoke(InstructionAdapter adapter) { + public Unit invoke(InstructionAdapter v) { Type actualType = generateImpl(codegen, v, returnType, element, arguments, receiver); StackValue.coerce(actualType, returnType, v); return Unit.INSTANCE$; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java index 64c9d99cf7b..bce856446d6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java @@ -44,7 +44,7 @@ public class Not extends IntrinsicMethod { else { stackValue = receiver; } - StackValue.not(StackValue.lazyCast(stackValue, Type.BOOLEAN_TYPE)).put(returnType, v); + StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE)).put(returnType, v); return returnType; } }