use of org.jetbrains.org.objectweb.asm.Type in project kotlin by JetBrains.
the class ExpressionCodegen method pushClosureOnStack.
public void pushClosureOnStack(@NotNull ClassDescriptor classDescriptor, boolean putThis, @NotNull CallGenerator callGenerator, @Nullable StackValue functionReferenceReceiver) {
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
if (closure == null)
return;
int paramIndex = 0;
if (putThis) {
ClassDescriptor captureThis = closure.getCaptureThis();
if (captureThis != null) {
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
}
}
KotlinType captureReceiver = closure.getCaptureReceiverType();
if (captureReceiver != null) {
StackValue capturedReceiver = functionReferenceReceiver != null ? functionReferenceReceiver : generateExtensionReceiver(unwrapOriginalReceiverOwnerForSuspendFunction(context));
callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
}
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closure.getCaptureVariables().entrySet()) {
Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
if (sharedVarType == null) {
sharedVarType = typeMapper.mapType((VariableDescriptor) entry.getKey());
}
StackValue capturedVar = lookupOuterValue(entry.getValue());
callGenerator.putCapturedValueOnStack(capturedVar, sharedVarType, paramIndex++);
}
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassNotAny(classDescriptor);
if (superClass != null) {
pushClosureOnStack(superClass, putThis && closure.getCaptureThis() == null, callGenerator, /* functionReferenceReceiver = */
null);
}
if (closure.isSuspend()) {
// resultContinuation
if (closure.isSuspendLambda()) {
v.aconst(null);
} else {
assert context.getFunctionDescriptor().isSuspend() : "Coroutines closure must be created only inside suspend functions";
ValueParameterDescriptor continuationParameter = CollectionsKt.last(context.getFunctionDescriptor().getValueParameters());
StackValue continuationValue = findLocalOrCapturedValue(continuationParameter);
assert continuationValue != null : "Couldn't find a value for continuation parameter of " + context.getFunctionDescriptor();
callGenerator.putCapturedValueOnStack(continuationValue, continuationValue.type, paramIndex++);
}
}
}
use of org.jetbrains.org.objectweb.asm.Type in project kotlin by JetBrains.
the class ExpressionCodegen method generateSafeQualifiedExpression.
private StackValue generateSafeQualifiedExpression(@NotNull KtSafeQualifiedExpression expression, @NotNull Label ifNull) {
KtExpression receiver = expression.getReceiverExpression();
KtExpression selector = expression.getSelectorExpression();
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.SafeCall(receiverType, receiverValue, isPrimitive(receiverType) ? null : ifNull);
return genQualified(newReceiver, selector);
}
use of org.jetbrains.org.objectweb.asm.Type in project kotlin by JetBrains.
the class ExpressionCodegen method returnExpression.
public void returnExpression(KtExpression expr) {
boolean isBlockedNamedFunction = expr instanceof KtBlockExpression && expr.getParent() instanceof KtNamedFunction;
FunctionDescriptor originalSuspendLambdaDescriptor = getOriginalSuspendLambdaDescriptorFromContext(context);
boolean isVoidCoroutineLambda = originalSuspendLambdaDescriptor != null && TypeSignatureMappingKt.hasVoidReturnType(originalSuspendLambdaDescriptor);
// If generating body for named block-bodied function or Unit-typed coroutine lambda, generate it as sequence of statements
Type typeForExpression = isBlockedNamedFunction || isVoidCoroutineLambda ? Type.VOID_TYPE : returnType;
gen(expr, typeForExpression);
// because if we don't there can be VerifyError (specific cases with Nothing-typed expressions)
if (!endsWithReturn(expr)) {
markLineNumber(expr, true);
if (isLambdaVoidBody(expr, typeForExpression)) {
markLineNumber((KtFunctionLiteral) expr.getParent(), true);
}
if (typeForExpression.getSort() == Type.VOID) {
StackValue.none().put(returnType, v);
}
v.areturn(returnType);
}
}
use of org.jetbrains.org.objectweb.asm.Type in project kotlin by JetBrains.
the class ExpressionCodegen method visitDestructuringDeclaration.
@Override
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
KtExpression initializer = multiDeclaration.getInitializer();
if (initializer == null)
return StackValue.none();
KotlinType initializerType = bindingContext.getType(initializer);
assert initializerType != null;
Type initializerAsmType = asmType(initializerType);
TransientReceiver initializerAsReceiver = new TransientReceiver(initializerType);
int tempVarIndex = myFrameMap.enterTemp(initializerAsmType);
gen(initializer, initializerAsmType);
v.store(tempVarIndex, initializerAsmType);
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
initializeDestructuringDeclarationVariables(multiDeclaration, initializerAsReceiver, local);
if (initializerAsmType.getSort() == Type.OBJECT || initializerAsmType.getSort() == Type.ARRAY) {
v.aconst(null);
v.store(tempVarIndex, initializerAsmType);
}
myFrameMap.leaveTemp(initializerAsmType);
return StackValue.none();
}
use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.
the class EnumPropertyCodeGenerator method generatePushValue.
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
final Type enumType = Type.getType(value.getClass());
generator.getStatic(enumType, value.toString(), enumType);
}
Aggregations