use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class MemberCodegen method generatePropertyMetadataArrayFieldIfNeeded.
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
List<KtProperty> delegatedProperties = new ArrayList<KtProperty>();
for (KtDeclaration declaration : ((KtDeclarationContainer) element).getDeclarations()) {
if (declaration instanceof KtProperty) {
KtProperty property = (KtProperty) declaration;
if (property.hasDelegate()) {
delegatedProperties.add(property);
}
}
}
if (delegatedProperties.isEmpty())
return;
v.newField(NO_ORIGIN, ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, "[" + K_PROPERTY_TYPE, null, null);
if (!state.getClassBuilderMode().generateBodies)
return;
InstructionAdapter iv = createOrGetClInitCodegen().v;
iv.iconst(delegatedProperties.size());
iv.newarray(K_PROPERTY_TYPE);
for (int i = 0, size = delegatedProperties.size(); i < size; i++) {
PropertyDescriptor property = (PropertyDescriptor) BindingContextUtils.getNotNull(bindingContext, VARIABLE, delegatedProperties.get(i));
iv.dup();
iv.iconst(i);
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) + (property.getExtensionReceiverParameter() != null ? 1 : 0);
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
iv.anew(implType);
iv.dup();
// TODO: generate the container once and save to a local field instead (KT-10495)
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
iv.aconst(property.getName().asString());
PropertyReferenceCodegen.generateCallableReferenceSignature(iv, property, state);
iv.invokespecial(implType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false);
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
iv.astore(K_PROPERTY_TYPE);
}
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, "[" + K_PROPERTY_TYPE);
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class FunctionCodegen method generateDelegateForDefaultImpl.
private void generateDelegateForDefaultImpl(@NotNull final FunctionDescriptor functionDescriptor, @Nullable PsiElement element) {
Method defaultImplMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.DEFAULT_IMPLS);
CodegenUtilKt.generateMethod(v, "Default Impl delegate in interface", Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, new Method(defaultImplMethod.getName() + JvmAbi.DEFAULT_IMPLS_DELEGATE_SUFFIX, defaultImplMethod.getDescriptor()), element, JvmDeclarationOrigin.NO_ORIGIN, state, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
Method interfaceMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.IMPLEMENTATION);
Type type = typeMapper.mapOwner(functionDescriptor);
generateDelegateToMethodBody(-1, adapter, interfaceMethod, type.getInternalName(), Opcodes.INVOKESPECIAL, true);
return null;
}
});
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class FunctionCodegen method generateDefaultImplBody.
public static void generateDefaultImplBody(@NotNull MethodContext methodContext, @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodVisitor mv, @NotNull DefaultParameterValueLoader loadStrategy, @Nullable KtNamedFunction function, @NotNull MemberCodegen<?> parentCodegen, @NotNull Method defaultMethod) {
GenerationState state = parentCodegen.state;
JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
FrameMap frameMap = createFrameMap(state, functionDescriptor, signature, isStatic);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
CallGenerator generator = codegen.getOrCreateCallGeneratorForDefaultImplBody(functionDescriptor, function);
InstructionAdapter iv = new InstructionAdapter(mv);
genDefaultSuperCallCheckIfNeeded(iv, functionDescriptor, defaultMethod);
List<JvmMethodParameterSignature> mappedParameters = signature.getValueParameters();
int capturedArgumentsCount = 0;
while (capturedArgumentsCount < mappedParameters.size() && mappedParameters.get(capturedArgumentsCount).getKind() != JvmMethodParameterKind.VALUE) {
capturedArgumentsCount++;
}
int maskIndex = 0;
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
for (int index = 0; index < valueParameters.size(); index++) {
if (index % Integer.SIZE == 0) {
maskIndex = frameMap.enterTemp(Type.INT_TYPE);
}
ValueParameterDescriptor parameterDescriptor = valueParameters.get(index);
Type type = mappedParameters.get(capturedArgumentsCount + index).getAsmType();
int parameterIndex = frameMap.getIndex(parameterDescriptor);
if (parameterDescriptor.declaresDefaultValue()) {
iv.load(maskIndex, Type.INT_TYPE);
iv.iconst(1 << (index % Integer.SIZE));
iv.and(Type.INT_TYPE);
Label loadArg = new Label();
iv.ifeq(loadArg);
StackValue.local(parameterIndex, type).store(loadStrategy.genValue(parameterDescriptor, codegen), iv);
iv.mark(loadArg);
}
}
// load arguments after defaults generation to avoid redundant stack normalization operations
loadExplicitArgumentsOnStack(OBJECT_TYPE, isStatic, signature, generator);
for (int index = 0; index < valueParameters.size(); index++) {
ValueParameterDescriptor parameterDescriptor = valueParameters.get(index);
Type type = mappedParameters.get(capturedArgumentsCount + index).getAsmType();
int parameterIndex = frameMap.getIndex(parameterDescriptor);
generator.putValueIfNeeded(type, StackValue.local(parameterIndex, type));
}
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
generator.genCall(method, null, false, codegen);
iv.areturn(signature.getReturnType());
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class ExpressionCodegen method visitPostfixExpression.
@Override
public StackValue visitPostfixExpression(@NotNull final KtPostfixExpression expression, StackValue receiver) {
if (expression.getOperationReference().getReferencedNameElementType() == KtTokens.EXCLEXCL) {
final StackValue base = genQualified(receiver, expression.getBaseExpression());
if (isPrimitive(base.type)) {
return base;
} else {
return StackValue.operation(base.type, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
base.put(base.type, v);
v.dup();
Label ok = new Label();
v.ifnonnull(ok);
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false);
v.mark(ok);
return null;
}
});
}
}
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
String originalOperationName = originalOperation != null ? originalOperation.getName().asString() : null;
final ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext);
DeclarationDescriptor op = resolvedCall.getResultingDescriptor();
if (!(op instanceof FunctionDescriptor) || originalOperation == null) {
throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + originalOperationName + " " + op);
}
final Type asmResultType = expressionType(expression);
final Type asmBaseType = expressionType(expression.getBaseExpression());
DeclarationDescriptor cls = op.getContainingDeclaration();
final int increment;
if (originalOperationName.equals("inc")) {
increment = 1;
} else if (originalOperationName.equals("dec")) {
increment = -1;
} else {
throw new UnsupportedOperationException("Unsupported postfix operation: " + originalOperationName + " " + op);
}
final boolean isPrimitiveNumberClassDescriptor = isPrimitiveNumberClassDescriptor(cls);
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
KtExpression operand = expression.getBaseExpression();
// Optimization for j = i++, when j and i are Int without any smart cast: we just work with primitive int
if (operand instanceof KtReferenceExpression && asmResultType == Type.INT_TYPE && bindingContext.get(BindingContext.SMARTCAST, operand) == null) {
int index = indexOfLocalNotDelegated((KtReferenceExpression) operand);
if (index >= 0) {
return StackValue.postIncrement(index, increment);
}
}
}
return StackValue.operation(asmBaseType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
value.put(asmBaseType, v);
AsmUtil.dup(v, asmBaseType);
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
previousValue.store(StackValue.onStack(asmBaseType), v);
Type storeType;
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
genIncrement(asmBaseType, increment, v);
storeType = asmBaseType;
} else {
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
result.put(result.type, v);
storeType = result.type;
}
value.store(StackValue.onStack(storeType), v, true);
previousValue.put(asmBaseType, v);
myFrameMap.leaveTemp(asmBaseType);
return Unit.INSTANCE;
}
});
}
use of org.jetbrains.org.objectweb.asm.commons.InstructionAdapter in project kotlin by JetBrains.
the class ExpressionCodegen method generateIfExpression.
/* package */
StackValue generateIfExpression(@NotNull final KtIfExpression expression, final boolean isStatement) {
final Type asmType = isStatement ? Type.VOID_TYPE : expressionTypeForBranchingOperation(expression);
final StackValue condition = gen(expression.getCondition());
final KtExpression thenExpression = expression.getThen();
final KtExpression elseExpression = expression.getElse();
if (isEmptyExpression(thenExpression)) {
if (isEmptyExpression(elseExpression)) {
return StackValue.coercion(condition, asmType);
}
return generateSingleBranchIf(condition, expression, elseExpression, false, isStatement);
} else {
if (isEmptyExpression(elseExpression)) {
return generateSingleBranchIf(condition, expression, thenExpression, true, isStatement);
}
}
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
Label elseLabel = new Label();
BranchedValue.Companion.condJump(condition, elseLabel, true, v);
Label end = new Label();
gen(thenExpression, asmType);
v.goTo(end);
v.mark(elseLabel);
gen(elseExpression, asmType);
markLineNumber(expression, isStatement);
v.mark(end);
return Unit.INSTANCE;
}
});
}
Aggregations