Get rid of lazy cast

This commit is contained in:
Michael Bogdanov
2014-11-11 14:42:28 +03:00
parent 4cb3d30e5b
commit 434c094ba9
8 changed files with 41 additions and 69 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetParameter;
@@ -24,18 +23,17 @@ import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorT
public interface DefaultParameterValueLoader { public interface DefaultParameterValueLoader {
void putValueOnStack(ValueParameterDescriptor descriptor, ExpressionCodegen codegen); StackValue genValue(ValueParameterDescriptor descriptor, ExpressionCodegen codegen);
DefaultParameterValueLoader DEFAULT = new DefaultParameterValueLoader() { DefaultParameterValueLoader DEFAULT = new DefaultParameterValueLoader() {
@Override @Override
public void putValueOnStack( public StackValue genValue(
ValueParameterDescriptor descriptor, ValueParameterDescriptor descriptor,
ExpressionCodegen codegen ExpressionCodegen codegen
) { ) {
JetParameter jetParameter = (JetParameter) descriptorToDeclaration(descriptor); JetParameter jetParameter = (JetParameter) descriptorToDeclaration(descriptor);
assert jetParameter != null; assert jetParameter != null;
Type propertyType = codegen.typeMapper.mapType(descriptor.getType()); return codegen.gen(jetParameter.getDefaultValue());
codegen.gen(jetParameter.getDefaultValue(), propertyType);
} }
}; };
} }
@@ -1966,16 +1966,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
boolean skipPropertyAccessors = forceField && !isBackingFieldInAnotherClass; boolean skipPropertyAccessors = forceField && !isBackingFieldInAnotherClass;
CodegenContext backingFieldContext = context.getParentContext(); CodegenContext backingFieldContext = context.getParentContext();
boolean changeOwnerOnTypeMap = isBackingFieldInAnotherClass; boolean changeOwnerOnTypeMapping = isBackingFieldInAnotherClass;
if (isBackingFieldInAnotherClass && forceField) { if (isBackingFieldInAnotherClass && forceField) {
//delegate call to classObject backingFieldOwner : OWNER
backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration()); backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration());
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty); int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || methodKind == MethodKind.SYNTHETIC_ACCESSOR || methodKind == MethodKind.INITIALIZER; skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || methodKind == MethodKind.SYNTHETIC_ACCESSOR || methodKind == MethodKind.INITIALIZER;
if (!skipPropertyAccessors) { if (!skipPropertyAccessors) {
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor, true, delegateType); propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor, true, delegateType);
changeOwnerOnTypeMap = changeOwnerOnTypeMap && !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass); changeOwnerOnTypeMapping = changeOwnerOnTypeMapping && !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass);
} }
} }
@@ -2015,7 +2014,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor); propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
Type backingFieldOwner = typeMapper.mapOwner(changeOwnerOnTypeMap ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, Type backingFieldOwner = typeMapper.mapOwner(changeOwnerOnTypeMapping ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor,
isCallInsideSameModuleAsDeclared(propertyDescriptor, context, state.getOutDirectory())); isCallInsideSameModuleAsDeclared(propertyDescriptor, context, state.getOutDirectory()));
String fieldName; String fieldName;
@@ -2395,12 +2394,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (cur instanceof ScriptContext) { if (cur instanceof ScriptContext) {
ScriptContext scriptContext = (ScriptContext) cur; ScriptContext scriptContext = (ScriptContext) cur;
Type currentScriptType = asmTypeForScriptDescriptor(bindingContext, scriptContext.getScriptDescriptor());
if (scriptContext.getScriptDescriptor() == receiver.getDeclarationDescriptor()) { if (scriptContext.getScriptDescriptor() == receiver.getDeclarationDescriptor()) {
//TODO lazy //TODO lazy
return result; return result;
} }
else { else {
Type currentScriptType = asmTypeForScriptDescriptor(bindingContext, scriptContext.getScriptDescriptor());
Type classType = asmTypeForScriptDescriptor(bindingContext, receiver.getDeclarationDescriptor()); Type classType = asmTypeForScriptDescriptor(bindingContext, receiver.getDeclarationDescriptor());
String fieldName = scriptContext.getScriptFieldName(receiver.getDeclarationDescriptor()); String fieldName = scriptContext.getScriptFieldName(receiver.getDeclarationDescriptor());
return StackValue.field(classType, currentScriptType, fieldName, false, result); return StackValue.field(classType, currentScriptType, fieldName, false, result);
@@ -2534,7 +2533,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
newArrayInstruction(outType); newArrayInstruction(outType);
for (int i = 0; i != size; ++i) { for (int i = 0; i != size; ++i) {
v.dup(); v.dup();
StackValue rightSide = genLazy(arguments.get(i).getArgumentExpression(), elementType); StackValue rightSide = gen(arguments.get(i).getArgumentExpression());
StackValue.arrayElement(elementType, StackValue.onStack(type), StackValue.constant(i, Type.INT_TYPE)).store(rightSide, v); StackValue.arrayElement(elementType, StackValue.onStack(type), StackValue.constant(i, Type.INT_TYPE)).store(rightSide, v);
} }
} }
@@ -3086,12 +3085,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (callable instanceof IntrinsicMethod) { if (callable instanceof IntrinsicMethod) {
// Compare two primitive values // Compare two primitive values
type = comparisonOperandType(expressionType(left), expressionType(right)); type = comparisonOperandType(expressionType(left), expressionType(right));
leftValue = genLazy(left, type); leftValue = gen(left);
rightValue = genLazy(right, type); rightValue = gen(right);
} }
else { else {
type = Type.INT_TYPE; type = Type.INT_TYPE;
leftValue = StackValue.coercion(invokeFunction(resolvedCall, receiver), type); leftValue = invokeFunction(resolvedCall, receiver);
rightValue = StackValue.constant(0, type); rightValue = StackValue.constant(0, type);
} }
return StackValue.cmp(expression.getOperationToken(), type, leftValue, rightValue); return StackValue.cmp(expression.getOperationToken(), type, leftValue, rightValue);
@@ -3101,8 +3100,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
StackValue stackValue = gen(expression.getLeft()); StackValue stackValue = gen(expression.getLeft());
JetExpression right = expression.getRight(); JetExpression right = expression.getRight();
assert right != null : expression.getText(); assert right != null : expression.getText();
StackValue rightSide = genLazy(right, stackValue.type); stackValue.store(gen(right), v);
stackValue.store(rightSide, v);
return StackValue.none(); return StackValue.none();
} }
@@ -3217,8 +3215,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
Type type = expressionType(expression.getBaseExpression()); Type type = expressionType(expression.getBaseExpression());
StackValue value = genLazy(expression.getBaseExpression(), type); StackValue value = gen(expression.getBaseExpression());
return StackValue.preIncrement(type, value, -1, callable, resolvedCall, this); return StackValue.preIncrement(type, value, -1, callable, resolvedCall, this);
} }
@@ -3314,14 +3311,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (initializer == null) { if (initializer == null) {
return StackValue.none(); return StackValue.none();
} }
initializeLocalVariable(property, new Function<VariableDescriptor, Void>() { initializeLocalVariable(property, gen(initializer));
@Override
public Void fun(VariableDescriptor descriptor) {
Type varType = asmType(descriptor.getType());
gen(initializer, varType);
return null;
}
});
return StackValue.none(); return StackValue.none();
} }
@@ -3344,17 +3334,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
final StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType); final StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
for (final JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) { for (final JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
initializeLocalVariable(variableDeclaration, new Function<VariableDescriptor, Void>() { ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration);
@Override assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
public Void fun(VariableDescriptor descriptor) { Call call = makeFakeCall(initializerAsReceiver);
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration); initializeLocalVariable(variableDeclaration, invokeFunction(call, resolvedCall, local));
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
Call call = makeFakeCall(initializerAsReceiver);
StackValue result = invokeFunction(call, resolvedCall, local);
result.put(result.type, v);
return null;
}
});
} }
if (initializerAsmType.getSort() == Type.OBJECT || initializerAsmType.getSort() == Type.ARRAY) { if (initializerAsmType.getSort() == Type.OBJECT || initializerAsmType.getSort() == Type.ARRAY) {
@@ -3368,7 +3351,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private void initializeLocalVariable( private void initializeLocalVariable(
@NotNull JetVariableDeclaration variableDeclaration, @NotNull JetVariableDeclaration variableDeclaration,
@NotNull Function<VariableDescriptor, Void> generateInitializer @NotNull StackValue initializer
) { ) {
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, variableDeclaration); VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, variableDeclaration);
@@ -3386,24 +3369,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type varType = asmType(variableDescriptor.getType()); Type varType = asmType(variableDescriptor.getType());
StackValue storeTo;
// SCRIPT: Variable at the top of the script is generated as field // SCRIPT: Variable at the top of the script is generated as field
if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) {
generateInitializer.fun(variableDescriptor);
JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration); JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration);
assert scriptPsi != null; assert scriptPsi != null;
Type scriptClassType = asmTypeForScriptPsi(bindingContext, scriptPsi); Type scriptClassType = asmTypeForScriptPsi(bindingContext, scriptPsi);
v.putfield(scriptClassType.getInternalName(), variableDeclaration.getName(), varType.getDescriptor()); storeTo = StackValue.field(varType, scriptClassType, variableDeclaration.getName(), false, StackValue.thiz());
} }
else if (sharedVarType == null) { else if (sharedVarType == null) {
generateInitializer.fun(variableDescriptor); storeTo = StackValue.local(index, varType);
v.store(index, varType);
} }
else { else {
v.load(index, OBJECT_TYPE); storeTo = StackValue.shared(index, varType);
generateInitializer.fun(variableDescriptor);
v.putfield(sharedVarType.getInternalName(), "element",
sharedVarType.equals(OBJECT_REF_TYPE) ? "Ljava/lang/Object;" : varType.getDescriptor());
} }
storeTo.store(initializer, v);
} }
@NotNull @NotNull
@@ -3547,7 +3528,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
else { else {
elementType = correctElementType(arrayType); elementType = correctElementType(arrayType);
} }
StackValue arrayValue = genLazy(array, arrayType); StackValue arrayValue = gen(array);
StackValue index = genLazy(indices.get(0), Type.INT_TYPE); StackValue index = genLazy(indices.get(0), Type.INT_TYPE);
return StackValue.arrayElement(elementType, arrayValue, index); return StackValue.arrayElement(elementType, arrayValue, index);
@@ -663,9 +663,7 @@ public class FunctionCodegen extends ParentCodegenAware {
Label loadArg = new Label(); Label loadArg = new Label();
iv.ifeq(loadArg); iv.ifeq(loadArg);
loadStrategy.putValueOnStack(parameterDescriptor, codegen); StackValue.local(parameterIndex, type).store(loadStrategy.genValue(parameterDescriptor, codegen), iv);
iv.store(parameterIndex, type);
iv.mark(loadArg); iv.mark(loadArg);
} }
@@ -795,14 +795,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
context.intoFunction(function), methodSignature, function, OwnerKind.IMPLEMENTATION, context.intoFunction(function), methodSignature, function, OwnerKind.IMPLEMENTATION,
new DefaultParameterValueLoader() { new DefaultParameterValueLoader() {
@Override @Override
public void putValueOnStack(ValueParameterDescriptor valueParameter, ExpressionCodegen codegen) { public StackValue genValue(ValueParameterDescriptor valueParameter, ExpressionCodegen codegen) {
assert KotlinBuiltIns.getInstance().isData((ClassDescriptor) function.getContainingDeclaration()) assert KotlinBuiltIns.getInstance().isData((ClassDescriptor) function.getContainingDeclaration())
: "Function container should be annotated with [data]: " + function; : "Function container should be annotated with [data]: " + function;
PropertyDescriptor property = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter); PropertyDescriptor property = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter);
assert property != null : "Copy function doesn't correspond to any property: " + function; assert property != null : "Copy function doesn't correspond to any property: " + function;
Type propertyType = typeMapper.mapType(property); return codegen.intermediateValueForProperty(property, false, null, StackValue.thiz());
codegen.intermediateValueForProperty(property, false, null, StackValue.thiz())
.put(propertyType, codegen.v);
} }
}, },
null null
@@ -1270,8 +1268,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DelegationFieldsInfo.Field fieldInfo = fieldsInfo.getInfo(specifier); DelegationFieldsInfo.Field fieldInfo = fieldsInfo.getInfo(specifier);
if (fieldInfo.generateField) { if (fieldInfo.generateField) {
iv.load(0, classAsmType); iv.load(0, classAsmType);
StackValue rightSide = codegen.genLazy(expression, codegen.expressionType(expression)); fieldInfo.getStackValue().store(codegen.gen(expression), iv);
fieldInfo.getStackValue().store(rightSide, iv);
} }
} }
@@ -236,16 +236,9 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
JetExpression initializer = property.getDelegateExpressionOrInitializer(); JetExpression initializer = property.getDelegateExpressionOrInitializer();
assert initializer != null : "shouldInitializeProperty must return false if initializer is null"; assert initializer != null : "shouldInitializeProperty must return false if initializer is null";
JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER, StackValue.thiz()); StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER, StackValue.thiz());
Type type = codegen.expressionType(initializer); propValue.store(codegen.gen(initializer), codegen.v);
if (jetType.isNullable()) {
type = boxType(type);
}
propValue.store(codegen.genLazy(initializer, type), codegen.v);
ResolvedCall<FunctionDescriptor> pdResolvedCall = ResolvedCall<FunctionDescriptor> pdResolvedCall =
bindingContext.get(BindingContext.DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor); bindingContext.get(BindingContext.DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor);
@@ -694,6 +694,11 @@ public abstract class StackValue implements IStackValue {
v.astore(this.type); v.astore(this.type);
} }
@Override
public int receiverSize() {
return 2;
}
@Override @Override
public void putNoReceiver( public void putNoReceiver(
@NotNull Type type, @NotNull InstructionAdapter v @NotNull Type type, @NotNull InstructionAdapter v
@@ -118,7 +118,7 @@ public class TailRecursionCodegen {
} }
else if (arg instanceof DefaultValueArgument) { else if (arg instanceof DefaultValueArgument) {
AsmUtil.pop(v, type); AsmUtil.pop(v, type);
DefaultParameterValueLoader.DEFAULT.putValueOnStack(parameterDescriptor, codegen); DefaultParameterValueLoader.DEFAULT.genValue(parameterDescriptor, codegen).put(type, v);
} }
else if (arg instanceof VarargValueArgument) { else if (arg instanceof VarargValueArgument) {
// assign the parameter below // assign the parameter below
@@ -45,14 +45,14 @@ public class IdentityEquals extends IntrinsicMethod {
StackValue left; StackValue left;
StackValue right; StackValue right;
if (element instanceof JetCallExpression) { if (element instanceof JetCallExpression) {
left = StackValue.coercion(receiver, OBJECT_TYPE); left = receiver;
right = codegen.genLazy(arguments.get(0), OBJECT_TYPE); right = codegen.gen(arguments.get(0));
} }
else { else {
assert element instanceof JetBinaryExpression; assert element instanceof JetBinaryExpression;
JetBinaryExpression e = (JetBinaryExpression) element; JetBinaryExpression e = (JetBinaryExpression) element;
left = codegen.genLazy(e.getLeft(), OBJECT_TYPE); left = codegen.gen(e.getLeft());
right = codegen.genLazy(e.getRight(), OBJECT_TYPE); right = codegen.gen(e.getRight());
} }
StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right).put(returnType, v); StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right).put(returnType, v);
return returnType; return returnType;