@Override public StackValue innerValue( DeclarationDescriptor d, LocalLookup localLookup, GenerationState state, MutableClosure closure, Type classType) { VariableDescriptor vd = (VariableDescriptor) d; boolean idx = localLookup != null && localLookup.lookupLocal(vd); if (!idx) return null; Type sharedVarType = state.getTypeMapper().getSharedVarType(vd); Type localType = state.getTypeMapper().mapType(vd); Type type = sharedVarType != null ? sharedVarType : localType; String fieldName = "$" + vd.getName(); StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, classType, fieldName) : StackValue.field(type, classType, fieldName, false); closure.recordField(fieldName, type); closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, type)); return innerValue; }
@Override public StackValue innerValue( DeclarationDescriptor d, LocalLookup localLookup, GenerationState state, MutableClosure closure, Type classType) { FunctionDescriptor vd = (FunctionDescriptor) d; boolean idx = localLookup != null && localLookup.lookupLocal(vd); if (!idx) return null; BindingContext bindingContext = state.getBindingContext(); Type localType = asmTypeForAnonymousClass(bindingContext, vd); MutableClosure localFunClosure = bindingContext.get(CLOSURE, bindingContext.get(CLASS_FOR_FUNCTION, vd)); 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); } String fieldName = "$" + vd.getName(); StackValue innerValue = StackValue.field(localType, classType, fieldName, false); closure.recordField(fieldName, localType); closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType)); return innerValue; }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.arraylength(); v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;"); return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE); }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { JetCallExpression call = (JetCallExpression) element; ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); Type type = state .getInjector() .getJetTypeMapper() .mapType( resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type); if (primitiveType != null) { v.getstatic( primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;"); } else { v.aconst(type); } return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE); }
@NotNull @Override public StackValue outerValue( @NotNull EnclosedValueDescriptor d, @NotNull ExpressionCodegen codegen) { CallableDescriptor descriptor = (CallableDescriptor) d.getDescriptor(); return StackValue.local(descriptor.getExpectedThisObject() != null ? 1 : 0, d.getType()); }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { if (arguments.size() == 1) { final Type leftType = receiver.type; final Type rightType = codegen.expressionType(arguments.get(0)); receiver.put(Type.INT_TYPE, v); codegen.gen(arguments.get(0), rightType); v.invokestatic( "jet/runtime/Ranges", forward ? "upTo" : "downTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); } else { JetBinaryExpression expression = (JetBinaryExpression) element; final Type leftType = codegen.expressionType(expression.getLeft()); final Type rightType = codegen.expressionType(expression.getRight()); // if (JetTypeMapper.isIntPrimitive(leftType)) { codegen.gen(expression.getLeft(), leftType); codegen.gen(expression.getRight(), rightType); v.invokestatic( "jet/runtime/Ranges", forward ? "upTo" : "downTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); // } // else { // throw new UnsupportedOperationException("ranges are only supported for int // objects"); // } } }
@NotNull public StackValue outerValue( @NotNull EnclosedValueDescriptor d, @NotNull ExpressionCodegen codegen) { int idx = codegen.lookupLocalIndex(d.getDescriptor()); assert idx != -1; return StackValue.local(idx, d.getType()); }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(receiver.type); if (primitiveType != null) { v.getstatic( primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;"); } else { receiver.put(receiver.type, v); v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;"); } return StackValue.onStack(AsmTypeConstants.getType(Class.class)); }
@NotNull @Override public Type generateImpl( @NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter v, @NotNull Type returnType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { StackValue stackValue; if (arguments.size() == 1) { stackValue = codegen.gen(arguments.get(0)); } else { stackValue = receiver; } stackValue.put(Type.BOOLEAN_TYPE, v); StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(returnType, v); return returnType; }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = JetTypeMapper.unboxType(expectedType); } if (receiver != null && receiver != StackValue.none()) receiver.put(expectedType, v); else { assert arguments != null; codegen.gen(arguments.get(0), expectedType); } return StackValue.onStack(expectedType); }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { receiver.put(AsmTypeConstants.OBJECT_TYPE, v); JetCallExpression call = (JetCallExpression) element; FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen .getBindingContext() .get( BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression()); assert funDescriptor != null; ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal(); if (containingDeclaration.equals(JetStandardLibrary.getInstance().getArray())) { v.invokestatic( "jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;"); return StackValue.onStack(AsmTypeConstants.JET_ITERATOR_TYPE); } else { for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); if (primitiveType.getArrayClassName().is(containingDeclaration)) { String methodSignature = "([" + jvmPrimitiveType.getJvmLetter() + ")" + jvmPrimitiveType.getIterator().getDescriptor(); v.invokestatic("jet/runtime/ArrayIterator", "iterator", methodSignature); return StackValue.onStack(jvmPrimitiveType.getIterator().getAsmType()); } } throw new UnsupportedOperationException(containingDeclaration.toString()); } }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = CodegenUtil.unboxType(expectedType); } receiver.put(expectedType, v); if (expectedType == Type.LONG_TYPE) { v.lconst(-1L); } else { v.iconst(-1); } v.xor(expectedType); return StackValue.onStack(expectedType); }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { final CallableMethod callableMethod = state.getTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION); codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver); return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType()); }
@Override public StackValue innerValue( DeclarationDescriptor d, LocalLookup enclosingLocalLookup, GenerationState state, MutableClosure closure, Type classType) { if (closure.getEnclosingReceiverDescriptor() != d) return null; JetType receiverType = ((CallableDescriptor) d).getReceiverParameter().getType(); Type type = state.getTypeMapper().mapType(receiverType); StackValue innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false); closure.setCaptureReceiver(); return innerValue; }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { boolean leftNullable = true; JetExpression rightExpr; if (element instanceof JetCallExpression) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); JetCallExpression jetCallExpression = (JetCallExpression) element; JetExpression calleeExpression = jetCallExpression.getCalleeExpression(); if (calleeExpression != null) { JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression); if (leftType != null) leftNullable = leftType.isNullable(); } rightExpr = arguments.get(0); } else { JetExpression leftExpr = arguments.get(0); leftNullable = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, leftExpr).isNullable(); codegen.gen(leftExpr).put(JetTypeMapper.TYPE_OBJECT, v); rightExpr = arguments.get(1); } JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr); codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v); return codegen.generateEqualsForExpressionsOnStack( JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, rightType.isNullable()); }